static void NaClDescIoDescDtor(struct NaClRefCount *vself) { struct NaClDescIoDesc *self = (struct NaClDescIoDesc *) vself; NaClLog(4, "NaClDescIoDescDtor(0x%08"NACL_PRIxPTR").\n", (uintptr_t) vself); if (0 != NaClHostDescClose(self->hd)) { NaClLog(LOG_FATAL, "NaClDescIoDescDtor: NaClHostDescClose failed\n"); } free(self->hd); self->hd = NULL; vself->vtbl = (struct NaClRefCountVtbl const *) &kNaClDescVtbl; (*vself->vtbl->Dtor)(vself); }
void CreateTestFile(struct NaClHostDesc *d_out, struct NaClHostDesc *d_ronly_out, char const *pathname, struct TestParams const *param) { struct NaClHostDesc hd; int err; printf("pathname = %s, perms %#o\n", pathname, param->file_perms); if (0 != (err = NaClHostDescOpen(&hd, pathname, NACL_ABI_O_WRONLY | NACL_ABI_O_CREAT | NACL_ABI_O_TRUNC, param->file_perms))) { fprintf(stderr, "Could not open test scratch file: NaCl errno %d\n", -err); exit(1); } if (0 != (err = CreateTestData(&hd))) { fprintf(stderr, "Could not write test data into test scratch file: NaCl errno %d\n", -err); exit(1); } if (0 != (err = NaClHostDescClose(&hd))) { fprintf(stderr, "Error while closing test data file, NaCl errno %d\n", -err); exit(1); } if (0 != (err = NaClHostDescOpen(d_out, pathname, param->open_flags, param->file_perms))) { fprintf(stderr, "Could not open test scratch file: NaCl errno %d\n", -err); exit(1); } if (0 != (err = NaClHostDescOpen(d_ronly_out, pathname, NACL_ABI_O_RDONLY, 0))) { fprintf(stderr, "Could not open read-only verification handle: NaCl errno %d\n", -err); exit(1); } }
static struct NaClDesc *NaClResourceFileFactory(char const *resource_locator, int nacl_flags, int mode) { struct NaClHostDesc *hd = NULL; struct NaClDescIoDesc *did = NULL; struct NaClDesc *rv = NULL; hd = malloc(sizeof *hd); did = malloc(sizeof *did); if (NULL == hd || NULL == did) { goto done; } NaClLog(4, ("NaClResourceFileFactory: invoking NaClHostDescOpen on" " %s, flags 0x%x, mode 0%o\n"), resource_locator, nacl_flags, mode); if (0 != NaClHostDescOpen(hd, resource_locator, nacl_flags, mode)) { NaClLog(LOG_INFO, "NaClResourceFileFactory: NaClHostDescOpen failed\n"); goto done; } if (!NaClDescIoDescCtor(did, hd)) { NaClLog(LOG_INFO, "NaClResourceFileFactory: NaClDescIoDescCtor failed\n"); if (0 != NaClHostDescClose(hd)) { NaClLog(LOG_FATAL, "NaClResourceFileFactory: NaClHostDescClose failed\n"); } goto done; } hd = NULL; /* ownership passed into did */ rv = (struct NaClDesc *) did; /* success */ did = NULL; done: free(hd); free(did); return rv; }
void CloseTestFile(struct NaClHostDesc *d) { CHECK(0 == NaClHostDescClose(d)); }
void CreateTestFile(struct NaClHostDesc *d_out, char const *pathname, struct TestParams *param) { struct NaClHostDesc hd; int err; nacl_off64_t off; size_t desired_write; ssize_t bytes_written; printf("pathname = %s, perms 0%o\n", pathname, param->file_perms); if (0 != (err = NaClHostDescOpen(&hd, pathname, NACL_ABI_O_WRONLY | NACL_ABI_O_CREAT | NACL_ABI_O_TRUNC, param->file_perms))) { fprintf(stderr, "Could not open test scratch file: NaCl errno %d\n", -err); exit(1); } if (0 != (err = CreateTestData(&hd))) { fprintf(stderr, "Could not write test data into test scratch file: NaCl errno %d\n", -err); exit(1); } if (NULL != param->test_data_start) { off = NaClHostDescSeek(&hd, 0, 0); if (off < 0) { fprintf(stderr, "Could not seek to create test data: NaCl errno %d\n", (int) -off); exit(1); } desired_write = param->test_data_size; bytes_written = NaClHostDescWrite(&hd, param->test_data_start, desired_write); if (bytes_written < 0) { fprintf(stderr, "Could not write specialized test data: NaCl errno %d\n", (int) -bytes_written); exit(1); } if ((size_t) bytes_written != desired_write) { fprintf(stderr, "Error while writing specialized test data:" " tried to write %d, actual %d\n", (int) desired_write, (int) bytes_written); exit(1); } } if (0 != (err = NaClHostDescClose(&hd))) { fprintf(stderr, "Error while closing test data file, errno %d\n", -err); exit(1); } if (0 != (err = NaClHostDescOpen(d_out, pathname, param->open_flags, param->file_perms))) { fprintf(stderr, "Could not open test scratch file: NaCl errno %d\n", -err); exit(1); } }
/* * It is the responsibility of the invoking environment to delete the * file passed as command-line argument. See the build.scons file. */ int main(int ac, char **av) { char const *test_dir_name = "/tmp/nacl_host_desc_mmap_win_test"; struct NaClHostDesc hd; int test_passed; size_t error_count; size_t ix; int opt; int num_runs = 1; int test_run; HANDLE h; int d; while (EOF != (opt = getopt(ac, av, "c:t:"))) { switch (opt) { case 'c': num_runs = atoi(optarg); break; case 't': test_dir_name = optarg; break; default: fprintf(stderr, "Usage: nacl_host_desc_mmap_win_test [-c run_count]\n" " [-t test_temp_dir]\n"); exit(1); } } NaClPlatformInit(); error_count = 0; for (test_run = 0; test_run < num_runs; ++test_run) { printf("Test run %d\n\n", test_run); for (ix = 0; ix < NACL_ARRAY_SIZE(tests); ++ix) { char test_file_name[PATH_MAX]; _snprintf_s(test_file_name, sizeof test_file_name, _TRUNCATE, "%s/f%d.%"NACL_PRIuS, test_dir_name, test_run, ix); printf("%s\n", tests[ix].test_info); printf("-- %s\n", tests[ix].file_type->file_type_description); h = CreateTestFile(test_file_name, tests[ix].file_type); if (ERROR_SUCCESS == tests[ix].expected_open_error) { if (INVALID_HANDLE_VALUE == h) { DWORD err = GetLastError(); NaClLog(LOG_ERROR, "CreateTestFile for %s failed, error %d\n", test_file_name, err); printf("FAILED\n"); ++error_count; continue; } d = _open_osfhandle((intptr_t) h, tests[ix].oflags); NaClHostDescPosixTake(&hd, d, tests[ix].posix_flags); test_passed = TryToMap(&hd, tests[ix].map_bytes, tests[ix].prot, tests[ix].map_flags, tests[ix].expected_mmap_errno); error_count += !test_passed; printf("%s\n", test_passed ? "PASSED" : "FAILED"); CHECK(0 == NaClHostDescClose(&hd)); AttemptToDeleteTestFile(test_file_name); } else { if (INVALID_HANDLE_VALUE == h) { DWORD err = GetLastError(); if (err != tests[ix].expected_open_error) { NaClLog(LOG_ERROR, "Expected CreateTestFile for %s to failed with" " error %d, but got error %d\n", test_file_name, err, tests[ix].expected_open_error); printf("FAILED\n"); ++error_count; } else { printf("PASSED (open failed)\n"); } continue; } else { NaClLog(LOG_ERROR, "Expected CreateTestFile for %s to fail with error %d," " but succeeded instead!\n", test_file_name, tests[ix].expected_open_error); (void) CloseHandle(h); AttemptToDeleteTestFile(test_file_name); printf("FAILED\n"); ++error_count; continue; } } } } printf("Total of %d error%s.\n", error_count, (error_count == 1) ? "" : "s"); NaClPlatformFini(); /* we ignore the 2^32 or 2^64 total errors case */ return (error_count > 255) ? 255 : error_count; }
/* set *out_desc to struct NaClDescIo * output */ int NaClDescIoInternalize(struct NaClDesc **out_desc, struct NaClDescXferState *xfer, struct NaClDescQuotaInterface *quota_interface) { int rv; NaClHandle h; int d; int flags; struct NaClHostDesc *nhdp; struct NaClDescIoDesc *ndidp; UNREFERENCED_PARAMETER(quota_interface); rv = -NACL_ABI_EIO; /* catch-all */ h = NACL_INVALID_HANDLE; nhdp = NULL; ndidp = NULL; nhdp = malloc(sizeof *nhdp); if (NULL == nhdp) { rv = -NACL_ABI_ENOMEM; goto cleanup; } ndidp = malloc(sizeof *ndidp); if (!ndidp) { rv = -NACL_ABI_ENOMEM; goto cleanup; } if (!NaClDescInternalizeCtor((struct NaClDesc *) ndidp, xfer)) { rv = -NACL_ABI_ENOMEM; goto cleanup; } if (xfer->next_handle == xfer->handle_buffer_end || xfer->next_byte + sizeof ndidp->hd->flags > xfer->byte_buffer_end) { rv = -NACL_ABI_EIO; goto cleanup_ndidp_dtor; } NACL_COMPILE_TIME_ASSERT(sizeof flags == sizeof(ndidp->hd->flags)); memcpy(&flags, xfer->next_byte, sizeof flags); xfer->next_byte += sizeof flags; h = *xfer->next_handle; *xfer->next_handle++ = NACL_INVALID_HANDLE; #if NACL_WINDOWS if (-1 == (d = _open_osfhandle((intptr_t) h, _O_RDWR | _O_BINARY))) { rv = -NACL_ABI_EIO; goto cleanup_ndidp_dtor; } #else d = h; #endif /* * We mark it as read/write, but don't really know for sure until we * try to make those syscalls (in which case we'd get EBADF). */ if ((rv = NaClHostDescPosixTake(nhdp, d, flags)) < 0) { goto cleanup_ndidp_dtor; } h = NACL_INVALID_HANDLE; /* nhdp took ownership of h */ if (!NaClDescIoDescSubclassCtor(ndidp, nhdp)) { rv = -NACL_ABI_ENOMEM; goto cleanup_nhdp_dtor; } /* * ndidp took ownership of nhdp, now give ownership of ndidp to caller. */ *out_desc = (struct NaClDesc *) ndidp; rv = 0; cleanup_nhdp_dtor: if (rv < 0) { if (0 != NaClHostDescClose(nhdp)) { NaClLog(LOG_FATAL, "NaClDescIoInternalize: NaClHostDescClose failed\n"); } } cleanup_ndidp_dtor: if (rv < 0) { NaClDescSafeUnref((struct NaClDesc *) ndidp); ndidp = NULL; } cleanup: if (rv < 0) { free(nhdp); free(ndidp); if (NACL_INVALID_HANDLE != h) { (void) NaClClose(h); } } return rv; }