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