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

📄 napms.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
/*	Copyright (c) 1984 AT&T	*//*	  All Rights Reserved  	*//*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*//*	The copyright notice above does not evidence any   	*//*	actual or intended publication of such source code.	*/#ifndef lintstatic	char sccsid[] = "@(#)napms.c 1.1 92/07/30 SMI"; /* from S5R3.1 1.12 */#endif#include	"curses_inc.h"#include	<signal.h>/* * napms.  Sleep for ms milliseconds.  We don't expect a particularly good * resolution - 60ths of a second is normal, 10ths might even be good enough, * but the rest of the program thinks in ms because the unit of resolution * varies from system to system.  (In some countries, it's 50ths, for example.) * Vaxen running 4.2BSD and 3B's use 100ths. * * Here are some reasonable ways to get a good nap. * * (1) Use the poll() or select() system calls in SVr3 or Berkeley 4.2BSD. * * (2) Use the 1/10th second resolution wait in the System V tty driver. *     It turns out this is hard to do - you need a tty line that is *     always unused that you have read permission on to sleep on. * * (3) Install the ft (fast timer) device in your kernel. *     This is a psuedo-device to which an ioctl will wait n ticks *     and then send you an alarm. * * (4) Install the nap system call in your kernel. *     This system call does a timeout for the requested number of ticks. * * (5) Write a routine that busy waits checking the time with ftime. *     Ftime is not present on SYSV systems, and since this busy waits, *     it will drag down response on your system.  But it works. */#ifdef	SIGPOLL/* on SVr3, use poll */#include	<sys/poll.h>napms(ms)int ms;{    (void) poll((struct pollfd *)0, 0L, ms);    return (OK);}#else	/* SIGPOLL */#ifdef	TIOCREMOTE#include <sys/types.h>#include <sys/time.h>static	struct	timeval	tz;#ifdef	BSD4_1C/* Delay for us microseconds, but not more than 1 second */static	long_dodelay(us)long	us;{    struct	timeval	old, now, d, want;    gettimeofday(&old, &tz);    want = old;    want.tv_usec += us;    want.tv_sec += want.tv_usec / 1000000;    want.tv_usec %= 1000000;    now = old;    do    {	d.tv_sec = 0;	d.tv_usec = _timediff(want, now);	select(20, (int *)0, (int *)0, (int *)0, &d);	gettimeofday(&now, &tz);    } while (_timediff(now, want) < 0);}static long_timediff(t1, t2)struct timeval t1, t2;{    return (t1.tv_usec - t2.tv_usec + 1000000 * (t1.tv_sec - t2.tv_sec));}#endif	/* BSD4_1C *//* on 4.2BSD, use select */napms(ms)int ms;{    struct	timeval	t;    /*     * This code has been tested on 4.1cBSD.  The 4.1c select call     * tends to return too early from a select, so we check and try     * again.  This will work ok, but if it waited much too long     * we would be in trouble.     */    t.tv_sec = ms/1000;    t.tv_usec = 1000 * (ms % 1000);    /*     * The next 3 lines are equivalent to a correctly working:     * select(0, (int *)0, (int *)0, (int *)0, &t);     */#ifdef	BSD4_1C    if (t.tv_sec > 0)	sleep(t.tv_sec);    _dodelay(t.tv_usec);#else	/* BSD4_1C */# ifdef FD_SET    select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);# else    select(0, (int *)0, (int *)0, (int *)0, &t);# endif  /* FD_SET */#endif	/* BSD4_1C */    return (OK);}#else	/* TIOCREMOTE */#define	NAPINTERVAL	100#ifdef	SYSV#include	<sys/param.h>#else	/* SYSV */#define	HZ	60#endif	/* SYSV *//* * Pause for ms milliseconds.  Convert to ticks and wait that long. * Call nap, which is either defined below or a system call. */napms(ms)int ms;{    int	ticks;    int rv;    ticks = ms / (1000 / HZ);    if (ticks <= 0)	ticks = 1;    rv = nap(ticks);  /* call either the code below or nap system call */    return (rv);}#if	!defined(HASNAP) && defined(FTIOCSET)#define	HASNAP/* * The following code is adapted from the sleep code in libc. * It uses the "fast timer" device posted to USENET in Feb 1982. * nap is like sleep but the units are ticks (e.g. 1/60ths of * seconds in the USA). */#include	<setjmp.h>static	jmp_buf	jmp;static	int	ftfd;/* don't call nap directly, you should call napms instead */static	intnap(n)unsigned	n;{    int	_napx();    unsigned	altime;    int		(*alsig)() = SIG_DFL;    char	*ftname;    struct	requestbuf		{		    short time;		    short signo;		} rb;    if (n == 0)	return (OK);    if (ftfd <= 0)    {	ftname = "/dev/ft0";	while (ftfd <= 0 && ftname[7] <= '~')	{	    ftfd = open(ftname, 0);	    if (ftfd <= 0)		ftname[7] ++;	}    }    if (ftfd <= 0)	/* Couldn't open a /dev/ft? */    {	_sleepnap(n);	return (ERR);    }    altime = alarm(1000);	/* time to maneuver */    if (setjmp(jmp))    {	(void) signal(SIGALRM, alsig);	alarm(altime);	return (OK);    }    if (altime)    {	if (altime > n)	    altime -= n;	else	{	    n = altime;	    altime = 1;	}    }    alsig = signal(SIGALRM, _napx);    rb.time = n;    rb.signo = SIGALRM;    ioctl(ftfd, FTIOCSET, &rb);    for(;;)	pause();    /*NOTREACHED*/}static_napx(){    longjmp(jmp, 1);}#endif	/* !defined(HASNAP) && defined(FTIOCSET) */#if	!defined(HASNAP) && defined(SYSV) && defined(HASIDLETTY)#define	HASNAP#define	IDLETTY	"/dev/idletty"/* * Do it with the timer in the tty driver.  Resolution is only 1/10th * of a second.  Problem is, if the user types something while we're * sleeping, we wake up immediately, and have no way to tell how long * we should sleep again.  So we're sneaky and use a tty which we are * pretty sure nobody is using. * * Note that we should be able to do this by setting VMIN to 100 and VTIME * to the proper number of ticks.  But due to a bug in the SYSV tty driver * (this bug was still there in 5.0) this hangs until VMIN chars are typed * no matter how much time elapses. * * This requires some care.  If you choose a tty that is a dialup or * which otherwise can show carrier, it will hang and you won't get * any response from the keyboard.  You can use /dev/tty if you have * no such tty, but response will feel funny as described above. * To find a suitable tty, try "stty > /dev/ttyxx" for various ttyxx's * that look unused.  If it hangs, you can't use it.  You might try * connecting a cable to your port that raises carrier to keep it from hanging. * * To use this feature on SYSV, you must *	ln /dev/ttyxx /dev/idletty, * where /dev/ttyxx is one of your tty lines that is never used but * won't hang on open.  Otherwise we always return ERR. * * THIS SYSV CODE IS UNSUPPORTED AND ON A USE-AT-YOUR-OWN-RISK BASIS. */static	intnap(ticks)int	ticks;{    struct	termio	t, ot;    static	int	ttyfd;    int		n, tenths;    char	c;    if (ttyfd == 0)	ttyfd = open(IDLETTY, 2);    if (ttyfd < 0)    {	_sleepnap(ticks);	return (ERR);    }    tenths = (ticks+(HZ/10)/2) / (HZ/10); /* Round to nearest 10th second */    (void) ioctl(ttyfd, TCGETA, &t);    ot = t;    t.c_lflag &= ~ICANON;    t.c_cc[VMIN] = 0;    t.c_cc[VTIME] = tenths;    (void) ioctl(ttyfd, TCSETAW, &t);    n = read(ttyfd, &c, 1);    (void) ioctl(ttyfd, TCSETAW, &ot);    /*     * Now we potentially have a character in c that somebody's going     * to want.  We just hope and pray they use getch, because there     * is no reasonable way to push it back onto the tty.     */    if (n > 0)	cur_term->_input_queue[cur_term->_chars_on_queue++] = c;    return (OK);}/* * Nothing better around, so we have to simulate nap with sleep. */static_sleepnap(ticks){    (void) sleep((ticks+(HZ-1))/HZ);}#endif	/* !defined(HASNAP) && defined(SYSV) && defined(HASIDLETTY) *//* If you have some other externally supplied nap(), add -DHASNAP to cflags */#ifndef	HASNAPintnap(ms)int	ms;{    (void) sleep((unsigned) (ms+999)/1000);    return (ERR);}#endif	/* HASNAP */#endif	/* TIOCREMOTE */#endif	/* SIGPOLL */

⌨️ 快捷键说明

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