static int execute_and_forward(char **argv, void *socket) { int rc = -1; int stdin_pipe[2]; if (pipe(stdin_pipe) == -1) { TRACE_ERRNO("pipe(stdin_pipe) failed"); goto _out; } TRACE("stdin=(r=%i, w=%i)", stdin_pipe[0], stdin_pipe[1]); int stdout_pipe[2]; if (pipe(stdout_pipe) == -1) { TRACE_ERRNO("pipe(stdout_pipe) failed"); goto _out_free_stdin; } TRACE("stdout=(r=%i, w=%i)", stdout_pipe[0], stdout_pipe[1]); int stderr_pipe[2]; if (pipe(stderr_pipe) == -1) { TRACE_ERRNO("pipe(stderr_pipe) failed"); goto _out_free_stdout; } TRACE("stderr=(r=%i, w=%i)", stderr_pipe[0], stderr_pipe[1]); sigset_t sigchld; if (sigemptyset(&sigchld) == -1) { TRACE_ERRNO("sigemptyset() failed"); goto _out_free_stderr; } if (sigaddset(&sigchld, SIGCHLD) == -1) { TRACE_ERRNO("sigaddset() failed"); goto _out_free_stderr; } if (sigprocmask(SIG_BLOCK, &sigchld, NULL) == -1) { TRACE_ERRNO("sigprocmask() failed"); goto _out_free_stderr; } int sigchld_fd = signalfd(-1, &sigchld, SFD_NONBLOCK | SFD_CLOEXEC); if (sigchld_fd == -1) { TRACE_ERRNO("signalfd() failed"); goto _out_free_stderr; } pid_t pid = fork(); if (pid == -1) { TRACE_ERRNO("fork() failed"); goto _out_close_sigchld_fd; } if (pid == 0) { if (sigprocmask(SIG_UNBLOCK, &sigchld, NULL) == -1) { TRACE_ERRNO("sigprocmask() failed"); _exit(1); } execute(argv, stdin_pipe, stdout_pipe, stderr_pipe); } if (forward(pid, &sigchld_fd, stdin_pipe, stdout_pipe, stderr_pipe, socket) == -1) goto _out_wait; rc = 0; _out_wait: if (rc == -1 && kill(pid, SIGKILL) == -1) TRACE_ERRNO("kill(%i, SIGKILL) failed", pid); int status; if (waitpid(pid, &status, 0) == -1) { TRACE_ERRNO("waitpid(%i) failed", pid); } else if (rc == 0) { TRACE("%s (%i) exited with status %i", argv[0], pid, status); int code; if (WIFEXITED(status)) code = WEXITSTATUS(status); else code = 1; if (socket_write_exit(socket, code) == -1) rc = -1; } _out_close_sigchld_fd: if (sigchld_fd != -1 && close(sigchld_fd) == -1) TRACE_ERRNO("close(%i) failed", sigchld_fd); _out_free_stderr: if (stderr_pipe[0] != -1 && close(stderr_pipe[0]) == -1) TRACE_ERRNO("close(%i) failed", stderr_pipe[0]); if (stderr_pipe[1] != -1 && close(stderr_pipe[1]) == -1) TRACE_ERRNO("close(%i) failed", stderr_pipe[1]); _out_free_stdout: if (stdout_pipe[0] != -1 && close(stdout_pipe[0]) == -1) TRACE_ERRNO("close(%i) failed", stdout_pipe[0]); if (stdout_pipe[1] != -1 && close(stdout_pipe[1]) == -1) TRACE_ERRNO("close(%i) failed", stdout_pipe[1]); _out_free_stdin: if (stdin_pipe[0] != -1 && close(stdin_pipe[0]) == -1) TRACE_ERRNO("close(%i) failed", stdin_pipe[0]); if (stdin_pipe[1] != -1 && close(stdin_pipe[1]) == -1) TRACE_ERRNO("close(%i) failed", stdin_pipe[1]); _out: return rc; }
void __pthread_restart_old(pthread_descr th) { if (atomic_increment(&th->p_resume_count) == -1) kill(th->p_pid, __pthread_sig_restart); }
void debug_break() { kill(getpid(), SIGTRAP); }
void daemonize() { pid_t pid, sid, parent; char *lockfile; lockfile = "/var/lock/subsys/" DAEMON_NAME; openlog(DAEMON_NAME, LOG_PID, LOG_LOCAL5); /* already a daemon */ if ( getppid() == 1 ) return; /* Create the lock file as the current user */ /* if ( lockfile && lockfile[0] ) { lfp = open(lockfile,O_RDWR|O_CREAT,0660); if ( lfp < 0 ) { fprintf(stderr,"Unable to create lock file %s\n", lockfile); syslog( LOG_ERR, "unable to create lock file %s, code=%d (%s)", lockfile, errno, strerror(errno) ); exit(EXIT_FAILURE); } } */ /* Drop user if there is one, and we were run as root */ if ( getuid() == 0 || geteuid() == 0 ) { struct passwd *pw = getpwnam(RUN_AS_USER); if ( pw ) { syslog( LOG_NOTICE, "setting user to " RUN_AS_USER ); setuid( pw->pw_uid ); } } /* Trap signals that we expect to recieve */ signal(SIGCHLD,child_handler); signal(SIGUSR1,child_handler); signal(SIGALRM,child_handler); /* Fork off the parent process */ pid = fork(); if (pid < 0) { syslog( LOG_ERR, "unable to fork daemon, code=%d (%s)", errno, strerror(errno) ); exit(EXIT_FAILURE); } /* If we got a good PID, then we can exit the parent process. */ if (pid > 0) { /* Wait for confirmation from the child via SIGTERM or SIGCHLD, or for two seconds to elapse (SIGALRM). pause() should not return. */ alarm(2); pause(); exit(EXIT_FAILURE); } /* At this point we are executing as the child process */ parent = getppid(); syslog(LOG_INFO, "Starting daemon " DAEMON_NAME); /* Cancel certain signals */ signal(SIGCHLD,SIG_DFL); /* A child process dies */ signal(SIGTSTP,SIG_IGN); /* Various TTY signals */ signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); signal(SIGHUP, SIG_IGN); /* Ignore hangup signal */ signal(SIGTERM,sigterm_handler); /* Die on SIGTERM */ /* Change the file mode mask */ umask(0); /* Create a new SID for the child process */ sid = setsid(); if (sid < 0) { syslog( LOG_ERR, "unable to create a new session, code %d (%s)", errno, strerror(errno) ); exit(EXIT_FAILURE); } /* Change the current working directory. This prevents the current directory from being locked; hence not being able to remove it. */ if ((chdir("/")) < 0) { syslog( LOG_ERR, "unable to change directory to %s, code %d (%s)", "/", errno, strerror(errno) ); exit(EXIT_FAILURE); } /* // write our pid to /var/run/DAEMON_NAME.pid pid_filename = "/var/run/" DAEMON_NAME ".pid"; pid_file = fopen(pid_filename, "w"); if (pid_file != NULL) { fprintf(pid_file, "%d\n", getpid()); } else { syslog (LOG_ERR, "Unable to create pid file %s %d %s", pid_filename, errno, strerror(errno)); } */ /* Redirect standard files to /dev/null */ freopen( "/dev/null", "r", stdin); freopen( "/dev/null", "w", stdout); freopen( "/var/tmp/" DAEMON_NAME, "w", stderr); chmod( "/var/tmp/" DAEMON_NAME, 0660); /* Tell the parent process that we are A-okay */ kill( parent, SIGUSR1 ); } // daemonize()
int main(void) { pid_t pid; pid = fork(); if (pid == 0) { /* child */ sigset_t tempmask, originalmask; struct sigaction act; act.sa_handler = handler; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigemptyset(&tempmask); sigaddset(&tempmask, SIGUSR2); if (sigaction(SIGUSR1, &act, 0) == -1) { perror ("Unexpected error while attempting to pre-conditions"); return PTS_UNRESOLVED; } if (sigaction(SIGUSR2, &act, 0) == -1) { perror ("Unexpected error while attempting to pre-conditions"); return PTS_UNRESOLVED; } sigemptyset(&originalmask); sigaddset(&originalmask, SIGUSR1); sigprocmask(SIG_SETMASK, &originalmask, NULL); printf("suspending child\n"); if (sigsuspend(&tempmask) != -1) perror("sigsuspend error"); printf("returned from suspend\n"); sleep(1); return 2; } else { int s; int exit_status; /* parent */ sleep(3); printf("parent sending child a SIGUSR2 signal\n"); kill(pid, SIGUSR2); if (SIGUSR2_called == 1) { printf ("Test FAILED: sigsuspend did not add SIGUSR2 to the temporary mask\n"); return PTS_FAIL; } printf("parent sending child a SIGUSR1 signal\n"); kill(pid, SIGUSR1); if (wait(&s) == -1) { perror("Unexpected error while setting up test " "pre-conditions"); return PTS_UNRESOLVED; } if (!WIFEXITED(s)) { printf("Test FAILED: Did not exit normally\n"); return PTS_FAIL; } exit_status = WEXITSTATUS(s); printf("Exit status from child is %d\n", exit_status); if (exit_status == 1) { printf ("Test UNRESOLVED: Either sigsuspend did not successfully block SIGUSR2, OR sigsuspend returned before handling the signal SIGUSR1\n"); return PTS_UNRESOLVED; } if (exit_status == 2) { printf ("Test FAILED: sigsuspend did not suspend the child\n"); return PTS_FAIL; } printf("Test PASSED\n"); return PTS_PASS; } }
bool InstallFiles() { ButtonBar.Clear(); ButtonBar.AddButton("C", "Cancel"); ButtonBar.Draw(); char *msg; char *dbuttons[2] = { GetTranslation("Continue"), GetTranslation("Exit program") }; if ((InstallInfo.dest_dir_type == DEST_SELECT) || (InstallInfo.dest_dir_type == DEST_DEFAULT)) { msg = CreateText(GetTranslation("This will install %s to the following directory:\n%s\nContinue?"), InstallInfo.program_name.c_str(), MakeCString(InstallInfo.dest_dir)); } else { msg = CreateText(GetTranslation("This will install %s\nContinue?"), InstallInfo.program_name.c_str()); } CCDKDialog Diag(CDKScreen, CENTER, CENTER, msg, dbuttons, 2); Diag.SetBgColor(26); int sel = Diag.Activate(); Diag.Destroy(); refreshCDKScreen(CDKScreen); if (sel == 1) return false; CCDKSWindow InstallOutput(CDKScreen, 0, 6, GetDefaultHeight()-5, -1, CreateText("<C></29/B>%s", GetTranslation("Install output")), 2000); InstallOutput.SetBgColor(5); nodelay(WindowOf(InstallOutput.GetSWin()), true); // Make sure input doesn't block const int maxx = getmaxx(InstallOutput.GetSWin()->win); CCDKSWindow ProggWindow(CDKScreen, 0, 2, 5, maxx, NULL, 4); ProggWindow.SetBgColor(5); ProggWindow.AddText(""); ProggWindow.AddText(CreateText("</B/29>%s:<!29!B>", GetTranslation("Status"))); ProggWindow.AddText(CreateText("%s (1/%d)", GetTranslation("Extracting files"), InstallInfo.command_entries.size()+1), true, BOTTOM, 24); CCDKHistogram ProgressBar(CDKScreen, 25, 3, 1, maxx-29, HORIZONTAL, CreateText("<C></29/B>%s", GetTranslation("Progress")), false); ProgressBar.SetBgColor(5); ProgressBar.SetHistogram(vPERCENT, TOP, 0, 100, 0, COLOR_PAIR (24) | A_REVERSE | ' ', A_BOLD); setCDKSwindowLLChar(ProggWindow.GetSWin(), ACS_LTEE); setCDKSwindowLRChar(ProggWindow.GetSWin(), ACS_RTEE); InstallOutput.Draw(); ProggWindow.Draw(); // Check if we need root access char *passwd = NULL; LIBSU::CLibSU SuHandler; SuHandler.SetUser("root"); SuHandler.SetTerminalOutput(false); bool askpass = false; for (std::list<command_entry_s *>::iterator it=InstallInfo.command_entries.begin(); it!=InstallInfo.command_entries.end(); it++) { if ((*it)->need_root != NO_ROOT) { // Command may need root permission, check if it is so if ((*it)->need_root == DEPENDED_ROOT) { param_entry_s *p = GetParamByVar((*it)->dep_param); if (p && !WriteAccess(p->value)) { (*it)->need_root = NEED_ROOT; if (!askpass) askpass = true; } } else if (!askpass) askpass = true; } } if (!askpass) askpass = !WriteAccess(InstallInfo.dest_dir); // Ask root password if one of the command entries need root access and root isn't passwordless if (askpass && SuHandler.NeedPassword()) { CCDKEntry entry(CDKScreen, CENTER, CENTER, GetTranslation("This installation requires root(administrator) privileges in order to continue\n" "Please enter the password of the root user"), "", 60, 0, 256, vHMIXED); entry.SetHiddenChar('*'); entry.SetBgColor(26); while(1) { char *sz = entry.Activate(); if ((entry.ExitType() != vNORMAL) || !sz || !sz[0]) { if (YesNoBox(GetTranslation("Root access is required to continue\nAbort installation?"))) EndProg(); refreshCDKScreen(CDKScreen); } else { if (SuHandler.TestSU(sz)) { passwd = strdup(sz); for (short s=0;s<strlen(sz);s++) sz[s] = 0; break; } for (short s=0;s<strlen(sz);s++) sz[s] = 0; entry.Clean(); // Some error appeared if (SuHandler.GetError() == LIBSU::CLibSU::SU_ERROR_INCORRECTPASS) { WarningBox(GetTranslation("Incorrect password given for root user\nPlease retype")); } else { throwerror(true, GetTranslation("Could not use su to gain root access\n" "Make sure you can use su(adding the current user to the wheel group may help)")); } } } // Restore screen entry.Destroy(); refreshCDKScreen(CDKScreen); } short percent = 0; bool alwaysroot = false; if (!WriteAccess(InstallInfo.dest_dir)) { CExtractAsRootFunctor Extracter; Extracter.SetUpdateProgFunc(SUUpdateProgress, &ProgressBar); Extracter.SetUpdateTextFunc(SUUpdateText, &InstallOutput); if (!Extracter(passwd)) { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "Error during extracting files"); } InstallOutput.AddText("Done!\n"); alwaysroot = true; // Install commands need root now too } else { while(percent<100) { std::string curfile; percent = ExtractArchive(curfile); InstallOutput.AddText("Extracting file: " + curfile, false); if (percent==100) InstallOutput.AddText("Done!", false); else if (percent==-1) throwerror(true, "Error during extracting files"); ProgressBar.SetValue(0, 100, percent/(1+InstallInfo.command_entries.size())); ProgressBar.Draw(); chtype input = getch(); if (input == 'c') { if (YesNoBox(GetTranslation("Install commands are still running\n" "If you abort now this may lead to a broken installation\n" "Are you sure?"))) { CleanPasswdString(passwd); passwd = NULL; EndProg(); } } } } SuHandler.SetThinkFunc(InstThinkFunc, passwd); SuHandler.SetOutputFunc(PrintInstOutput, &InstallOutput); percent = 100/(1+InstallInfo.command_entries.size()); // Convert to overall progress short step = 2; // Not 1, because extracting files is also a step for (std::list<command_entry_s*>::iterator it=InstallInfo.command_entries.begin(); it!=InstallInfo.command_entries.end(); it++, step++) { if ((*it)->command.empty()) continue; ProggWindow.Clear(); ProggWindow.AddText(""); ProggWindow.AddText(CreateText("</B/29>%s:<!29!B>", GetTranslation("Status"))); ProggWindow.AddText(CreateText("%s (%d/%d)", GetTranslation((*it)->description.c_str()), step, InstallInfo.command_entries.size()+1), true, BOTTOM, 24); ProgressBar.Draw(); std::string command = (*it)->command + " " + GetParameters(*it); InstallOutput.AddText(""); InstallOutput.AddText(CreateText("Execute: %s", command.c_str())); InstallOutput.AddText(""); InstallOutput.AddText(""); if (((*it)->need_root == NEED_ROOT) || alwaysroot) { SuHandler.SetPath((*it)->path.c_str()); SuHandler.SetCommand(command); if (!SuHandler.ExecuteCommand(passwd)) { if ((*it)->exit_on_failure) { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "%s\n('%s')", GetTranslation("Failed to execute install command"), SuHandler.GetErrorMsgC()); } } } else { // Redirect stderr to stdout, so that errors will be displayed too command += " 2>&1"; setenv("PATH", (*it)->path.c_str(), 1); FILE *pipe = popen(command.c_str(), "r"); char term[1024]; if (pipe) { while (fgets(term, sizeof(term), pipe)) { InstallOutput.AddText(term); chtype input = getch(); if (input == 'c') /*injectCDKSwindow(InstallOutput.GetSWin(), input);*/ { if (YesNoBox(GetTranslation("Install commands are still running\n" "If you abort now this may lead to a broken installation\n" "Are you sure?"))) { CleanPasswdString(passwd); passwd = NULL; EndProg(); } } } // Check if command exitted normally and close pipe int state = pclose(pipe); if (!WIFEXITED(state) || (WEXITSTATUS(state) == 127)) // SH returns 127 if command execution failes { if ((*it)->exit_on_failure) { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "Failed to execute install command"); } } } else { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "Could not execute installation commands (could not open pipe)"); } #if 0 // Need to find a good way to safely suspend a process...this code doesn't always work :( int pipefd[2]; pipe(pipefd); pid_t pid = fork(); if (pid == -1) throwerror(true, "Error during command execution: Could not fork process"); else if (pid) // Parent process { close(pipefd[1]); // We're not going to write here std::string out; char c; int compid = -1; // PID of the executed command while(read(pipefd[0], &c, sizeof(c)) > 0) { out += c; if (c == '\n') { if (compid == -1) { compid = atoi(out.c_str()); InstallOutput.AddText(CreateText("pid: %d compid: %d", pid, compid), false); } else InstallOutput.AddText(out, false); out.clear(); } chtype input = getch(); if (input != ERR) /*injectCDKSwindow(InstallOutput.GetSWin(), input);*/ { if (kill(compid, SIGTSTP) < 0) // Pause command execution WarningBox("PID Error: %s\n", strerror(errno)); char *buttons[2] = { GetTranslation("Yes"), GetTranslation("No") }; CCharListHelper msg; msg.AddItem(GetTranslation("This will abort the installation")); msg.AddItem(GetTranslation("Are you sure?")); CCDKDialog dialog(CDKScreen, CENTER, CENTER, msg, msg.Count(), buttons, 2); dialog.SetBgColor(26); int ret = dialog.Activate(); bool cont = ((ret == 1) || (dialog.ExitType() != vNORMAL)); dialog.Destroy(); refreshCDKScreen(CDKScreen); if (!cont) { kill(pid, SIGTERM); EndProg(); } kill(compid, SIGCONT); // Continue command execution } } close (pipefd[0]); int status; //waitpid(pid, &status, 0); } else // Child process { // Redirect stdout to pipe close(STDOUT_FILENO); dup (pipefd[1]); close (pipefd[0]); // No need to read here // Make sure no errors are printed and write pid of new command command += " 2> /dev/null & echo $!"; execl("/bin/sh", "sh", "-c", command.c_str(), NULL); system(CreateText("echo %s", strerror(errno))); _exit(1); } #endif } percent += (1.0f/((float)InstallInfo.command_entries.size()+1.0f))*100.0f; ProgressBar.SetValue(0, 100, percent); } ProgressBar.SetValue(0, 100, 100); ProgressBar.Draw(); CleanPasswdString(passwd); passwd = NULL; ButtonBar.Clear(); ButtonBar.AddButton("Arrows", "Scroll install output"); ButtonBar.AddButton("Enter", (FileExists(InstallInfo.own_dir + "/config/finish")) ? "Continue" : "Finish"); // HACK ButtonBar.Draw(); WarningBox("Installation of %s complete!", InstallInfo.program_name.c_str()); InstallOutput.Activate(); return (InstallOutput.ExitType() == vNORMAL); }
static void _signal_handler(int signal) { kill(child_pid, signal); }
int main(void) { int n,prev,pos,next,nn,ppd; int pig=0; int i,j;//,k; //int inlist=0; int utmpfd;//, hashkey; init_all(); pos=-1; #if 1 utmpfd = utmp_lock(); utmphead->hashhead[0]=0; for (i = 0; i <= USHM_SIZE - 1; i++) { if (!utmpshm->uinfo[i].active) { add_empty(i+1); } } utmp_unlock(utmpfd); printf("end\n"); // return; #endif j=0; for(i = utmphead->hashhead[0]; i; i = utmphead->next[i - 1]) j++; printf("items on hashhead[0] chain:%d\n",j); j=0; pig=0; for(i=0;i<USHM_SIZE;i++){ if (!utmpshm->uinfo[i].active) j++; else pig++; } printf("direct iteration: inactive:%d, active:%d\n",j,pig); pig=0; for(n=1;n<=UTMP_HASHSIZE;n++) { ppd=false; next = utmphead->hashhead[n]; prev = -1; while(next) { nn = utmphead->next[next - 1]; if (!utmpshm->uinfo[next - 1].active) { if (pos==-1) pos=prev; //printf("%d, %d, %s\n", next, nn, utmpshm->uinfo[next - 1].userid); ppd=true; } else { int hash = utmp_hash(getuserid2(utmpshm->uinfo[next - 1].uid)); if (hash!=n) { printf("utmp_hash err: %d %d %d %d %s\n", n, next, utmphead->hashhead[n], nn, getuserid2(utmpshm->uinfo[next - 1].uid)); if (0) { if (utmphead->hashhead[n] == next) { utmphead->hashhead[n] = nn; } else { utmphead->next[prev - 1] = nn; } } } } prev = next; next = nn; pig++; } if(ppd) printf("ERROR:%d,%d,%d\n", n, utmphead->hashhead[n], pos); } printf("active: %d, total: %d\n", pig, pig+j); n=utmphead->listhead; pig=0; prev=-1; while(n) { pig++; if (prev>0) { if (strcasecmp(utmpshm->uinfo[prev-1].userid, utmpshm->uinfo[n-1].userid) > 0) { printf("list chain error: %d %d\n", prev, n); } } prev=n; n=utmphead->list_next[n-1]; if (utmphead->list_prev[n-1]!=prev) { printf("list chain list_prev error: %d %d\n", prev, n); } if (n==utmphead->listhead) { break; } } printf("active on list chain: %d\n", pig); // return 0; #if 0 for (i = 0; i <= USHM_SIZE - 1; i++) { if (!utmpshm->uinfo[i].active) { if(!in_hash(i+1)){ //printf("%d empty but not in hash\n", i); pig ++; if(in_list(i)) inlist++; //if(pig >=40) break; } } } printf("%d total,%d inlist\n", pig, inlist); if(i==USHM_SIZE) return; return; k=utmphead->listhead; for(j=utmphead->list_next[k-1]; j!=k && j; j=utmphead->list_next[j-1]){ if(j==i+1) printf("in listhead\n"); } return; #endif pig=0; next = utmphead->hashhead[0]; while(next) { if (pos!=-1 &&pos==next) { printf("%d: on empty list\n", pos); return 0; } nn = utmphead->next[next - 1]; next = nn; pig++; } printf("%d %ld %ld\n", pig, utmphead->uptime, time(NULL)); time_t now = time(NULL); int web=0;int kick=0; pig=0; for (n = 0; n < USHM_SIZE; n++) { struct user_info *uentp = &(utmpshm->uinfo[n]); //printf("%d, %d\n", n, uentp->pid); if ((uentp->pid == 1) && ((now - uentp->freshtime) < IDLE_TIMEOUT)) { continue; } if (uentp->pid==0 && uentp->active) kick++; if (/*uentp->active &&*/ uentp->pid && kill(uentp->pid, 0) == -1) { /*uentp¼ì²é */ pig++; if(uentp->pid==1) web++; } } printf("killable: %d, web: %d, pid0: %d\n", pig, web, kick); return 0; }
int main(int argc, char * const *argv) { int i, seed = -1; int num_procs = 3; int num_loops = 5000; int hash_size = 2; int c; extern char *optarg; pid_t *pids; struct tdb_logging_context log_ctx; log_ctx.log_fn = tdb_log; while ((c = getopt(argc, argv, "n:l:s:H:h")) != -1) { switch (c) { case 'n': num_procs = strtol(optarg, NULL, 0); break; case 'l': num_loops = strtol(optarg, NULL, 0); break; case 'H': hash_size = strtol(optarg, NULL, 0); break; case 's': seed = strtol(optarg, NULL, 0); break; default: usage(); } } unlink("torture.tdb"); pids = calloc(sizeof(pid_t), num_procs); pids[0] = getpid(); for (i=0;i<num_procs-1;i++) { if ((pids[i+1]=fork()) == 0) break; } db = tdb_open_ex("torture.tdb", hash_size, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0600, &log_ctx, NULL); if (!db) { fatal("db open failed"); } if (seed == -1) { seed = (getpid() + time(NULL)) & 0x7FFFFFFF; } if (i == 0) { printf("testing with %d processes, %d loops, %d hash_size, seed=%d\n", num_procs, num_loops, hash_size, seed); } srand(seed + i); srandom(seed + i); for (i=0;i<num_loops && error_count == 0;i++) { addrec_db(); } if (error_count == 0) { tdb_traverse_read(db, NULL, NULL); tdb_traverse(db, traverse_fn, NULL); tdb_traverse(db, traverse_fn, NULL); } tdb_close(db); if (getpid() != pids[0]) { return error_count; } for (i=1;i<num_procs;i++) { int status, j; pid_t pid; if (error_count != 0) { /* try and stop the test on any failure */ for (j=1;j<num_procs;j++) { if (pids[j] != 0) { kill(pids[j], SIGTERM); } } } pid = waitpid(-1, &status, 0); if (pid == -1) { perror("failed to wait for child\n"); exit(1); } for (j=1;j<num_procs;j++) { if (pids[j] == pid) break; } if (j == num_procs) { printf("unknown child %d exited!?\n", (int)pid); exit(1); } if (WEXITSTATUS(status) != 0) { printf("child %d exited with status %d\n", (int)pid, WEXITSTATUS(status)); error_count++; } pids[j] = 0; } if (error_count == 0) { printf("OK\n"); } return error_count; }
/** * \brief Initialize the item. */ void bear::natural_forced_movement_creator::build() { set_forced_movement(m_movement); kill(); } // natural_forced_movement_creator::build()
static void kill_handler(int sig) { if (sig == SIGALRM && waited) { kill(waited, SIGKILL); } }
int getnewutmpent( struct user_info *up) { int utmpfd; struct user_info *uentp; time_t now; int i, n, num[2]; FILE * fp; fp=fopen(ULIST, "rw+"); utmpfd = fileno(fp); if (utmpfd < 0) return -1; flock(utmpfd, LOCK_EX); resolve_utmp(); flock(utmpfd, LOCK_EX); if (utmpshm->max_login_num < count_users) utmpshm->max_login_num = count_users; for (i = 0; i < USHM_SIZE; i++) { uentp = &(utmpshm->uinfo[i]); if (!uentp->active || !uentp->pid) break; } if (i >= USHM_SIZE) { flock(utmpfd, LOCK_UN); close(utmpfd);/* add by yiyo */ return -2; } utmpshm->uinfo[i] = *up; now = time(0); if (now > utmpshm->uptime + 60) { num[0] = num[1] = 0; utmpshm->uptime = now; for (n = 0; n < USHM_SIZE; n++) { uentp = &(utmpshm->uinfo[n]); if (uentp->active && uentp->pid) { //web登陆没有守护进程,pid没有意义,所以,不检测web的pid if (uentp->mode < 20000 && kill(uentp->pid, 0) == -1) { //huangxu@071220:貌似不能这样 //kill(uentp->pid, 9); //memset(uentp, 0, sizeof(struct user_info)); continue; } else { num[(uentp->invisible == YEA) ? 1 : 0]++; //huangxu@071203:这个数组有嘛用?还是尝试清0吧。 //memset(uentp, 0, sizeof(struct user_info)); //todo:需要一个专门的函数处理时间计算。 } } } utmpshm->usersum = allusers(); n = USHM_SIZE - 1; while (n > 0 && utmpshm->uinfo[n].active == 0) n--; ftruncate(utmpfd, 0); write(utmpfd, utmpshm->uinfo, (n + 1) * sizeof(struct user_info)); } flock(utmpfd, LOCK_UN); close(utmpfd); return i + 1; }
int main(int argc, char* argv[]){ int numChildren = atoi(argv[1]); char* string = argv[2]; int i; char ch; char* strI = malloc(sizeof(char) * 3); pid_t forkID; pid_t* childID = malloc(sizeof(pid_t) * numChildren); char* argvs[] = {"link", "string", "strI", NULL};//{"link", string, strI, NULL}; int readPrev; int firstLastPipe[2]; //represents the pipe between the first and last children int curPipe[2]; //represents the pipe between the current child and the next //printf("Passed string: %s\n", string); argvs[1] = string; argvs[2] = strI; //printf("Parent pid: %d\n", getpid()); pipe(firstLastPipe); for(i = 0; i < numChildren; i++){ if(i != 0) readPrev = curPipe[0]; pipe(curPipe); forkID = fork(); //FORK ERROR if(forkID < 0){ perror("parent: Can't fork"); exit(1); //CHILD }else if (forkID == 0){ snprintf(strI, 3, "%d", i); argvs[2] = strI; //FIRST CHILD if(i == 0){ close(curPipe[0]); //close read for first child, as it is not needed //read close(0); dup(firstLastPipe[0]); close(firstLastPipe[0]); //write close(1); dup(curPipe[1]); close(curPipe[1]); //LAST CHILD }else if(i == numChildren - 1){ close(curPipe[1]); //close write for last child, as it is not needed //read close(0); dup(readPrev); close(readPrev); //write close(1); dup(firstLastPipe[1]); close(firstLastPipe[1]); //MIDDLE CHILDREN }else{ //read close(0); dup(readPrev); close(readPrev); //write close(1); dup(curPipe[1]); close(curPipe[1]); } //printf("Executing child #%d\n", i); execve("link", argvs, NULL); perror("child: Can't execve"); exit(1); //PARENT }else{ childID[i] = forkID; close(curPipe[1]); } } //for(i = 0; i < numChildren; i++){ // printf("parent: childID[%d] = %d\n", i, childID[i]); //} printf("hit enter/return to start\n"); //while( getchar() != '\n' ); getchar(); //printf("Sending SIGUSR1...\n"); kill(childID[0], SIGUSR1); printf("hit enter/return to stop\n"); getchar(); for(i = 0; i < numChildren; i++){ kill(childID[i], SIGTERM); } }
void VT_Dyn_attach() { int mutatee_pid = getpid(); vt_cntl_msg(1, "[%i]: Attaching instrumentor", mutatee_pid); /* Install signal handler for continue execution (SIGUSR1) and abort execution (SIGUSR2) */ if( signal(SIGUSR1, sig_usr1_handler) == SIG_ERR ) vt_error_msg("Could not install handler for signal SIGUSR1"); if( signal(SIGUSR2, sig_usr2_handler) == SIG_ERR ) vt_error_msg("Could not install handler for signal SIGUSR2"); /* The Dyninst attach library (libvt-dynatt) could be set by LD_PRELOAD. Unset this environment variable to avoid recursion. */ putenv((char*)"LD_PRELOAD="); putenv((char*)"DYLD_INSERT_LIBRARIES="); /* equivalent on MacOS */ /* Attach Dyninst instrumentor on running executable */ switch( fork() ) { case -1: { vt_error_msg("Could not attach Dyninst instrumentor"); break; } case 0: { int rc; char cmd[1024]; char* filter = vt_env_filter_spec(); char* shlibs = vt_env_dyn_shlibs(); char* shlibs_arg = NULL; char* mutatee_path = NULL; /* Restore original signal handler */ signal(SIGUSR1, SIG_DFL); signal(SIGUSR2, SIG_DFL); /* Try to get path of mutatee */ vt_pform_init(); mutatee_path = vt_env_apppath(); /* Replace all colons by commas in list of shared libraries */ if ( shlibs && strlen(shlibs) > 0 ) { char* tk; shlibs_arg = (char*)calloc(strlen(shlibs)+2, sizeof(char)); tk = strtok( shlibs, ":" ); do { strcat(shlibs_arg, tk); strcat(shlibs_arg, ","); } while( (tk = strtok( 0, ":" )) ); shlibs_arg[strlen(shlibs_arg)-1] = '\0'; } snprintf(cmd, sizeof(cmd)-1, "%s/vtdyn %s %s %s %s %s %s %s %s %s %s %s " "-p %i %s", vt_installdirs_get(VT_INSTALLDIR_BINDIR), (vt_env_verbose() == 0) ? "-q" : "", (vt_env_verbose() >= 2) ? "-v" : "", filter ? "-f" : "", filter ? filter : "", shlibs_arg ? "-s" : "", shlibs_arg ? shlibs_arg : "", (vt_env_dyn_outer_loops()) ? "--outer-loops" : "", (vt_env_dyn_inner_loops()) ? "--inner-loops" : "", (vt_env_dyn_loop_iters()) ? "--loop-iters" : "", (vt_env_dyn_ignore_nodbg()) ? "--ignore-nodbg" : "", (vt_env_dyn_detach()) ? "" : "--nodetach", mutatee_pid, mutatee_path ? mutatee_path : ""); if ( shlibs_arg ) free(shlibs_arg); /* Start mutator (instrumentor) */ vt_cntl_msg(2, "[%i]: Executing %s", mutatee_pid, cmd); rc = system(cmd); /* Kill mutatee, if an error occurred during attaching */ if(rc != 0) kill(mutatee_pid, SIGUSR2); exit(rc); break; } default: { /* Wait until mutator send signal to continue execution */ vt_cntl_msg(1, "[%i]: Waiting until instrumentation is done", mutatee_pid); do { usleep(1000); } while(mutatee_cont == 0); if ( !mutator_error ) { /* Restore original signal handler */ signal(SIGUSR1, SIG_DFL); signal(SIGUSR2, SIG_DFL); } else { vt_error_msg("An error occurred during instrumenting"); } break; } } }
void Process_terminate(Process_T P) { assert(P); kill(P->pid, SIGTERM); }
int main (int argc, char const *argv[]) { char *msg_file = NULL; SMFSmtpStatus_T *status = NULL; SMFSettings_T *settings = smf_settings_new(); SMFEnvelope_T *env = smf_envelope_new(); pid_t pid; smf_settings_set_pid_file(settings, "/tmp/smf_test_smtpd.pid"); smf_settings_set_bind_ip(settings, "127.0.0.1"); smf_settings_set_foreground(settings, 1); smf_settings_set_spare_childs(settings, 0); smf_settings_set_max_childs(settings,1); smf_settings_set_debug(settings,1); smf_settings_set_queue_dir(settings, BINARY_DIR); smf_settings_set_engine(settings, "smtpd"); /* add test modules */ smf_settings_add_module(settings, BINARY_DIR "/libtestmod1.so"); smf_settings_add_module(settings, BINARY_DIR "/libtestmod2.so"); printf("Start smf_smtpd tests...\n"); printf("* preparing smtpd engine...\t\t\t"); printf("passed\n"); switch(pid = fork()) { case -1: printf("failed\n"); break; case 0: if (load(settings) != 0) { return -1; } break; default: printf("* sending test message ...\t\t\t"); asprintf(&msg_file, "%s/m0001.txt",SAMPLES_DIR); smf_envelope_set_nexthop(env, "127.0.0.1:33332"); smf_envelope_set_sender(env, test_email); smf_envelope_add_rcpt(env, test_email); status = smf_smtp_deliver(env, SMF_TLS_DISABLED, msg_file, NULL); if (status->code == -1) { kill(pid,SIGTERM); printf("failed\n"); return -1; } smf_smtp_status_free(status); printf("passed\n"); kill(pid,SIGTERM); waitpid(pid, NULL, 0); break; } if(msg_file != NULL) free(msg_file); smf_settings_free(settings); smf_envelope_free(env); return 0; }
void Process_kill(Process_T P) { assert(P); kill(P->pid, SIGKILL); }
int main(int argc, char *argv[]) { int errors, numsig, pid; char *ep; if (argc < 2) usage(); numsig = SIGTERM; argc--, argv++; if (!strcmp(*argv, "-l")) { argc--, argv++; if (argc > 1) usage(); if (argc == 1) { if (!isdigit(**argv)) usage(); numsig = strtol(*argv, &ep, 10); if (!**argv || *ep) errx(2, "illegal signal number: %s", *argv); if (numsig >= 128) numsig -= 128; if (numsig <= 0 || numsig >= sys_nsig) nosig(*argv); printf("%s\n", sys_signame[numsig]); return (0); } printsignals(stdout); return (0); } if (!strcmp(*argv, "-s")) { argc--, argv++; if (argc < 1) { warnx("option requires an argument -- s"); usage(); } if (strcmp(*argv, "0")) { if ((numsig = signame_to_signum(*argv)) < 0) nosig(*argv); } else numsig = 0; argc--, argv++; } else if (**argv == '-' && *(*argv + 1) != '-') { ++*argv; if (isalpha(**argv)) { if ((numsig = signame_to_signum(*argv)) < 0) nosig(*argv); } else if (isdigit(**argv)) { numsig = strtol(*argv, &ep, 10); if (!**argv || *ep) errx(2, "illegal signal number: %s", *argv); if (numsig < 0) nosig(*argv); } else nosig(*argv); argc--, argv++; } if (argc > 0 && strncmp(*argv, "--", 2) == 0) argc--, argv++; if (argc == 0) usage(); for (errors = 0; argc; argc--, argv++) { #ifdef SHELL if (**argv == '%') pid = getjobpgrp(*argv); else #endif { pid = strtol(*argv, &ep, 10); if (!**argv || *ep) errx(2, "illegal process id: %s", *argv); } if (kill(pid, numsig) == -1) { warn("%s", *argv); errors = 1; } } return (errors); }
void AnimatedSprite::hurt() { health -= 20; if(health <= 0) kill(); }
/*************catchClose**************** * Handle close signal *****************************************/ void catchClose(int signal_number){ printf("Exiting..."); close(fd); kill(getpid(), SIGKILL); }
/* CHANGED in 2.0.7: wsgi_req is useless ! */ char *uwsgi_spool_request(struct wsgi_request *wsgi_req, char *buf, size_t len, char *body, size_t body_len) { struct timeval tv; static uint64_t internal_counter = 0; int fd = -1; struct spooler_req sr; if (len > 0xffff) { uwsgi_log("[uwsgi-spooler] args buffer is limited to 64k, use the 'body' for bigger values\n"); return NULL; } // parse the request buffer memset(&sr, 0, sizeof(struct spooler_req)); uwsgi_hooked_parse(buf, len, spooler_req_parser_hook, &sr); struct uwsgi_spooler *uspool = uwsgi.spoolers; if (!uspool) { uwsgi_log("[uwsgi-spooler] no spooler available\n"); return NULL; } // if it is a number, get the spooler by id instead of by name if (sr.spooler && sr.spooler_len) { uspool = uwsgi_get_spooler_by_name(sr.spooler, sr.spooler_len); if (!uspool) { uwsgi_log("[uwsgi-spooler] unable to find spooler \"%.*s\"\n", sr.spooler_len, sr.spooler); return NULL; } } // this lock is for threads, the pid value in filename will avoid multiprocess races uwsgi_lock(uspool->lock); // we increase it even if the request fails internal_counter++; gettimeofday(&tv, NULL); char *filename = NULL; size_t filename_len = 0; if (sr.priority && sr.priority_len) { filename_len = strlen(uspool->dir) + sr.priority_len + strlen(uwsgi.hostname) + 256; filename = uwsgi_malloc(filename_len); int ret = snprintf(filename, filename_len, "%s/%.*s", uspool->dir, (int) sr.priority_len, sr.priority); if (ret <= 0 || ret >= (int) filename_len) { uwsgi_log("[uwsgi-spooler] error generating spooler filename\n"); free(filename); uwsgi_unlock(uspool->lock); return NULL; } // no need to check for errors... (void) mkdir(filename, 0777); ret = snprintf(filename, filename_len, "%s/%.*s/uwsgi_spoolfile_on_%s_%d_%llu_%d_%llu_%llu", uspool->dir, (int)sr.priority_len, sr.priority, uwsgi.hostname, (int) getpid(), (unsigned long long) internal_counter, rand(), (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec); if (ret <= 0 || ret >=(int) filename_len) { uwsgi_log("[uwsgi-spooler] error generating spooler filename\n"); free(filename); uwsgi_unlock(uspool->lock); return NULL; } } else { filename_len = strlen(uspool->dir) + strlen(uwsgi.hostname) + 256; filename = uwsgi_malloc(filename_len); int ret = snprintf(filename, filename_len, "%s/uwsgi_spoolfile_on_%s_%d_%llu_%d_%llu_%llu", uspool->dir, uwsgi.hostname, (int) getpid(), (unsigned long long) internal_counter, rand(), (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec); if (ret <= 0 || ret >= (int) filename_len) { uwsgi_log("[uwsgi-spooler] error generating spooler filename\n"); free(filename); uwsgi_unlock(uspool->lock); return NULL; } } fd = open(filename, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR); if (fd < 0) { uwsgi_error_open(filename); free(filename); uwsgi_unlock(uspool->lock); return NULL; } // now lock the file, it will no be runnable, until the lock is not removed // a race could come if the spooler take the file before fcntl is called // in such case the spooler will detect a zeroed file and will retry later if (uwsgi_fcntl_lock(fd)) { close(fd); free(filename); uwsgi_unlock(uspool->lock); return NULL; } struct uwsgi_header uh; uh.modifier1 = 17; uh.modifier2 = 0; uh._pktsize = (uint16_t) len; #ifdef __BIG_ENDIAN__ uh._pktsize = uwsgi_swap16(uh._pktsize); #endif if (write(fd, &uh, 4) != 4) { uwsgi_log("[spooler] unable to write header for %s\n", filename); goto clear; } if (write(fd, buf, len) != (ssize_t) len) { uwsgi_log("[spooler] unable to write args for %s\n", filename); goto clear; } if (body && body_len > 0) { if ((size_t) write(fd, body, body_len) != body_len) { uwsgi_log("[spooler] unable to write body for %s\n", filename); goto clear; } } if (sr.at > 0) { #ifdef __UCLIBC__ struct timespec ts[2]; ts[0].tv_sec = sr.at; ts[0].tv_nsec = 0; ts[1].tv_sec = sr.at; ts[1].tv_nsec = 0; if (futimens(fd, ts)) { uwsgi_error("uwsgi_spooler_request()/futimens()"); } #else struct timeval tv[2]; tv[0].tv_sec = sr.at; tv[0].tv_usec = 0; tv[1].tv_sec = sr.at; tv[1].tv_usec = 0; #ifdef __sun__ if (futimesat(fd, NULL, tv)) { #else if (futimes(fd, tv)) { #endif uwsgi_error("uwsgi_spooler_request()/futimes()"); } #endif } // here the file will be unlocked too close(fd); if (!uwsgi.spooler_quiet) uwsgi_log("[spooler] written %lu bytes to file %s\n", (unsigned long) len + body_len + 4, filename); // and here waiting threads can continue uwsgi_unlock(uspool->lock); /* wake up the spoolers attached to the specified dir ... (HACKY) no need to fear races, as USR1 is harmless an all of the uWSGI processes... it could be a problem if a new process takes the old pid, but modern systems should avoid that */ struct uwsgi_spooler *spoolers = uwsgi.spoolers; while (spoolers) { if (!strcmp(spoolers->dir, uspool->dir)) { if (spoolers->pid > 0 && spoolers->running == 0) { (void) kill(spoolers->pid, SIGUSR1); } } spoolers = spoolers->next; } return filename; clear: uwsgi_unlock(uspool->lock); uwsgi_error("uwsgi_spool_request()/write()"); if (unlink(filename)) { uwsgi_error("uwsgi_spool_request()/unlink()"); } free(filename); // unlock the file too close(fd); return NULL; } void spooler(struct uwsgi_spooler *uspool) { // prevent process blindly reading stdin to make mess int nullfd; // asked by Marco Beri #ifdef __HAIKU__ #ifdef UWSGI_DEBUG uwsgi_log("lowering spooler priority to %d\n", B_LOW_PRIORITY); #endif set_thread_priority(find_thread(NULL), B_LOW_PRIORITY); #else #ifdef UWSGI_DEBUG uwsgi_log("lowering spooler priority to %d\n", PRIO_MAX); #endif setpriority(PRIO_PROCESS, getpid(), PRIO_MAX); #endif nullfd = open("/dev/null", O_RDONLY); if (nullfd < 0) { uwsgi_error_open("/dev/null"); exit(1); } if (nullfd != 0) { dup2(nullfd, 0); close(nullfd); } int spooler_event_queue = event_queue_init(); int interesting_fd = -1; if (uwsgi.master_process) { event_queue_add_fd_read(spooler_event_queue, uwsgi.shared->spooler_signal_pipe[1]); } // reset the tasks counter uspool->tasks = 0; for (;;) { if (chdir(uspool->dir)) { uwsgi_error("chdir()"); exit(1); } if (uwsgi.spooler_ordered) { spooler_scandir(uspool, NULL); } else { spooler_readdir(uspool, NULL); } int timeout = uwsgi.shared->spooler_frequency ? uwsgi.shared->spooler_frequency : uwsgi.spooler_frequency; if (wakeup > 0) { timeout = 0; } if (event_queue_wait(spooler_event_queue, timeout, &interesting_fd) > 0) { if (uwsgi.master_process) { if (interesting_fd == uwsgi.shared->spooler_signal_pipe[1]) { uwsgi_receive_signal(NULL, interesting_fd, "spooler", (int) getpid()); } } } // avoid races uint64_t tmp_wakeup = wakeup; if (tmp_wakeup > 0) { tmp_wakeup--; } wakeup = tmp_wakeup; } }
int main(int argc, char *argv[]){ unsigned char stop, temp; unsigned char cmd; unsigned char arg1, arg2; char arg1buf[4], arg2buf[4]; packet recievepkt; packet sendpkt; int fd_joy; // File Descriptor for joystick int temp1; struct js_event e; temp1 = 0; // Set first time stamp to zero fd_joy = open_joystick(); // /Initalize the joystick // printf("fd_joy: %d\n", fd_joy); strncpy(device, argv[1], DEVICE_MAX_SIZE); //set up serial port if((fd = configDevice()) < 2){ perror("Error opening/configuring device\n"); return -1; } menu(); //set handler for close command signal(SIGUSR2, catchClose); signal(SIGTERM, catchClose); //create timer for ping pid = fork(); if (pid < 0) printf("Error creating ping timer process\n"); else if(pid == 0){ //die if parent dies prctl(PR_SET_PDEATHSIG, SIGHUP); //set alarm for ping timeout signal(SIGALRM, sendPing); //prime Timeout reset handler signal(SIGUSR1, catchTimeoutReset); alarm(PING_INTERVAL); for(timeouts = 0; timeouts < PING_RETRIES;){ //spin wheels. exit if ping timeout occurs } //kill parent process if ping timeout printf("Ping timeout. %d unanswered pings\n", timeouts); //tell parent to exit kill(getppid(), SIGKILL); return 1; } int readcount; char zeroflag; //main control loop for(stop = 0; stop <= 0;){ //cmd = 'V'; //arg1 = 0; //arg2 = 0; /*scanf("%c %s %s%c", &cmd, arg1buf, arg2buf, NULL); //get command //strcpy(arg1buf, "Z"); arg1 = (unsigned char)atoi(arg1buf); arg2 = (unsigned char)atoi(arg2buf); if(arg1 == 0){ arg1 = 1; } if(arg2 == 0){ arg2 = 1; }*/ readcount = read (fd_joy, &e, sizeof(e)); //printf("servo: %d\r", e.time); //printf("bytes read from joystick: %d\n", readcount); //if(e.time > temp1) { //printf("Bryan\n"); if(e.type == 1 && e.value == 1){ if(e.time > temp1){ button_press(e.number); temp1 = e.time; } } if(e.type == 2 /*&& e.value != 0*/){ if(!zeroflag){ axis_press(e.number, e.value); } //set zeroflag if event input zero //necessary to not keep resending packages //when in the zero (stopped) position zeroflag = (e.value == 0) ? 1 : 0; //printf("zeroflag %c\n", zeroflag); } } //while((temp = getchar()) != '\n' && temp != EOF); //clear buffer //printf("CMD: %c ARG1: %c ARG2: %c\n", cmd, arg1, arg2); //stop = parseCommand(cmd, arg1, arg2); } close(fd); //tell child to exit kill(pid, SIGUSR2); t1.join(); scanf("", NULL); return 0; }
/* We don't want SIGQUIT to core dump */ static void sigquit_handler(int sig) { signal(SIGINT, SIG_DFL); kill(getpid(), SIGINT); }
void MainWindow::closeEvent(QCloseEvent *) { kill(getpid(), SIGTERM); }
int main (int argc, char **argv) { char *user_line = NULL, *qp_reply = NULL; size_t qp_reply_len = 0, user_len = 0; int ret = 0; /* reading to the from Quickplot */ FILE *file_from = NULL; char path_to[FIFO_PATH_LEN], path_from[FIFO_PATH_LEN]; *path_to = '\0'; *path_from = '\0'; if(argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))) usage(); if(argc == 2 && argv[1][0] > '0' && argv[1][0] < '9') { char *end; pid = strtoul(argv[1], &end, 10); if(*end != '\0') { printf("Cannot parse PID from \"%s\"\n\n", argv[1]); usage(); } } if(pid == -1) { char *qp_path; size_t len; len = strlen(argv[0]); /* remove the _shell part of stuff/path_to/quickplot_shell */ if(len >= 15) { qp_path = qp_strdup(argv[0]); qp_path[len-6] = '\0'; } else qp_path = qp_strdup("quickplot"); signal(SIGUSR1, usr1_catcher); errno = 0; pid = fork(); if(pid == -1) { QP_EERROR("failed to fork()\n"); return 1; } if(pid != 0) { // parent runs quickplot char **e_argv; int i; char last_arg[64]; e_argv = qp_malloc((argc+2)*sizeof(*e_argv)); e_argv[0] = qp_strdup("quickplot"); for(i=1;i<argc;++i) e_argv[i] = argv[i]; snprintf(last_arg, 64, "--signal=%d", pid); e_argv[i++] = last_arg; e_argv[i] = NULL; execv(qp_path, e_argv); QP_EERROR("failed to execute %s\n", qp_path); // we failed, kill my child. kill(pid, SIGINT); return 1; // failed } else { pid = getppid(); /* wait for sig SIGCONT */ DEBUG("pid=%d waiting for signal\n", getpid()); while(!got_usr1) usleep(100000); DEBUG("pid=%d got signal\n", getpid()); } } errno = 0; if(kill(pid, SIGCONT)) { QP_EERROR("Failed to signal pid %d\n", pid); return 1; } errno = 0; if(mkfifo(set_to_qp_fifo_path(path_to, pid, getpid()), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)) { QP_EERROR("Failed to create fifo %s\n", path_to); *path_to = '\0'; ret = 1; goto cleanup; } errno = 0; if(mkfifo(set_from_qp_fifo_path(path_from, pid, getpid()), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)) { QP_EERROR("Failed to create fifo %s\n", path_from); *path_from = '\0'; ret = 1; goto cleanup; } /* Since the FIFO block on fopen(,"r") we will signal * before we call fopen(,"r"). * * Looks like fopen(,"w") blocks too. */ errno = 0; if(kill(pid, SIGUSR1)) { QP_EERROR("Failed to signal pid %d\n", pid); return 1; } errno = 0; if(!(file_to = fopen(path_to, "w"))) { QP_EERROR("fopen(\"%s\",\"a\") failed\n", path_to); ret = 1; goto cleanup_with_signal; } errno = 0; if(!(file_from = fopen(path_from, "r"))) { QP_EERROR("fopen(\"%s\",\"r\") failed\n", path_from); ret = 1; goto cleanup_with_signal; } setlinebuf(file_from); prompt = allocate_prompt(); #ifdef QP_DEBUG signal(SIGSEGV, debug_sighandler); signal(SIGABRT, debug_sighandler); #endif signal(SIGTERM, term_sighandler); signal(SIGQUIT, term_sighandler); signal(SIGINT, term_sighandler); stdin_isatty = isatty(fileno(stdin)); qp_shell_initialize(1); #ifdef HAVE_LIBREADLINE if(stdin_isatty) { use_readline = 1; printf("Using readline version: %d.%d\n", RL_VERSION_MAJOR, RL_VERSION_MINOR); } else { #else printf("Using getline()\n"); #endif #ifdef HAVE_LIBREADLINE } #endif /* Exercise the pipe so it does not block the Quickplot * service on fopen(,"r"). */ fprintf(file_to, "start\n"); fflush(file_to); if(read_and_spew_until_end(&qp_reply, &qp_reply_len, file_from, pid)) goto cleanup_with_signal; /* We can hide the FIFO files now that both parties are connected. * The OS will keep the FIFO files in existence so long as one of * the two processes have them open. */ unlink(path_to); *path_to = '\0'; unlink(path_from); *path_from = '\0'; while((Getline(&user_line, &user_len))) { char **argv; int argc; size_t len; char *history_mem = NULL; len = strlen(user_line) + 1; argv = get_args(user_line, &argc); if(argc > 0) { if(!strcmp("exit", *argv)) // exit break; if(!strcmp("quit", *argv)) // quit { fprintf(file_to, "quit\n"); fflush(file_to); break; } if(process_client_side_commands(&argc, &argv, stdin, stdout, len, &history_mem #ifdef HAVE_LIBREADLINE , 0, &use_readline #endif )) { if(!strcmp("input", *argv) && argc > 1) { stdin_isatty = isatty(fileno(stdin)); } } else // command to server { int i; #ifdef QP_DEBUG if(SPEW_LEVEL() <= 1) { printf("Read user line: \"%s\"", argv[0]); for(i=1; i<argc; ++i) printf(" %s", argv[i]); printf("\n"); } #endif fprintf(file_to, "%s", argv[0]); for(i=1; i<argc; ++i) fprintf(file_to, " %s", argv[i]); fprintf(file_to,"\n"); fflush(file_to); // read and print reply if(read_and_spew_until_end(&qp_reply, &qp_reply_len, file_from, pid)) goto cleanup_with_signal; } } if(history_mem) free(history_mem); free(argv); } #ifdef HAVE_READLINE_HISTORY Save_history(); #endif cleanup_with_signal: signal_exit(); cleanup: if(*path_to) unlink(path_to); if(*path_from) unlink(path_from); printf("exiting\n"); return ret; }
int main(int argc, char *argv[]) { int listenfd; int res = 0; int lfd; struct flock lock; char pids[10]; parse_opts(argc, argv); argc -= optind; argv += optind; if (!foreground) { verbose += LL_WARNING; log_enable_syslog(); } else { verbose += LL_NOTICE; } /* set log level to specified verbosity */ log_level = verbose; usbmuxd_log(LL_NOTICE, "usbmuxd v%s starting up", PACKAGE_VERSION); should_exit = 0; should_discover = 0; set_signal_handlers(); signal(SIGPIPE, SIG_IGN); res = lfd = open(lockfile, O_WRONLY|O_CREAT, 0644); if(res == -1) { usbmuxd_log(LL_FATAL, "Could not open lockfile"); goto terminate; } lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; lock.l_pid = 0; fcntl(lfd, F_GETLK, &lock); close(lfd); if (lock.l_type != F_UNLCK) { if (opt_exit) { if (lock.l_pid && !kill(lock.l_pid, 0)) { usbmuxd_log(LL_NOTICE, "Sending signal %d to instance with pid %d", exit_signal, lock.l_pid); res = 0; if (kill(lock.l_pid, exit_signal) < 0) { usbmuxd_log(LL_FATAL, "Could not deliver signal %d to pid %d", exit_signal, lock.l_pid); res = -1; } goto terminate; } else { usbmuxd_log(LL_ERROR, "Could not determine pid of the other running instance!"); res = -1; goto terminate; } } else { if (!opt_disable_hotplug) { usbmuxd_log(LL_ERROR, "Another instance is already running (pid %d). exiting.", lock.l_pid); res = -1; } else { usbmuxd_log(LL_NOTICE, "Another instance is already running (pid %d). Telling it to check for devices.", lock.l_pid); if (lock.l_pid && !kill(lock.l_pid, 0)) { usbmuxd_log(LL_NOTICE, "Sending signal SIGUSR2 to instance with pid %d", lock.l_pid); res = 0; if (kill(lock.l_pid, SIGUSR2) < 0) { usbmuxd_log(LL_FATAL, "Could not deliver SIGUSR2 to pid %d", lock.l_pid); res = -1; } } else { usbmuxd_log(LL_ERROR, "Could not determine pid of the other running instance!"); res = -1; } } goto terminate; } } unlink(lockfile); if (opt_exit) { usbmuxd_log(LL_NOTICE, "No running instance found, none killed. Exiting."); goto terminate; } if (!foreground) { if ((res = daemonize()) < 0) { fprintf(stderr, "usbmuxd: FATAL: Could not daemonize!\n"); usbmuxd_log(LL_FATAL, "Could not daemonize!"); goto terminate; } } // now open the lockfile and place the lock res = lfd = open(lockfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644); if(res < 0) { usbmuxd_log(LL_FATAL, "Could not open lockfile"); goto terminate; } lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; if ((res = fcntl(lfd, F_SETLK, &lock)) < 0) { usbmuxd_log(LL_FATAL, "Lockfile locking failed!"); goto terminate; } sprintf(pids, "%d", getpid()); if ((size_t)(res = write(lfd, pids, strlen(pids))) != strlen(pids)) { usbmuxd_log(LL_FATAL, "Could not write pidfile!"); if(res >= 0) res = -2; goto terminate; } // set number of file descriptors to higher value struct rlimit rlim; getrlimit(RLIMIT_NOFILE, &rlim); rlim.rlim_max = 65536; setrlimit(RLIMIT_NOFILE, (const struct rlimit*)&rlim); usbmuxd_log(LL_INFO, "Creating socket"); res = listenfd = create_socket(); if(listenfd < 0) goto terminate; #ifdef HAVE_LIBIMOBILEDEVICE const char* userprefdir = config_get_config_dir(); struct stat fst; memset(&fst, '\0', sizeof(struct stat)); if (stat(userprefdir, &fst) < 0) { if (mkdir(userprefdir, 0775) < 0) { usbmuxd_log(LL_FATAL, "Failed to create required directory '%s': %s", userprefdir, strerror(errno)); res = -1; goto terminate; } if (stat(userprefdir, &fst) < 0) { usbmuxd_log(LL_FATAL, "stat() failed after creating directory '%s': %s", userprefdir, strerror(errno)); res = -1; goto terminate; } } // make sure permission bits are set correctly if (fst.st_mode != 02775) { if (chmod(userprefdir, 02775) < 0) { usbmuxd_log(LL_WARNING, "chmod(%s, 02775) failed: %s", userprefdir, strerror(errno)); } } #endif // drop elevated privileges if (drop_privileges && (getuid() == 0 || geteuid() == 0)) { struct passwd *pw; if (!drop_user) { usbmuxd_log(LL_FATAL, "No user to drop privileges to?"); res = -1; goto terminate; } pw = getpwnam(drop_user); if (!pw) { usbmuxd_log(LL_FATAL, "Dropping privileges failed, check if user '%s' exists!", drop_user); res = -1; goto terminate; } if (pw->pw_uid == 0) { usbmuxd_log(LL_INFO, "Not dropping privileges to root"); } else { #ifdef HAVE_LIBIMOBILEDEVICE /* make sure the non-privileged user has proper access to the config directory */ if ((fst.st_uid != pw->pw_uid) || (fst.st_gid != pw->pw_gid)) { if (chown(userprefdir, pw->pw_uid, pw->pw_gid) < 0) { usbmuxd_log(LL_WARNING, "chown(%s, %d, %d) failed: %s", userprefdir, pw->pw_uid, pw->pw_gid, strerror(errno)); } } #endif if ((res = initgroups(drop_user, pw->pw_gid)) < 0) { usbmuxd_log(LL_FATAL, "Failed to drop privileges (cannot set supplementary groups)"); goto terminate; } if ((res = setgid(pw->pw_gid)) < 0) { usbmuxd_log(LL_FATAL, "Failed to drop privileges (cannot set group ID to %d)", pw->pw_gid); goto terminate; } if ((res = setuid(pw->pw_uid)) < 0) { usbmuxd_log(LL_FATAL, "Failed to drop privileges (cannot set user ID to %d)", pw->pw_uid); goto terminate; } // security check if (setuid(0) != -1) { usbmuxd_log(LL_FATAL, "Failed to drop privileges properly!"); res = -1; goto terminate; } if (getuid() != pw->pw_uid || getgid() != pw->pw_gid) { usbmuxd_log(LL_FATAL, "Failed to drop privileges properly!"); res = -1; goto terminate; } usbmuxd_log(LL_NOTICE, "Successfully dropped privileges to '%s'", drop_user); } } client_init(); device_init(); usbmuxd_log(LL_INFO, "Initializing USB"); if((res = usb_init()) < 0) goto terminate; usbmuxd_log(LL_INFO, "%d device%s detected", res, (res==1)?"":"s"); usbmuxd_log(LL_NOTICE, "Initialization complete"); if (report_to_parent) if((res = notify_parent(0)) < 0) goto terminate; if(opt_disable_hotplug) { usbmuxd_log(LL_NOTICE, "Automatic device discovery on hotplug disabled."); usb_autodiscover(0); // discovery to be triggered by new instance } if (opt_enable_exit) { usbmuxd_log(LL_NOTICE, "Enabled exit on SIGUSR1 if no devices are attached. Start a new instance with \"--exit\" to trigger."); } res = main_loop(listenfd); if(res < 0) usbmuxd_log(LL_FATAL, "main_loop failed"); usbmuxd_log(LL_NOTICE, "usbmuxd shutting down"); device_kill_connections(); usb_shutdown(); device_shutdown(); client_shutdown(); usbmuxd_log(LL_NOTICE, "Shutdown complete"); terminate: log_disable_syslog(); if (res < 0) res = -res; else res = 0; if (report_to_parent) notify_parent(res); return res; }
void CL_Thread::kill() { impl->kill(); }
static void sl (void) { FILE *f = fopen (pidfile, "w"); if (f == NULL) exit (1); fprintf (f, "%lld\n", (long long) getpid ()); fflush (f); struct flock fl = { .l_type = F_WRLCK, .l_start = 0, .l_whence = SEEK_SET, .l_len = 1 }; if (fcntl (fileno (f), F_SETLK, &fl) != 0) exit (1); sigset_t ss; sigfillset (&ss); sigsuspend (&ss); exit (0); } static void do_prepare (int argc, char *argv[]) { if (command == NULL) command = argv[0]; if (pidfile) sl (); int fd = mkstemp (pidfilename); if (fd == -1) { puts ("mkstemp failed"); exit (1); } write (fd, " ", 1); close (fd); } static int do_test (void) { pthread_t th; if (pthread_create (&th, NULL, tf, NULL) != 0) { puts ("pthread_create failed"); return 1; } do sleep (1); while (access (pidfilename, R_OK) != 0); if (pthread_cancel (th) != 0) { puts ("pthread_cancel failed"); return 1; } void *r; if (pthread_join (th, &r) != 0) { puts ("pthread_join failed"); return 1; } sleep (1); FILE *f = fopen (pidfilename, "r+"); if (f == NULL) { puts ("no pidfile"); return 1; } long long ll; if (fscanf (f, "%lld\n", &ll) != 1) { puts ("could not read pid"); unlink (pidfilename); return 1; } struct flock fl = { .l_type = F_WRLCK, .l_start = 0, .l_whence = SEEK_SET, .l_len = 1 }; if (fcntl (fileno (f), F_GETLK, &fl) != 0) { puts ("F_GETLK failed"); unlink (pidfilename); return 1; } if (fl.l_type != F_UNLCK) { printf ("child %lld still running\n", (long long) fl.l_pid); if (fl.l_pid == ll) kill (fl.l_pid, SIGKILL); unlink (pidfilename); return 1; } fclose (f); unlink (pidfilename); return r != PTHREAD_CANCELED; } static void do_cleanup (void) { FILE *f = fopen (pidfilename, "r+"); long long ll; if (f != NULL && fscanf (f, "%lld\n", &ll) == 1) { struct flock fl = { .l_type = F_WRLCK, .l_start = 0, .l_whence = SEEK_SET, .l_len = 1 }; if (fcntl (fileno (f), F_GETLK, &fl) == 0 && fl.l_type != F_UNLCK && fl.l_pid == ll) kill (fl.l_pid, SIGKILL); fclose (f); } unlink (pidfilename); }
int pgrp_kill(void) { pid_t grp = getpgrp(); return kill(-grp, SIGKILL); }
int main() { mqd_t mq; int status; struct mq_attr attr; int pid; fd_set set; mq_unlink(MQNAME); attr.mq_maxmsg = 5; attr.mq_msgsize = 128; mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr); if (mq == (mqd_t)-1) err(1, "mq_open()"); status = mq_getattr(mq, &attr); if (status) err(1, "mq_getattr()"); pid = fork(); if (pid == 0) { /* child */ int prio, j, i; char *buf; mq_close(mq); signal(SIGALRM, sighandler); mq = mq_open(MQNAME, O_RDWR); if (mq == (mqd_t)-1) err(1, "child process: mq_open"); buf = malloc(attr.mq_msgsize); for (j = 0; j < LOOPS; ++j) { FD_ZERO(&set); FD_SET(__mq_oshandle(mq), &set); alarm(3); status = select(__mq_oshandle(mq)+1, &set, NULL, NULL, NULL); if (status != 1) err(1, "child process: select()"); status = mq_receive(mq, buf, attr.mq_msgsize, &prio); if (status == -1) err(2, "child process: mq_receive"); for (i = 0; i < attr.mq_msgsize; ++i) if (buf[i] != i) err(3, "message data corrupted"); if (prio != PRIO) err(4, "priority is incorrect: %d", prio); } alarm(0); free(buf); mq_close(mq); return (0); } else if (pid == -1) { err(1, "fork()"); } else { char *buf; int i, j, prio; signal(SIGALRM, sighandler); buf = malloc(attr.mq_msgsize); for (j = 0; j < LOOPS; ++j) { for (i = 0; i < attr.mq_msgsize; ++i) { buf[i] = i; } alarm(3); FD_ZERO(&set); FD_SET(__mq_oshandle(mq), &set); status = select(__mq_oshandle(mq)+1, NULL, &set, NULL, NULL); if (status != 1) err(1, "select()"); status = mq_send(mq, buf, attr.mq_msgsize, PRIO); if (status) { kill(pid, SIGKILL); err(2, "mq_send()"); } } alarm(3); wait(&status); alarm(0); } status = mq_close(mq); if (status) err(1, "mq_close"); mq_unlink(MQNAME); return (0); }