⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sleep.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic	char	*sccsid = "@(#)sleep.c	4.1	(ULTRIX)	7/3/90";#endif/*	Modification History						 *									 *	001 - Mark A. Parenti						 *		Rewrote to return unslept time.  Also fixed problem	 *		where alarm would not be sent until AFTER the sleep	 *		had returned.						 * *	002 - Mark A. Parenti *		Use getsysinfo() to determine environment.  POSIX and SYSV *		sleep() is interrupted by any signal.  BSD sleep() is not *		interrupted by signals. * *	003 - Mark A. Parenti *		Delete mask macro and use the equivalent sigmask macro *		instead. * *	004 - Mark A. Parenti *		Fix bug which caused sleep() to hang if SIGALRM was ignored *		and a previous alarm would shorten sleep().  The fix is to *		use kill() instead of setitimer() to send SIGALRM to process. * *	004 - Mark A. Parenti *		Change progenv to short because getsysinfo() only copyout's *		a short from the kernel. * *	005 - dws *		Fixed handling of unslept amount. */#include <sys/time.h>#include <sys/exec.h>#include <sys/sysinfo.h>#include <signal.h>#define	setvec(vec, a) \	vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0static int ringring;unsignedsleep(n)	unsigned n;{	void sleepx();	int omask;	int alrm_flg = 0;	struct itimerval itv, oitv, ritv;	register struct itimerval *itp = &itv;	struct sigvec vec, ovec;	unsigned unslept, left_ovr;	short	progenv;	if (n == 0)		return;	timerclear(&itp->it_interval);	timerclear(&itp->it_value);	if (setitimer(ITIMER_REAL, itp, &oitv) < 0)		return;	left_ovr = 0;	unslept = 0;	if( getsysinfo(GSI_PROG_ENV, &progenv, sizeof(int), 0, 0, 0) < 1 )		progenv = A_BSD;	setvec(ovec, SIG_DFL);	omask = sigblock(0);	itp->it_value.tv_sec = n;	if (timerisset(&oitv.it_value)) {		if (timercmp(&oitv.it_value, &itp->it_value, >)) {			alrm_flg = 1;			oitv.it_value.tv_sec -= itp->it_value.tv_sec;		}		else {			alrm_flg = 2;			left_ovr =  itp->it_value.tv_sec - oitv.it_value.tv_sec;			itp->it_value = oitv.it_value;			oitv.it_value.tv_sec = 0;			oitv.it_value.tv_usec = 200;		}	}	setvec(vec, sleepx);	(void) sigvec(SIGALRM, &vec, &ovec);	ringring = 0;	sigsetmask(-1); /* Block all signals while we setup alarm */	(void) setitimer(ITIMER_REAL, itp, (struct timeval *)0);	/* In BSD mode signals do not interrupt sleep.  In POSIX and System V	 * mode, any caught signal interrupts the sleep.	 */	if(progenv == A_BSD) {	    while (!ringring)		sigpause(omask &~ sigmask(SIGALRM));	}	else	    sigpause(omask);	sigsetmask(omask); /* Reset signal mask */	(void) sigvec(SIGALRM, &ovec, (struct sigvec *)0);	(void) getitimer(ITIMER_REAL, &ritv);	unslept = ritv.it_value.tv_sec;	/* Unslept amount, if any */	/*	 * If alarm shortened sleep, then send SIGALRM before 	 * we return. If alarm is past sleep then restart	 * alarm with remaining time.  If no previous alarm	 * but unslept time then reset timer.	 */	switch (alrm_flg) {	case 2  : /* previous timer shorter than sleep time */		kill(getpid(), SIGALRM);		break;	case 1  : /* previous timer longer than sleep time */		oitv.it_value.tv_sec += unslept;		(void) setitimer(ITIMER_REAL, &oitv, (struct timeval *)0);		break;	case 0  : /* no previous timer */	default :		if (unslept > 0) { /* Received unexpected SIGALRM */			timerclear(&oitv.it_value);			(void) setitimer(ITIMER_REAL, &oitv, (struct timeval *)0);		}		break;	}	/*	 *  Mark Parenti	 *  Change to return unslept amount (if any).	 *  POSIX requirement.	 */	return(left_ovr + unslept);}static voidsleepx(){	ringring = 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -