/* * Process the iBCS sigset function. * * This is basically the same as the signal() routine with the exception * that it will accept a SIG_HOLD parameter. * * A SIG_HOLD will defer the processing of the signal until a sigrelse() * function is called. */ int abi_sigset (struct pt_regs * regs) { sigset_t newmask, oldmask; __sighandler_t vec; int sig, answer; mm_segment_t old_fs; if (abi_signo (regs, &sig)) { vec = (__sighandler_t) SECOND_PARAM; if (vec != SIG_HOLD) { deactivate_signal(current, sig); abi_sig_handler (regs, sig, vec, 0); } else { /* * Process the hold function */ sigemptyset (&newmask); sigaddset (&newmask, sig); TO_KERNEL (old_fs); answer = SYS(rt_sigprocmask) (SIG_BLOCK, &newmask, &oldmask, sizeof(sigset_t)); FROM_KERNEL (old_fs); if (answer < 0) { set_error (regs, iABI_errors (-answer)); } } } return 0; }
/* * Process the SVR4 sigset function. * * This is basically the same as the signal() routine with the * exception that it will accept a SIG_HOLD parameter. * * A SIG_HOLD will defer the processing of the signal until a sigrelse() * function is called or the signal handler is set again using this function. */ int abi_sigset(struct pt_regs *regp) { int sig, error; sigset_t newmask, oldmask; __sighandler_t vec; mm_segment_t fs; int action; if (abi_signo(regp, &sig) == 0) return 0; vec = (__sighandler_t)SECOND_PARAM(regp); action = SIG_BLOCK; if (vec != SIG_HOLD) { action = SIG_UNBLOCK; deactivate_signal(current, sig); abi_sig_handler(regp, sig, vec, 0); } /* * Process the signal hold/unhold function. */ sigemptyset(&newmask); sigaddset(&newmask, sig); fs = get_fs(); set_fs(get_ds()); error = SYS(rt_sigprocmask,action, &newmask, &oldmask, sizeof(sigset_t)); set_fs(fs); if (error < 0) set_error(regp, iABI_errors(-error)); return 0; }
/* Note: for SCO OpenServer 5.0.6 the original nap was fixed so that it no longer waits a minimum of 2 tick (20ms) but fewer time with a 10 ms granularity */ long xnx_nap(long period) { #ifdef USE_NEW_NAP_CODE // Hz means the number of jiffies per second. // the below code needs HZ to be 1 <= HZ <= 1000 // in order to work correctly in any case. #if HZ > 1000 #error this code only works with HZ <= 1000 #endif struct timeval tv1, tv2; struct timezone tz; mm_segment_t oldfs; long period_s; // seconds part long period_ms_hz; // milli seconds part, scaled to a base of HZ long period_j; // jiffies if (!period) return 0; // zereo request, zero reply oldfs = get_fs(); set_fs(get_ds()); sys_gettimeofday(&tv1, &tz); period_s = period / 1000; period_ms_hz = (period - period_s * 1000) * HZ; period_j = period_s * HZ + period_ms_hz / 1000; // take care of rounding errors, round up if (period > period_j * (1000 / HZ)) period_j++; set_current_state(TASK_INTERRUPTIBLE); schedule_timeout (period_j); sys_gettimeofday(&tv2, &tz); set_fs(oldfs); if (signal_pending(current)) return -EINTR; // interrupted return (tv2.tv_sec - tv1.tv_sec) * 1000 + (tv2.tv_usec - tv1.tv_usec + 500) / 1000; #else __sighandler_t old_handler; struct itimerval it; struct timeval tv1, tv2; struct timezone tz; mm_segment_t oldfs; if (!period) return 0; it.it_interval.tv_sec = 0; it.it_interval.tv_usec = 0; it.it_value.tv_sec = 0; it.it_value.tv_usec = period * 1000; oldfs = get_fs(); set_fs(get_ds()); sys_gettimeofday(&tv1, &tz); old_handler = sigaction(SIGALRM, SIG_DFL); // SIG_DFL -> terminate sys_setitimer(ITIMER_REAL, &it, NULL); sys_pause(); sigaction(SIGALRM, old_handler); sys_gettimeofday(&tv2, &tz); set_fs(oldfs); deactivate_signal(current, SIGALRM); if (signal_pending(current)) return -EINTR; return ((tv2.tv_sec - tv1.tv_sec) * 1000000 + (tv2.tv_usec - tv1.tv_usec)) / 1000; #endif }