static void cleanup_tmpdir(const atf_fs_path_t *dir, const atf_fs_path_t *outfile, const atf_fs_path_t *errfile) { { atf_error_t err = atf_fs_unlink(outfile); if (atf_is_error(err)) { INV(atf_error_is(err, "libc") && atf_libc_error_code(err) == ENOENT); atf_error_free(err); } else INV(!atf_is_error(err)); } { atf_error_t err = atf_fs_unlink(errfile); if (atf_is_error(err)) { INV(atf_error_is(err, "libc") && atf_libc_error_code(err) == ENOENT); atf_error_free(err); } else INV(!atf_is_error(err)); } { atf_error_t err = atf_fs_rmdir(dir); INV(!atf_is_error(err)); } }
ATF_TC_BODY(no_memory_twice, tc) { { atf_error_t err = atf_no_memory_error(); ATF_REQUIRE(atf_error_is(err, "no_memory")); ATF_REQUIRE(atf_error_data(err) == NULL); atf_error_free(err); } { atf_error_t err = atf_no_memory_error(); ATF_REQUIRE(atf_error_is(err, "no_memory")); ATF_REQUIRE(atf_error_data(err) == NULL); atf_error_free(err); } }
ATF_TC_BODY(init_raw, tc) { const char *src = "String 1, String 2"; atf_dynstr_t str; RE(atf_dynstr_init_raw(&str, src, 0)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_raw(&str, src, 8)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_raw(&str, src + 10, 8)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0); atf_dynstr_fini(&str); RE(atf_dynstr_init_raw(&str, "String\0Lost", 11)); ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String") == 0); atf_dynstr_fini(&str); { atf_error_t err = atf_dynstr_init_raw(&str, "NULL", SIZE_MAX - 1); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "no_memory")); atf_error_free(err); } }
ATF_TC_BODY(libc_new, tc) { atf_error_t err; err = atf_libc_error(ENOMEM, "Test message 1"); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOMEM); ATF_REQUIRE(strcmp(atf_libc_error_msg(err), "Test message 1") == 0); atf_error_free(err); err = atf_libc_error(EPERM, "%s message %d", "Test", 2); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE_EQ(atf_libc_error_code(err), EPERM); ATF_REQUIRE(strcmp(atf_libc_error_msg(err), "Test message 2") == 0); atf_error_free(err); }
static void no_memory_format(const atf_error_t err, char *buf, size_t buflen) { PRE(atf_error_is(err, "no_memory")); snprintf(buf, buflen, "Not enough memory"); }
ATF_TC_BODY(error_new, tc) { atf_error_t err; int data; err = atf_error_new("test_error", NULL, 0, NULL); ATF_REQUIRE(atf_error_is(err, "test_error")); ATF_REQUIRE(!atf_error_is(err, "unknown_error")); ATF_REQUIRE(atf_error_data(err) == NULL); atf_error_free(err); data = 5; err = atf_error_new("test_data_error", &data, sizeof(data), NULL); ATF_REQUIRE(atf_error_is(err, "test_data_error")); ATF_REQUIRE(!atf_error_is(err, "unknown_error")); ATF_REQUIRE(atf_error_data(err) != NULL); ATF_REQUIRE_EQ(*((const int *)atf_error_data(err)), 5); atf_error_free(err); }
int atf_libc_error_code(const atf_error_t err) { const struct atf_libc_error_data *data; PRE(atf_error_is(err, "libc")); data = atf_error_data(err); return data->m_errno; }
const char * atf_libc_error_msg(const atf_error_t err) { const struct atf_libc_error_data *data; PRE(atf_error_is(err, "libc")); data = atf_error_data(err); return data->m_what; }
static void libc_format(const atf_error_t err, char *buf, size_t buflen) { const atf_libc_error_data_t *data; PRE(atf_error_is(err, "libc")); data = atf_error_data(err); snprintf(buf, buflen, "%s: %s", data->m_what, strerror(data->m_errno)); }
static void test_format(const atf_error_t err, char *buf, size_t buflen) { const test_error_data_t* data; PRE(atf_error_is(err, "test")); data = static_cast< const test_error_data_t * >(atf_error_data(err)); snprintf(buf, buflen, "Message: %s", data->m_msg); }
ATF_TC_BODY(error_new_wo_memory, tc) { atf_error_t err; void *invalid; invalid = (void *)1; err = atf_error_new("test_error", invalid, SIZE_MAX, NULL); ATF_REQUIRE(atf_error_is(err, "no_memory")); ATF_REQUIRE(atf_error_data(err) == NULL); atf_error_free(err); }
static void unknown_type_format(const atf_error_t err, char *buf, size_t buflen) { const unknown_type_error_data_t *data; PRE(atf_error_is(err, "unknown_type")); data = atf_error_data(err); snprintf(buf, buflen, "Unknown file type %d of %s", data->m_type, data->m_path); }
ATF_TC_BODY(init_rep, tc) { const size_t maxlen = 8192; char buf[maxlen + 1]; size_t i; buf[0] = '\0'; for (i = 0; i < maxlen; i++) { atf_dynstr_t str; RE(atf_dynstr_init_rep(&str, i, 'a')); if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { fprintf(stderr, "Failed at iteration %zd\n", i); atf_tc_fail("Failed to construct dynstr by repeating %zd " "times the '%c' character", i, 'a'); } atf_dynstr_fini(&str); strcat(buf, "a"); } { atf_dynstr_t str; atf_error_t err; err = atf_dynstr_init_rep(&str, SIZE_MAX, 'a'); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "no_memory")); atf_error_free(err); err = atf_dynstr_init_rep(&str, SIZE_MAX - 1, 'a'); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "no_memory")); atf_error_free(err); } }
static void invalid_umask_format(const atf_error_t err, char *buf, size_t buflen) { const invalid_umask_error_data_t *data; PRE(atf_error_is(err, "invalid_umask")); data = atf_error_data(err); snprintf(buf, buflen, "Could not create the temporary %s %s because " "it will not have enough access rights due to the current " "umask %05o", stat_type_to_string(data->m_type), data->m_path, (unsigned int)data->m_umask); }
static void print_error(const atf_error_t err) { char buf[4096]; PRE(atf_is_error(err)); atf_error_format(err, buf, sizeof(buf)); fprintf(stderr, "%s: ERROR: %s\n", progname, buf); if (atf_error_is(err, "usage")) fprintf(stderr, "%s: See atf-test-program(1) for usage details.\n", progname); }
atf_error_t atf_fs_exists(const atf_fs_path_t *p, bool *b) { atf_error_t err; err = atf_fs_eaccess(p, atf_fs_access_f); if (atf_is_error(err)) { if (atf_error_is(err, "libc") && atf_libc_error_code(err) == ENOENT) { atf_error_free(err); err = atf_no_error(); *b = false; } } else *b = true; return err; }
ATF_TC_BODY(rmdir_enotempty, tc) { atf_fs_path_t p; atf_error_t err; RE(atf_fs_path_init_fmt(&p, "test-dir")); ATF_REQUIRE(mkdir("test-dir", 0755) != -1); ATF_REQUIRE(exists(&p)); create_file("test-dir/foo", 0644); err = atf_fs_rmdir(&p); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOTEMPTY); atf_error_free(err); atf_fs_path_fini(&p); }
ATF_TC_BODY(exec_umask, tc) { atf_check_result_t result; atf_fs_path_t process_helpers; const char *argv[3]; get_process_helpers_path(tc, false, &process_helpers); argv[0] = atf_fs_path_cstring(&process_helpers); argv[1] = "exit-success"; argv[2] = NULL; umask(0222); atf_error_t err = atf_check_exec_array(argv, &result); ATF_CHECK(atf_is_error(err)); ATF_CHECK(atf_error_is(err, "invalid_umask")); atf_error_free(err); atf_fs_path_fini(&process_helpers); }
ATF_TC_BODY(exists, tc) { atf_error_t err; atf_fs_path_t pdir, pfile; bool b; RE(atf_fs_path_init_fmt(&pdir, "dir")); RE(atf_fs_path_init_fmt(&pfile, "dir/file")); create_dir(atf_fs_path_cstring(&pdir), 0755); create_file(atf_fs_path_cstring(&pfile), 0644); printf("Checking existence of a directory\n"); RE(atf_fs_exists(&pdir, &b)); ATF_REQUIRE(b); printf("Checking existence of a file\n"); RE(atf_fs_exists(&pfile, &b)); ATF_REQUIRE(b); /* XXX: This should probably be a separate test case to let the user * be aware that some tests were skipped because privileges were not * correct. */ if (!atf_user_is_root()) { printf("Checking existence of a file inside a directory without " "permissions\n"); ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0000) != -1); err = atf_fs_exists(&pfile, &b); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0755) != -1); atf_error_free(err); } printf("Checking existence of a non-existent file\n"); ATF_REQUIRE(unlink(atf_fs_path_cstring(&pfile)) != -1); RE(atf_fs_exists(&pfile, &b)); ATF_REQUIRE(!b); atf_fs_path_fini(&pfile); atf_fs_path_fini(&pdir); }
ATF_TC_BODY(mkdtemp_err, tc) { atf_error_t err; atf_fs_path_t p; ATF_REQUIRE(mkdir("dir", 0555) != -1); RE(atf_fs_path_init_fmt(&p, "dir/testdir.XXXXXX")); err = atf_fs_mkdtemp(&p); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_CHECK_EQ(atf_libc_error_code(err), EACCES); atf_error_free(err); ATF_CHECK(!exists(&p)); ATF_CHECK(strcmp(atf_fs_path_cstring(&p), "dir/testdir.XXXXXX") == 0); atf_fs_path_fini(&p); }
static void do_umask_check(atf_error_t (*const mk_func)(atf_fs_path_t *), atf_fs_path_t *path, const mode_t test_mask, const char *str_mask, const char *exp_name) { char buf[1024]; int old_umask; atf_error_t err; printf("Creating temporary %s with umask %s\n", exp_name, str_mask); old_umask = umask(test_mask); err = mk_func(path); (void)umask(old_umask); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "invalid_umask")); atf_error_format(err, buf, sizeof(buf)); ATF_CHECK(strstr(buf, exp_name) != NULL); ATF_CHECK(strstr(buf, str_mask) != NULL); atf_error_free(err); }
ATF_TC_BODY(rmdir_eperm, tc) { atf_fs_path_t p; atf_error_t err; RE(atf_fs_path_init_fmt(&p, "test-dir/foo")); ATF_REQUIRE(mkdir("test-dir", 0755) != -1); ATF_REQUIRE(mkdir("test-dir/foo", 0755) != -1); ATF_REQUIRE(chmod("test-dir", 0555) != -1); ATF_REQUIRE(exists(&p)); err = atf_fs_rmdir(&p); if (atf_user_is_root()) { ATF_REQUIRE(!atf_is_error(err)); } else { ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE_EQ(atf_libc_error_code(err), EACCES); atf_error_free(err); } atf_fs_path_fini(&p); }
static void child_spawn_loop_and_wait_eintr (void *v) { atf_process_child_t child; atf_process_status_t status; struct sigaction sighup, old_sighup; #define RE_ABORT(expr) \ do { \ atf_error_t _aux_err = expr; \ if (atf_is_error(_aux_err)) { \ atf_error_free(_aux_err); \ abort(); \ } \ } while (0) { atf_process_stream_t outsb, errsb; RE_ABORT (atf_process_stream_init_capture (&outsb)); RE_ABORT (atf_process_stream_init_inherit (&errsb)); RE_ABORT (atf_process_fork (&child, child_loop, &outsb, &errsb, NULL)); atf_process_stream_fini (&outsb); atf_process_stream_fini (&errsb); } sighup.sa_handler = nop_signal; sigemptyset (&sighup.sa_mask); sighup.sa_flags = 0; if (sigaction (SIGHUP, &sighup, &old_sighup) == -1) abort (); printf ("waiting\n"); fflush (stdout); fprintf (stderr, "Child entering wait(2)\n"); atf_error_t err = atf_process_child_wait (&child, &status); fprintf (stderr, "Child's wait(2) terminated\n"); if (!atf_is_error (err)) { fprintf (stderr, "wait completed successfully (not interrupted)\n"); abort (); } if (!atf_error_is (err, "libc")) { fprintf (stderr, "wait did not raise libc_error\n"); abort (); } if (atf_libc_error_code (err) != EINTR) { fprintf (stderr, "libc_error is not EINTR\n"); abort (); } atf_error_free (err); sigaction (SIGHUP, &old_sighup, NULL); fprintf (stderr, "Child is killing subchild\n"); kill (atf_process_child_pid (&child), SIGTERM); RE_ABORT (atf_process_child_wait (&child, &status)); atf_process_status_fini (&status); #undef RE_ABORT exit (EXIT_SUCCESS); }
ATF_TC_BODY(eaccess, tc) { const int modes[] = { atf_fs_access_f, atf_fs_access_r, atf_fs_access_w, atf_fs_access_x, 0 }; const int *m; struct tests { mode_t fmode; int amode; int uerror; int rerror; } tests[] = { { 0000, atf_fs_access_r, EACCES, 0 }, { 0000, atf_fs_access_w, EACCES, 0 }, { 0000, atf_fs_access_x, EACCES, EACCES }, { 0001, atf_fs_access_r, EACCES, 0 }, { 0001, atf_fs_access_w, EACCES, 0 }, { 0001, atf_fs_access_x, EACCES, 0 }, { 0002, atf_fs_access_r, EACCES, 0 }, { 0002, atf_fs_access_w, EACCES, 0 }, { 0002, atf_fs_access_x, EACCES, EACCES }, { 0004, atf_fs_access_r, EACCES, 0 }, { 0004, atf_fs_access_w, EACCES, 0 }, { 0004, atf_fs_access_x, EACCES, EACCES }, { 0010, atf_fs_access_r, EACCES, 0 }, { 0010, atf_fs_access_w, EACCES, 0 }, { 0010, atf_fs_access_x, 0, 0 }, { 0020, atf_fs_access_r, EACCES, 0 }, { 0020, atf_fs_access_w, 0, 0 }, { 0020, atf_fs_access_x, EACCES, EACCES }, { 0040, atf_fs_access_r, 0, 0 }, { 0040, atf_fs_access_w, EACCES, 0 }, { 0040, atf_fs_access_x, EACCES, EACCES }, { 0100, atf_fs_access_r, EACCES, 0 }, { 0100, atf_fs_access_w, EACCES, 0 }, { 0100, atf_fs_access_x, 0, 0 }, { 0200, atf_fs_access_r, EACCES, 0 }, { 0200, atf_fs_access_w, 0, 0 }, { 0200, atf_fs_access_x, EACCES, EACCES }, { 0400, atf_fs_access_r, 0, 0 }, { 0400, atf_fs_access_w, EACCES, 0 }, { 0400, atf_fs_access_x, EACCES, EACCES }, { 0, 0, 0, 0 } }; struct tests *t; atf_fs_path_t p; atf_error_t err; RE(atf_fs_path_init_fmt(&p, "the-file")); printf("Non-existent file checks\n"); for (m = &modes[0]; *m != 0; m++) { err = atf_fs_eaccess(&p, *m); ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOENT); atf_error_free(err); } create_file(atf_fs_path_cstring(&p), 0000); ATF_REQUIRE(chown(atf_fs_path_cstring(&p), geteuid(), getegid()) != -1); for (t = &tests[0]; t->amode != 0; t++) { const int experr = atf_user_is_root() ? t->rerror : t->uerror; printf("\n"); printf("File mode : %04o\n", (unsigned int)t->fmode); printf("Access mode : 0x%02x\n", t->amode); ATF_REQUIRE(chmod(atf_fs_path_cstring(&p), t->fmode) != -1); /* First, existence check. */ err = atf_fs_eaccess(&p, atf_fs_access_f); ATF_REQUIRE(!atf_is_error(err)); /* Now do the specific test case. */ printf("Expected error: %d\n", experr); err = atf_fs_eaccess(&p, t->amode); if (atf_is_error(err)) { if (atf_error_is(err, "libc")) printf("Error : %d\n", atf_libc_error_code(err)); else printf("Error : Non-libc error\n"); } else printf("Error : None\n"); if (experr == 0) { ATF_REQUIRE(!atf_is_error(err)); } else { ATF_REQUIRE(atf_is_error(err)); ATF_REQUIRE(atf_error_is(err, "libc")); ATF_REQUIRE_EQ(atf_libc_error_code(err), experr); atf_error_free(err); } } atf_fs_path_fini(&p); }