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(Solaris)183 else version (Solaris)
184 {
185 static if (__USE_FILE_OFFSET64 && __WORDSIZE != 64)
186 {
187 int fgetpos64(FILE*, fpos_t *);
188 alias fgetpos = fgetpos64;
189
190 FILE* fopen64(in char*, in char*);
191 alias fopen = fopen64;
192
193 FILE* freopen64(in char*, in char*, FILE*);
194 alias freopen = freopen64;
195
196 int fseek(FILE*, c_long, int);
197
198 int fsetpos64(FILE*, in fpos_t*);
199 alias fsetpos = fsetpos64;
200
201 FILE* tmpfile64();
202 alias tmpfile = tmpfile64;
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 }
214
215 //
216 // C Extension (CX)
217 //
218 /*
219 L_ctermid
220
221 char* ctermid(char*);
222 FILE* fdopen(int, in char*);
223 int fileno(FILE*);
224 int fseeko(FILE*, off_t, int);
225 off_t ftello(FILE*);
226 char* gets(char*);
227 int pclose(FILE*);
228 FILE* popen(in char*, in char*);
229 */
230
version(CRuntime_Glibc)231 version (CRuntime_Glibc)
232 {
233 enum L_ctermid = 9;
234
235 static if ( __USE_FILE_OFFSET64 )
236 {
237 int fseeko64(FILE*, off_t, int);
238 alias fseeko64 fseeko;
239 }
240 else
241 {
242 int fseeko(FILE*, off_t, int);
243 }
244
245 static if ( __USE_FILE_OFFSET64 )
246 {
247 off_t ftello64(FILE*);
248 alias ftello64 ftello;
249 }
250 else
251 {
252 off_t ftello(FILE*);
253 }
254 }
version(CRuntime_UClibc)255 else version (CRuntime_UClibc)
256 {
257 enum L_ctermid = 9;
258 enum L_cuserid = 9;
259
260 static if ( __USE_FILE_OFFSET64 )
261 {
262 int fseeko64(FILE*, off_t, int);
263 alias fseeko64 fseeko;
264 }
265 else
266 {
267 int fseeko(FILE*, off_t, int);
268 }
269
270 static if ( __USE_FILE_OFFSET64 )
271 {
272 off_t ftello64(FILE*);
273 alias ftello64 ftello;
274 }
275 else
276 {
277 off_t ftello(FILE*);
278 }
279 }
version(Solaris)280 else version (Solaris)
281 {
282 enum L_ctermid = 9;
283 enum L_cuserid = 9;
284
285 static if (__USE_FILE_OFFSET64 && __WORDSIZE != 64)
286 {
287 int fseeko64(FILE*, off_t, int);
288 alias fseeko = fseeko64;
289 }
290 else
291 {
292 int fseeko(FILE*, off_t, int);
293 }
294
295 static if (__USE_FILE_OFFSET64 && __WORDSIZE != 64)
296 {
297 off_t ftello64(FILE*);
298 alias ftello = ftello64;
299 }
300 else
301 {
302 off_t ftello(FILE*);
303 }
304 }
version(Posix)305 else version (Posix)
306 {
307 int fseeko(FILE*, off_t, int);
308 off_t ftello(FILE*);
309 }
310
311 char* ctermid(char*);
312 FILE* fdopen(int, in char*);
313 int fileno(FILE*);
314 //int fseeko(FILE*, off_t, int);
315 //off_t ftello(FILE*);
316 char* gets(char*);
317 int pclose(FILE*);
318 FILE* popen(in char*, in char*);
319
320
321 // memstream functions are conforming to POSIX.1-2008. These functions are
322 // not specified in POSIX.1-2001 and are not widely available on other
323 // systems.
324 version (CRuntime_Glibc) // as of glibc 1.0x
325 version = HaveMemstream;
326 else version (FreeBSD) // as of FreeBSD 9.2
327 version = HaveMemstream;
328 else version (DragonFlyBSD) // for DragonFlyBSD
329 version = HaveMemstream;
330 else version (OpenBSD) // as of OpenBSD 5.4
331 version = HaveMemstream;
332 else version (CRuntime_UClibc)
333 version = HaveMemstream;
334
version(HaveMemstream)335 version (HaveMemstream)
336 {
337 FILE* fmemopen(in void* buf, in size_t size, in char* mode);
338 FILE* open_memstream(char** ptr, size_t* sizeloc);
339 version (CRuntime_UClibc) {} else
340 FILE* open_wmemstream(wchar_t** ptr, size_t* sizeloc);
341 }
342
343 //
344 // Thread-Safe Functions (TSF)
345 //
346 /*
347 void flockfile(FILE*);
348 int ftrylockfile(FILE*);
349 void funlockfile(FILE*);
350 int getc_unlocked(FILE*);
351 int getchar_unlocked();
352 int putc_unlocked(int, FILE*);
353 int putchar_unlocked(int);
354 */
355
version(CRuntime_Glibc)356 version (CRuntime_Glibc)
357 {
358 void flockfile(FILE*);
359 int ftrylockfile(FILE*);
360 void funlockfile(FILE*);
361 int getc_unlocked(FILE*);
362 int getchar_unlocked();
363 int putc_unlocked(int, FILE*);
364 int putchar_unlocked(int);
365 }
version(OpenBSD)366 else version (OpenBSD)
367 {
368 void flockfile(FILE*);
369 int ftrylockfile(FILE*);
370 void funlockfile(FILE*);
371 int getc_unlocked(FILE*);
372 int getchar_unlocked();
373 int putc_unlocked(int, FILE*);
374 int putchar_unlocked(int);
375 }
version(Solaris)376 else version (Solaris)
377 {
378 void flockfile(FILE*);
379 int ftrylockfile(FILE*);
380 void funlockfile(FILE*);
381 int getc_unlocked(FILE*);
382 int getchar_unlocked();
383 int putc_unlocked(int, FILE*);
384 int putchar_unlocked(int);
385 }
version(CRuntime_UClibc)386 else version (CRuntime_UClibc)
387 {
388 void flockfile(FILE*);
389 int ftrylockfile(FILE*);
390 void funlockfile(FILE*);
391 int getc_unlocked(FILE*);
392 int getchar_unlocked();
393 int putc_unlocked(int, FILE*);
394 int putchar_unlocked(int);
395 }
396
397 //
398 // XOpen (XSI)
399 //
400 /*
401 P_tmpdir
402 va_list (defined in core.stdc.stdarg)
403
404 char* tempnam(in char*, in char*);
405 */
406
407 char* tempnam(in char*, in char*);
408
version(CRuntime_Glibc)409 version (CRuntime_Glibc)
410 {
411 enum P_tmpdir = "/tmp";
412 }
version(CRuntime_Musl)413 version (CRuntime_Musl)
414 {
415 enum P_tmpdir = "/tmp";
416 }
version(Darwin)417 version (Darwin)
418 {
419 enum P_tmpdir = "/var/tmp";
420 }
version(FreeBSD)421 version (FreeBSD)
422 {
423 enum P_tmpdir = "/var/tmp/";
424 }
version(NetBSD)425 version (NetBSD)
426 {
427 enum P_tmpdir = "/var/tmp/";
428 }
version(OpenBSD)429 version (OpenBSD)
430 {
431 enum P_tmpdir = "/tmp/";
432 }
version(DragonFlyBSD)433 version (DragonFlyBSD)
434 {
435 enum P_tmpdir = "/var/tmp/";
436 }
version(Solaris)437 version (Solaris)
438 {
439 enum P_tmpdir = "/var/tmp/";
440 }
version(CRuntime_UClibc)441 version (CRuntime_UClibc)
442 {
443 enum P_tmpdir = "/tmp";
444 }
445
version(HaveMemstream)446 version (HaveMemstream)
447 unittest
448 { /* fmemopen */
449 import core.stdc.string : memcmp;
450 byte[10] buf;
451 auto f = fmemopen(buf.ptr, 10, "w");
452 assert(f !is null);
453 assert(fprintf(f, "hello") == "hello".length);
454 assert(fflush(f) == 0);
455 assert(memcmp(buf.ptr, "hello".ptr, "hello".length) == 0);
456 //assert(buf
457 assert(fclose(f) == 0);
458 }
459
version(HaveMemstream)460 version (HaveMemstream)
461 unittest
462 { /* Note: open_memstream is only useful for writing */
463 import core.stdc.string : memcmp;
464 char* ptr = null;
465 char[6] testdata = ['h', 'e', 'l', 'l', 'o', 0];
466 size_t sz = 0;
467 auto f = open_memstream(&ptr, &sz);
468 assert(f !is null);
469 assert(fprintf(f, "%s", testdata.ptr) == 5);
470 assert(fflush(f) == 0);
471 assert(memcmp(ptr, testdata.ptr, testdata.length) == 0);
472 assert(fclose(f) == 0);
473 }
474
version(CRuntime_UClibc)475 version (CRuntime_UClibc) {} else
version(HaveMemstream)476 version (HaveMemstream)
477 unittest
478 { /* Note: open_wmemstream is only useful for writing */
479 import core.stdc.string : memcmp;
480 import core.stdc.wchar_ : fwprintf;
481 wchar_t* ptr = null;
482 wchar_t[6] testdata = ['h', 'e', 'l', 'l', 'o', 0];
483 size_t sz = 0;
484 auto f = open_wmemstream(&ptr, &sz);
485 assert(f !is null);
486 assert(fwprintf(f, testdata.ptr) == 5);
487 assert(fflush(f) == 0);
488 assert(memcmp(ptr, testdata.ptr, testdata.length*wchar_t.sizeof) == 0);
489 assert(fclose(f) == 0);
490 }
491
492
493 ssize_t getdelim (char** lineptr, size_t* n, int delimiter, FILE* stream);
494 ssize_t getline (char** lineptr, size_t* n, FILE* stream);
495