Esempio n. 1
0
/*
 *      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;
}
Esempio n. 2
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;
}
Esempio n. 3
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
}