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

📄 buffer.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Source: /u/mark/src/pax/RCS/buffer.c,v $ * * $Revision: 1.2 $ * * buffer.c - Buffer management functions * * DESCRIPTION * *	These functions handle buffer manipulations for the archiving *	formats.  Functions are provided to get memory for buffers,  *	flush buffers, read and write buffers and de-allocate buffers.   *	Several housekeeping functions are provided as well to get some  *	information about how full buffers are, etc. * * AUTHOR * *	Mark H. Colburn, NAPS International (mark@jhereg.mn.org) * * Sponsored by The USENIX Association for public distribution.  * * Copyright (c) 1989 Mark H. Colburn. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice is duplicated in all such  * forms and that any documentation, advertising materials, and other  * materials related to such distribution and use acknowledge that the  * software was developed * by Mark H. Colburn and sponsored by The  * USENIX Association.  * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * $Log:	buffer.c,v $ * Revision 1.2  89/02/12  10:04:02  mark * 1.2 release fixes *  * Revision 1.1  88/12/23  18:02:01  mark * Initial revision *  */#ifndef lintstatic char *ident = "$Id: buffer.c,v 1.2 89/02/12 10:04:02 mark Exp $";static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";#endif /* ! lint *//* Headers */#include "pax.h"/* Function Prototypes */#ifdef __STDC__static int ar_write(int, char *, uint);static void buf_pad(OFFSET);static int indata(int, OFFSET, char *);static void outflush(void);static void buf_use(uint);static int buf_in_avail(char **, uint *);static uint buf_out_avail(char **);#else /* !__STDC__ */static int ar_write();static void buf_pad();static int indata();static void outflush();static void buf_use();static int buf_in_avail();static uint buf_out_avail();#endif /* __STDC__ *//* inentry - install a single archive entry * * DESCRIPTION * *	Inentry reads an archive entry from the archive file and writes it *	out the the named file.  If we are in PASS mode during archive *	processing, the pass() function is called, otherwise we will *	extract from the archive file. * *	Inentry actaully calls indata to process the actual data to the *	file. * * PARAMETERS * *	char	*name	- name of the file to extract from the archive *	Stat	*asb	- stat block of the file to be extracted from the *			  archive. * * RETURNS * * 	Returns zero if successful, -1 otherwise.  */#ifdef __STDC__int inentry(char *name, Stat *asb)#elseint inentry(name, asb)char           *name;Stat           *asb;#endif{    Link           *linkp;    int             ifd;    int             ofd;    time_t          tstamp[2];    if ((ofd = openout(name, asb, linkp = linkfrom(name, asb), 0)) > 0) {	if (asb->sb_size || linkp == (Link *)NULL || linkp->l_size == 0) {	    close(indata(ofd, asb->sb_size, name));	} else if ((ifd = open(linkp->l_path->p_name, O_RDONLY)) < 0) {	    warn(linkp->l_path->p_name, strerror());	} else {	    passdata(linkp->l_path->p_name, ifd, name, ofd);	    close(ifd);	    close(ofd);	}    } else {	return(buf_skip((OFFSET) asb->sb_size) >= 0);    }    tstamp[0] = (!f_pass && f_access_time) ? asb->sb_atime : time((time_t *) 0);    tstamp[1] = f_mtime ? asb->sb_mtime : time((time_t *) 0);    utime(name, tstamp);    return (0);}/* outdata - write archive data * * DESCRIPTION * *	Outdata transfers data from the named file to the archive buffer. *	It knows about the file padding which is required by tar, but no *	by cpio.  Outdata continues after file read errors, padding with  *	null characters if neccessary.   Closes the input file descriptor  *	when finished. * * PARAMETERS * *	int	fd	- file descriptor of file to read data from *	char   *name	- name of file *	OFFSET	size	- size of the file * */#ifdef __STDC__void outdata(int fd, char *name, OFFSET size)#elsevoid outdata(fd, name, size)int             fd;char           *name;OFFSET          size;#endif{    uint            chunk;    int             got;    int             oops;    uint            avail;    int		    pad;    char           *buf;    oops = got = 0;    if (pad = (size % BLOCKSIZE)) {	pad = (BLOCKSIZE - pad);    }    while (size) {	avail = buf_out_avail(&buf);	size -= (chunk = size < avail ? (uint) size : avail);	if (oops == 0 && (got = read(fd, buf, (unsigned int) chunk)) < 0) {	    oops = -1;	    warn(name, strerror());	    got = 0;	}	if (got < chunk) {	    if (oops == 0) {		oops = -1;	    }	    warn(name, "Early EOF");	    while (got < chunk) {		buf[got++] = '\0';	    }	}	buf_use(chunk);    }    close(fd);    if (ar_format == TAR) {	buf_pad((OFFSET) pad);    }}/* write_eot -  write the end of archive record(s) * * DESCRIPTION * *	Write out an End-Of-Tape record.  We actually zero at least one  *	record, through the end of the block.  Old tar writes garbage after  *	two zeroed records -- and PDtar used to. */#ifdef __STDC__void write_eot(void)#elsevoid write_eot()#endif{    OFFSET           pad;    char            header[M_STRLEN + H_STRLEN + 1];    if (ar_format == TAR) {	/* write out two zero blocks for trailer */	pad = 2 * BLOCKSIZE;    } else {	if (pad = (total + M_STRLEN + H_STRLEN + TRAILZ) % BLOCKSIZE) {	    pad = BLOCKSIZE - pad;	}	strcpy(header, M_ASCII);	sprintf(header + M_STRLEN, H_PRINT, 0, 0,		       0, 0, 0, 1, 0, (time_t) 0, TRAILZ, pad);	outwrite(header, M_STRLEN + H_STRLEN);	outwrite(TRAILER, TRAILZ);    }    buf_pad((OFFSET) pad);    outflush();} /* outwrite -  write archive data * * DESCRIPTION * *	Writes out data in the archive buffer to the archive file.  The *	buffer index and the total byte count are incremented by the number *	of data bytes written. * * PARAMETERS *	 *	char   *idx	- pointer to data to write *	uint	len	- length of the data to write */#ifdef __STDC__void outwrite(char *idx, uint len)#elsevoid outwrite(idx, len)char           *idx;	/* pointer to data to write */uint            len;	/* length of data to write */#endif{    uint            have;    uint            want;    char           *endx;    endx = idx + len;    while (want = endx - idx) {	if (bufend - bufidx < 0) {	    fatal("Buffer overlow in out_write\n");	}	if ((have = bufend - bufidx) == 0) {	    outflush();	}	if (have > want) {	    have = want;	}	memcpy(bufidx, idx, (int) have);	bufidx += have;	idx += have;	total += have;    }}/* passdata - copy data to one file * * DESCRIPTION * *	Copies a file from one place to another.  Doesn't believe in input  *	file descriptor zero (see description of kludge in openin() comments).  *	Closes the provided output file descriptor.  * * PARAMETERS * *	char	*from	- input file name (old file) *	int	ifd	- input file descriptor *	char	*to	- output file name (new file) *	int	ofd	- output file descriptor */#ifdef __STDC__void passdata(char *from, int ifd, char *to, int ofd)#elsevoid passdata(from, ifd, to, ofd)char           *from;int             ifd;char           *to;int             ofd;#endif{    int             got;    int             sparse;    char            block[BUFSIZ];    if (ifd) {	lseek(ifd, (OFFSET) 0, 0);	sparse = 0;	while ((got = read(ifd, block, sizeof(block))) > 0	       && (sparse = ar_write(ofd, block, (uint) got)) >= 0) {	    total += got;	}	if (got) {	    warn(got < 0 ? from : to, strerror());	} else if (sparse > 0		 && (lseek(ofd, (OFFSET)(-sparse), 1) < 0		     || write(ofd, block, (uint) sparse) != sparse)) {	    warn(to, strerror());	}    }    close(ofd);}/* buf_allocate - get space for the I/O buffer  * * DESCRIPTION * *	buf_allocate allocates an I/O buffer using malloc.  The resulting *	buffer is used for all data buffering throughout the program. *	Buf_allocate must be called prior to any use of the buffer or any *	of the buffering calls. * * PARAMETERS * *	int	size	- size of the I/O buffer to request * * ERRORS * *	If an invalid size is given for a buffer or if a buffer of the  *	required size cannot be allocated, then the function prints out an  *	error message and returns a non-zero exit status to the calling  *	process, terminating the program. * */#ifdef __STDC__void buf_allocate(OFFSET size)#elsevoid buf_allocate(size)OFFSET            size;#endif{    if (size <= 0) {	fatal("invalid value for blocksize");    }    if ((bufstart = malloc((unsigned) size)) == (char *)NULL) {	fatal("Cannot allocate I/O buffer");    }    bufend = bufidx = bufstart;    bufend += size;}/* buf_skip - skip input archive data * * DESCRIPTION * *	Buf_skip skips past archive data.  It is used when the length of *	the archive data is known, and we do not wish to process the data. * * PARAMETERS * *	OFFSET	len	- number of bytes to skip * * RETURNS * * 	Returns zero under normal circumstances, -1 if unreadable data is  * 	encountered.  */#ifdef __STDC__int buf_skip(OFFSET len)#elseint buf_skip(len)OFFSET           len;#endif{    uint            chunk;    int             corrupt = 0;    while (len) {	if (bufend - bufidx < 0) {	    fatal("Buffer overlow in buf_skip\n");	}	while ((chunk = bufend - bufidx) == 0) {

⌨️ 快捷键说明

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