/* * abort() - terminate current process with dump via SIGABRT */ void abort(void) { sigset_t set; struct sigaction act; if (!sigaction(SIGABRT, NULL, &act) && act.sa_handler != SIG_DFL && act.sa_handler != SIG_IGN) { /* * User handler is installed, invokes user handler before * taking default action. * * Send SIGABRT, unblock SIGABRT if blocked. * If there is pending signal SIGABRT, we only need to unblock * SIGABRT. */ if (!sigprocmask(SIG_SETMASK, NULL, &set) && sigismember(&set, SIGABRT)) { if (!sigpending(&set) && !sigismember(&set, SIGABRT)) (void) raise(SIGABRT); (void) sigrelse(SIGABRT); } else (void) raise(SIGABRT); } if (++pass == 1) __cleanup(); for (;;) { (void) signal(SIGABRT, SIG_DFL); (void) sigrelse(SIGABRT); (void) raise(SIGABRT); } }
/** * Decrements the value of the given semaphore. * If the value goes below 0, the thread is put into a WAIT state. */ void semaphore_wait(int semaphore) { // disable alarm while working with semaphore sighold(SIGALRM); #if DEBUG == 1 char print[100]; sprintf(print, "wait called on semaphore %d with value %d\n", semaphore, semaphores[semaphore]->value); perror(print); #endif semaphores[semaphore]->value -= 1; if (semaphores[semaphore]->value < 0) { #if DEBUG == 1 sprintf(print, "thread %d put on waitqueue\n", current_thread); perror(print); #endif // block thread threads[current_thread]->state = WAIT; // put it on the wait queue list_append_int(semaphores[semaphore]->thread_queue, current_thread); //unblock alarm and wait for scheduler to take over sigrelse(SIGALRM); while (threads[current_thread]->state == WAIT) ; // when semaphore is signaled thread will be RUNNABLE again and return from this function } else { //don't block thread, unblock alarm and go back to the thread sigrelse(SIGALRM); } }
static int do_test (void) { int result = 0; int e; #define RUN(test) \ errno = 0; \ e = test; \ if (e != -1) \ { \ printf ("%s returned %d\n", #test, e); \ result = 1; \ } \ else if (errno != EINVAL) \ { \ printf ("%s didn't set errno to EINVAL (%s instead)\n", \ #test, strerror (errno)); \ result = 1; \ } RUN (sighold (-1)); RUN (sighold (_NSIG + 100)); RUN (sigrelse (-1)); RUN (sigrelse (_NSIG + 100)); return result; }
void twine_mutex_lock(twine_mutex *lockVar) { sighold(SIGALRM); // stop signals for atomic operation while (lockVar->value) { // wait while lock is 1 (locked) sigrelse(SIGALRM); sighold(SIGALRM); } lockVar->value = 1; // 1 = locked sigrelse(SIGALRM); }
void semaphore::wait(void){ sighold(SIGALRM); this->value -= 1; if(this->value < 0){ getRunningThread()->state = BLOCKED; this->waitQueue.push(getRunningThread()); sigrelse(SIGALRM); raise(SIGALRM); } else{ sigrelse(SIGALRM); } }
/* * Tries to gain access to a critical section. * Will either continue, or be put in the semaphore's private queue */ void sem_wait(sem_t *s){ sighold(14); if(s->count > 0){ s->count--; sigrelse(14); return; } /* Count is 0 */ sem_enq(s, running); deq(); if(s->last) swapcontext(s->last->thread_context, running->thread_context); sigrelse(14); }
void cupsdReleaseSignals(void) { holdcount --; if (holdcount > 0) return; #ifdef HAVE_SIGSET sigrelse(SIGTERM); sigrelse(SIGCHLD); #elif defined(HAVE_SIGACTION) sigprocmask(SIG_SETMASK, &holdmask, NULL); #endif /* HAVE_SIGSET */ }
/* * Release signals SIGHUP - SIGQUIT */ void relsesigs(void) { #ifndef OLD_BSD_SIGS if (--sigdepth == 0) #ifdef VMUNIX sigsetmask(omask); #else sigprocmask(SIG_SETMASK, &omask, NULL); #endif #else sigrelse(SIGHUP); sigrelse(SIGINT); sigrelse(SIGQUIT); #endif }
/** * Increments the value of the given semaphore. * If the value was 0, then the thread at the top of the wait queue is put on the runqueue. */ void semaphore_signal(int semaphore) { int next_thread; // disable alarm while working with semaphore sighold(SIGALRM); #if DEBUG == 1 char print[100]; sprintf(print, "signaling semaphore %d with value %d\n", semaphore, semaphores[semaphore]->value); perror(print); #endif if (semaphores[semaphore]->value < 0) { // make first thread on the wait queue RUNNABLE next_thread = list_shift_int(semaphores[semaphore]->thread_queue); if (next_thread == 0) { perror("no threads on waitqueue\n"); exit(-1); } #if DEBUG == 1 sprintf(print, "signaling thread %d\n", next_thread); perror(print); #endif threads[next_thread]->state = RUNNABLE; list_append_int(runqueue, next_thread); } semaphores[semaphore]->value += 1; sigrelse(SIGALRM); }
/* * We can't use abort(3C), since it closes all of the standard library * FILEs, which can call free(). * * In addition, we can't just raise(SIGABRT), since the current handler * might do allocation. We give them once chance, though. */ static void __NORETURN umem_do_abort(void) { #ifdef _WIN32 abort(); #else if (firstexit(UMEM_EXIT_ABORT)) { (void) raise(SIGABRT); } for (;;) { #if defined(__FreeBSD__) sigset_t set; struct sigaction sa; sa.sa_handler = SIG_DFL; (void) sigaction(SIGABRT, &sa, NULL); (void) sigemptyset (&set); (void) sigaddset (&set, SIGABRT); (void) sigprocmask (SIG_UNBLOCK, &set, NULL); (void) raise (SIGABRT); #else (void) signal(SIGABRT, SIG_DFL); #if !defined(ANDROID) && !defined(ROUTER) && !defined(ARM) (void) sigrelse(SIGABRT); #endif (void) raise(SIGABRT); #endif } #endif }
void pause_on_sigusr( int which ) { #ifndef HAVE_DOSISH_SYSTEM #ifdef HAVE_SIGPROCMASK sigset_t mask, oldmask; assert( which == 1 ); sigemptyset( &mask ); sigaddset( &mask, SIGUSR1 ); sigprocmask( SIG_BLOCK, &mask, &oldmask ); while( !caught_sigusr1 ) sigsuspend( &oldmask ); caught_sigusr1 = 0; sigprocmask( SIG_UNBLOCK, &mask, NULL ); #else assert (which == 1); sighold (SIGUSR1); while (!caught_sigusr1) sigpause(SIGUSR1); caught_sigusr1 = 0; sigrelse(SIGUSR1); ???? #endif /*!HAVE_SIGPROCMASK*/ #endif }
TEST(signal, sighold_sigpause_sigrelse) { static int sigalrm_handler_call_count; auto sigalrm_handler = [](int) { sigalrm_handler_call_count++; }; ScopedSignalHandler sigalrm{SIGALRM, sigalrm_handler}; ScopedSignalMask mask; sigset_t set; // sighold(SIGALRM) should add SIGALRM to the signal mask ... ASSERT_EQ(0, sighold(SIGALRM)); ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set)); EXPECT_TRUE(sigismember(&set, SIGALRM)); // ... preventing our SIGALRM handler from running ... raise(SIGALRM); ASSERT_EQ(0, sigalrm_handler_call_count); // ... until sigpause(SIGALRM) temporarily unblocks it. ASSERT_EQ(-1, sigpause(SIGALRM)); ASSERT_EQ(EINTR, errno); ASSERT_EQ(1, sigalrm_handler_call_count); // But sigpause(SIGALRM) shouldn't permanently unblock SIGALRM. ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set)); EXPECT_TRUE(sigismember(&set, SIGALRM)); ASSERT_EQ(0, sigrelse(SIGALRM)); ASSERT_EQ(0, sigprocmask(SIG_SETMASK, 0, &set)); EXPECT_FALSE(sigismember(&set, SIGALRM)); }
/* * Name: BIO_dump_cmd * Description: Dump the output of invoking a command * to a BIO. * * Arguments: cmd - Command to invoke * bio - BIO to dump output of command to * only 'stdout' is dumped. * Returns : 0 - success * nonzero - failure. errors printed to screen. */ int BIO_dump_cmd(char *cmd, BIO *bio) { char buf[BLK_SIZE]; FILE *fp; int rc; /* start up the process */ if ((fp = epopen(cmd, "r")) == NULL) { rpterr(); return (1); } /* read output in chunks, transfer to BIO */ while (fread(buf, BLK_SIZE, 1, fp) == 1) { if (BIO_write(bio, buf, BLK_SIZE) != BLK_SIZE) { (void) sighold(SIGINT); (void) sighold(SIGHUP); (void) epclose(fp); (void) sigrelse(SIGINT); (void) sigrelse(SIGHUP); rpterr(); return (1); } } /* done with stream, make sure no errors were encountered */ if (ferror(fp)) { (void) epclose(fp); rpterr(); return (1); } /* done, close stream, report any errors */ (void) sighold(SIGINT); (void) sighold(SIGHUP); rc = epclose(fp); (void) sigrelse(SIGINT); (void) sigrelse(SIGHUP); if (rc != 0) { rpterr(); return (1); } return (rc); }
void emulator_run(struct emulator *emu) { cur_run_emu = emu; sigset(SIGINT, sig_int_handler); while (!emu->stop_prog) emulator_run_next_inst(emu); sigrelse(SIGINT); }
/* * Tells the other semaphores that the running thread is done with the critical section * Removes the first waiting thread in the semaphore queue */ void sem_signal(sem_t *s){ sighold(14); if(s->first == NULL || s->count > 0){ s->count++; }else if(s->count <= 0){ /* There is a waiting thread, counter is 0 */ sem_deq(s);/* Add thread to ready queue */ } sigrelse(14); }
/* * void * cleanup() - performs all ONE TIME cleanup for this test at * completion or premature exit. * Release the signal 'SIGUSR1' if still in pending state. */ void cleanup(void) { /* Release the signal 'SIGUSR1' if in pending state */ if (sigrelse(SIGUSR1) == -1) { tst_brkm(TBROK, NULL, "Failed to release 'SIGUSR1' in cleanup"); } }
void semaphore::signal(void){ sighold(SIGALRM); this->value += 1; if(this->value < 0){ this->waitQueue.front()->state = RUNNABLE; this->waitQueue.pop(); } sigrelse(SIGALRM); }
int main(void) { if (sigrelse(SIGABRT) != 0) { perror("Sigrelse failed"); return PTS_UNRESOLVED; } printf("Test PASSED\n"); return PTS_PASS; }
int main() { if ((int)sigrelse(SIGABRT) != 0) { perror("sigrelse failed -- returned -- test aborted"); return PTS_UNRESOLVED; } printf("sigrelse passed\n"); return PTS_PASS; }
void ReleaseSignal(int sig) { #ifdef HAVE_SIGRELSE sigrelse(sig); #else sigset_t set, oset; sigemptyset(&set); sigaddset(&set, sig); sigprocmask(SIG_UNBLOCK, &set, &oset); #endif }
void release_signals(void *parm) { #ifdef HAVE_SIGACTION sigprocmask(SIG_UNBLOCK, (sigset_t *)parm, NULL); #endif #ifdef HAVE_SIGHOLD sigrelse(SIGINT); sigrelse(SIGQUIT); sigrelse(SIGTSTP); #ifdef SIGWINCH sigrelse(SIGWINCH); #endif #endif #ifdef BSD_SIGNALS (void) sigsetmask((int)parm); #endif }
/* * void * cleanup() - performs all ONE TIME cleanup for this test at * completion or premature exit. * Release the signal 'SIGUSR1' if still in pending state. */ void cleanup() { /* * print timing stats if that option was specified. * print errno log if that option was specified. */ TEST_CLEANUP; /* Release the signal 'SIGUSR1' if in pending state */ if (sigrelse(SIGUSR1) == -1) { tst_brkm(TBROK, NULL, "Failed to release 'SIGUSR1' in cleanup"); } }
/** * Start a process in the foreground and wait for the process to finish. */ void foreground(char *args[ARGS_SIZE]) { char *command = args[0]; pid_t group_id = getpid(); pid_t pid; pid = fork(); if (pid == 0) { /* Child */ setpgid(0, group_id); run_child(args, command); } else if (pid > 0) { /* Parent */ int status = 0; struct rusage before; struct rusage after; setpgid(pid, group_id); if (getrusage(RUSAGE_CHILDREN, &before) == -1) { perror("Catastrophic failure"); exit(EXIT_FAILURE); } sighold(SIGCHLD); if (waitpid(pid, &status, 0) == -1) { printf("waitpid failed %d\n", errno); } else { getrusage(RUSAGE_CHILDREN, &after); print_time(&before, &after); if (WIFEXITED(status)) { printf("Exited with status %d\n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("Exited through signal %d\n", WTERMSIG(status)); } else { putz("Exited abnormally"); } } sigrelse(SIGCHLD); } else { /* System fork err */ printf("Fork failed"); exit(0xCC); } }
int main() { #if !__gnu_linux__ && !__APPLE__ sigset_t pendingset; #endif struct sigaction act; act.sa_handler = myhandler; act.sa_flags = 0; sigemptyset(&act.sa_mask); if (sigaction(SIGCHLD, &act, 0) != 0) { perror("Unexpected error while using sigaction()"); return PTS_UNRESOLVED; } #if __gnu_linux__ || __APPLE__ /* TODO: fix the following code * For some reason it fails on GNU/Linux and OS X */ #else /* !__gnu_linux__ */ if (sigset(SIGCHLD,SIG_HOLD) != SIG_HOLD) { perror("Unexpected error while using sigset()"); return PTS_UNRESOLVED; } raise(SIGCHLD); if (sigpending(&pendingset) == -1) { printf("Error calling sigpending()\n"); return PTS_UNRESOLVED; } if (sigismember(&pendingset, SIGCHLD) != 1) { printf("Test UNRESOLVED: Signal SIGCHLD was not successfully blocked\n"); return PTS_UNRESOLVED; } sigrelse(SIGCHLD); if (handler_called != 1) { printf("Test FAILED: Signal wasn't delivered even though it was removed from the signal mask\n"); return PTS_FAIL; } #endif /* !__gnu_linux__ */ return PTS_PASS; }
/* * Function to handle commands that are not built in * to the shell. It receives information wether the process * should be run in forground or background, and a list of * arguments, where the command is the first argument and * NULL is the last argument. Max 5 other arguments allowed. */ int handleCommand(bool bg, char *param[7]){ pid_t pid; struct timeval start, end; /*Saves start and end time of process.*/ double timeUsed; /*Will hold the total time consumed.*/ pid = fork(); if (pid == -1) { /*Fork returns -1 if it fails.*/ perror("\nfork\n"); exit(EXIT_FAILURE); } else if(pid == 0) { /*In the child.*/ /* * If execvp returns -1 an error has occured. Otherwise it will * terminate the child when finished. */ if(execvp(param[0], param) < 0){ perror("Could not execute command"); } exit(1); } else{ /*In the parent.*/ if(bg){ /*If background has been chosen.*/ if (!poll) { /*If SIGDET has been defined.*/ /* * Register a signalhandler to listen for signals * from children that terminate. */ register_signalhandler(SIGCHLD, signal_handler); } } else { /*Foreground process has been chosen.*/ sighold(SIGCHLD); /*Don't let signals interrupt.*/ gettimeofday(&start, NULL); waitpid(pid, NULL, 0); /*Wait for the child to terminate.*/ gettimeofday(&end, NULL); /* * Calculating time used. Timeval stores time as seconds and microseconds. * They are combined and stored as a double instead. */ timeUsed = (end.tv_sec + ((double)end.tv_usec/1000000))-(start.tv_sec+((double)start.tv_usec/1000000)); printf("Process terminated in: %f seconds\n", timeUsed); sigrelse(SIGCHLD); /*Let signals through again.*/ } } return 0; }
/* * void * cleanup() - performs all ONE TIME cleanup for this test at * completion or premature exit. * Release the signal 'SIGUSR1' if still in pending state. */ void cleanup() { /* * print timing stats if that option was specified. * print errno log if that option was specified. */ TEST_CLEANUP; /* Release the signal 'SIGUSR1' if in pending state */ if (sigrelse(SIGUSR1) == -1) { tst_brkm(TBROK, NULL, "Failed to release 'SIGUSR1' in cleanup"); } /* exit with return code appropriate for results */ tst_exit(); } /* End cleanup() */
/* * Interrupt handler for builtin_editor(). */ static void builtin_interrupt_handler(int sig) { signal(SIGINT, builtin_interrupt_handler); signal(SIGQUIT, builtin_interrupt_handler); ++builtin_interrupt_count; #if defined(SIGSET) && defined(HASSIGHOLD) /* * During execution of a signal handler set with sigset(), * the originating signal is held. It must be released or * it cannot recur. */ sigrelse(sig); #endif /* SIGSET and HASSIGHOLD */ LONGJMP(builtin_jmpbuf, 1); }
/* * Python's entry point to this module */ static char * call_editline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) { char *p; PyOS_sighandler_t old_inthandler; EditLineObject *el_gi = editline_module_state->global_instance; /* init missing... */ if (el_gi == NULL) { PyErr_SetString(PyExc_SystemError, "invalid editline global instance"); return NULL; } /* don't do the allocation unless it is different... */ if (strncmp(prompt, el_gi->prompt, strlen(prompt)) != 0) { p = PyMem_RawMalloc(strlen(prompt)+1); if (p == NULL) { PyErr_NoMemory(); return NULL; } strcpy(p, prompt); if (el_gi->prompt != NULL) PyMem_RawFree(el_gi->prompt); el_gi->prompt = p; } /* * this seems like a hack, although it is from readline.c * but it gets around a '\n' needed to interpret a ^C signal */ old_inthandler = PyOS_setsig(SIGINT, onintr); if (setjmp(jbuf)) { #ifdef HAVE_SIGRELSE /* This seems necessary on SunOS 4.1 (Rasmus Hahn) */ sigrelse(SIGINT); #endif PyOS_setsig(SIGINT, old_inthandler); return NULL; } /* interact with the user */ return common_line_interaction(el_gi); }
void write_wbuf(void) { int i; /* verify target threads */ for (i = 0; i < num_targets; i++) if (target[i].state != INACTIVE) glob_masks.num_working++; /* release target threads */ for (i = 0; i < num_targets; i++) if (target[i].state != INACTIVE) pthread_mutex_unlock(&targ[i].wait); /* wake up */ sigrelse(SIGCHLD); pthread_mutex_lock(&mainwait); sighold(SIGCHLD); }
void release_signal(int sig) { #ifdef HAVE_SIGACTION sigset_t set; sigemptyset(&set); sigaddset(&set, sig); sigprocmask(SIG_UNBLOCK, &set, NULL); #endif #ifdef HAVE_SIGHOLD sigrelse(sig); #endif #ifdef BSD_SIGNALS (void) sigsetmask(sigblock(0) & ~(sigmask(sig))); #endif }