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

📄 tmp.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* tmp.c *//* Author: *	Steve Kirkendall *	14407 SW Teal Blvd. #C *	Beaverton, OR 97005 *	kirkenda@cs.pdx.edu *//* This file contains functions which create & readback a TMPFILE */#include "config.h"#include "vi.h"#if TOS# include <stat.h>#else# if OSK#  include "osk.h"# else#  if AMIGA#   include "amistat.h"#  else#   include <sys/stat.h>#  endif# endif#endif#if TURBOC# include <process.h>#endif#ifndef NO_MODELINESstatic void do_modelines(l, stop)	long	l;	/* line number to start at */	long	stop;	/* line number to stop at */{	char	*str;	/* used to scan through the line */	char	*start;	/* points to the start of the line */	char	buf[80];	/* if modelines are disabled, then do nothing */	if (!*o_modelines)	{		return;	}	/* for each line... */	for (; l <= stop; l++)	{		/* for each position in the line.. */		for (str = fetchline(l); *str; str++)		{			/* if it is the start of a modeline command... */			if ((str[0] == 'e' && str[1] == 'x'			  || str[0] == 'v' && str[1] == 'i')			  && str[2] == ':')			{				start = str += 3;				/* find the end */				for (str = start + strlen(start); *--str != ':'; )				{				}				/* if it is a well-formed modeline, execute it */				if (str > start && str - start < sizeof buf)				{					strncpy(buf, start, (int)(str - start));					exstring(buf, str - start, '\\');					break;				}			}		}	}}#endif/* The FAIL() macro prints an error message and then exits. */#define FAIL(why,arg)	mode = MODE_EX; msg(why, arg); endwin(); exit(9)/* This is the name of the temp file */static char	tmpname[80];/* This function creates the temp file and copies the original file into it. * Returns if successful, or stops execution if it fails. */int tmpstart(filename)	char		*filename; /* name of the original file */{	int		origfd;	/* fd used for reading the original file */	struct stat	statb;	/* stat buffer, used to examine inode */	REG BLK		*this;	/* pointer to the current block buffer */	REG BLK		*next;	/* pointer to the next block buffer */	int		inbuf;	/* number of characters in a buffer */	int		nread;	/* number of bytes read */	REG int		j, k;	int		i;	long		nbytes;	/* switching to a different file certainly counts as a change */	changes++;	redraw(MARK_UNSET, FALSE);	/* open the original file for reading */	*origname = '\0';	if (filename && *filename)	{		strcpy(origname, filename);		origfd = open(origname, O_RDONLY);		if (origfd < 0 && errno != ENOENT)		{			msg("Can't open \"%s\"", origname);			return tmpstart("");		}		if (origfd >= 0)		{			if (stat(origname, &statb) < 0)			{				FAIL("Can't stat \"%s\"", origname);			}#if TOS			if (origfd >= 0 && (statb.st_mode & S_IJDIR))#else# if OSK			if (origfd >= 0 && (statb.st_mode & S_IFDIR))# else			if (origfd >= 0 && (statb.st_mode & S_IFMT) != S_IFREG)# endif#endif			{				msg("\"%s\" is not a regular file", origname);				return tmpstart("");			}		}		else		{			stat(".", &statb);		}		if (origfd >= 0)		{			origtime = statb.st_mtime;#if OSK			if (*o_readonly || !(statb.st_mode &				  ((getuid() >> 16) == 0 ? S_IOWRITE | S_IWRITE :				  ((statb.st_gid != (getuid() >> 16) ? S_IOWRITE : S_IWRITE)))))#endif#if AMIGA || MSDOS || (TOS && defined(__GNUC__))			if (*o_readonly || !(statb.st_mode & S_IWRITE))#endif#if TOS && !defined(__GNUC__)			if (*o_readonly || (statb.st_mode & S_IJRON))#endif#if ANY_UNIX			if (*o_readonly || !(statb.st_mode &				  ((geteuid() == 0) ? 0222 :				  ((statb.st_uid != geteuid() ? 0022 : 0200)))))#endif#if VMS			if (*o_readonly)#endif			{				setflag(file, READONLY);			}		}		else		{			origtime = 0L;		}	}	else	{		setflag(file, NOFILE);		origfd = -1;		origtime = 0L;		stat(".", &statb);	}	/* make a name for the tmp file */	tmpnum++;#if MSDOS || TOS	/* MS-Dos doesn't allow multiple slashes, but supports drives	 * with current directories.	 * This relies on TMPNAME beginning with "%s\\"!!!!	 */	strcpy(tmpname, o_directory);	if ((i = strlen(tmpname)) && !strchr(":/\\", tmpname[i-1]))		tmpname[i++]=SLASH;	sprintf(tmpname+i, TMPNAME+3, getpid(), tmpnum);#else	sprintf(tmpname, TMPNAME, o_directory, getpid(), tmpnum);#endif	/* make sure nobody else is editing the same file */	if (access(tmpname, 0) == 0)	{		FAIL("Temp file \"%s\" already exists?", tmpname);	}	/* create the temp file */#if ANY_UNIX	close(creat(tmpname, 0600));		/* only we can read it */#else	close(creat(tmpname, FILEPERMS));	/* anybody body can read it, alas */#endif	tmpfd = open(tmpname, O_RDWR | O_BINARY);	if (tmpfd < 0)	{		FAIL("Can't create temp file... Does directory \"%s\" exist?", o_directory);		return 1;	}	/* allocate space for the header in the file */	write(tmpfd, hdr.c, (unsigned)BLKSIZE);	write(tmpfd, tmpblk.c, (unsigned)BLKSIZE);#ifndef NO_RECYCLE	/* initialize the block allocator */	/* This must already be done here, before the first attempt	 * to write to the new file! GB */	garbage();#endif	/* initialize lnum[] */	for (i = 1; i < MAXBLKS; i++)	{		lnum[i] = INFINITY;	}	lnum[0] = 0;	/* if there is no original file, then create a 1-line file */	if (origfd < 0)	{		hdr.n[0] = 0;	/* invalid inode# denotes new file */		this = blkget(1); 	/* get the new text block */		strcpy(this->c, "\n");	/* put a line in it */		lnum[1] = 1L;	/* block 1 ends with line 1 */		nlines = 1L;	/* there is 1 line in the file */		nbytes = 1L;		if (*origname)		{			msg("\"%s\" [NEW FILE]  1 line, 1 char", origname);		}		else		{			msg("\"[NO FILE]\"  1 line, 1 char");		}	}	else /* there is an original file -- read it in */	{		nbytes = nlines = 0;		/* preallocate 1 "next" buffer */		i = 1;		next = blkget(i);		inbuf = 0;		/* loop, moving blocks from orig to tmp */		for (;;)		{			/* "next" buffer becomes "this" buffer */			this = next;			/* read [more] text into this block */			nread = tread(origfd, &this->c[inbuf], BLKSIZE - 1 - inbuf);			if (nread < 0)			{				close(origfd);				close(tmpfd);				tmpfd = -1;				unlink(tmpname);				FAIL("Error reading \"%s\"", origname);			}			/* convert NUL characters to something else */			for (j = k = inbuf; k < inbuf + nread; k++)			{				if (!this->c[k])				{					setflag(file, HADNUL);					this->c[j++] = 0x80;				}#ifndef CRUNCH				else if (*o_beautify && this->c[k] < ' ' && this->c[k] > 0)				{					if (this->c[k] == '\t'					 || this->c[k] == '\n'					 || this->c[k] == '\f')					{						this->c[j++] = this->c[k];					}					else if (this->c[k] == '\b')					{						/* delete '\b', but complain */						setflag(file, HADBS);					}					/* else silently delete control char */				}#endif				else				{					this->c[j++] = this->c[k];				}			}			inbuf = j;			/* if the buffer is empty, quit */			if (inbuf == 0)			{				goto FoundEOF;			}#if MSDOS || TOS/* BAH! MS text mode read fills inbuf, then compresses eliminating \r   but leaving garbage at end of buf. The same is true for TURBOC. GB. */			memset(this->c + inbuf, '\0', BLKSIZE - inbuf);#endif			/* search backward for last newline */			for (k = inbuf; --k >= 0 && this->c[k] != '\n';)			{			}			if (k++ < 0)			{				if (inbuf >= BLKSIZE - 1)				{					k = 80;				}				else				{					k = inbuf;				}			}			/* allocate next buffer */			next = blkget(++i);			/* move fragmentary last line to next buffer */			inbuf -= k;			for (j = 0; k < BLKSIZE; j++, k++)			{				next->c[j] = this->c[k];				this->c[k] = 0;			}			/* if necessary, add a newline to this buf */			for (k = BLKSIZE - inbuf; --k >= 0 && !this->c[k]; )			{			}			if (this->c[k] != '\n')			{				setflag(file, ADDEDNL);				this->c[k + 1] = '\n';			}			/* count the lines in this block */			for (k = 0; k < BLKSIZE && this->c[k]; k++)			{				if (this->c[k] == '\n')				{					nlines++;				}				nbytes++;			}			lnum[i - 1] = nlines;		}FoundEOF:		/* if this is a zero-length file, add 1 line */		if (nlines == 0)		{			this = blkget(1); 	/* get the new text block */			strcpy(this->c, "\n");	/* put a line in it */			lnum[1] = 1;	/* block 1 ends with line 1 */

⌨️ 快捷键说明

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