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