Merge pull request #601 from knocte/sock_improvements
[mono.git] / support / unistd.c
1 /*
2  * <unistd.h> wrapper functions.
3  *
4  * Authors:
5  *   Jonathan Pryor (jonpryor@vt.edu)
6  *
7  * Copyright (C) 2004-2006 Jonathan Pryor
8  */
9
10 #ifndef _GNU_SOURCE
11 #define _GNU_SOURCE
12 #endif /* ndef _GNU_SOURCE */
13
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <errno.h>
19 #include <limits.h>
20 #include <string.h>     /* for swab(3) on Mac OS X */
21
22 #include "map.h"
23 #include "mph.h"
24
25 G_BEGIN_DECLS
26
27 mph_off_t
28 Mono_Posix_Syscall_lseek (gint32 fd, mph_off_t offset, gint32 whence)
29 {
30         mph_return_if_off_t_overflow (offset);
31
32         return lseek (fd, offset, whence);
33 }
34
35 mph_ssize_t
36 Mono_Posix_Syscall_read (gint32 fd, void *buf, mph_size_t count)
37 {
38         mph_return_if_size_t_overflow (count);
39         return read (fd, buf, (size_t) count);
40 }
41
42 mph_ssize_t
43 Mono_Posix_Syscall_write (gint32 fd, void *buf, mph_size_t count)
44 {
45         mph_return_if_size_t_overflow (count);
46         return write (fd, buf, (size_t) count);
47 }
48
49 mph_ssize_t
50 Mono_Posix_Syscall_pread (gint32 fd, void *buf, mph_size_t count, mph_off_t offset)
51 {
52         mph_return_if_size_t_overflow (count);
53         mph_return_if_off_t_overflow (offset);
54
55         return pread (fd, buf, (size_t) count, (off_t) offset);
56 }
57
58 mph_ssize_t
59 Mono_Posix_Syscall_pwrite (gint32 fd, void *buf, mph_size_t count, mph_off_t offset)
60 {
61         mph_return_if_size_t_overflow (count);
62         mph_return_if_off_t_overflow (offset);
63
64         return pwrite (fd, buf, (size_t) count, (off_t) offset);
65 }
66
67 gint32
68 Mono_Posix_Syscall_pipe (gint32 *reading, gint32 *writing)
69 {
70         int filedes[2] = {-1, -1};
71         int r;
72
73         if (reading == NULL || writing == NULL) {
74                 errno = EFAULT;
75                 return -1;
76         }
77
78         r = pipe (filedes);
79
80         *reading = filedes[0];
81         *writing = filedes[1];
82         return r;
83 }
84
85 void*
86 Mono_Posix_Syscall_getcwd (char *buf, mph_size_t size)
87 {
88         mph_return_val_if_size_t_overflow (size, NULL);
89         return getcwd (buf, (size_t) size);
90 }
91
92 gint64
93 Mono_Posix_Syscall_fpathconf (int filedes, int name, int defaultError)
94 {
95         errno = defaultError;
96         if (Mono_Posix_FromPathconfName (name, &name) == -1)
97                 return -1;
98         return fpathconf (filedes, name);
99 }
100
101 gint64
102 Mono_Posix_Syscall_pathconf (const char *path, int name, int defaultError)
103 {
104         errno = defaultError;
105         if (Mono_Posix_FromPathconfName (name, &name) == -1)
106                 return -1;
107         return pathconf (path, name);
108 }
109
110 gint64
111 Mono_Posix_Syscall_sysconf (int name, int defaultError)
112 {
113         errno = defaultError;
114         if (Mono_Posix_FromSysconfName (name, &name) == -1)
115                 return -1;
116         return sysconf (name);
117 }
118
119 #if HAVE_CONFSTR
120 mph_size_t
121 Mono_Posix_Syscall_confstr (int name, char *buf, mph_size_t len)
122 {
123         mph_return_if_size_t_overflow (len);
124         if (Mono_Posix_FromConfstrName (name, &name) == -1)
125                 return -1;
126         return confstr (name, buf, (size_t) len);
127 }
128 #endif  /* def HAVE_CONFSTR */
129
130 #ifdef HAVE_TTYNAME_R
131 gint32
132 Mono_Posix_Syscall_ttyname_r (int fd, char *buf, mph_size_t len)
133 {
134         mph_return_if_size_t_overflow (len);
135         return ttyname_r (fd, buf, (size_t) len);
136 }
137 #endif /* ndef HAVE_TTYNAME_R */
138
139 gint32
140 Mono_Posix_Syscall_readlink (const char *path, char *buf, mph_size_t len)
141 {
142         int r;
143         mph_return_if_size_t_overflow (len);
144         r = readlink (path, buf, (size_t) len);
145         if (r >= 0 && r < len)
146                 buf [r] = '\0';
147         return r;
148 }
149
150 #ifdef HAVE_READLINKAT
151 gint32
152 Mono_Posix_Syscall_readlinkat (int dirfd, const char *path, char *buf, mph_size_t len)
153 {
154         int r;
155         mph_return_if_size_t_overflow (len);
156         r = readlinkat (dirfd, path, buf, (size_t) len);
157         if (r >= 0 && r < len)
158                 buf [r] = '\0';
159         return r;
160 }
161 #endif /* def HAVE_READLINKAT */
162
163 #if HAVE_GETLOGIN_R
164 gint32
165 Mono_Posix_Syscall_getlogin_r (char *buf, mph_size_t len)
166 {
167         mph_return_if_size_t_overflow (len);
168         return getlogin_r (buf, (size_t) len);
169 }
170 #endif  /* def HAVE_GETLOGIN_R */
171
172 gint32
173 Mono_Posix_Syscall_gethostname (char *buf, mph_size_t len)
174 {
175         mph_return_if_size_t_overflow (len);
176         return gethostname (buf, (size_t) len);
177 }
178
179 #if HAVE_SETHOSTNAME
180 gint32
181 Mono_Posix_Syscall_sethostname (const char *name, mph_size_t len)
182 {
183         mph_return_if_size_t_overflow (len);
184         return sethostname (name, (size_t) len);
185 }
186 #endif  /* def HAVE_SETHOSTNAME */
187
188 #if HAVE_GETHOSTID
189 gint64
190 Mono_Posix_Syscall_gethostid (void)
191 {
192         return gethostid ();
193 }
194 #endif  /* def HAVE_GETHOSTID */
195
196 #ifdef HAVE_SETHOSTID
197 gint32
198 Mono_Posix_Syscall_sethostid (gint64 hostid)
199 {
200         mph_return_if_long_overflow (hostid);
201 #ifdef MPH_ON_BSD
202         sethostid ((long) hostid);
203         return 0;
204 #else
205         return sethostid ((long) hostid);
206 #endif
207 }
208 #endif /* def HAVE_SETHOSTID */
209
210 #ifdef HAVE_GETDOMAINNAME
211 gint32
212 Mono_Posix_Syscall_getdomainname (char *name, mph_size_t len)
213 {
214         mph_return_if_size_t_overflow (len);
215         return getdomainname (name, (size_t) len);
216 }
217 #endif /* def HAVE_GETDOMAINNAME */
218
219 #ifdef HAVE_SETDOMAINNAME
220 gint32
221 Mono_Posix_Syscall_setdomainname (const char *name, mph_size_t len)
222 {
223         mph_return_if_size_t_overflow (len);
224         return setdomainname (name, (size_t) len);
225 }
226 #endif /* def HAVE_SETDOMAINNAME */
227
228 /* Android implements truncate, but doesn't declare it.
229  * Result is a warning during compilation, so skip it.
230  */
231 #ifndef PLATFORM_ANDROID
232 gint32
233 Mono_Posix_Syscall_truncate (const char *path, mph_off_t length)
234 {
235         mph_return_if_off_t_overflow (length);
236         return truncate (path, (off_t) length);
237 }
238 #endif
239
240 gint32
241 Mono_Posix_Syscall_ftruncate (int fd, mph_off_t length)
242 {
243         mph_return_if_off_t_overflow (length);
244         return ftruncate (fd, (off_t) length);
245 }
246
247 #if HAVE_LOCKF
248 gint32
249 Mono_Posix_Syscall_lockf (int fd, int cmd, mph_off_t len)
250 {
251         mph_return_if_off_t_overflow (len);
252         if (Mono_Posix_FromLockfCommand (cmd, &cmd) == -1)
253                 return -1;
254         return lockf (fd, cmd, (off_t) len);
255 }
256 #endif  /* def HAVE_LOCKF */
257
258 #if HAVE_SWAB
259 int
260 Mono_Posix_Syscall_swab (void *from, void *to, mph_ssize_t n)
261 {
262         if (mph_have_long_overflow (n))
263                 return -1;
264         swab (from, to, (ssize_t) n);
265         return 0;
266 }
267 #endif  /* def HAVE_SWAB */
268
269 #if HAVE_SETUSERSHELL
270 int
271 Mono_Posix_Syscall_setusershell (void)
272 {
273         setusershell ();
274         return 0;
275 }
276 #endif  /* def HAVE_SETUSERSHELL */
277
278 #if HAVE_ENDUSERSHELL
279 int
280 Mono_Posix_Syscall_endusershell (void)
281 {
282         endusershell ();
283         return 0;
284 }
285 #endif  /* def HAVE_ENDUSERSHELL */
286
287 int
288 Mono_Posix_Syscall_sync (void)
289 {
290         sync ();
291         return 0;
292 }
293
294
295 G_END_DECLS
296
297 /*
298  * vim: noexpandtab
299  */