Disable sockets and locking when using NACL.
[mono.git] / mono / io-layer / locking.c
1 /*
2  * io.c:  File, console and find handles
3  *
4  * Author:
5  *      Dick Porter (dick@ximian.com)
6  *
7  * (C) 2002 Ximian, Inc.
8  * Copyright (c) 2002-2009 Novell, Inc.
9  */
10 #include <config.h>
11 #include <stdio.h>
12 #include <glib.h>
13 #include <fcntl.h>
14 #include <errno.h>
15 #include <mono/io-layer/wapi.h>
16 #include <mono/io-layer/wapi-private.h>
17 #include <mono/io-layer/handles-private.h>
18 #include <mono/io-layer/io-private.h>
19
20 #define LOGDEBUG(...)
21 //#define LOGDEBUG(...) g_message (__VA_ARGS__)
22
23 gboolean
24 _wapi_lock_file_region (int fd, off_t offset, off_t length)
25 {
26 #if defined(__native_client__)
27         printf("WARNING: locking.c: _wapi_lock_file_region(): fcntl() not available on Native Client!\n");
28         // behave as below -- locks are not available
29         return(TRUE);
30 #else
31         struct flock lock_data;
32         int ret;
33
34         lock_data.l_type = F_WRLCK;
35         lock_data.l_whence = SEEK_SET;
36         lock_data.l_start = offset;
37         lock_data.l_len = length;
38         
39         do {
40                 ret = fcntl (fd, F_SETLK, &lock_data);
41         } while(ret == -1 && errno == EINTR);
42         
43         LOGDEBUG ("%s: fcntl returns %d", __func__, ret);
44
45         if (ret == -1) {
46                 /*
47                  * if locks are not available (NFS for example),
48                  * ignore the error
49                  */
50                 if (errno == ENOLCK
51 #ifdef EOPNOTSUPP
52                     || errno == EOPNOTSUPP
53 #endif
54 #ifdef ENOTSUP
55                     || errno == ENOTSUP
56 #endif
57                    ) {
58                         return (TRUE);
59                 }
60                 
61                 SetLastError (ERROR_LOCK_VIOLATION);
62                 return(FALSE);
63         }
64
65         return(TRUE);
66 #endif /* __native_client__ */
67 }
68
69 gboolean
70 _wapi_unlock_file_region (int fd, off_t offset, off_t length)
71 {
72 #if defined(__native_client__)
73         printf("WARNING: locking.c: _wapi_unlock_file_region(): fcntl() not available on Native Client!\n");
74         return (TRUE);
75 #else
76         struct flock lock_data;
77         int ret;
78
79         lock_data.l_type = F_UNLCK;
80         lock_data.l_whence = SEEK_SET;
81         lock_data.l_start = offset;
82         lock_data.l_len = length;
83         
84         do {
85                 ret = fcntl (fd, F_SETLK, &lock_data);
86         } while(ret == -1 && errno == EINTR);
87         
88         LOGDEBUG ("%s: fcntl returns %d", __func__, ret);
89         
90         if (ret == -1) {
91                 /*
92                  * if locks are not available (NFS for example),
93                  * ignore the error
94                  */
95                 if (errno == ENOLCK
96 #ifdef EOPNOTSUPP
97                     || errno == EOPNOTSUPP
98 #endif
99 #ifdef ENOTSUP
100                     || errno == ENOTSUP
101 #endif
102                    ) {
103                         return (TRUE);
104                 }
105                 
106                 SetLastError (ERROR_LOCK_VIOLATION);
107                 return(FALSE);
108         }
109
110         return(TRUE);
111 #endif /* __native_client__ */
112 }
113
114 gboolean
115 LockFile (gpointer handle, guint32 offset_low, guint32 offset_high,
116           guint32 length_low, guint32 length_high)
117 {
118         struct _WapiHandle_file *file_handle;
119         gboolean ok;
120         off_t offset, length;
121         int fd = GPOINTER_TO_UINT(handle);
122         
123         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
124                                   (gpointer *)&file_handle);
125         if (ok == FALSE) {
126                 g_warning ("%s: error looking up file handle %p", __func__,
127                            handle);
128                 SetLastError (ERROR_INVALID_HANDLE);
129                 return(FALSE);
130         }
131
132         if (!(file_handle->fileaccess & GENERIC_READ) &&
133             !(file_handle->fileaccess & GENERIC_WRITE) &&
134             !(file_handle->fileaccess & GENERIC_ALL)) {
135                 LOGDEBUG ("%s: handle %p doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
136                 SetLastError (ERROR_ACCESS_DENIED);
137                 return(FALSE);
138         }
139
140 #ifdef HAVE_LARGE_FILE_SUPPORT
141         offset = ((gint64)offset_high << 32) | offset_low;
142         length = ((gint64)length_high << 32) | length_low;
143
144         LOGDEBUG ("%s: Locking handle %p, offset %lld, length %lld", __func__, handle, offset, length);
145 #else
146         offset = offset_low;
147         length = length_low;
148
149 #ifdef DEBUG
150         g_message ("%s: Locking handle %p, offset %ld, length %ld", __func__,
151                    handle, offset, length);
152 #endif
153 #endif
154
155         return(_wapi_lock_file_region (fd, offset, length));
156 }
157
158 gboolean
159 UnlockFile (gpointer handle, guint32 offset_low,
160             guint32 offset_high, guint32 length_low,
161             guint32 length_high)
162 {
163         struct _WapiHandle_file *file_handle;
164         gboolean ok;
165         off_t offset, length;
166         int fd = GPOINTER_TO_UINT(handle);
167         
168         ok = _wapi_lookup_handle (handle, WAPI_HANDLE_FILE,
169                                   (gpointer *)&file_handle);
170         if (ok == FALSE) {
171                 g_warning ("%s: error looking up file handle %p", __func__,
172                            handle);
173                 SetLastError (ERROR_INVALID_HANDLE);
174                 return(FALSE);
175         }
176         
177         if (!(file_handle->fileaccess & GENERIC_READ) &&
178             !(file_handle->fileaccess & GENERIC_WRITE) &&
179             !(file_handle->fileaccess & GENERIC_ALL)) {
180                 LOGDEBUG ("%s: handle %p doesn't have GENERIC_READ or GENERIC_WRITE access: %u", __func__, handle, file_handle->fileaccess);
181                 SetLastError (ERROR_ACCESS_DENIED);
182                 return(FALSE);
183         }
184
185 #ifdef HAVE_LARGE_FILE_SUPPORT
186         offset = ((gint64)offset_high << 32) | offset_low;
187         length = ((gint64)length_high << 32) | length_low;
188
189         LOGDEBUG ("%s: Unlocking handle %p, offset %lld, length %lld", __func__, handle, offset, length);
190 #else
191         offset = offset_low;
192         length = length_low;
193
194         LOGDEBUG ("%s: Unlocking handle %p, offset %ld, length %ld", __func__, handle, offset, length);
195 #endif
196
197         return(_wapi_unlock_file_region (fd, offset, length));
198 }