void check(tree_node_t *tree) { if (tree == NULL) return; if(tree->data->pid == PID_UNDEFINED) { if (tree->first_child != NULL) { kill_all(tree->first_child); } start_self(tree); if (tree->first_child != NULL) { start_all(tree->first_child); } } else { if (tree->first_child != NULL) { check(tree->first_child); } } if (tree->next_sibling != NULL) { check(tree->next_sibling); } }
/** * Catches SIGUSR2 and restarts the external process * */ void PCAPExporterPipe::handleSigUsr2(int sig) { if (! restartOnSignal) return; int pid = fifoReaderPid; fifoReaderPid = 0; kill_all(pid); handleSigChld(sig); }
int main(int argc, char ** argv) { int pid[NRTASKS], i, parm[NRTASKS], ret; test_init(argc, argv); parm[0] = -20; parm[1] = 19; parm[2] = 1; for (i = 0; i < NRTASKS; i++) { pid[i] = fork(); if (!pid[i]) return do_nothing(); if (setpriority(PRIO_PROCESS, pid[i], parm[i])) { pr_perror("Can't set prio %d", i); kill_all(pid, i); return -1; } } test_daemon(); test_waitsig(); for (i = 0; i < NRTASKS; i++) { errno = 0; ret = getpriority(PRIO_PROCESS, pid[i]); if (errno) { fail("No prio for task %d", i); break; } if (ret != parm[i]) { fail("Broken nice for %d", i); break; } } if (i == NRTASKS) pass(); kill_all(pid, NRTASKS); return 0; }
void PCAPExporterPipe::stopProcess() { close(pcapFile); if (fifoReaderPid != 0 ) { kill_all(fifoReaderPid); } msg(MSG_INFO, "Stopped process with fifoReaderCmd \'%s\' and fifoReaderPid = %d", fifoReaderCmd.c_str(), fifoReaderPid); }
/** * Kills the process with PID fifoReaderPid and deletes the shared memory segment */ void PCAPExporterMem::stopProcess() { std::string name = "/" + boost::lexical_cast<std::string>(fifoReaderPid); if (fifoReaderPid != 0 ) { kill_all(fifoReaderPid); } removeSHM(fifoReaderPid); msg(MSG_INFO, "PCAPExporterMem: stopped process with fifoReaderCmd \'%s\' and fifoReaderPid = %d", fifoReaderCmd.c_str(), fifoReaderPid); }
/** * Creates a new shared memory of size "size". * Returns a pointer to the newly allocated memory */ void *PCAPExporterMem::getNewSharedMemory(int *fd, int size, std::string name) { if ((*fd = shm_open(name.c_str(), O_CREAT | O_EXCL | O_RDWR, 00666)) == -1) { int err = errno; if (fifoReaderPid) kill_all(fifoReaderPid); THROWEXCEPTION("shm_open failed: %s", strerror(err)); } if (ftruncate(*fd, size)) { int err = errno; if(fifoReaderPid) kill_all(fifoReaderPid); THROWEXCEPTION("ftruncate failed: %s", strerror(err)); } void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0); if (ptr == NULL) { int err = errno; if(fifoReaderPid) kill_all(fifoReaderPid); THROWEXCEPTION("mmap failed: %s", strerror(err)); } return ptr; }
void release_all_resources() { int ret; ret = lib.deinit(); if (ret == -1) LOG("Library termination failed\n"); kill_all(); release_data(); fflush(stderr); fclose(stderr); }
void PCAPExporterPipe::performShutdown() { SignalHandler::getInstance().unregisterSignalHandler(SIGCHLD, this); SignalHandler::getInstance().unregisterSignalHandler(SIGPIPE, this); if(restartOnSignal) SignalHandler::getInstance().unregisterSignalHandler(SIGUSR2, this); msg(MSG_DEBUG, "Performing shutdown for PID %d", fifoReaderPid); sleep(1); if (dumper) { if (-1 == pcap_dump_flush(dumper)) { msg(MSG_FATAL, "PCAPExporterPipe: Could not flush dump file"); } pcap_dump_close(dumper); if (fifoReaderPid != 0 ) { kill_all(fifoReaderPid); } } }
int close_jobs() { register struct process *pw = pwlist; register int count = 0; if((states&MONITOR)==0) return(0); # ifdef SXT for(;pw;pw=pw->p_next) { if((pw->p_flag&P_STOPPED)==0) continue; if(beenhere) kill(-pw->p_pgrp,SIGTERM); count++; } # endif /* SXT */ if(beenhere++ == 0 && pwlist && login_sh) # ifdef SXT { if(count) { fputs(j_terminate,output); return(-1); } if(login_sh || jobstat.maxjob) # endif /* SXT */ { fputs(j_running,output); return(-1); } # ifdef SXT } if(jobstat.maxjob) kill_all(); # endif /* SXT */ return(0); }
/* not really optimal, or efficient, but it's easier this way, and it's not like we are going to be killing thousands, or even tens or processes. */ static void kill_all(DWORD pid, HANDLE process) { HANDLE process_snapshot_h = INVALID_HANDLE_VALUE; if ( !pid ) { pid = get_process_id(process); } process_snapshot_h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); if (INVALID_HANDLE_VALUE != process_snapshot_h) { BOOL ok = TRUE; PROCESSENTRY32 pinfo; pinfo.dwSize = sizeof(PROCESSENTRY32); for ( ok = Process32First(process_snapshot_h,&pinfo); TRUE == ok; ok = Process32Next(process_snapshot_h,&pinfo) ) { if (pinfo.th32ParentProcessID == pid) { /* found a child, recurse to kill it and anything else below it */ HANDLE ph = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pinfo.th32ProcessID); if (NULL != ph) { kill_all(pinfo.th32ProcessID,ph); CloseHandle(ph); } } } CloseHandle(process_snapshot_h); } /* now that the children are all dead, kill the root */ TerminateProcess(process,-2); }
/* Check all file systems, using the /etc/fstab table. */ static int check_all(void) { struct fs_info *fs = NULL; int status = EXIT_OK; int not_done_yet = 1; int passno = 1; int pass_done; if (verbose) fputs("Checking all file systems.\n", stdout); /* * Do an initial scan over the filesystem; mark filesystems * which should be ignored as done, and resolve any "auto" * filesystem types (done as a side-effect of calling ignore()). */ for (fs = filesys_info; fs; fs = fs->next) { if (ignore(fs)) fs->flags |= FLAG_DONE; } /* * Find and check the root filesystem. */ if (!parallel_root) { for (fs = filesys_info; fs; fs = fs->next) { if (LONE_CHAR(fs->mountpt, '/')) break; } if (fs) { if (!skip_root && !ignore(fs)) { fsck_device(fs, 1); status |= wait_many(FLAG_WAIT_ALL); if (status > EXIT_NONDESTRUCT) return status; } fs->flags |= FLAG_DONE; } } /* * This is for the bone-headed user who enters the root * filesystem twice. Skip root will skep all root entries. */ if (skip_root) for (fs = filesys_info; fs; fs = fs->next) if (LONE_CHAR(fs->mountpt, '/')) fs->flags |= FLAG_DONE; while (not_done_yet) { not_done_yet = 0; pass_done = 1; for (fs = filesys_info; fs; fs = fs->next) { if (cancel_requested) break; if (fs->flags & FLAG_DONE) continue; /* * If the filesystem's pass number is higher * than the current pass number, then we don't * do it yet. */ if (fs->passno > passno) { not_done_yet++; continue; } /* * If a filesystem on a particular device has * already been spawned, then we need to defer * this to another pass. */ if (device_already_active(fs->device)) { pass_done = 0; continue; } /* * Spawn off the fsck process */ fsck_device(fs, serialize); fs->flags |= FLAG_DONE; /* * Only do one filesystem at a time, or if we * have a limit on the number of fsck's extant * at one time, apply that limit. */ if (serialize || (max_running && (num_running >= max_running))) { pass_done = 0; break; } } if (cancel_requested) break; if (verbose > 1) printf("--waiting-- (pass %d)\n", passno); status |= wait_many(pass_done ? FLAG_WAIT_ALL : FLAG_WAIT_ATLEAST_ONE); if (pass_done) { if (verbose > 1) printf("----------------------------------\n"); passno++; } else not_done_yet++; } if (cancel_requested && !kill_sent) { kill_all(SIGTERM); kill_sent++; } status |= wait_many(FLAG_WAIT_ATLEAST_ONE); return status; }
/* Check all file systems, using the /etc/fstab table. */ static int check_all(NOARGS) { struct fs_info *fs = NULL; int status = EXIT_OK; int not_done_yet = 1; int passno = 1; int pass_done; if (verbose) printf(_("Checking all file systems.\n")); /* * Do an initial scan over the filesystem; mark filesystems * which should be ignored as done, and resolve LABEL= and * UUID= specifications to the real device. */ for (fs = filesys_info; fs; fs = fs->next) { if (ignore(fs)) fs->flags |= FLAG_DONE; else fs->device = interpret_device(fs->device); } /* * Find and check the root filesystem. */ if (!parallel_root) { for (fs = filesys_info; fs; fs = fs->next) { if (!strcmp(fs->mountpt, "/")) break; } if (fs) { if (!skip_root && !ignore(fs)) { fsck_device(fs->device, 1); status |= wait_all(0); if (status > EXIT_NONDESTRUCT) return status; } fs->flags |= FLAG_DONE; } } /* * This is for the bone-headed user who enters the root * filesystem twice. Skip root will skep all root entries. */ if (skip_root) for (fs = filesys_info; fs; fs = fs->next) if (!strcmp(fs->mountpt, "/")) fs->flags |= FLAG_DONE; while (not_done_yet) { not_done_yet = 0; pass_done = 1; for (fs = filesys_info; fs; fs = fs->next) { if (cancel_requested) break; if (fs->flags & FLAG_DONE) continue; /* * If the filesystem's pass number is higher * than the current pass number, then we don't * do it yet. */ if (fs->passno > passno) { not_done_yet++; continue; } /* * If a filesystem on a particular device has * already been spawned, then we need to defer * this to another pass. */ if (device_already_active(fs->device)) { pass_done = 0; continue; } /* * Spawn off the fsck process */ fsck_device(fs->device, serialize); fs->flags |= FLAG_DONE; /* * Only do one filesystem at a time, or if we * have a limit on the number of fsck's extant * at one time, apply that limit. */ if (serialize || (max_running && (num_running >= max_running))) { pass_done = 0; break; } } if (cancel_requested) break; if (verbose > 1) printf(_("--waiting-- (pass %d)\n"), passno); status |= wait_all(pass_done ? 0 : WNOHANG); if (pass_done) { if (verbose > 1) printf("----------------------------------\n"); passno++; } else not_done_yet++; } if (cancel_requested && !kill_sent) { kill_all(SIGTERM); kill_sent++; } status |= wait_all(0); return status; }
int main(int argc, char *argv[]) { int i; int status = 0; int interactive = 0; char *oldpath = getenv("PATH"); const char *fstab; #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); setlocale(LC_CTYPE, ""); bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); #endif PRS(argc, argv); if (!notitle) printf("fsck %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); fstab = getenv("FSTAB_FILE"); if (!fstab) fstab = _PATH_MNTTAB; load_fs_info(fstab); /* Update our search path to include uncommon directories. */ if (oldpath) { fsck_path = malloc (strlen (fsck_prefix_path) + 1 + strlen (oldpath) + 1); strcpy (fsck_path, fsck_prefix_path); strcat (fsck_path, ":"); strcat (fsck_path, oldpath); } else { fsck_path = string_copy(fsck_prefix_path); } if ((num_devices == 1) || (serialize)) interactive = 1; /* If -A was specified ("check all"), do that! */ if (doall) return check_all(); if (num_devices == 0) { serialize++; interactive++; return check_all(); } for (i = 0 ; i < num_devices; i++) { if (cancel_requested) { if (!kill_sent) { kill_all(SIGTERM); kill_sent++; } break; } fsck_device(devices[i], interactive); if (serialize || (max_running && (num_running >= max_running))) { struct fsck_instance *inst; inst = wait_one(0); if (inst) { status |= inst->exit_status; free_instance(inst); } if (verbose > 1) printf("----------------------------------\n"); } } status |= wait_all(0); free(fsck_path); return status; }
/** * Eventually calls exit(), passing @p code, therefore does not return. * * @param code one of the RERR_* codes from errcode.h. **/ NORETURN void _exit_cleanup(int code, const char *file, int line) { static int switch_step = 0; static int exit_code = 0, exit_line = 0; static const char *exit_file = NULL; static int first_code = 0; SIGACTION(SIGUSR1, SIG_IGN); SIGACTION(SIGUSR2, SIG_IGN); if (!exit_code) { /* Preserve first error exit info when recursing. */ exit_code = code; exit_file = file; exit_line = line < 0 ? -line : line; } /* If this is the exit at the end of the run, the server side * should not attempt to output a message (see log_exit()). */ if (am_server && code == 0) am_server = 2; /* Some of our actions might cause a recursive call back here, so we * keep track of where we are in the cleanup and never repeat a step. */ switch (switch_step) { #include "case_N.h" /* case 0: */ switch_step++; first_code = code; if (output_needs_newline) { fputc('\n', stdout); output_needs_newline = 0; } if (DEBUG_GTE(EXIT, 2)) { rprintf(FINFO, "[%s] _exit_cleanup(code=%d, file=%s, line=%d): entered\n", who_am_i(), code, file, line); } /* FALLTHROUGH */ #include "case_N.h" switch_step++; if (cleanup_child_pid != -1) { int status; int pid = wait_process(cleanup_child_pid, &status, WNOHANG); if (pid == cleanup_child_pid) { status = WEXITSTATUS(status); if (status > exit_code) exit_code = status; } } /* FALLTHROUGH */ #include "case_N.h" switch_step++; if (cleanup_got_literal && (cleanup_fname || cleanup_fd_w != -1)) { if (cleanup_fd_r != -1) { close(cleanup_fd_r); cleanup_fd_r = -1; } if (cleanup_fd_w != -1) { flush_write_file(cleanup_fd_w); close(cleanup_fd_w); cleanup_fd_w = -1; } if (cleanup_fname && cleanup_new_fname && keep_partial && handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) { int tweak_modtime = 0; const char *fname = cleanup_fname; cleanup_fname = NULL; if (!partial_dir) { /* We don't want to leave a partial file with a modern time or it * could be skipped via --update. Setting the time to something * really old also helps it to stand out as unfinished in an ls. */ tweak_modtime = 1; cleanup_file->modtime = 0; } finish_transfer(cleanup_new_fname, fname, NULL, NULL, cleanup_file, tweak_modtime, !partial_dir); } } /* FALLTHROUGH */ #include "case_N.h" switch_step++; if (flush_ok_after_signal) { flush_ok_after_signal = False; if (code == RERR_SIGNAL) io_flush(FULL_FLUSH); } if (!exit_code && !code) io_flush(FULL_FLUSH); /* FALLTHROUGH */ #include "case_N.h" switch_step++; if (cleanup_fname) do_unlink(cleanup_fname); if (exit_code) kill_all(SIGUSR1); if (cleanup_pid && cleanup_pid == getpid()) { char *pidf = lp_pid_file(); if (pidf && *pidf) unlink(lp_pid_file()); } if (exit_code == 0) { if (code) exit_code = code; if (io_error & IOERR_DEL_LIMIT) exit_code = RERR_DEL_LIMIT; if (io_error & IOERR_VANISHED) exit_code = RERR_VANISHED; if (io_error & IOERR_GENERAL || got_xfer_error) exit_code = RERR_PARTIAL; } /* If line < 0, this exit is after a MSG_ERROR_EXIT event, so * we don't want to output a duplicate error. */ if ((exit_code && line > 0) || am_daemon || (logfile_name && (am_server || !INFO_GTE(STATS, 1)))) log_exit(exit_code, exit_file, exit_line); /* FALLTHROUGH */ #include "case_N.h" switch_step++; if (DEBUG_GTE(EXIT, 1)) { rprintf(FINFO, "[%s] _exit_cleanup(code=%d, file=%s, line=%d): " "about to call exit(%d)\n", who_am_i(), first_code, exit_file, exit_line, exit_code); } /* FALLTHROUGH */ #include "case_N.h" switch_step++; if (exit_code && exit_code != RERR_SOCKETIO && exit_code != RERR_STREAMIO && exit_code != RERR_SIGNAL1 && exit_code != RERR_TIMEOUT && !shutting_down && (protocol_version >= 31 || am_receiver)) { if (line > 0) { if (DEBUG_GTE(EXIT, 3)) { rprintf(FINFO, "[%s] sending MSG_ERROR_EXIT with exit_code %d\n", who_am_i(), exit_code); } send_msg_int(MSG_ERROR_EXIT, exit_code); } noop_io_until_death(); } /* FALLTHROUGH */ #include "case_N.h" switch_step++; if (am_server && exit_code) msleep(100); close_all(); /* FALLTHROUGH */ default: break; } exit(exit_code); }
static int check_all(NOARGS) { struct fs_info *fs = NULL; int status = EXIT_OK; int not_done_yet = 1; int passno = 1; int pass_done; if (verbose) fputs(_("Checking all file systems.\n"), stdout); for (fs = filesys_info; fs; fs = fs->next) { if (ignore(fs)) fs->flags |= FLAG_DONE; } if (!parallel_root) { for (fs = filesys_info; fs; fs = fs->next) { if (!strcmp(fs->mountpt, "/")) break; } if (fs) { if (!skip_root && !ignore(fs) && !(ignore_mounted && is_mounted(fs->device))) { fsck_device(fs, 1); status |= wait_many(FLAG_WAIT_ALL); if (status > EXIT_NONDESTRUCT) return status; } fs->flags |= FLAG_DONE; } } if (skip_root) for (fs = filesys_info; fs; fs = fs->next) if (!strcmp(fs->mountpt, "/")) fs->flags |= FLAG_DONE; while (not_done_yet) { not_done_yet = 0; pass_done = 1; for (fs = filesys_info; fs; fs = fs->next) { if (cancel_requested) break; if (fs->flags & FLAG_DONE) continue; if (fs->passno > passno) { not_done_yet++; continue; } if (ignore_mounted && is_mounted(fs->device)) { fs->flags |= FLAG_DONE; continue; } if (device_already_active(fs->device)) { pass_done = 0; continue; } fsck_device(fs, serialize); fs->flags |= FLAG_DONE; if (serialize || (max_running && (num_running >= max_running))) { pass_done = 0; break; } } if (cancel_requested) break; if (verbose > 1) printf(_("--waiting-- (pass %d)\n"), passno); status |= wait_many(pass_done ? FLAG_WAIT_ALL : FLAG_WAIT_ATLEAST_ONE); if (pass_done) { if (verbose > 1) printf("----------------------------------\n"); passno++; } else not_done_yet++; } if (cancel_requested && !kill_sent) { kill_all(SIGTERM); kill_sent++; } status |= wait_many(FLAG_WAIT_ATLEAST_ONE); return status; }
XBT_ATTRIB_DEPRECATED_v323("Please use Actor::kill_all() with no parameter") static void killAll(int resetPid) { kill_all(); }
static struct fsck_instance *wait_one(int flags) { int status; int sig; struct fsck_instance *inst, *inst2, *prev; pid_t pid; if (!instance_list) return NULL; if (noexecute) { inst = instance_list; prev = 0; #ifdef RANDOM_DEBUG while (inst->next && (random() & 1)) { prev = inst; inst = inst->next; } #endif inst->exit_status = 0; goto ret_inst; } inst = prev = NULL; do { pid = waitpid(-1, &status, flags); if (cancel_requested && !kill_sent) { kill_all(SIGTERM); kill_sent++; } if ((pid == 0) && (flags & WNOHANG)) return NULL; if (pid < 0) { if ((errno == EINTR) || (errno == EAGAIN)) continue; if (errno == ECHILD) { fprintf(stderr, _("%s: wait: No more child process?!?\n"), progname); return NULL; } perror("wait"); continue; } for (prev = 0, inst = instance_list; inst; prev = inst, inst = inst->next) { if (inst->pid == pid) break; } } while (!inst); if (WIFEXITED(status)) status = WEXITSTATUS(status); else if (WIFSIGNALED(status)) { sig = WTERMSIG(status); if (sig == SIGINT) { status = EXIT_UNCORRECTED; } else { printf(_("Warning... %s for device %s exited " "with signal %d.\n"), inst->prog, inst->device, sig); status = EXIT_ERROR; } } else { printf(_("%s %s: status is %x, should never happen.\n"), inst->prog, inst->device, status); status = EXIT_ERROR; } inst->exit_status = status; inst->flags |= FLAG_DONE; if (progress && (inst->flags & FLAG_PROGRESS) && !progress_active()) { for (inst2 = instance_list; inst2; inst2 = inst2->next) { if (inst2->flags & FLAG_DONE) continue; if (strcmp(inst2->type, "ext2") && strcmp(inst2->type, "ext3") && strcmp(inst2->type, "ext4") && strcmp(inst2->type, "ext4dev")) continue; if (inst2->start_time < time(0)+2) { if (fork() == 0) { sleep(1); kill(inst2->pid, SIGUSR1); exit(0); } } else kill(inst2->pid, SIGUSR1); inst2->flags |= FLAG_PROGRESS; break; } } ret_inst: if (prev) prev->next = inst->next; else instance_list = inst->next; if (verbose > 1) printf(_("Finished with %s (exit status %d)\n"), inst->device, inst->exit_status); num_running--; return inst; }
int main (int argc, char **argv) { char *name; int sig_num; int optc; int myoptind; struct passwd *pwent = NULL; char yt[16]; char ot[16]; //int optsig = 0; struct option options[] = { {"exact", 0, NULL, 'e'}, {"ignore-case", 0, NULL, 'I'}, {"process-group", 0, NULL, 'g'}, {"younger-than", 1, NULL, 'y'}, {"older-than", 1, NULL, 'o'}, {"interactive", 0, NULL, 'i'}, {"list-signals", 0, NULL, 'l'}, {"quiet", 0, NULL, 'q'}, {"regexp", 0, NULL, 'r'}, {"signal", 1, NULL, 's'}, {"user", 1, NULL, 'u'}, {"verbose", 0, NULL, 'v'}, {"wait", 0, NULL, 'w'}, #ifdef WITH_SELINUX {"context", 1, NULL, 'Z'}, #endif /*WITH_SELINUX*/ {"version", 0, NULL, 'V'}, {0,0,0,0 }}; /* Setup the i18n */ #ifdef ENABLE_NLS setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif #ifdef WITH_SELINUX security_context_t scontext = NULL; regex_t scontext_reg; if ( argc < 2 ) usage(NULL); /* do the obvious thing... */ #endif /*WITH_SELINUX*/ name = strrchr (*argv, '/'); if (name) name++; else name = *argv; sig_num = SIGTERM; opterr = 0; #ifdef WITH_SELINUX while ( (optc = getopt_long_only(argc,argv,"egy:o:ilqrs:u:vwZ:VI",options,NULL)) != -1) { #else while ( (optc = getopt_long_only(argc,argv,"egy:o:ilqrs:u:vwVI",options,NULL)) != -1) { #endif switch (optc) { case 'e': exact = 1; break; case 'g': process_group = 1; break; case 'y': strncpy(yt, optarg, 16); yt[15] = '\0'; if ( 0 >= (younger_than = parse_time_units(yt) ) ) usage(_("Invalid time format")); break; case 'o': strncpy(ot, optarg, 16); ot[15] = '\0'; if ( 0 >= (older_than = parse_time_units(ot) ) ) usage(_("Invalid time format")); break; case 'i': interactive = 1; break; case 'l': list_signals(); return 0; break; case 'q': quiet = 1; break; case 'r': reg = 1; break; case 's': sig_num = get_signal (optarg, "killall"); break; case 'u': if (!(pwent = getpwnam(optarg))) { fprintf (stderr, _("Cannot find user %s\n"), optarg); exit (1); } break; case 'v': verbose = 1; break; case 'w': wait_until_dead = 1; break; case 'I': /* option check is optind-1 but sig name is optind */ if (strcmp(argv[optind-1],"-I") == 0 || strncmp(argv[optind-1],"--",2) == 0) { ignore_case = 1; } else { sig_num = get_signal (argv[optind]+1, "killall"); } break; case 'V': /* option check is optind-1 but sig name is optind */ if (strcmp(argv[optind-1],"-V") == 0 || strncmp(argv[optind-1],"--",2) == 0) { print_version(); return 0; } sig_num = get_signal (argv[optind]+1, "killall"); break; #ifdef WITH_SELINUX case 'Z': if (is_selinux_enabled()>0) { scontext=optarg; if (regcomp(&scontext_reg, scontext, REG_EXTENDED|REG_NOSUB) != 0) { fprintf(stderr, _("Bad regular expression: %s\n"), scontext); exit (1); } } else fprintf(stderr, "Warning: -Z (--context) ignored. Requires an SELinux enabled kernel\n"); break; #endif /*WITH_SELINUX*/ case '?': /* Signal names are in uppercase, so check to see if the argv * is upper case */ if (argv[optind-1][1] >= 'A' && argv[optind-1][1] <= 'Z') { sig_num = get_signal (argv[optind-1]+1, "killall"); } else { /* Might also be a -## signal too */ if (argv[optind-1][1] >= '0' && argv[optind-1][1] <= '9') { sig_num = atoi(argv[optind-1]+1); } else { usage(NULL); } } break; } } myoptind = optind; #ifdef WITH_SELINUX if ((argc - myoptind < 1) && pwent==NULL && scontext==NULL) #else if ((argc - myoptind < 1) && pwent==NULL) #endif usage(NULL); if (argc - myoptind > MAX_NAMES) { fprintf (stderr, _("killall: Maximum number of names is %d\n"), MAX_NAMES); exit (1); } if (!have_proc_self_stat()) { fprintf (stderr, _("killall: %s lacks process entries (not mounted ?)\n"), PROC_BASE); exit (1); } argv = argv + myoptind; /*printf("sending signal %d to procs\n", sig_num);*/ #ifdef WITH_SELINUX return kill_all(sig_num,argc - myoptind, argv, pwent, scontext ? &scontext_reg : NULL); #else /*WITH_SELINUX*/ return kill_all(sig_num,argc - myoptind, argv, pwent); #endif /*WITH_SELINUX*/ }
/** * Eventually calls exit(), passing @p code, therefore does not return. * * @param code one of the RERR_* codes from errcode.h. **/ NORETURN void _exit_cleanup(int code, const char *file, int line) { static int switch_step = 0; static int exit_code = 0, exit_line = 0; static const char *exit_file = NULL; static int unmodified_code = 0; SIGACTION(SIGUSR1, SIG_IGN); SIGACTION(SIGUSR2, SIG_IGN); if (exit_code) { /* Preserve first exit info when recursing. */ code = exit_code; file = exit_file; line = exit_line; } /* If this is the exit at the end of the run, the server side * should not attempt to output a message (see log_exit()). */ if (am_server && code == 0) am_server = 2; /* Some of our actions might cause a recursive call back here, so we * keep track of where we are in the cleanup and never repeat a step. */ switch (switch_step) { #include "case_N.h" /* case 0: */ switch_step++; exit_code = unmodified_code = code; exit_file = file; exit_line = line; if (verbose > 3) { rprintf(FINFO, "[%s] _exit_cleanup(code=%d, file=%s, line=%d): entered\n", who_am_i(), code, file, line); } /* FALLTHROUGH */ #include "case_N.h" switch_step++; if (cleanup_child_pid != -1) { int status; int pid = wait_process(cleanup_child_pid, &status, WNOHANG); if (pid == cleanup_child_pid) { status = WEXITSTATUS(status); if (status > code) code = exit_code = status; } } /* FALLTHROUGH */ #include "case_N.h" switch_step++; if (cleanup_got_literal && cleanup_fname && cleanup_new_fname && keep_partial && handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) { const char *fname = cleanup_fname; cleanup_fname = NULL; if (cleanup_fd_r != -1) bpc_close(cleanup_fd_r); if (cleanup_fd_w != -1) { flush_write_file(cleanup_fd_w); bpc_close(cleanup_fd_w); } finish_transfer(cleanup_new_fname, fname, NULL, NULL, cleanup_file, 0, !partial_dir); } /* FALLTHROUGH */ #include "case_N.h" switch_step++; if (!code || am_server || am_receiver) io_flush(FULL_FLUSH); /* FALLTHROUGH */ #include "case_N.h" switch_step++; bpc_sysCall_cleanup(); if (cleanup_fname) do_unlink(cleanup_fname); if (code) kill_all(SIGUSR1); if (cleanup_pid && cleanup_pid == getpid()) { char *pidf = lp_pid_file(); if (pidf && *pidf) unlink(lp_pid_file()); } if (code == 0) { if (io_error & IOERR_DEL_LIMIT) code = exit_code = RERR_DEL_LIMIT; if (io_error & IOERR_VANISHED) code = exit_code = RERR_VANISHED; if (io_error & IOERR_GENERAL || got_xfer_error) code = exit_code = RERR_PARTIAL; } if (code || am_daemon || (logfile_name && (am_server || !verbose))) log_exit(code, file, line); /* FALLTHROUGH */ #include "case_N.h" switch_step++; if (verbose > 2) { rprintf(FINFO, "[%s] _exit_cleanup(code=%d, file=%s, line=%d): " "about to call exit(%d)\n", who_am_i(), unmodified_code, file, line, code); } /* FALLTHROUGH */ #include "case_N.h" switch_step++; if (am_server && code) msleep(100); close_all(); /* FALLTHROUGH */ default: break; } exit(code); }
static int my_wait( int *status ) { int i, num_active = 0; DWORD exitcode, waitcode; HANDLE active_handles[MAXJOBS]; /* first see if any non-waited-for processes are dead, * and return if so. */ for ( i = 0; i < globs.jobs; i++ ) { int pid = cmdtab[i].pid; if ( pid ) { process_state state = check_process_exit((HANDLE)pid, status, active_handles, &num_active); if ( state == process_error ) goto FAILED; else if ( state == process_finished ) return pid; } } /* if a child exists, wait for it to die */ if ( !num_active ) { errno = ECHILD; return -1; } if ( globs.timeout > 0 ) { unsigned int alert_wait = 1; /* with a timeout we wait for a finish or a timeout, we check every second to see if something timed out */ for (waitcode = WAIT_TIMEOUT; waitcode == WAIT_TIMEOUT; ++alert_wait) { waitcode = WaitForMultipleObjects( num_active, active_handles, FALSE, 1*1000 /* 1 second */ ); if ( waitcode == WAIT_TIMEOUT ) { /* check if any jobs have surpassed the maximum run time. */ for ( i = 0; i < num_active; ++i ) { double t = running_time(active_handles[i]); /* periodically (each 5 secs) check and close message boxes displayed by any of our child processes */ if ((alert_wait % ((unsigned int) 5)) == 0) close_alert(active_handles[i]); if ( t > (double)globs.timeout ) { /* the job may have left an alert dialog around, try and get rid of it before killing */ close_alert(active_handles[i]); /* we have a "runaway" job, kill it */ kill_all(0,active_handles[i]); /* indicate the job "finished" so we query its status below */ waitcode = WAIT_ABANDONED_0+i; } } } } } else { /* no timeout, so just wait indefinately for something to finish */ waitcode = WaitForMultipleObjects( num_active, active_handles, FALSE, INFINITE ); } if ( waitcode != WAIT_FAILED ) { if ( waitcode >= WAIT_ABANDONED_0 && waitcode < WAIT_ABANDONED_0 + num_active ) i = waitcode - WAIT_ABANDONED_0; else i = waitcode - WAIT_OBJECT_0; if ( check_process_exit(active_handles[i], status, 0, 0) == process_finished ) return (int)active_handles[i]; } FAILED: errno = GetLastError(); return -1; }
int fsck_main(int argc, char *argv[]) { int i, status = 0; int interactive = 0; const char *fstab; struct fs_info *fs; setvbuf(stdout, NULL, _IONBF, BUFSIZ); setvbuf(stderr, NULL, _IONBF, BUFSIZ); blkid_get_cache(&cache, NULL); PRS(argc, argv); if (!notitle) printf("fsck %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); fstab = getenv("FSTAB_FILE"); if (!fstab) fstab = _PATH_MNTTAB; load_fs_info(fstab); fsck_path = e2fs_set_sbin_path(); if ((num_devices == 1) || (serialize)) interactive = 1; /* If -A was specified ("check all"), do that! */ if (doall) return check_all(); if (num_devices == 0) { serialize++; interactive++; return check_all(); } for (i = 0 ; i < num_devices; i++) { if (cancel_requested) { if (!kill_sent) { kill_all(SIGTERM); kill_sent++; } break; } fs = lookup(devices[i]); if (!fs) { fs = create_fs_device(devices[i], 0, "auto", 0, -1, -1); if (!fs) continue; } fsck_device(fs, interactive); if (serialize || (max_running && (num_running >= max_running))) { struct fsck_instance *inst; inst = wait_one(0); if (inst) { status |= inst->exit_status; free_instance(inst); } if (verbose > 1) printf("----------------------------------\n"); } } status |= wait_many(FLAG_WAIT_ALL); blkid_put_cache(cache); return status; }
int main (int argc, char **argv) { char *name; int sig_num; int optc; int myoptind; struct passwd *pwent = NULL; struct stat isproc; //int optsig = 0; struct option options[] = { {"exact", 0, NULL, 'e'}, {"ignore-case", 0, NULL, 'I'}, {"process-group", 0, NULL, 'g'}, {"interactive", 0, NULL, 'i'}, {"list-signals", 0, NULL, 'l'}, {"quiet", 0, NULL, 'q'}, {"regexp", 0, NULL, 'r'}, {"signal", 1, NULL, 's'}, {"user", 1, NULL, 'u'}, {"verbose", 0, NULL, 'v'}, {"wait", 0, NULL, 'w'}, #ifdef WITH_SELINUX {"context", 1, NULL, 'Z'}, #endif /*WITH_SELINUX*/ {"version", 0, NULL, 'V'}, {0,0,0,0 }}; /* Setup the i18n */ #ifdef ENABLE_NLS setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif #ifdef WITH_SELINUX security_context_t scontext = NULL; regex_t scontext_reg; if ( argc < 2 ) usage(); /* do the obvious thing... */ #endif /*WITH_SELINUX*/ name = strrchr (*argv, '/'); if (name) name++; else name = *argv; pidof = strcmp (name, "killall"); sig_num = SIGTERM; opterr = 0; #ifdef WITH_SELINUX while ( (optc = getopt_long_only(argc,argv,"egilqrs:u:vwZ:VI",options,NULL)) != EOF) { #else while ( (optc = getopt_long_only(argc,argv,"egilqrs:u:vwVI",options,NULL)) != EOF) { #endif switch (optc) { case 'e': exact = 1; break; case 'g': process_group = 1; break; case 'i': if (pidof) usage(); interactive = 1; break; case 'l': if (pidof) usage(); list_signals(); return 0; break; case 'q': if (pidof) usage(); quiet = 1; break; case 'r': if (pidof) usage(); reg = 1; break; case 's': sig_num = get_signal (optarg, "killall"); break; case 'u': if (pidof) usage(); if (!(pwent = getpwnam(optarg))) { fprintf (stderr, _("Cannot find user %s\n"), optarg); exit (1); } break; case 'v': if (pidof) usage(); verbose = 1; break; case 'w': if (pidof) usage(); wait_until_dead = 1; break; case 'I': ignore_case = 1; break; case 'V': print_version(); return 0; break; #ifdef WITH_SELINUX case 'Z': if (is_selinux_enabled()>0) { scontext=optarg; if (regcomp(&scontext_reg, scontext, REG_EXTENDED|REG_NOSUB) != 0) { fprintf(stderr, _("Bad regular expression: %s\n"), scontext); exit (1); } } else fprintf(stderr, "Warning: -Z (--context) ignored. Requires an SELinux enabled kernel\n"); break; #endif /*WITH_SELINUX*/ case '?': /* Signal names are in uppercase, so check to see if the argv * is upper case */ if (argv[optind-1][1] >= 'A' && argv[optind-1][1] <= 'Z') { sig_num = get_signal (argv[optind-1]+1, "killall"); } else { /* Might also be a -## signal too */ if (argv[optind-1][1] >= '0' && argv[optind-1][1] <= '9') { sig_num = atoi(argv[optind-1]+1); } else { usage(); } } break; } } myoptind = optind; #ifdef WITH_SELINUX if ((argc - myoptind < 1) && pwent==NULL && scontext==NULL) #else if ((argc - myoptind < 1) && pwent==NULL) #endif usage(); if (argc - myoptind > MAX_NAMES + 1) { fprintf (stderr, _("Maximum number of names is %d\n"), MAX_NAMES); exit (1); } if (stat("/proc/self/stat", &isproc)==-1) { fprintf (stderr, _("%s is empty (not mounted ?)\n"), PROC_BASE); exit (1); } argv = argv + myoptind; /*printf("sending signal %d to procs\n", sig_num);*/ #ifdef WITH_SELINUX return kill_all(sig_num,argc - myoptind, argv, pwent, scontext ? &scontext_reg : NULL); #else /*WITH_SELINUX*/ return kill_all(sig_num,argc - myoptind, argv, pwent); #endif /*WITH_SELINUX*/ }
/* * Wait for one child process to exit; when it does, unlink it from * the list of executing child processes, and return it. */ static struct fsck_instance *wait_one(int flags) { int status; int sig; struct fsck_instance *inst, *inst2, *prev; pid_t pid; if (!instance_list) return NULL; if (noexecute) { inst = instance_list; prev = 0; #ifdef RANDOM_DEBUG while (inst->next && (random() & 1)) { prev = inst; inst = inst->next; } #endif inst->exit_status = 0; goto ret_inst; } /* * gcc -Wall fails saving throw against stupidity * (inst and prev are thought to be uninitialized variables) */ inst = prev = NULL; do { pid = waitpid(-1, &status, flags); if (cancel_requested && !kill_sent) { kill_all(SIGTERM); kill_sent++; } if ((pid == 0) && (flags & WNOHANG)) return NULL; if (pid < 0) { if ((errno == EINTR) || (errno == EAGAIN)) continue; if (errno == ECHILD) { bb_error_msg("wait: no more child process?!?"); return NULL; } perror("wait"); continue; } for (prev = 0, inst = instance_list; inst; prev = inst, inst = inst->next) { if (inst->pid == pid) break; } } while (!inst); if (WIFEXITED(status)) status = WEXITSTATUS(status); else if (WIFSIGNALED(status)) { sig = WTERMSIG(status); if (sig == SIGINT) { status = EXIT_UNCORRECTED; } else { printf("Warning... %s for device %s exited " "with signal %d.\n", inst->prog, inst->device, sig); status = EXIT_ERROR; } } else { printf("%s %s: status is %x, should never happen.\n", inst->prog, inst->device, status); status = EXIT_ERROR; } inst->exit_status = status; if (progress && (inst->flags & FLAG_PROGRESS) && !progress_active()) { for (inst2 = instance_list; inst2; inst2 = inst2->next) { if (inst2->flags & FLAG_DONE) continue; if (strcmp(inst2->type, "ext2") && strcmp(inst2->type, "ext3")) continue; /* * If we've just started the fsck, wait a tiny * bit before sending the kill, to give it * time to set up the signal handler */ if (inst2->start_time < time(0)+2) { if (fork() == 0) { sleep(1); kill(inst2->pid, SIGUSR1); exit(0); } } else kill(inst2->pid, SIGUSR1); inst2->flags |= FLAG_PROGRESS; break; } } ret_inst: if (prev) prev->next = inst->next; else instance_list = inst->next; if (verbose > 1) printf("Finished with %s (exit status %d)\n", inst->device, inst->exit_status); num_running--; return inst; }
XBT_ATTRIB_DEPRECATED_v323("Please use Actor::kill_all()") static void killAll() { kill_all(); }
/** * Eventually calls exit(), passing @p code, therefore does not return. * * @param code one of the RERR_* codes from errcode.h. **/ void _exit_cleanup(int code, const char *file, int line) { int ocode = code; static int inside_cleanup = 0; if (inside_cleanup > 10) { /* prevent the occasional infinite recursion */ return; } inside_cleanup++; signal(SIGUSR1, SIG_IGN); signal(SIGUSR2, SIG_IGN); if (verbose > 3) { rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): entered\n", code, safe_fname(file), line); } if (cleanup_child_pid != -1) { int status; if (waitpid(cleanup_child_pid, &status, WNOHANG) == cleanup_child_pid) { status = WEXITSTATUS(status); if (status > code) code = status; } } if (cleanup_got_literal && cleanup_fname && keep_partial && handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) { char *fname = cleanup_fname; cleanup_fname = NULL; if (cleanup_fd_r != -1) close(cleanup_fd_r); if (cleanup_fd_w != -1) { flush_write_file(cleanup_fd_w); close(cleanup_fd_w); } finish_transfer(cleanup_new_fname, fname, cleanup_file, 0, !partial_dir); } io_flush(FULL_FLUSH); if (cleanup_fname) do_unlink(cleanup_fname); if (code) kill_all(SIGUSR1); if (cleanup_pid && cleanup_pid == getpid()) { char *pidf = lp_pid_file(); if (pidf && *pidf) unlink(lp_pid_file()); } if (code == 0) { if (io_error & IOERR_DEL_LIMIT) code = RERR_DEL_LIMIT; if (io_error & IOERR_VANISHED) code = RERR_VANISHED; if (io_error & IOERR_GENERAL || log_got_error) code = RERR_PARTIAL; } if (code) log_exit(code, file, line); if (verbose > 2) { rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): about to call exit(%d)\n", ocode, safe_fname(file), line, code); } close_all(); exit(code); }
int main(int argc, char *argv[]) { int i, status = 0; int interactive = 0; char *oldpath = getenv("PATH"); const char *fstab; struct fs_info *fs; setvbuf(stdout, NULL, _IONBF, BUFSIZ); setvbuf(stderr, NULL, _IONBF, BUFSIZ); #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); setlocale(LC_CTYPE, ""); bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); #endif blkid_get_cache(&cache, NULL); PRS(argc, argv); if (!notitle) printf("fsck %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); fstab = getenv("FSTAB_FILE"); if (!fstab) fstab = _PATH_MNTTAB; load_fs_info(fstab); /* Update our search path to include uncommon directories. */ if (oldpath) { fsck_path = malloc (strlen (fsck_prefix_path) + 1 + strlen (oldpath) + 1); if (!fsck_path) { fprintf(stderr, "%s: Unable to allocate memory for fsck_path\n", progname); exit(EXIT_ERROR); } strcpy (fsck_path, fsck_prefix_path); strcat (fsck_path, ":"); strcat (fsck_path, oldpath); } else { fsck_path = string_copy(fsck_prefix_path); } if ((num_devices == 1) || (serialize)) interactive = 1; /* If -A was specified ("check all"), do that! */ if (doall) return check_all(); if (num_devices == 0) { serialize++; interactive++; return check_all(); } for (i = 0 ; i < num_devices; i++) { if (cancel_requested) { if (!kill_sent) { kill_all(SIGTERM); kill_sent++; } break; } fs = lookup(devices[i]); if (!fs) { fs = create_fs_device(devices[i], 0, "auto", 0, -1, -1); if (!fs) continue; } if (ignore_mounted && is_mounted(fs->device)) continue; fsck_device(fs, interactive); if (serialize || (max_running && (num_running >= max_running))) { struct fsck_instance *inst; inst = wait_one(0); if (inst) { status |= inst->exit_status; free_instance(inst); } if (verbose > 1) printf("----------------------------------\n"); } } status |= wait_many(FLAG_WAIT_ALL); free(fsck_path); blkid_put_cache(cache); return status; }