1*74989affSNico Weber // RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s
2*74989affSNico Weber
3*74989affSNico Weber // CHECK: READ CALLED; len={{[0-9]*}}
4*74989affSNico Weber // CHECK-NEXT: READ: test
5*74989affSNico Weber // CHECK-NEXT: WRITE CALLED: test
6*74989affSNico Weber // CHECK-NEXT: READ CALLED; len={{[0-9]*}}
7*74989affSNico Weber // CHECK-NEXT: READ: test
8*74989affSNico Weber // CHECK-NEXT: WRITE CALLED: test
9*74989affSNico Weber // CHECK-NEXT: CLOSE CALLED
10*74989affSNico Weber // CHECK-NEXT: SEEK CALLED; off=100, whence=0
11*74989affSNico Weber // CHECK-NEXT: READ CALLED; len={{[0-9]*}}
12*74989affSNico Weber // CHECK-NEXT: READ: test
13*74989affSNico Weber //
14*74989affSNico Weber // UNSUPPORTED: linux, darwin, solaris
15*74989affSNico Weber
16*74989affSNico Weber #include <assert.h>
17*74989affSNico Weber #include <stdio.h>
18*74989affSNico Weber #include <stdlib.h>
19*74989affSNico Weber #include <string.h>
20*74989affSNico Weber
21*74989affSNico Weber int cookie_var;
22*74989affSNico Weber
f_read(void * cookie,char * buf,int len)23*74989affSNico Weber int f_read(void *cookie, char *buf, int len) {
24*74989affSNico Weber assert(cookie == &cookie_var);
25*74989affSNico Weber assert(len >= 6);
26*74989affSNico Weber printf("READ CALLED; len=%d\n", len);
27*74989affSNico Weber return strlcpy(buf, "test\n", len);
28*74989affSNico Weber }
29*74989affSNico Weber
f_write(void * cookie,const char * buf,int len)30*74989affSNico Weber int f_write(void *cookie, const char *buf, int len) {
31*74989affSNico Weber assert(cookie == &cookie_var);
32*74989affSNico Weber char *data = strndup(buf, len);
33*74989affSNico Weber assert(data);
34*74989affSNico Weber printf("WRITE CALLED: %s\n", data);
35*74989affSNico Weber free(data);
36*74989affSNico Weber return len;
37*74989affSNico Weber }
38*74989affSNico Weber
f_seek(void * cookie,off_t off,int whence)39*74989affSNico Weber off_t f_seek(void *cookie, off_t off, int whence) {
40*74989affSNico Weber assert(cookie == &cookie_var);
41*74989affSNico Weber assert(whence == SEEK_SET);
42*74989affSNico Weber printf("SEEK CALLED; off=%d, whence=%d\n", (int)off, whence);
43*74989affSNico Weber return off;
44*74989affSNico Weber }
45*74989affSNico Weber
f_close(void * cookie)46*74989affSNico Weber int f_close(void *cookie) {
47*74989affSNico Weber assert(cookie == &cookie_var);
48*74989affSNico Weber printf("CLOSE CALLED\n");
49*74989affSNico Weber return 0;
50*74989affSNico Weber }
51*74989affSNico Weber
main(void)52*74989affSNico Weber int main(void) {
53*74989affSNico Weber FILE *fp;
54*74989affSNico Weber char buf[10];
55*74989affSNico Weber
56*74989affSNico Weber // 1. read-only variant
57*74989affSNico Weber fp = fropen(&cookie_var, f_read);
58*74989affSNico Weber assert(fp);
59*74989affSNico Weber // verify that fileno() does not crash or report nonsense
60*74989affSNico Weber assert(fileno(fp) == -1);
61*74989affSNico Weber assert(fgets(buf, sizeof(buf), fp));
62*74989affSNico Weber printf("READ: %s", buf);
63*74989affSNico Weber assert(!fclose(fp));
64*74989affSNico Weber
65*74989affSNico Weber // 2. write-only variant
66*74989affSNico Weber fp = fwopen(&cookie_var, f_write);
67*74989affSNico Weber assert(fp);
68*74989affSNico Weber assert(fileno(fp) == -1);
69*74989affSNico Weber assert(fputs("test", fp) >= 0);
70*74989affSNico Weber assert(!fclose(fp));
71*74989affSNico Weber
72*74989affSNico Weber // 3. read+write+close
73*74989affSNico Weber fp = funopen(&cookie_var, f_read, f_write, NULL, f_close);
74*74989affSNico Weber assert(fp);
75*74989affSNico Weber assert(fileno(fp) == -1);
76*74989affSNico Weber assert(fgets(buf, sizeof(buf), fp));
77*74989affSNico Weber printf("READ: %s", buf);
78*74989affSNico Weber assert(fputs("test", fp) >= 0);
79*74989affSNico Weber assert(!fclose(fp));
80*74989affSNico Weber
81*74989affSNico Weber // 4. read+seek
82*74989affSNico Weber fp = funopen(&cookie_var, f_read, NULL, f_seek, NULL);
83*74989affSNico Weber assert(fp);
84*74989affSNico Weber assert(fileno(fp) == -1);
85*74989affSNico Weber assert(fseek(fp, 100, SEEK_SET) == 0);
86*74989affSNico Weber assert(fgets(buf, sizeof(buf), fp));
87*74989affSNico Weber printf("READ: %s", buf);
88*74989affSNico Weber assert(!fclose(fp));
89*74989affSNico Weber
90*74989affSNico Weber return 0;
91*74989affSNico Weber }
92