1 /**
2   * D header file for GNU stdio.
3   *
4   * Copyright: Danny Milosavljevic 2014
5   * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
6   * Authors: Danny Milosavljevic
7   */
8 module core.sys.linux.stdio;
9 version (CRuntime_Glibc):
10 public import core.sys.posix.stdio;
11 import core.sys.posix.sys.types : ssize_t, off64_t = off_t;
12 import core.sys.linux.config : __USE_FILE_OFFSET64;
13 import core.stdc.stdio : FILE;
14 import core.stdc.stddef : wchar_t;
15 
16 extern(C) nothrow
17 {
18     alias ssize_t function(void *cookie, char *buf, size_t size) cookie_read_function_t;
19     alias ssize_t function(void *cookie, const(char) *buf, size_t size) cookie_write_function_t;
20     alias int function(void *cookie, off64_t *offset, int whence) cookie_seek_function_t;
21     alias int function(void *cookie) cookie_close_function_t;
22 
23     struct cookie_io_functions_t
24     {
25         cookie_read_function_t read;
26         cookie_write_function_t write;
27         cookie_seek_function_t seek;
28         cookie_close_function_t close;
29     }
30     FILE* fopencookie(in void* cookie, in char* mode, cookie_io_functions_t io_funcs);
31     void setbuffer(FILE *stream, char *buf, size_t size); // note: _DEFAULT_SOURCE
32 }
33 
34 unittest
35 {
36     static int flag = 0;
37     static int written = 0;
38     static int closed = 0;
39     // Note: this test needs to run on both a 32 and a 64 bit machine, both have to pass.
40     import core.stdc.errno : errno, EBADF;
41     //import core.sys.posix.sys.stat : off64_t;
42     import core.stdc.stdio : FILE, fflush, fileno, fprintf, fgetc, EOF, fclose;
43     import core.stdc.string : memcpy, memset;
specialRead(void * cookie,char * buf,size_t size)44     extern (C) ssize_t specialRead(void *cookie, char *buf, size_t size) nothrow
45     {
46         memset(buf, 'a', size);
47         return size;
48     }
specialClose(void * cookie)49     extern (C) int specialClose(void* cookie) nothrow
50     {
51         ++closed;
52         return 0;
53     }
specialWrite(void * cookie,const (char)* buf,size_t size)54     extern (C) ssize_t specialWrite(void *cookie, const(char) *buf, size_t size) nothrow
55     {
56         int* c = cast(int*) cookie;
57         flag = *c;
58         written += size;
59         return size;
60     }
61     int dummy = 42;
62     cookie_io_functions_t fns =
63     {
64         read: &specialRead,
65         write: &specialWrite,
66         close: &specialClose,
67     };
68     FILE* f = fopencookie(&dummy, "r+", fns);
69     assert(f !is null);
70     //File.open();
71     //auto g = File(f);
72     assert(fileno(f) == -1 && errno == EBADF);
73     assert(fprintf(f, "hello") == "hello".length);
74     //assert(errno == EBADF);
75     assert(fflush(f) == 0);
76     assert(written == "hello".length);
77     // Note: do not swap reading and writing here.
78     int c = 0;
79     while ((c = fgetc(f)) != EOF)
80     {
81         assert(c == 'a');
82         break; // endless otherwise
83     }
84     assert(c == 'a');
85     assert(fclose(f) == 0);
86     assert(closed == 1);
87     assert(flag == dummy);
88     //stdin.getFP();
89     //assert(stdin.fileno() == 0);
90 }
91 
92 unittest
93 { /* setbuffer */
94     char buf;
95     int c;
96     byte[10] dummy = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
97     FILE* f = fmemopen(dummy.ptr, 10, "r");
98     assert(f !is null);
99     setbuffer(f, &buf, 1);
100     assert(fgetc(f) == 1);
101     assert(fgetc(f) == 2);
102     assert(fgetc(f) == 3);
103     assert(fgetc(f) == 4);
104     assert(fclose(f) == 0);
105 }
106