1 // RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s
3 // CHECK: READ CALLED; len={{[0-9]*}}
4 // CHECK-NEXT: READ: test
5 // CHECK-NEXT: WRITE CALLED: test
6 // CHECK-NEXT: READ CALLED; len={{[0-9]*}}
7 // CHECK-NEXT: READ: test
8 // CHECK-NEXT: WRITE CALLED: test
9 // CHECK-NEXT: CLOSE CALLED
10 // CHECK-NEXT: SEEK CALLED; off=100, whence=0
11 // CHECK-NEXT: READ CALLED; len={{[0-9]*}}
12 // CHECK-NEXT: READ: test
13 // CHECK-NEXT: WRITE CALLED: test
14 // CHECK-NEXT: FLUSH CALLED
15 // CHECK-NEXT: WRITE CALLED: test
16 // CHECK-NEXT: FLUSH CALLED
25 ssize_t
f_read(void *cookie
, void *buf
, size_t len
) {
26 assert(cookie
== &cookie_var
);
28 printf("READ CALLED; len=%zd\n", len
);
29 return strlcpy((char*)buf
, "test\n", len
);
32 ssize_t
f_write(void *cookie
, const void *buf
, size_t len
) {
33 assert(cookie
== &cookie_var
);
34 char *data
= strndup((char*)buf
, len
);
36 printf("WRITE CALLED: %s\n", data
);
41 off_t
f_seek(void *cookie
, off_t off
, int whence
) {
42 assert(cookie
== &cookie_var
);
43 assert(whence
== SEEK_SET
);
44 printf("SEEK CALLED; off=%d, whence=%d\n", (int)off
, whence
);
48 int f_flush(void *cookie
) {
49 assert(cookie
== &cookie_var
);
50 printf("FLUSH CALLED\n");
54 int f_close(void *cookie
) {
55 assert(cookie
== &cookie_var
);
56 printf("CLOSE CALLED\n");
64 // 1. read-only variant
65 fp
= fropen2(&cookie_var
, f_read
);
67 // verify that fileno() does not crash or report nonsense
68 assert(fileno(fp
) == -1);
69 assert(fgets(buf
, sizeof(buf
), fp
));
70 printf("READ: %s", buf
);
73 // 2. write-only variant
74 fp
= fwopen2(&cookie_var
, f_write
);
76 assert(fileno(fp
) == -1);
77 assert(fputs("test", fp
) >= 0);
80 // 3. read+write+close
81 fp
= funopen2(&cookie_var
, f_read
, f_write
, NULL
, NULL
, f_close
);
83 assert(fileno(fp
) == -1);
84 assert(fgets(buf
, sizeof(buf
), fp
));
85 printf("READ: %s", buf
);
86 assert(fputs("test", fp
) >= 0);
91 fp
= funopen2(&cookie_var
, f_read
, NULL
, f_seek
, NULL
, NULL
);
93 assert(fileno(fp
) == -1);
94 assert(fseek(fp
, 100, SEEK_SET
) == 0);
95 assert(fgets(buf
, sizeof(buf
), fp
));
96 printf("READ: %s", buf
);
100 fp
= funopen2(&cookie_var
, NULL
, f_write
, NULL
, f_flush
, NULL
);
102 assert(fileno(fp
) == -1);
103 assert(fputs("test", fp
) >= 0);
105 assert(fputs("test", fp
) >= 0);
106 // NB: fclose() also implicitly calls flush