static int create_files(struct kernfs_node *parent, struct kobject *kobj, const struct attribute_group *grp, int update) { struct attribute *const *attr; struct bin_attribute *const *bin_attr; int error = 0, i; if (grp->attrs) { for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) { umode_t mode = (*attr)->mode; /* * In update mode, we're changing the permissions or * visibility. Do this by first removing then * re-adding (if required) the file. */ if (update) kernfs_remove_by_name(parent, (*attr)->name); if (grp->is_visible) { mode = grp->is_visible(kobj, *attr, i); if (!mode) continue; } WARN(mode & ~(SYSFS_PREALLOC | 0664), "Attribute %s: Invalid permissions 0%o\n", (*attr)->name, mode); mode &= SYSFS_PREALLOC | 0664; error = sysfs_add_file_mode_ns(parent, *attr, false, mode, NULL); if (unlikely(error)) break; } if (error) { remove_files(parent, grp); goto exit; } } if (grp->bin_attrs) { for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) { if (update) kernfs_remove_by_name(parent, (*bin_attr)->attr.name); error = sysfs_add_file_mode_ns(parent, &(*bin_attr)->attr, true, (*bin_attr)->attr.mode, NULL); if (error) break; } if (error) remove_files(parent, grp); } exit: return error; }
static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, const struct attribute_group *grp, int update) { struct attribute *const* attr; struct bin_attribute *const* bin_attr; int error = 0, i; if (grp->attrs) { for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) { umode_t mode = 0; /* * In update mode, we're changing the permissions or * visibility. Do this by first removing then * re-adding (if required) the file. */ if (update) sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name); if (grp->is_visible) { mode = grp->is_visible(kobj, *attr, i); if (!mode) continue; } error = sysfs_add_file_mode(dir_sd, *attr, SYSFS_KOBJ_ATTR, (*attr)->mode | mode); if (unlikely(error)) break; } if (error) { remove_files(dir_sd, kobj, grp); goto exit; } } if (grp->bin_attrs) { for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) { if (update) sysfs_remove_bin_file(kobj, *bin_attr); error = sysfs_create_bin_file(kobj, *bin_attr); if (error) break; } if (error) remove_files(dir_sd, kobj, grp); } exit: return error; }
void panic(char *str) { errmsg(str); printf("\n"); remove_files(); exit(-1); }
void sys_panic(char *str) { printf("panic\n"); perror(str); remove_files(); exit(-1); }
void *thread_worker_remove(void *arg) { struct my_thread_arg *arg1 = (struct my_thread_arg*)arg; remove_files(arg1->dir, arg1->nums); return NULL; }
/** * sysfs_remove_group: remove a group from a kobject * @kobj: kobject to remove the group from * @grp: group to remove * * This function removes a group of attributes from a kobject. The attributes * previously have to have been created for this group, otherwise it will fail. */ void sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp) { struct kernfs_node *parent = kobj->sd; struct kernfs_node *kn; if (grp->name) { kn = kernfs_find_and_get(parent, grp->name); if (!kn) { WARN(!kn, KERN_WARNING "sysfs group %p not found for kobject '%s'\n", grp, kobject_name(kobj)); return; } } else { kn = parent; kernfs_get(kn); } remove_files(kn, kobj, grp); if (grp->name) kernfs_remove(kn); kernfs_put(kn); }
int file_cmd_cleanup(void) { if (parse_arguments()) return 1; return remove_files(); }
static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, const struct attribute_group *grp, int update) { struct attribute *const* attr; int error = 0, i; for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) { umode_t mode = 0; if (update) sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name); if (grp->is_visible) { mode = grp->is_visible(kobj, *attr, i); if (!mode) continue; } error = sysfs_add_file_mode(dir_sd, *attr, SYSFS_KOBJ_ATTR, (*attr)->mode | mode); if (unlikely(error)) break; } if (error) remove_files(dir_sd, kobj, grp); return error; }
/** @details -# If we have not called init yet (pthread_id == 0), call init. -# Delete existing log files. */ int Trick::DataRecordDispatcher::restart() { // if we restarted from scratch without calling init jobs, need to call init if ( drd_writer_thread.get_pthread_id() == 0 ) { init() ; } // remove the current log files remove_files() ; return 0 ; }
char * get_input_file(Test *test) { char *tmpsuff = "testXXXXXX"; size_t tmplen = strlen(P_tmpdir) + strlen(tmpsuff) + 2; char *name = malloc(tmplen); size_t offset = 0; int fd; if (NULL == name) { perror(NULL); return NULL; } /* Make a temporary file */ snprintf(name, tmplen, "%s/%s", P_tmpdir, tmpsuff); fd = mkstemp(name); if (-1 == fd) { fprintf(stderr, "Couldn't make temporary file %s : %s\n", name, strerror(errno)); free(name); return NULL; } /* Fill it with test data */ if (gen_data(name, fd, test->in_len, &offset, 0, 0) < 0) { remove_files(&name, 1); free(name); return NULL; } assert(offset == test->in_len); /* Close fd as no longer needed */ if (0 != close(fd)) { fprintf(stderr, "Error closing temporary file %s : %s\n", name, strerror(errno)); remove_files(&name, 1); free(name); return NULL; } return name; }
/** * driver exit point */ static void __exit etm_exit(void) { kfree(tracer.etm_info); kfree(tracer.etm_regs); remove_files(); if (misc_deregister(&etm_device)) { pr_err("Fail to deregister dervice\n"); } }
static int cnv_board_dir(struct boardheader *bh, void *arg) { printf("=======================================\n"); printf("Boardname: %s\n", bh->filename); build_dir(bh->filename); convert_normal(bh->filename); convert_delete(bh->filename); convert_junk(bh->filename); convert_ding(bh->filename); remove_files(bh->filename); return 0; }
static int create_files(struct sysfs_dirent *dir_sd, const struct attribute_group *grp) { struct attribute *const* attr; int error = 0; for (attr = grp->attrs; *attr && !error; attr++) error = sysfs_add_file(dir_sd, *attr, SYSFS_KOBJ_ATTR); if (error) remove_files(dir_sd, grp); return error; }
int file_cmd_prepare(void) { if (parse_arguments()) return 1; /* Make sure that files do not exist for 'sequential write' test mode, create test files for other test modes */ if (test_mode == MODE_WRITE) return remove_files(); return create_files(); }
/* * setup() - performs all ONE TIME setup for this test. */ void setup() { int max_open; tst_sig(NOFORK, DEF_HANDLER, cleanup); TEST_PAUSE; /* make a temporary directory and cd to it */ tst_tmpdir(); umask(0); mypid = getpid(); sprintf(fname, "creat05.%d", mypid); unlink(fname); /* create a file to get the first file descriptor available */ if ((first = fd = creat(fname, MODE)) == -1) { tst_brkm(TFAIL, cleanup, "Cannot open first file"); } close(fd); unlink(fname); tst_resm(TINFO, "first file is #%d", fd); /* get the maximum number of files that we can open */ max_open = getdtablesize(); /* Allocate memory for stat and ustat structure variables */ if ((buf = (int *)malloc(sizeof(int) * max_open - first)) == NULL) { tst_brkm(TBROK, NULL, "Failed to allocate Memory"); } /* now open as many files as we can up to max_open */ for (ifile = first; ifile <= max_open; ifile++) { sprintf(fname, "creat05.%d.%d", ifile, mypid); if ((fd = creat(fname, 0666)) == -1) { tst_resm(TINFO, "could not creat file " "#%d", ifile + 1); if (errno != EMFILE) { remove_files(ifile); tst_brkm(TBROK | TERRNO, cleanup, "Failed unexpectedly (expected EMFILE)"); } break; } buf[ifile - first] = fd; } }
void sysfs_remove_group(struct kobject * kobj, const struct attribute_group * grp) { struct dentry * dir; if (grp->name) dir = lookup_one_len(grp->name, kobj->dentry, strlen(grp->name)); else dir = dget(kobj->dentry); remove_files(dir,grp); if (grp->name) sysfs_remove_subdir(dir); /* release the ref. taken in this routine */ dput(dir); }
void sysfs_remove_group(struct kobject * kobj, const struct attribute_group * grp) { struct sysfs_dirent *dir_sd = kobj->sd; struct sysfs_dirent *sd; if (grp->name) { sd = sysfs_get_dirent(dir_sd, grp->name); BUG_ON(!sd); } else sd = sysfs_get(dir_sd); remove_files(sd, grp); if (grp->name) sysfs_remove_subdir(sd); sysfs_put(sd); }
/*********************************************** Method: process_client_removal_request Description: Remove the clients files & connection information ***********************************************/ static void process_client_removal_request ( p2p_serv_conn_info_t * conn, void * request ) { int i; /*---------------------------------------- Send the response ----------------------------------------*/ udp_rdt_send_response( UDP_RDT_RESP_ID_OK, &conn->serv_state, &conn->client, NULL, 0 ); /*---------------------------------------- Remove all files given by conn ----------------------------------------*/ remove_files(conn); }
int main(int ac, char **av) { int lc; char *msg; if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); TEST_EXP_ENOS(exp_enos); for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; TEST(creat(fname, MODE)); if (TEST_RETURN != -1) { tst_resm(TFAIL, "call succeeded unexpectedly"); continue; } TEST_ERROR_LOG(TEST_ERRNO); if (TEST_ERRNO == EMFILE) { tst_resm(TPASS, "call failed with expected error - " "EMFILE"); } else { tst_resm(TFAIL | TTERRNO, "Expected EMFILE"); } remove_files(ifile); } cleanup(); tst_exit(); }
void sysfs_remove_group(struct kobject * kobj, const struct attribute_group * grp) { struct sysfs_dirent *dir_sd = kobj->sd; struct sysfs_dirent *sd; if (grp->name) { sd = sysfs_get_dirent(dir_sd, NULL, grp->name); if (!sd) { WARN(!sd, KERN_WARNING "sysfs group %p not found for " "kobject '%s'\n", grp, kobject_name(kobj)); return; } } else sd = sysfs_get(dir_sd); remove_files(sd, kobj, grp); if (grp->name) sysfs_remove_subdir(sd); sysfs_put(sd); }
int run_main (int argc, ACE_TCHAR *argv []) { ACE_START_TEST (ACE_TEXT ("Logging_Strategy_Test")); ACE_TCHAR *l_argv[4]; if (argc > 1) { if (parse_args (argc, argv) == -1) ACE_ERROR_RETURN ((LM_ERROR, "Invalid command-line parameters.\n"), 1); } else { l_argv[0] = argv[0]; l_argv[1] = (ACE_TCHAR *) ACE_TEXT ("-slog/Logging_Strategy_Test") ACE_LOG_FILE_EXT_NAME; l_argv[2] = (ACE_TCHAR *) ACE_TEXT ("-o"); l_argv[3] = 0; if (parse_args (3, l_argv) == -1) ACE_ERROR_RETURN ((LM_ERROR, "Invalid command-line parameters.\n"), 1); argv = l_argv; argc = 3; } // Remove existing files. remove_files (); // This is necessary only if the provided logfile name is the same // as the default name. If so, nothing will be written as the // previous ofstream is closed only at the end (ACE_END_TEST) ACE_CLOSE_TEST_LOG; // When Dlls are used, we utilize the dynamic service configuration // mechanism to activate the logging strategy. This is not a must // though, and you may activate the logging strategy as described in // the non-DLL section below under DLL environments as well. #if !defined (ACE_HAS_STATIC_LIBS) && \ (defined (ACE_WIN32) || defined (ACE_HAS_SVR4_DYNAMIC_LINKING) || \ defined (__hpux)) // Platform support DLLs, and not configured to link statically ACE_TCHAR arg_str[250]; ACE_OS::sprintf (arg_str, ACE_TEXT ("dynamic Logger Service_Object ") ACE_TEXT ("*ACE:_make_ACE_Logging_Strategy()") ACE_TEXT ("\"")); for (int i = 1; i < argc; i++) { ACE_OS::strcat (arg_str, argv[i]); ACE_OS::strcat (arg_str, ACE_TEXT (" ")); } ACE_OS::strcat (arg_str, ACE_TEXT ("\"")); if (ACE_Service_Config::process_directive (arg_str) == -1) ACE_ERROR_RETURN ((LM_ERROR, "Error opening _make_ACE_Log_Strategy.\n"), 1); #else // Platform doesn't support DLLs, or configured to link // statically ACE_Logging_Strategy logging_strategy; char ls_argc = argc - 1; ACE_Auto_Basic_Ptr<ACE_TCHAR *> ls_argv (new ACE_TCHAR *[ls_argc]); for (char c = 0; c < ls_argc; c++) (ls_argv.get ())[c] = argv[c+1]; if (logging_strategy.init (ls_argc, ls_argv.get ()) == -1) ACE_ERROR_RETURN ((LM_ERROR, "Error initializing the ACE_Logging_Strategy.\n"), 1); #endif /* !ACE_HAS_STATIC_LIBS && (ACE_WIN32 || ACE_HAS_SVR4_DYNAMIC_LINKING || __hpux) */ // launch a new Thread if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (run_reactor)) == -1) ACE_ERROR_RETURN ((LM_ERROR, "Spawning Reactor.\n"), 1); // Function to print the message print_till_death (); // Counts the generated files count_files (); // Get the file order order (); // Wait for the thread to exit before we exit. ACE_Thread_Manager::instance ()->wait (); ACE_END_TEST; return 0; }
int main() { PASS_TWO(); remove_files(); }
int run_test(int argc, char **argv, unsigned int test_num, Test *test, char **fifos) { char *in_file = NULL; int in_fd = -1; char **out_files = NULL; int *out_fds = NULL; int fifo_fds[MAX_READERS]; pid_t child = 0; int i, res = 0, wres; /* Write some information about the test to the log */ print_test_info(test_num, test); assert(test->npipes <= MAX_READERS); for (i = 0; i < MAX_READERS; i++) fifo_fds[i] = -1; /* Open any output files needed */ if (test->nfiles > 0) { if (0 != get_output_files(test, &out_files, &out_fds)) goto BAIL; } /* Create an input file if the test needs one */ if (test->in_type == IN_FILE) { if (NULL == (in_file = get_input_file(test))) goto BAIL; } /* Start the program under test */ child = start_prog(argc, argv, test, &in_fd, in_file, fifos, out_files); if (child < 0) goto BAIL; /* Open any named pipes required */ if (test->npipes > 0) { if (0 != open_fifos(test->npipes, fifos, fifo_fds)) goto BAIL; } if (test->npipes) { /* reading from pipes, run the full poll loop */ res = run_poll_loop(test, in_fd, fifo_fds, fifos); /* Close any pipes that are still open */ if (0 != close_fifos(test->npipes, fifos, fifo_fds)) { res = -1; } } else if (test->in_type == IN_PIPE || test->in_type == IN_SLOW_PIPE) { /* only sending to a pipe, so just shove the data down it */ size_t offset = 0; if (gen_data("pipe", in_fd, test->in_len, &offset, 0, 0) != test->in_len) { res = -1; } if (0 != close(in_fd)) { perror("Closing pipe"); res = -1; } } /* Wait for the program to finish and check the exit status */ wres = wait_child(child); if (-99 == wres) goto BAIL; if (wres < 0) res = -1; /* Check the contents of any regular files that were created */ if (test->nfiles > 0) { if (0 != check_output_files(test, out_fds, out_files)) res = -1; } /* Clean up */ if (NULL != in_file) remove_files(&in_file, 1); if (test->nfiles > 0) { remove_files(out_files, test->nfiles); } return res; BAIL: /* Something went wrong, clean up and return 99 */ if (NULL != in_file) remove_files(&in_file, 1); if (test->nfiles > 0 && NULL != out_files) { remove_files(out_files, test->nfiles); } if (test->npipes > 0) { close_fifos(test->npipes, fifos, fifo_fds); } return 99; }
int run_tests(int argc, char **argv) { char *fifos[MAX_READERS] = { NULL }; /* The test schedule */ TestSegment test_segs1[1] = {{{ 100 }}}; TestSegment test_segs2[1] = {{{ 100, 100 }}}; TestSegment test_segs3[2] = {{{ 100, 0 }}, {{ 0, 100 }}}; TestSegment test_segs4[1] = {{{ 100, -1 }}}; TestSegment test_segs5[2] = {{{ 50, 50 }}, {{ -1, -1 }}}; TestSegment test_segs6[2] = {{{ 100, 100 }}, {{ -1, 900 }}}; TestSegment test_segs7[20] = {{{1000000, 0}}, {{0, 1000000}}, {{1000000, 0}}, {{0, 1000000}}, {{1000000, 0}}, {{0, 1000000}}, {{1000000, 0}}, {{0, 1000000}}, {{1000000, 0}}, {{0, 1000000}}, {{1000000, 0}}, {{0, 1000000}}, {{1000000, 0}}, {{0, 1000000}}, {{1000000, 0}}, {{0, 1000000}}, {{1000000, 0}}, {{0, 1000000}}, {{1000000, 0}}, {{0, 1000000}}}; TestSegment test_segs8[3] = {{{1000000, 1000000}}, {{8000000, -1}}, {{1000000, -1}}}; TestSegment test_segs9[2] = {{{10000000, 0}}, {{0, 10000000}}}; TestSegment test_segs10[2] = {{{1000000, 100}}, {{-1, -1}}}; Test tests[] = {{ 100, IN_PIPE, 1, 0, 0, 1, NULL }, { 100, IN_PIPE, 2, 0, 0, 1, NULL }, { 100, IN_PIPE, 0, 1, 1, 1, test_segs1 }, { 100, IN_PIPE, 0, 1, 2, 1, test_segs2 }, { 100, IN_PIPE, 0, 2, 2, 1, test_segs3 }, { 100, IN_PIPE, 0, 1, 2, 1, test_segs4 }, { 100, IN_PIPE, 0, 2, 2, 1, test_segs5 }, { 1000, IN_PIPE, 0, 2, 2, 7, test_segs6 }, { 10000000, IN_PIPE, 0, 20, 2, 167, test_segs7 }, { 10000000, IN_PIPE, 0, 20, 2, 167, test_segs7 }, { 10000000, IN_PIPE, 0, 3, 2, 167, test_segs8 }, { 10000000, IN_PIPE, 0, 2, 2, 167, test_segs9 }, { 10000000, IN_PIPE, 0, 2, 2, 167, test_segs10 }, { 10000000, IN_PIPE, 1, 2, 2, 167, test_segs10 }, }; unsigned int ntests = sizeof(tests) / sizeof(tests[0]); unsigned int i, res, failed = 0, test_num = 0; /* Create the named pipes */ if (0 != make_fifos(fifos)) { res = 99; goto BAIL; } /* Print the expected number of tests for the driver */ printf("1..%u\n", ntests * 3); /* Run all the tests twice, once reading a pipe and once reading a file */ for (i = 0; i < ntests; i++) { Test t = tests[i]; for (t.in_type = IN_PIPE; t.in_type <= IN_FILE; t.in_type++) { res = run_test(argc, argv, ++test_num, &t, fifos); /* Print the result to the driver */ printf("%s %d - %s\n", res ? "not ok" : "ok", test_num, summarize_test(&t)); failed |= res; if (res == 99) break; } if (res == 99) break; } BAIL: if (res == 99) { /* Fatal error, tell the driver we gave up */ printf("Bail out!\n"); } /* Clean up and return the overall result */ remove_files(fifos, MAX_READERS); return failed; }
int get_output_files(Test *test, char ***out_files_out, int **out_fds_out) { char **out_files = NULL; int *out_fds = NULL; char *tmpsuff = "testXXXXXX"; size_t tmplen = strlen(P_tmpdir) + strlen(tmpsuff) + 2; unsigned int i = 0; /* Create the out_files and out_fds arrays */ out_files = calloc(test->nfiles, sizeof(char *)); if (NULL == out_files) { perror(NULL); goto fail; } out_fds = malloc(test->nfiles * sizeof(int)); if (NULL == out_fds) { perror(NULL); goto fail; } for (i = 0; i < test->nfiles; i++) out_fds[i] = -1; for (i = 0; i < test->nfiles; i++) { /* Allocate space for the name */ out_files[i] = malloc(tmplen); if (NULL == out_files[i]) { perror(NULL); goto fail; } /* Try to make the file */ snprintf(out_files[i], tmplen, "%s/%s", P_tmpdir, tmpsuff); out_fds[i] = mkstemp(out_files[i]); if (-1 == out_fds[i]) { fprintf(stderr, "Couldn't make temporary file %s : %s\n", out_files[i], strerror(errno)); free(out_files[i]); /* Remove unused name on failure */ out_files[i] = NULL; goto fail; } } /* Pass back the array locations */ *out_files_out = out_files; *out_fds_out = out_fds; return 0; fail: /* Clean up */ if (NULL != out_files) { unsigned int j; if (i > 0) remove_files(out_files, i); for (j = 0; j < i; j++) { free(out_files[j]); } free(out_files); } if (NULL != out_fds) free(out_fds); return -1; }
RETINFO_t * map_and_thread( char *tmpfile, /* name of temporary file to be created */ void *(*exec_func)(void *), /* thread function to execute */ int fault_type, /* type of fault to be generated */ int num_thread, /* number of threads to create */ RETINFO_t *retinfo) /* return map address and oper status */ { int fd = 0; /* file descriptor of the file created */ int thrd_ndx = 0; /* index to the number of threads created */ int map_type = 0; /* specifies the type of the mapped object */ int *th_status = 0; /* status of the thread when it is finished */ long th_args[5]; /* argument list passed to thread_fault() */ char *empty_buf = NULL; /* empty buffer used to fill temp file */ long pagesize /* contains page size at runtime */ = sysconf(_SC_PAGESIZE); static pthread_t pthread_ids[NUMTHREAD]; /* contains ids of the threads created */ caddr_t map_addr = NULL; /* address where the file is mapped */ /* Create a file with permissions 0666, and open it with RDRW perms */ /* if the name is not a NULL */ if (strcmp(tmpfile, "NULL")) { if ((fd = open(tmpfile, O_RDWR|O_CREAT, S_IRWXO|S_IRWXU|S_IRWXG)) == -1 ) { perror("map_and_thread(): open()"); close(fd); fflush(NULL); retinfo->status = FAILED; return retinfo; } /* Write pagesize * pages_num bytes to the file */ empty_buf = (char *)malloc(pagesize*pages_num); if (write(fd, empty_buf, pagesize*pages_num) != (pagesize*pages_num)) { perror("map_and_thread(): write()"); free(empty_buf); fflush(NULL); remove_files(tmpfile, NULL); close(fd); retinfo->status = FAILED; return retinfo; } map_type = (fault_type == COW_FAULT) ? MAP_PRIVATE : MAP_SHARED; /* Map the file, if the required fault type is COW_FAULT map the file */ /* private, else map the file shared. if READ_FAULT is required to be */ /* generated map the file with read protection else map with read - */ /* write protection. */ if ((map_addr = (caddr_t)mmap(0, pagesize*pages_num, ((fault_type == READ_FAULT) ? PROT_READ : PROT_READ|PROT_WRITE), map_type, fd, 0)) == MAP_FAILED) { perror("map_and_thread(): mmap()"); free(empty_buf); fflush(NULL); remove_files(tmpfile, NULL); close(fd); retinfo->status = FAILED; return retinfo; } else { retinfo->mapaddr = map_addr; if (verbose_print) tst_resm(TINFO, "map_and_thread(): mmap success, address = %p", map_addr); fflush(NULL); } } /* As long as wait is set to TRUE, the thread that will be created will */ /* loop in its exec routine */ wait_thread = TRUE; /* Create a few threads, ideally number of threads equals number of CPU'S */ /* so that we can assume that each thread will run on a single CPU in */ /* of SMP machines. Currently we will create NR_CPUS number of threads. */ th_args[1] = (long)map_addr; th_args[2] = pagesize; th_args[3] = fault_type; do { th_args[0] = thrd_ndx; th_args[4] = (long)0; /*************************************************************/ /* The way it was, args could be overwritten by subsequent uses * of it before the called routine had a chance to fully initialize. * This flag stops the overwrite until that routine gets to * begin. At that point, it is done initializing and it is * safe for the this thread to continue (which will change * args). * A basic race condition. */ thread_begin = TRUE; if (pthread_create(&pthread_ids[thrd_ndx++], NULL, exec_func, (void *)&th_args)) { perror("map_and_thread(): pthread_create()"); thread_begin = FALSE; free(empty_buf); fflush(NULL); remove_files(tmpfile, map_addr); close(fd); retinfo->status = FAILED; return retinfo; } else { /***************************************************/ /* Yield until new thread is done with args. */ while (thread_begin) sched_yield(); } } while (thrd_ndx < num_thread); if (verbose_print) tst_resm(TINFO, "map_and_thread(): pthread_create() success"); wait_thread = FALSE; th_status = malloc(sizeof(int *)); /* suspend the execution of the calling thread till the execution of the */ /* other thread has been terminated. */ for (thrd_ndx = 0; thrd_ndx < NUMTHREAD; thrd_ndx++) { if (pthread_join(pthread_ids[thrd_ndx], (void **)th_status)) { perror("map_and_thread(): pthread_join()"); free(empty_buf); fflush(NULL); remove_files(tmpfile, map_addr); close(fd); retinfo->status = FAILED; return retinfo; } else { if ((int)*th_status == 1) { tst_resm(TINFO, "thread [%ld] - process exited with errors", (long)pthread_ids[thrd_ndx]); free(empty_buf); remove_files(tmpfile, map_addr); close(fd); exit(1); } } } /* remove the temporary file that was created. - clean up */ /* but dont try to remove special files. */ /***********************************************/ /* Was if !(remove_files()) ... * If that routine succeeds, it returns SUCCESS, which * happens to be 0. So if the routine succeeded, the * above condition would indicate failure. This change * fixes that. */ if (remove_files(tmpfile, map_addr) == FAILED) { free(empty_buf); free(th_status); retinfo->status = FAILED; return retinfo; } free(empty_buf); free(th_status); close(fd); retinfo->status = SUCCESS; return retinfo; }