1 /**
2 * D header file for POSIX.
3 *
4 * Copyright: Copyright Sean Kelly 2005 - 2009.
5 * License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 * Authors: Sean Kelly
7 * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8 */
9
10 /* Copyright Sean Kelly 2005 - 2009.
11 * Distributed under the Boost Software License, Version 1.0.
12 * (See accompanying file LICENSE or copy at
13 * http://www.boost.org/LICENSE_1_0.txt)
14 */
15 module core.sys.posix.stdio;
16
17 private import core.sys.posix.config;
18 public import core.stdc.stdio;
19 public import core.sys.posix.sys.types; // for off_t
20
21 version (OSX)
22 version = Darwin;
23 else version (iOS)
24 version = Darwin;
25 else version (TVOS)
26 version = Darwin;
27 else version (WatchOS)
28 version = Darwin;
29
version(Posix)30 version (Posix):
31 extern (C):
32
33 nothrow:
34 @nogc:
35
36 //
37 // Required (defined in core.stdc.stdio)
38 //
39 /*
40 BUFSIZ
41 _IOFBF
42 _IOLBF
43 _IONBF
44 L_tmpnam
45 SEEK_CUR
46 SEEK_END
47 SEEK_SET
48 FILENAME_MAX
49 FOPEN_MAX
50 TMP_MAX
51 EOF
52 NULL
53 stderr
54 stdin
55 stdout
56 FILE
57 fpos_t
58 size_t
59
60 void clearerr(FILE*);
61 int fclose(FILE*);
62 int feof(FILE*);
63 int ferror(FILE*);
64 int fflush(FILE*);
65 int fgetc(FILE*);
66 int fgetpos(FILE*, fpos_t *);
67 char* fgets(char*, int, FILE*);
68 FILE* fopen(in char*, in char*);
69 int fprintf(FILE*, in char*, ...);
70 int fputc(int, FILE*);
71 int fputs(in char*, FILE*);
72 size_t fread(void *, size_t, size_t, FILE*);
73 FILE* freopen(in char*, in char*, FILE*);
74 int fscanf(FILE*, in char*, ...);
75 int fseek(FILE*, c_long, int);
76 int fsetpos(FILE*, in fpos_t*);
77 c_long ftell(FILE*);
78 size_t fwrite(in void *, size_t, size_t, FILE*);
79 int getc(FILE*);
80 int getchar();
81 char* gets(char*);
82 void perror(in char*);
83 int printf(in char*, ...);
84 int putc(int, FILE*);
85 int putchar(int);
86 int puts(in char*);
87 int remove(in char*);
88 int rename(in char*, in char*);
89 void rewind(FILE*);
90 int scanf(in char*, ...);
91 void setbuf(FILE*, char*);
92 int setvbuf(FILE*, char*, int, size_t);
93 int snprintf(char*, size_t, in char*, ...);
94 int sprintf(char*, in char*, ...);
95 int sscanf(in char*, in char*, int ...);
96 FILE* tmpfile();
97 char* tmpnam(char*);
98 int ungetc(int, FILE*);
99 int vfprintf(FILE*, in char*, va_list);
100 int vfscanf(FILE*, in char*, va_list);
101 int vprintf(in char*, va_list);
102 int vscanf(in char*, va_list);
103 int vsnprintf(char*, size_t, in char*, va_list);
104 int vsprintf(char*, in char*, va_list);
105 int vsscanf(in char*, in char*, va_list arg);
106 */
107
108 version (CRuntime_Glibc)
109 {
110 /*
111 * actually, if __USE_FILE_OFFSET64 && !_LARGEFILE64_SOURCE
112 * the *64 functions shouldn't be visible, but the aliases should
113 * still be supported
114 */
115 static if ( __USE_FILE_OFFSET64 )
116 {
117 int fgetpos64(FILE*, fpos_t *);
118 alias fgetpos64 fgetpos;
119
120 FILE* fopen64(in char*, in char*);
121 alias fopen64 fopen;
122
123 FILE* freopen64(in char*, in char*, FILE*);
124 alias freopen64 freopen;
125
126 int fseek(FILE*, c_long, int);
127
128 int fsetpos64(FILE*, in fpos_t*);
129 alias fsetpos64 fsetpos;
130
131 FILE* tmpfile64();
132 alias tmpfile64 tmpfile;
133 }
134 else
135 {
136 int fgetpos(FILE*, fpos_t *);
137 FILE* fopen(in char*, in char*);
138 FILE* freopen(in char*, in char*, FILE*);
139 int fseek(FILE*, c_long, int);
140 int fsetpos(FILE*, in fpos_t*);
141 FILE* tmpfile();
142 }
143 }
version(CRuntime_Bionic)144 else version (CRuntime_Bionic)
145 {
146 int fgetpos(FILE*, fpos_t *);
147 FILE* fopen(in char*, in char*);
148 FILE* freopen(in char*, in char*, FILE*);
149 int fseek(FILE*, c_long, int);
150 int fsetpos(FILE*, in fpos_t*);
151 }
version(CRuntime_UClibc)152 else version (CRuntime_UClibc)
153 {
154 static if ( __USE_FILE_OFFSET64 )
155 {
156 int fgetpos64(FILE*, fpos_t *);
157 alias fgetpos64 fgetpos;
158
159 FILE* fopen64(in char*, in char*);
160 alias fopen64 fopen;
161
162 FILE* freopen64(in char*, in char*, FILE*);
163 alias freopen64 freopen;
164
165 int fseek(FILE*, c_long, int);
166
167 int fsetpos64(FILE*, in fpos_t*);
168 alias fsetpos64 fsetpos;
169
170 FILE* tmpfile64();
171 alias tmpfile64 tmpfile;
172 }
173 else
174 {
175 int fgetpos(FILE*, fpos_t *);
176 FILE* fopen(in char*, in char*);
177 FILE* freopen(in char*, in char*, FILE*);
178 int fseek(FILE*, c_long, int);
179 int fsetpos(FILE*, in fpos_t*);
180 FILE* tmpfile();
181 }
182 }
version(CRuntime_Musl)183 else version (CRuntime_Musl)
184 {
185 static if ( __USE_FILE_OFFSET64 )
186 {
187 int fgetpos64(FILE*, fpos_t *);
188 alias fgetpos64 fgetpos;
189
190 FILE* fopen64(in char*, in char*);
191 alias fopen64 fopen;
192
193 FILE* freopen64(in char*, in char*, FILE*);
194 alias freopen64 freopen;
195
196 int fseek(FILE*, c_long, int);
197
198 int fsetpos64(FILE*, in fpos_t*);
199 alias fsetpos64 fsetpos;
200
201 FILE* tmpfile64();
202 alias tmpfile64 tmpfile;
203 }
204 else
205 {
206 int fgetpos(FILE*, fpos_t *);
207 FILE* fopen(in char*, in char*);
208 FILE* freopen(in char*, in char*, FILE*);
209 int fseek(FILE*, c_long, int);
210 int fsetpos(FILE*, in fpos_t*);
211 FILE* tmpfile();
212 }
213 }
version(Solaris)214 else version (Solaris)
215 {
216 static if (__USE_FILE_OFFSET64 && __WORDSIZE != 64)
217 {
218 int fgetpos64(FILE*, fpos_t *);
219 alias fgetpos = fgetpos64;
220
221 FILE* fopen64(in char*, in char*);
222 alias fopen = fopen64;
223
224 FILE* freopen64(in char*, in char*, FILE*);
225 alias freopen = freopen64;
226
227 int fseek(FILE*, c_long, int);
228
229 int fsetpos64(FILE*, in fpos_t*);
230 alias fsetpos = fsetpos64;
231
232 FILE* tmpfile64();
233 alias tmpfile = tmpfile64;
234 }
235 else
236 {
237 int fgetpos(FILE*, fpos_t *);
238 FILE* fopen(in char*, in char*);
239 FILE* freopen(in char*, in char*, FILE*);
240 int fseek(FILE*, c_long, int);
241 int fsetpos(FILE*, in fpos_t*);
242 FILE* tmpfile();
243 }
244 }
245
246 //
247 // C Extension (CX)
248 //
249 /*
250 L_ctermid
251
252 char* ctermid(char*);
253 FILE* fdopen(int, in char*);
254 int fileno(FILE*);
255 int fseeko(FILE*, off_t, int);
256 off_t ftello(FILE*);
257 char* gets(char*);
258 int pclose(FILE*);
259 FILE* popen(in char*, in char*);
260 */
261
version(CRuntime_Glibc)262 version (CRuntime_Glibc)
263 {
264 enum L_ctermid = 9;
265
266 static if ( __USE_FILE_OFFSET64 )
267 {
268 int fseeko64(FILE*, off_t, int);
269 alias fseeko64 fseeko;
270 }
271 else
272 {
273 int fseeko(FILE*, off_t, int);
274 }
275
276 static if ( __USE_FILE_OFFSET64 )
277 {
278 off_t ftello64(FILE*);
279 alias ftello64 ftello;
280 }
281 else
282 {
283 off_t ftello(FILE*);
284 }
285 }
version(CRuntime_UClibc)286 else version (CRuntime_UClibc)
287 {
288 enum L_ctermid = 9;
289 enum L_cuserid = 9;
290
291 static if ( __USE_FILE_OFFSET64 )
292 {
293 int fseeko64(FILE*, off_t, int);
294 alias fseeko64 fseeko;
295 }
296 else
297 {
298 int fseeko(FILE*, off_t, int);
299 }
300
301 static if ( __USE_FILE_OFFSET64 )
302 {
303 off_t ftello64(FILE*);
304 alias ftello64 ftello;
305 }
306 else
307 {
308 off_t ftello(FILE*);
309 }
310 }
version(CRuntime_Musl)311 else version (CRuntime_Musl)
312 {
313 enum L_ctermid = 20;
314
315 static if ( __USE_FILE_OFFSET64 )
316 {
317 int fseeko64(FILE*, off_t, int);
318 alias fseeko64 fseeko;
319 }
320 else
321 {
322 int fseeko(FILE*, off_t, int);
323 }
324
325 static if ( __USE_FILE_OFFSET64 )
326 {
327 off_t ftello64(FILE*);
328 alias ftello64 ftello;
329 }
330 else
331 {
332 off_t ftello(FILE*);
333 }
334 }
version(Solaris)335 else version (Solaris)
336 {
337 enum L_ctermid = 9;
338 enum L_cuserid = 9;
339
340 static if (__USE_FILE_OFFSET64 && __WORDSIZE != 64)
341 {
342 int fseeko64(FILE*, off_t, int);
343 alias fseeko = fseeko64;
344 }
345 else
346 {
347 int fseeko(FILE*, off_t, int);
348 }
349
350 static if (__USE_FILE_OFFSET64 && __WORDSIZE != 64)
351 {
352 off_t ftello64(FILE*);
353 alias ftello = ftello64;
354 }
355 else
356 {
357 off_t ftello(FILE*);
358 }
359 }
version(Posix)360 else version (Posix)
361 {
362 int fseeko(FILE*, off_t, int);
363 off_t ftello(FILE*);
364 }
365
366 char* ctermid(char*);
367 FILE* fdopen(int, in char*);
368 int fileno(FILE*);
369 //int fseeko(FILE*, off_t, int);
370 //off_t ftello(FILE*);
371 char* gets(char*);
372 int pclose(FILE*);
373 FILE* popen(in char*, in char*);
374
375
376 // memstream functions are conforming to POSIX.1-2008. These functions are
377 // not specified in POSIX.1-2001 and are not widely available on other
378 // systems.
379 version (CRuntime_Glibc) // as of glibc 1.0x
380 version = HaveMemstream;
381 else version (FreeBSD) // as of FreeBSD 9.2
382 version = HaveMemstream;
383 else version (DragonFlyBSD) // for DragonFlyBSD
384 version = HaveMemstream;
385 else version (OpenBSD) // as of OpenBSD 5.4
386 version = HaveMemstream;
387 else version (CRuntime_UClibc)
388 version = HaveMemstream;
389 // http://git.musl-libc.org/cgit/musl/commit/src/stdio/open_memstream.c?id=b158b32a44d56ef20407d4285b58180447ffff1f
390 else version (CRuntime_Musl)
391 version = HaveMemstream;
392
version(HaveMemstream)393 version (HaveMemstream)
394 {
395 FILE* fmemopen(in void* buf, in size_t size, in char* mode);
396 FILE* open_memstream(char** ptr, size_t* sizeloc);
397 version (CRuntime_UClibc) {} else
398 FILE* open_wmemstream(wchar_t** ptr, size_t* sizeloc);
399 }
400
401 //
402 // Thread-Safe Functions (TSF)
403 //
404 /*
405 void flockfile(FILE*);
406 int ftrylockfile(FILE*);
407 void funlockfile(FILE*);
408 int getc_unlocked(FILE*);
409 int getchar_unlocked();
410 int putc_unlocked(int, FILE*);
411 int putchar_unlocked(int);
412 */
413
version(CRuntime_Glibc)414 version (CRuntime_Glibc)
415 {
416 void flockfile(FILE*);
417 int ftrylockfile(FILE*);
418 void funlockfile(FILE*);
419 int getc_unlocked(FILE*);
420 int getchar_unlocked();
421 int putc_unlocked(int, FILE*);
422 int putchar_unlocked(int);
423 }
version(OpenBSD)424 else version (OpenBSD)
425 {
426 void flockfile(FILE*);
427 int ftrylockfile(FILE*);
428 void funlockfile(FILE*);
429 int getc_unlocked(FILE*);
430 int getchar_unlocked();
431 int putc_unlocked(int, FILE*);
432 int putchar_unlocked(int);
433 }
version(Solaris)434 else version (Solaris)
435 {
436 void flockfile(FILE*);
437 int ftrylockfile(FILE*);
438 void funlockfile(FILE*);
439 int getc_unlocked(FILE*);
440 int getchar_unlocked();
441 int putc_unlocked(int, FILE*);
442 int putchar_unlocked(int);
443 }
version(CRuntime_UClibc)444 else version (CRuntime_UClibc)
445 {
446 void flockfile(FILE*);
447 int ftrylockfile(FILE*);
448 void funlockfile(FILE*);
449 int getc_unlocked(FILE*);
450 int getchar_unlocked();
451 int putc_unlocked(int, FILE*);
452 int putchar_unlocked(int);
453 }
454
455 //
456 // XOpen (XSI)
457 //
458 /*
459 P_tmpdir
460 va_list (defined in core.stdc.stdarg)
461
462 char* tempnam(in char*, in char*);
463 */
464
465 char* tempnam(in char*, in char*);
466
version(CRuntime_Glibc)467 version (CRuntime_Glibc)
468 {
469 enum P_tmpdir = "/tmp";
470 }
version(CRuntime_Musl)471 version (CRuntime_Musl)
472 {
473 enum P_tmpdir = "/tmp";
474 }
version(Darwin)475 version (Darwin)
476 {
477 enum P_tmpdir = "/var/tmp";
478 }
version(FreeBSD)479 version (FreeBSD)
480 {
481 enum P_tmpdir = "/var/tmp/";
482 }
version(NetBSD)483 version (NetBSD)
484 {
485 enum P_tmpdir = "/var/tmp/";
486 }
version(OpenBSD)487 version (OpenBSD)
488 {
489 enum P_tmpdir = "/tmp/";
490 }
version(DragonFlyBSD)491 version (DragonFlyBSD)
492 {
493 enum P_tmpdir = "/var/tmp/";
494 }
version(Solaris)495 version (Solaris)
496 {
497 enum P_tmpdir = "/var/tmp/";
498 }
version(CRuntime_UClibc)499 version (CRuntime_UClibc)
500 {
501 enum P_tmpdir = "/tmp";
502 }
503
version(HaveMemstream)504 version (HaveMemstream)
505 unittest
506 { /* fmemopen */
507 import core.stdc.string : memcmp;
508 byte[10] buf;
509 auto f = fmemopen(buf.ptr, 10, "w");
510 assert(f !is null);
511 assert(fprintf(f, "hello") == "hello".length);
512 assert(fflush(f) == 0);
513 assert(memcmp(buf.ptr, "hello".ptr, "hello".length) == 0);
514 //assert(buf
515 assert(fclose(f) == 0);
516 }
517
version(HaveMemstream)518 version (HaveMemstream)
519 unittest
520 { /* Note: open_memstream is only useful for writing */
521 import core.stdc.string : memcmp;
522 char* ptr = null;
523 char[6] testdata = ['h', 'e', 'l', 'l', 'o', 0];
524 size_t sz = 0;
525 auto f = open_memstream(&ptr, &sz);
526 assert(f !is null);
527 assert(fprintf(f, "%s", testdata.ptr) == 5);
528 assert(fflush(f) == 0);
529 assert(memcmp(ptr, testdata.ptr, testdata.length) == 0);
530 assert(fclose(f) == 0);
531 }
532
version(CRuntime_UClibc)533 version (CRuntime_UClibc) {} else
version(HaveMemstream)534 version (HaveMemstream)
535 unittest
536 { /* Note: open_wmemstream is only useful for writing */
537 import core.stdc.string : memcmp;
538 import core.stdc.wchar_ : fwprintf;
539 wchar_t* ptr = null;
540 wchar_t[6] testdata = ['h', 'e', 'l', 'l', 'o', 0];
541 size_t sz = 0;
542 auto f = open_wmemstream(&ptr, &sz);
543 assert(f !is null);
544 assert(fwprintf(f, testdata.ptr) == 5);
545 assert(fflush(f) == 0);
546 assert(memcmp(ptr, testdata.ptr, testdata.length*wchar_t.sizeof) == 0);
547 assert(fclose(f) == 0);
548 }
549
550
551 ssize_t getdelim (char** lineptr, size_t* n, int delimiter, FILE* stream);
552 ssize_t getline (char** lineptr, size_t* n, FILE* stream);
553