1 // This is a test for access_extended(), one of the more ridiculous syscalls 2 // ever devised. For bug 200760. See the comments on the wrapper in 3 // syswrap-darwin.c to understand what is going on here. 4 5 #include <sys/syscall.h> 6 #include <unistd.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 11 int main(void) 12 { 13 char* name1 = "access_extended.c"; 14 char* name2 = "no_such_file"; 15 // Space for three descriptors and the two strings (and NUL chars for them). 16 size_t entries_szB = 17 sizeof(struct accessx_descriptor) * 3 + 18 strlen(name1) + 1 + 19 strlen(name2) + 1; 20 struct accessx_descriptor* entries = malloc(entries_szB); 21 char* string1 = (char*)&entries[3]; 22 char* string2 = string1 + strlen(name1) + 1; 23 int results[3]; 24 int retval; 25 26 entries[0].ad_name_offset = string1 - (char*)entries; 27 entries[1].ad_name_offset = 0; // reuse the previous entry's string 28 entries[2].ad_name_offset = string2 - (char*)entries; 29 entries[0].ad_flags = F_OK; // succeeds 30 entries[1].ad_flags = X_OK; // fails 31 entries[2].ad_flags = F_OK; // fails 32 strcpy(string1, name1); 33 strcpy(string2, name2); 34 35 retval = syscall(SYS_access_extended, entries, entries_szB, results, 36 /*uid--unused?*/0); 37 38 fprintf(stderr, "retval = %d\n", retval); 39 fprintf(stderr, "%s(F_OK) = %d (%s)\n", 40 name1, results[0], strerror(results[0])); 41 fprintf(stderr, "%s(X_OK) = %d (%s)\n", 42 name1, results[1], strerror(results[1])); 43 fprintf(stderr, "%s(F_OK) = %d (%s)\n", 44 name2, results[2], strerror(results[2])); 45 46 return 0; 47 } 48 49