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

📄 rcsutil.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *                     RCS utilities *//* Copyright (C) 1982, 1988, 1989 Walter Tichy   Copyright 1990, 1991 by Paul Eggert   Distributed under license by the Free Software Foundation, Inc.This file is part of RCS.RCS is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.RCS is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with RCS; see the file COPYING.  If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.Report problems and direct all questions to:    rcs-bugs@cs.purdue.edu*//* $Log: rcsutil.c,v $ * Revision 5.10  1991/10/07  17:32:46  eggert * Support piece tables even if !has_mmap. * * Revision 5.9  1991/08/19  03:13:55  eggert * Add spawn() support.  Explicate assumptions about getting invoker's name. * Standardize user-visible dates.  Tune. * * Revision 5.8  1991/04/21  11:58:30  eggert * Plug setuid security hole. * * Revision 5.6  1991/02/26  17:48:39  eggert * Fix setuid bug.  Use fread, fwrite more portably. * Support waitpid.  Don't assume -1 is acceptable to W* macros. * strsave -> str_save (DG/UX name clash) * * Revision 5.5  1990/12/04  05:18:49  eggert * Don't output a blank line after a signal diagnostic. * Use -I for prompts and -q for diagnostics. * * Revision 5.4  1990/11/01  05:03:53  eggert * Remove unneeded setid check.  Add awrite(), fremember(). * * Revision 5.3  1990/10/06  00:16:45  eggert * Don't fread F if feof(F). * * Revision 5.2  1990/09/04  08:02:31  eggert * Store fread()'s result in an fread_type object. * * Revision 5.1  1990/08/29  07:14:07  eggert * Declare getpwuid() more carefully. * * Revision 5.0  1990/08/22  08:13:46  eggert * Add setuid support.  Permit multiple locks per user. * Remove compile-time limits; use malloc instead. * Switch to GMT.  Permit dates past 1999/12/31. * Add -V.  Remove snooping.  Ansify and Posixate. * Tune.  Some USG hosts define NSIG but not sys_siglist. * Don't run /bin/sh if it's hopeless. * Don't leave garbage behind if the output is an empty pipe. * Clean up after SIGXCPU or SIGXFSZ.  Print name of signal that caused cleanup. * * Revision 4.6  89/05/01  15:13:40  narten * changed copyright header to reflect current distribution rules *  * Revision 4.5  88/11/08  16:01:02  narten * corrected use of varargs routines *  * Revision 4.4  88/08/09  19:13:24  eggert * Check for memory exhaustion. * Permit signal handlers to yield either 'void' or 'int'; fix oldSIGINT botch. * Use execv(), not system(); yield exit status like diff(1)'s. *  * Revision 4.3  87/10/18  10:40:22  narten * Updating version numbers. Changes relative to 1.1 actually * relative to 4.1 *  * Revision 1.3  87/09/24  14:01:01  narten * Sources now pass through lint (if you ignore printf/sprintf/fprintf  * warnings) *  * Revision 1.2  87/03/27  14:22:43  jenkins * Port to suns *  * Revision 4.1  83/05/10  15:53:13  wft * Added getcaller() and findlock(). * Changed catchints() to check SIGINT for SIG_IGN before setting up the signal * (needed for background jobs in older shells). Added restoreints(). * Removed printing of full RCS path from logcommand(). *  * Revision 3.8  83/02/15  15:41:49  wft * Added routine fastcopy() to copy remainder of a file in blocks. * * Revision 3.7  82/12/24  15:25:19  wft * added catchints(), ignoreints() for catching and ingnoring interrupts; * fixed catchsig(). * * Revision 3.6  82/12/08  21:52:05  wft * Using DATEFORM to format dates. * * Revision 3.5  82/12/04  18:20:49  wft * Replaced SNOOPDIR with SNOOPFILE; changed addlock() to update * lockedby-field. * * Revision 3.4  82/12/03  17:17:43  wft * Added check to addlock() ensuring only one lock per person. * Addlock also returns a pointer to the lock created. Deleted fancydate(). * * Revision 3.3  82/11/27  12:24:37  wft * moved rmsema(), trysema(), trydiraccess(), getfullRCSname() to rcsfnms.c. * Introduced macro SNOOP so that snoop can be placed in directory other than * TARGETDIR. Changed %02d to %.2d for compatibility reasons. * * Revision 3.2  82/10/18  21:15:11  wft * added function getfullRCSname(). * * Revision 3.1  82/10/13  16:17:37  wft * Cleanup message is now suppressed in quiet mode. */#include "rcsbase.h"libId(utilId, "$Id: rcsutil.c,v 5.10 1991/10/07 17:32:46 eggert Exp $")#if !has_memcmp	intmemcmp(s1, s2, n)	void const *s1, *s2;	size_t n;{	register unsigned char const		*p1 = (unsigned char const*)s1,		*p2 = (unsigned char const*)s2;	register size_t i = n;	register int r = 0;	while (i--  &&  !(r = (*p1++ - *p2++)))		;	return r;}#endif#if !has_memcpy	void *memcpy(s1, s2, n)	void *s1;	void const *s2;	size_t n;{	register char *p1 = (char*)s1;	register char const *p2 = (char const*)s2;	while (n--)		*p1++ = *p2++;	return s1;}#endif#if lint	malloc_type lintalloc;#endif/* * list of blocks allocated with ftestalloc() * These blocks can be freed by ffree when we're done with the current file. * We could put the free block inside struct alloclist, rather than a pointer * to the free block, but that would be less portable. */struct alloclist {	malloc_type alloc;	struct alloclist *nextalloc;};static struct alloclist *alloced;	static malloc_typeokalloc(p)	malloc_type p;{	if (!p)		faterror("out of memory");	return p;}	malloc_typetestalloc(size)	size_t size;/* Allocate a block, testing that the allocation succeeded.  */{	return okalloc(malloc(size));}	malloc_typetestrealloc(ptr, size)	malloc_type ptr;	size_t size;/* Reallocate a block, testing that the allocation succeeded.  */{	return okalloc(realloc(ptr, size));}	malloc_typefremember(ptr)	malloc_type ptr;/* Remember PTR in 'alloced' so that it can be freed later.  Yield PTR.  */{	register struct alloclist *q = talloc(struct alloclist);	q->nextalloc = alloced;	alloced = q;	return q->alloc = ptr;}	malloc_typeftestalloc(size)	size_t size;/* Allocate a block, putting it in 'alloced' so it can be freed later. */{	return fremember(testalloc(size));}	voidffree()/* Free all blocks allocated with ftestalloc().  */{	register struct alloclist *p, *q;	for (p = alloced;  p;  p = q) {		q = p->nextalloc;		tfree(p->alloc);		tfree(p);	}	alloced = nil;}	voidffree1(f)	register char const *f;/* Free the block f, which was allocated by ftestalloc.  */{	register struct alloclist *p, **a = &alloced;	while ((p = *a)->alloc  !=  f)		a = &p->nextalloc;	*a = p->nextalloc;	tfree(p->alloc);	tfree(p);}	char *str_save(s)	char const *s;/* Save s in permanently allocated storage. */{	return strcpy(tnalloc(char, strlen(s)+1), s);}	char *fstr_save(s)	char const *s;/* Save s in storage that will be deallocated when we're done with this file. */{	return strcpy(ftnalloc(char, strlen(s)+1), s);}	char *cgetenv(name)	char const *name;/* Like getenv(), but yield a copy; getenv() can overwrite old results. */{	register char *p;	return (p=getenv(name)) ? str_save(p) : p;}	char const *getusername(suspicious)	int suspicious;/* Get the caller's login name.  Trust only getwpuid if SUSPICIOUS.  */{	static char *name;	if (!name) {		if (		    /* Prefer getenv() unless suspicious; it's much faster.  */#		    if getlogin_is_secure			    (suspicious			    ||				!(name = cgetenv("LOGNAME"))			    &&  !(name = cgetenv("USER")))			&&  !(name = getlogin())#		    else			suspicious			||				!(name = cgetenv("LOGNAME"))			    &&  !(name = cgetenv("USER"))			    &&  !(name = getlogin())#		    endif		) {#if has_getuid && has_getpwuid			struct passwd const *pw = getpwuid(ruid());			if (!pw)			    faterror("no password entry for userid %lu",				     (unsigned long)ruid()			    );			name = pw->pw_name;#else#if has_setuid			faterror("setuid not supported");#else			faterror("Who are you?  Please set LOGNAME.");#endif#endif		}		checksid(name);	}	return name;}#if has_signal/* *	 Signal handling * * Standard C places too many restrictions on signal handlers. * We obey as many of them as we can. * Posix places fewer restrictions, and we are Posix-compatible here. */static sig_atomic_t volatile heldsignal, holdlevel;	static signal_typecatchsig(s)	int s;{	char const *sname;	char buf[BUFSIZ];#if sig_zaps_handler	/* If a signal arrives before we reset the signal handler, we lose. */	VOID signal(s, SIG_IGN);#endif	if (holdlevel) {		heldsignal = s;		return;	}	ignoreints();	setrid();	if (!quietflag) {	    sname = nil;#if has_sys_siglist && defined(NSIG)	    if ((unsigned)s < NSIG) {#		ifndef sys_siglist		    extern char const *sys_siglist[];#		endif		sname = sys_siglist[s];	    }#else	    switch (s) {#ifdef SIGHUP		case SIGHUP:	sname = "Hangup";  break;#endif#ifdef SIGINT		case SIGINT:	sname = "Interrupt";  break;#endif#ifdef SIGPIPE		case SIGPIPE:	sname = "Broken pipe";  break;#endif#ifdef SIGQUIT		case SIGQUIT:	sname = "Quit";  break;#endif#ifdef SIGTERM		case SIGTERM:	sname = "Terminated";  break;#endif#ifdef SIGXCPU		case SIGXCPU:	sname = "Cputime limit exceeded";  break;#endif#ifdef SIGXFSZ		case SIGXFSZ:	sname = "Filesize limit exceeded";  break;#endif	    }#endif	    if (sname)		VOID sprintf(buf, "\nRCS: %s.  Cleaning up.\n", sname);	    else		VOID sprintf(buf, "\nRCS: Signal %d.  Cleaning up.\n", s);	    VOID write(STDERR_FILENO, buf, strlen(buf));	}	exiterr();}	voidignoreints(){	++holdlevel;}	voidrestoreints(){	if (!--holdlevel && heldsignal)		VOID catchsig(heldsignal);}static int const sig[] = {#ifdef SIGHUP	SIGHUP,#endif#ifdef SIGINT	SIGINT,#endif#ifdef SIGPIPE	SIGPIPE,#endif#ifdef SIGQUIT	SIGQUIT,#endif#ifdef SIGTERM	SIGTERM,#endif#ifdef SIGXCPU	SIGXCPU,#endif#ifdef SIGXFSZ	SIGXFSZ,#endif};#define SIGS (sizeof(sig)/sizeof(*sig))#if has_sigaction	static void  check_sig(r)	int r;  {	if (r != 0)		efaterror("signal");  }	static void  setup_catchsig()  {	register int i;	sigset_t blocked;	struct sigaction act;	check_sig(sigemptyset(&blocked));	for (i=SIGS; 0<=--i; )	    check_sig(sigaddset(&blocked, sig[i]));	for (i=SIGS; 0<=--i; ) {	    check_sig(sigaction(sig[i], (struct sigaction*)nil, &act));	    if (act.sa_handler != SIG_IGN) {		    act.sa_handler = catchsig;		    act.sa_mask = blocked;		    check_sig(sigaction(sig[i], &act, (struct sigaction*)nil));	    }	}  }#else#if has_sigblock	static void  setup_catchsig()  {	register int i;	int mask;	mask = 0;	for (i=SIGS; 0<=--i; )		mask |= sigmask(sig[i]);	mask = sigblock(mask);	for (i=SIGS; 0<=--i; )		if (		    signal(sig[i], catchsig) == SIG_IGN  &&		    signal(sig[i], SIG_IGN) != catchsig		)			faterror("signal catcher failure");	VOID sigsetmask(mask);  }

⌨️ 快捷键说明

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