// This is a test for access_extended(), one of the more ridiculous syscalls // ever devised. For bug 200760. See the comments on the wrapper in // syswrap-darwin.c to understand what is going on here. #include #include #include #include #include int main(void) { char* name1 = "access_extended.c"; char* name2 = "no_such_file"; // Space for three descriptors and the two strings (and NUL chars for them). size_t entries_szB = sizeof(struct accessx_descriptor) * 3 + strlen(name1) + 1 + strlen(name2) + 1; struct accessx_descriptor* entries = malloc(entries_szB); char* string1 = (char*)&entries[3]; char* string2 = string1 + strlen(name1) + 1; int results[3]; int retval; entries[0].ad_name_offset = string1 - (char*)entries; entries[1].ad_name_offset = 0; // reuse the previous entry's string entries[2].ad_name_offset = string2 - (char*)entries; entries[0].ad_flags = F_OK; // succeeds entries[1].ad_flags = X_OK; // fails entries[2].ad_flags = F_OK; // fails strcpy(string1, name1); strcpy(string2, name2); retval = syscall(SYS_access_extended, entries, entries_szB, results, /*uid--unused?*/0); fprintf(stderr, "retval = %d\n", retval); fprintf(stderr, "%s(F_OK) = %d (%s)\n", name1, results[0], strerror(results[0])); fprintf(stderr, "%s(X_OK) = %d (%s)\n", name1, results[1], strerror(results[1])); fprintf(stderr, "%s(F_OK) = %d (%s)\n", name2, results[2], strerror(results[2])); return 0; }