service.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 717 行

C
717
字号
#ifndef lintstatic CHTYPE *sccsid = "@(#)service.c	4.1      7/17/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* * *   Modification History: * * 002 - Gary A. Gaudet, Wed Nov  9 10:24:49 EST 1988 *	 	MIPS portability and bug fixes * * 001 - Gary Gaudet for Andy Gadsby 09-mar-88 *	i18n version of csh * * * *//* * UNIX shell * * Bell Telephone Laboratories * */#include	"defs.h"#include	<errno.h>#define ARGMK	01extern int	gsort();extern CHTYPE	*sysmsg[];extern short topfd;/* * service routines for `execute' */initio(iop, save)	struct ionod	*iop;	int		save;{	extern long	lseek();	/* DAG -- bug fix (was missing) */	register CHTYPE	*ion;	register int	iof, fd;	int		ioufd;	short	lastfd;	lastfd = topfd;	while (iop)	{		iof = iop->iofile;		ion = mactrim(iop->ioname);		ioufd = iof & IOUFD;		if (*ion && (flags&noexec) == 0)		{			if (save)			{				fdmap[topfd].org_fd = ioufd;				fdmap[topfd++].dup_fd = savefd(ioufd);			}			if (iof & IODOC)			{				struct tempblk tb;				subst(chkopen(ion), (fd = tmpfil(&tb)));				poptemp();	/* pushed in tmpfil() --						   bug fix for problem with						   in-line scripts						*/				fd = chkopen(tmpout);				unlink(wtoc(tmpout));			}			else if (iof & IOMOV)			{				if (eq(minus, ion))				{					fd = -1;					close(ioufd);				}				else if ((fd = stoi(ion)) >= USERIO)					failed(ion, badfile);				else					fd = dup(fd);			}			else if (iof & IORDW)	/* DAG -- added (due to Brian Horn) */			{				if ((fd = open(ion, 2)) < 0)					failed(ion, badopen);					/*NOTREACHED*/			}			else if ((iof & IOPUT) == 0)				fd = chkopen(ion);			else if (flags & rshflg)				failed(ion, restricted);			else if (iof & IOAPP && (fd = open(wtoc(ion), 1)) >= 0)				lseek(fd, 0L, 2);			else				fd = create(ion);			if (fd >= 0)				rename(fd, ioufd);		}		iop = iop->ionxt;	}	return(lastfd);}CHTYPE *simple(s)CHTYPE	*s;{	CHTYPE	*sname;	sname = s;	while (1)	{		if (any('/', sname))			while (*sname++ != '/')				;		else			return(sname);	}}CHTYPE *getpath(s)	CHTYPE	*s;{	register CHTYPE	*path;	if (any('/', s) || any(('/' | QUOTE), s))	{		if (flags & rshflg)			failed(s, restricted);			/*NOTREACHED*/		/* DAG -- keep lint happy */		else			return(nullstr);	}	else if ((path = pathnod.namval) == 0)		return(defpath);	else		return(cpystak(path));}pathopen(path, name)register CHTYPE *path, *name;{	register int	f;	do	{		path = catpath(path, name);	} while ((f = open(wtoc(curstak()), 0)) < 0 && path);	return(f);}CHTYPE *catpath(path, name)register CHTYPE	*path;CHTYPE	*name;{	/*	 * leaves result on top of stack	 */	register CHTYPE	*scanp = path;	register CHTYPE	*argp = locstak();	while (*scanp && *scanp != COLON)		*argp++ = *scanp++;	if (scanp != path)		*argp++ = '/';	if (*scanp == COLON)		scanp++;	path = (*scanp ? scanp : 0);	scanp = name;	while ((*argp++ = *scanp++))		;	return(path);}CHTYPE *nextpath(path)	register CHTYPE	*path;{	register CHTYPE	*scanp = path;	while (*scanp && *scanp != COLON)		scanp++;	if (*scanp == COLON)		scanp++;	return(*scanp ? scanp : 0);}static CHTYPE	*xecmsg;static CHTYPE	**xecenv;int	execa(at, pos)	CHTYPE	*at[];	short pos;{	register CHTYPE	*path;	register CHTYPE	**t = at;	int		cnt;	if ((flags & noexec) == 0)	{		xecmsg = notfound;		path = getpath(*t);		xecenv = setenv();		if (pos > 0)		{			cnt = 1;			while (cnt != pos)			{				++cnt;				path = nextpath(path);			}			execs(path, t);			path = getpath(*t);		}		while (path = execs(path,t))			;		failed(*t, xecmsg);	}}static CHTYPE *execs(ap, t)CHTYPE	*ap;register CHTYPE	*t[];{	register CHTYPE *p, *prefix, *ptr;	char **newep, **newap;	char **convargs();	prefix = catpath(ap, t[0]);	trim(p = curstak());	sigchk();		/*	 * convert argument and environment lists from 	 * CHTYPE * to char * for exec. Unfortunatly catpath uses locstak	 * but does not set staktop so we need to find the top here	 */	ptr = p;	while (*ptr++)		; 	newap = (char **) (Rcheat(ptr) + 3 & ~3); /* GAG - byte align ptr */	newep = convargs(t, newap);	convargs(xecenv, newep);		execve(wtoc(p), newap, newep);	switch (errno)	{	case ENOEXEC:		/* could be a shell script */		funcnt = 0;		flags = 0;		*flagadr = 0;		comdiv = 0;		ioset = 0;		clearup();	/* remove open files and for loop junk */		if (input)			close(input);		input = chkopen(p);	#ifdef ACCT		preacct(p);	/* reset accounting */#endif		/*		 * set up new args		 */				setargs(t);		longjmp(subshell, 1);	case ENOMEM:		failed(p, toobig);	case E2BIG:		failed(p, arglist);	case ETXTBSY:		failed(p, txtbsy);	default:		xecmsg = badexec;	case ENOENT:		return(prefix);	}}/* * for processes to be waited for */#define MAXP 20static int	pwlist[MAXP];static int	pwc;postclr(){	register int	*pw = pwlist;	while (pw <= &pwlist[pwc])		*pw++ = 0;	pwc = 0;}post(pcsid)int	pcsid;{	register int	*pw = pwlist;	if (pcsid)	{		while (*pw)			pw++;		if (pwc >= MAXP - 1)			pw--;		else			pwc++;		*pw = pcsid;	}}await(i, bckg)int	i, bckg;{	int	rc = 0, wx = 0;	int	w;	int	ipwc = pwc;	post(i);	while (pwc)	{		register int	p;		register int	sig;		int		w_hi;		int	found = 0;		{			register int	*pw = pwlist;			p = wait(&w);			if (wasintr)			{				wasintr = 0;				if (bckg)				{					break;				}			}			while (pw <= &pwlist[ipwc])			{				if (*pw == p)				{					*pw = 0;					pwc--;					found++;				}				else					pw++;			}		}		if (p == -1)		{			if (bckg)			{				register int *pw = pwlist;				while (pw <= &pwlist[ipwc] && i != *pw)					pw++;				if (i == *pw)				{					*pw = 0;					pwc--;				}			}			continue;		}		w_hi = (w >> 8) & LOBYTE;		if (sig = w & 0177)		{			if (sig == 0177)	/* ptrace! return */			{				prs("ptrace: ");				sig = w_hi;			}			if (sysmsg[sig])			{				if (i != p || (flags & prompt) == 0)				{					prp();					prn(p);					blank();				}				prs(sysmsg[sig]);				if (w & 0200)					prs(coredump);			}			newline();		}		if (rc == 0 && found != 0)			rc = (sig ? sig | SIGFLG : w_hi);		wx |= w;		if (p == i)		{			break;		}	}	if (wx && flags & errflg)		exitsh(rc);	flags |= eflag;	exitval = rc;	exitset();}BOOL		nosubst;trim(at)CHTYPE	*at;{	register CHTYPE	*p;	register CHTYPE 	*ptr;	register CHTYPE	c;	register CHTYPE	q = 0;	if (p = at)	{		ptr = p;		while (c = *p++)		{			if (*ptr = c & STRIP)				++ptr;			q |= c;		}		*ptr = 0;	}	nosubst = q & QUOTE;}CHTYPE *mactrim(s)CHTYPE	*s;{	register CHTYPE	*t = macro(s);	trim(t);	return(t);}CHTYPE **scan(argn)int	argn;{	register struct argnod *argp = (struct argnod *)(Rcheat(gchain) & ~ARGMK);	register CHTYPE **comargn, **comargm;	comargn = (CHTYPE **)getstak(BYTESPERWORD * argn + BYTESPERWORD);	comargm = comargn += argn;	*comargn = ENDARGS;	while (argp)	{		*--comargn = argp->argval;		trim(*comargn);		argp = argp->argnxt;		if (argp == 0 || Rcheat(argp) & ARGMK)		{			gsort(comargn, comargm);			comargm = comargn;		}		/* Lcheat(argp) &= ~ARGMK; */		argp = (struct argnod *)(Rcheat(argp) & ~ARGMK);	}	return(comargn);}static intgsort(from, to)CHTYPE	*from[], *to[];{	int	k, m, n;	register int	i, j;	if ((n = to - from) <= 1)		return;	for (j = 1; j <= n; j *= 2)		;	for (m = 2 * j - 1; m /= 2; )	{		k = n - m;		for (j = 0; j < k; j++)		{			for (i = j; i >= 0; i -= m)			{				register CHTYPE **fromi;				fromi = &from[i];				if (cf(fromi[m], fromi[0]) > 0)				{					break;				}				else				{					CHTYPE *s;					s = fromi[m];					fromi[m] = fromi[0];					fromi[0] = s;				}			}		}	}}/* * Argument list generation */getarg(ac)struct comnod	*ac;{	register struct argnod	*argp;	register int		count = 0;	register struct comnod	*c;	if (c = ac)	{		argp = c->comarg;		while (argp)		{			count += split(macro(argp->argval));			argp = argp->argnxt;		}	}	return(count);}static intsplit(s)		/* blank interpretation routine */register CHTYPE	*s;{	register CHTYPE	*argp;	register int	c;	int		count = 0;	for (;;)	{		sigchk();		argp = (CHTYPE *)((char *)locstak() + BYTESPERWORD);		while ((c = *s++, !any(c, ifsnod.namval) && c))			*argp++ = c;		if (argp == (CHTYPE *)((char *)staktop + BYTESPERWORD))		{			if (c)			{				continue;			}			else			{				return(count);			}		}		else if (c == 0)			s--;		/*		 * file name generation		 */		argp = endstak(argp);		if ((flags & nofngflg) == 0 && 			(c = expand(((struct argnod *)argp)->argval, 0)))			count += c;		else		{			makearg(argp);			count++;		}		gchain = (struct argnod *)((int)gchain | ARGMK);	}}#ifdef ACCT#include	<sys/types.h>#include	"acctdef.h"#include	<sys/acct.h>#include 	<sys/times.h>struct acct sabuf;struct tms buffer;extern long times();static long before;static int shaccton;	/* 0 implies do not write record on exit			   1 implies write acct record on exit			*//* *	suspend accounting until turned on by preacct() */suspacct(){	shaccton = 0;}preacct(cmdadr)	CHTYPE *cmdadr;{	CHTYPE *simple();	if (acctnod.namval && *acctnod.namval)	{		sabuf.ac_btime = time((long *)0);		before = times(&buffer);		sabuf.ac_uid = getuid();		sabuf.ac_gid = getgid();		strncpy(sabuf.ac_comm, wtoc(simple(cmdadr)), sizeof(sabuf.ac_comm));		shaccton = 1;	}}#include	<fcntl.h>doacct(){	int fd;	long int after;	if (shaccton)	{		after = times(&buffer);		sabuf.ac_utime = compress(buffer.tms_utime + buffer.tms_cutime);		sabuf.ac_stime = compress(buffer.tms_stime + buffer.tms_cstime);		sabuf.ac_etime = compress(after - before);		if ((fd = open(wtoc(acctnod.namval), O_WRONLY | O_APPEND | O_CREAT, 0666)) != -1)		{			write(fd, &sabuf, sizeof(sabuf));			close(fd);		}	}}/* *	Produce a pseudo-floating point representation *	with 3 bits base-8 exponent, 13 bits fraction */compress(t)	register time_t t;{	register exp = 0;	register rund = 0;	while (t >= 8192)	{		exp++;		rund = t & 04;		t >>= 3;	}	if (rund)	{		t++;		if (t >= 8192)		{			t >>= 3;			exp++;		}	}	return((exp << 13) + t);}#endif

⌨️ 快捷键说明

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