Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / support / stdio.c
1 /*
2  * <stdio.h> wrapper functions.
3  *
4  * Authors:
5  *   Jonathan Pryor (jonpryor@vt.edu)
6  *
7  * Copyright (C) 2004-2006 Jonathan Pryor
8  */
9
10 #include <stdarg.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13
14 #include "map.h"
15 #include "mph.h"
16
17 G_BEGIN_DECLS
18
19 gint32
20 Mono_Posix_Syscall_L_ctermid (void)
21 {
22 #ifndef HOST_WIN32
23         return L_ctermid;
24 #else
25         return -1;
26 #endif
27 }
28
29 gint32
30 Mono_Posix_Syscall_L_cuserid (void)
31 {
32 #if defined(__APPLE__) || defined (__OpenBSD__) || defined (HOST_WIN32)
33         return -1;
34 #else
35         return L_cuserid;
36 #endif
37 }
38
39 mph_size_t
40 Mono_Posix_Stdlib_fread (unsigned char *ptr, mph_size_t size, mph_size_t nmemb, void *stream)
41 {
42         mph_return_if_size_t_overflow (size);
43         mph_return_if_size_t_overflow (nmemb);
44
45         return fread (ptr, (size_t) size, (size_t) nmemb, (FILE*) stream);
46 }
47
48 mph_size_t
49 Mono_Posix_Stdlib_fwrite (unsigned char *ptr, mph_size_t size, mph_size_t nmemb, void *stream)
50 {
51         mph_return_if_size_t_overflow (size);
52         mph_return_if_size_t_overflow (nmemb);
53
54         size_t ret = fwrite (ptr, (size_t) size, (size_t) nmemb, (FILE*) stream);
55 #ifdef HOST_WIN32
56         // Workaround for a particular weirdness on Windows triggered by the
57         // StdioFileStreamTest.Write() test method. The test writes 15 bytes to a
58         // file, then rewinds the file pointer and reads the same bytes. It then
59         // writes 15 additional bytes to the file. This second write fails on
60         // Windows with 0 returned from fwrite(). Calling fseek() followed by a retry
61         // of fwrite() like we do here fixes the issue.
62         if (ret != nmemb)
63         {
64                 fseek (stream, 0, SEEK_CUR);
65                 ret = fwrite (ptr + (ret * nmemb), (size_t) size, (size_t) nmemb - ret, (FILE*) stream);
66         }
67 #endif
68         return ret;
69 }
70
71 #ifdef HAVE_VSNPRINTF
72 gint32
73 Mono_Posix_Stdlib_snprintf (char *s, mph_size_t n, char *format, ...);
74 gint32
75 Mono_Posix_Stdlib_snprintf (char *s, mph_size_t n, char *format, ...)
76 {
77         va_list ap;
78         gint32 r;
79         mph_return_if_size_t_overflow (n);
80
81         va_start (ap, format);
82         r = vsnprintf (s, (size_t) n, format, ap);
83         va_end (ap);
84
85         return r;
86 }
87 #endif /* def HAVE_VSNPRINTF */
88
89 gint32
90 Mono_Posix_Stdlib__IOFBF (void)
91 {
92         return _IOFBF;
93 }
94
95 gint32
96 Mono_Posix_Stdlib__IOLBF (void)
97 {
98         return _IOLBF;
99 }
100
101 gint32
102 Mono_Posix_Stdlib__IONBF (void)
103 {
104         return _IONBF;
105 }
106
107 gint32
108 Mono_Posix_Stdlib_BUFSIZ (void)
109 {
110         return BUFSIZ;
111 }
112
113 gint32
114 Mono_Posix_Stdlib_EOF (void)
115 {
116         return EOF;
117 }
118
119 gint32
120 Mono_Posix_Stdlib_FOPEN_MAX (void)
121 {
122         return FOPEN_MAX;
123 }
124
125 gint32
126 Mono_Posix_Stdlib_FILENAME_MAX (void)
127 {
128         return FILENAME_MAX;
129 }
130
131 gint32
132 Mono_Posix_Stdlib_L_tmpnam (void)
133 {
134         return L_tmpnam;
135 }
136
137 void*
138 Mono_Posix_Stdlib_stdin (void)
139 {
140         return stdin;
141 }
142
143 void*
144 Mono_Posix_Stdlib_stdout (void)
145 {
146         return stdout;
147 }
148
149 void*
150 Mono_Posix_Stdlib_stderr (void)
151 {
152         return stderr;
153 }
154
155 gint32
156 Mono_Posix_Stdlib_TMP_MAX (void)
157 {
158         return TMP_MAX;
159 }
160
161 void*
162 Mono_Posix_Stdlib_tmpfile (void)
163 {
164         return tmpfile ();
165 }
166
167 gint32
168 Mono_Posix_Stdlib_setvbuf (void* stream, void *buf, int mode, mph_size_t size)
169 {
170         mph_return_if_size_t_overflow (size);
171         return setvbuf (stream, (char *) buf, mode, (size_t) size);
172 }
173
174 int 
175 Mono_Posix_Stdlib_setbuf (void* stream, void* buf)
176 {
177         setbuf (stream, buf);
178         return 0;
179 }
180
181 void*
182 Mono_Posix_Stdlib_fopen (char* path, char* mode)
183 {
184         return fopen (path, mode);
185 }
186
187 void*
188 Mono_Posix_Stdlib_freopen (char* path, char* mode, void *stream)
189 {
190         return freopen (path, mode, stream);
191 }
192
193 gint32
194 Mono_Posix_Stdlib_fprintf (void* stream, char* format, char *message)
195 {
196         return fprintf (stream, format, message);
197 }
198
199 gint32
200 Mono_Posix_Stdlib_fgetc (void* stream)
201 {
202         return fgetc (stream);
203 }
204
205 char*
206 Mono_Posix_Stdlib_fgets (char* str, gint32 size, void* stream)
207 {
208         return fgets (str, size, stream);
209 }
210
211 gint32
212 Mono_Posix_Stdlib_fputc (gint32 c, void* stream)
213 {
214         return fputc (c, stream);
215 }
216
217 gint32
218 Mono_Posix_Stdlib_fputs (char* s, void* stream)
219 {
220         return fputs (s, stream);
221 }
222
223 gint32
224 Mono_Posix_Stdlib_fclose (void* stream)
225 {
226         return fclose (stream);
227 }
228
229 gint32
230 Mono_Posix_Stdlib_fflush (void* stream)
231 {
232         return fflush (stream);
233 }
234
235 gint32
236 Mono_Posix_Stdlib_fseek (void* stream, gint64 offset, int origin)
237 {
238         mph_return_if_long_overflow (offset);
239
240         return fseek (stream, offset, origin);
241 }
242
243 gint64
244 Mono_Posix_Stdlib_ftell (void* stream)
245 {
246         return ftell (stream);
247 }
248
249 void*
250 Mono_Posix_Stdlib_CreateFilePosition (void)
251 {
252         fpos_t* pos = malloc (sizeof(fpos_t));
253         return pos;
254 }
255
256 gint32
257 Mono_Posix_Stdlib_fgetpos (void* stream, void *pos)
258 {
259         return fgetpos (stream, (fpos_t*) pos);
260 }
261
262 gint32
263 Mono_Posix_Stdlib_fsetpos (void* stream, void *pos)
264 {
265         return fsetpos (stream, (fpos_t*) pos);
266 }
267
268 int
269 Mono_Posix_Stdlib_rewind (void* stream)
270 {
271         do {
272                 rewind (stream);
273         } while (errno == EINTR);
274         mph_return_if_val_in_list5(errno, EAGAIN, EBADF, EFBIG, EINVAL, EIO);
275         mph_return_if_val_in_list5(errno, ENOSPC, ENXIO, EOVERFLOW, EPIPE, ESPIPE);
276         return 0;
277 }
278
279 int
280 Mono_Posix_Stdlib_clearerr (void* stream)
281 {
282         clearerr (((FILE*) stream));
283         return 0;
284 }
285
286 gint32
287 Mono_Posix_Stdlib_ungetc (gint32 c, void* stream)
288 {
289         return ungetc (c, stream);
290 }
291
292 gint32
293 Mono_Posix_Stdlib_feof (void* stream)
294 {
295         return feof (((FILE*) stream));
296 }
297
298 gint32
299 Mono_Posix_Stdlib_ferror (void* stream)
300 {
301         return ferror (((FILE*) stream));
302 }
303
304 int
305 Mono_Posix_Stdlib_perror (const char* s, int err)
306 {
307         errno = err;
308         perror (s);
309         return 0;
310 }
311
312 #define MPH_FPOS_LENGTH (sizeof(fpos_t)*2)
313
314 int
315 Mono_Posix_Stdlib_DumpFilePosition (char *dest, void *pos, gint32 len)
316 {
317         char *destp;
318         unsigned char *posp, *pose;
319
320         if (dest == NULL)
321                 return MPH_FPOS_LENGTH;
322
323         if (pos == NULL || len <= 0) {
324                 errno = EINVAL;
325                 return -1;
326         }
327
328         posp = (unsigned char*) pos;
329         pose = posp + sizeof(fpos_t);
330         destp = dest;
331
332         for ( ; posp < pose && len > 1; destp += 2, ++posp, len -= 2) {
333                 sprintf (destp, "%02X", *posp);
334         }
335
336         if (len)
337                 dest[MPH_FPOS_LENGTH] = '\0';
338
339         return destp - dest;
340 }
341
342 G_END_DECLS
343
344 /*
345  * vim: noexpandtab
346  */