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

📄 output.c

📁 操作系统源代码
💻 C
字号:
/*- * Copyright (c) 1991 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Kenneth Almquist. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)output.c	5.1 (Berkeley) 3/7/91";#endif /* not lint *//* * Shell output routines.  We use our own output routines because: *	When a builtin command is interrupted we have to discard *		any pending output. *	When a builtin command appears in back quotes, we want to *		save the output of the command in a region obtained *		via malloc, rather than doing a fork and reading the *		output of the command via a pipe. *	Our output routines may be smaller than the stdio routines. */#include <stdio.h>	/* defines BUFSIZ */#include "shell.h"#include "syntax.h"#include "output.h"#include "memalloc.h"#include "error.h"#ifdef __STDC__#include "stdarg.h"#else#include <varargs.h>#endif#include <errno.h>#define OUTBUFSIZ BUFSIZ#define BLOCK_OUT -2		/* output to a fixed block of memory */#define MEM_OUT -3		/* output to dynamically allocated memory */#define OUTPUT_ERR 01		/* error occurred on output */struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0};struct output errout = {NULL, 0, NULL, 100, 2, 0};struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0};struct output *out1 = &output;struct output *out2 = &errout;#ifdef mkinitINCLUDE "output.h"INCLUDE "memalloc.h"RESET {	out1 = &output;	out2 = &errout;	if (memout.buf != NULL) {		ckfree(memout.buf);		memout.buf = NULL;	}}#endif#ifdef notdef	/* no longer used *//* * Set up an output file to write to memory rather than a file. */voidopen_mem(block, length, file)	char *block;	int length;	struct output *file;	{	file->nextc = block;	file->nleft = --length;	file->fd = BLOCK_OUT;	file->flags = 0;}#endifvoidout1str(p)	char *p;	{	outstr(p, out1);}voidout2str(p)	char *p;	{	outstr(p, out2);}voidoutstr(p, file)	register char *p;	register struct output *file;	{	while (*p)		outc(*p++, file);}char out_junk[16];voidemptyoutbuf(dest)	struct output *dest;	{	int offset;	if (dest->fd == BLOCK_OUT) {		dest->nextc = out_junk;		dest->nleft = sizeof out_junk;		dest->flags |= OUTPUT_ERR;	} else if (dest->buf == NULL) {		INTOFF;		dest->buf = ckmalloc(dest->bufsize);		dest->nextc = dest->buf;		dest->nleft = dest->bufsize;		INTON;	} else if (dest->fd == MEM_OUT) {		offset = dest->bufsize;		INTOFF;		dest->bufsize <<= 1;		dest->buf = ckrealloc(dest->buf, dest->bufsize);		dest->nleft = dest->bufsize - offset;		dest->nextc = dest->buf + offset;		INTON;	} else {		flushout(dest);	}	dest->nleft--;}voidflushall() {	flushout(&output);	flushout(&errout);}voidflushout(dest)	struct output *dest;	{	if (dest->buf == NULL || dest->nextc == dest->buf || dest->fd < 0)		return;	if (xwrite(dest->fd, dest->buf, dest->nextc - dest->buf) < 0)		dest->flags |= OUTPUT_ERR;	dest->nextc = dest->buf;	dest->nleft = dest->bufsize;}voidfreestdout() {	INTOFF;	if (output.buf) {		ckfree(output.buf);		output.buf = NULL;		output.nleft = 0;	}	INTON;}#ifdef __STDC__voidoutfmt(struct output *file, char *fmt, ...) {	va_list ap;	va_start(ap, fmt);	doformat(file, fmt, ap);	va_end(ap);}voidout1fmt(char *fmt, ...) {	va_list ap;	va_start(ap, fmt);	doformat(out1, fmt, ap);	va_end(ap);}voidfmtstr(char *outbuf, int length, char *fmt, ...) {	va_list ap;	struct output strout;	va_start(ap, fmt);	strout.nextc = outbuf;	strout.nleft = length;	strout.fd = BLOCK_OUT;	strout.flags = 0;	doformat(&strout, fmt, ap);	outc('\0', &strout);	if (strout.flags & OUTPUT_ERR)		outbuf[length - 1] = '\0';	va_end(ap);}#else /* not __STDC__ */voidoutfmt(va_alist)	va_dcl	{	va_list ap;	struct output *file;	char *fmt;	va_start(ap);	file = va_arg(ap, struct output *);	fmt = va_arg(ap, char *);	doformat(file, fmt, ap);	va_end(ap);}voidout1fmt(va_alist)	va_dcl	{	va_list ap;	char *fmt;	va_start(ap);	fmt = va_arg(ap, char *);	doformat(out1, fmt, ap);	va_end(ap);}voidfmtstr(va_alist)	va_dcl	{	va_list ap;	struct output strout;	char *outbuf;	int length;	char *fmt;	va_start(ap);	outbuf = va_arg(ap, char *);	length = va_arg(ap, int);	fmt = va_arg(ap, char *);	strout.nextc = outbuf;	strout.nleft = length;	strout.fd = BLOCK_OUT;	strout.flags = 0;	doformat(&strout, fmt, ap);	outc('\0', &strout);	if (strout.flags & OUTPUT_ERR)		outbuf[length - 1] = '\0';}#endif /* __STDC__ *//* * Formatted output.  This routine handles a subset of the printf formats: * - Formats supported: d, u, o, X, s, and c. * - The x format is also accepted but is treated like X. * - The l modifier is accepted. * - The - and # flags are accepted; # only works with the o format. * - Width and precision may be specified with any format except c. * - An * may be given for the width or precision. * - The obsolete practice of preceding the width with a zero to get *   zero padding is not supported; use the precision field. * - A % may be printed by writing %% in the format string. */#define TEMPSIZE 24#ifdef __STDC__static const char digit[16] = "0123456789ABCDEF";#elsestatic const char digit[17] = "0123456789ABCDEF";#endifvoiddoformat(dest, f, ap)	register struct output *dest;	register char *f;		/* format string */	va_list ap;	{	register char c;	char temp[TEMPSIZE];	int flushleft;	int sharp;	int width;	int prec;	int islong;	char *p;	int sign;	long l;	unsigned long num;	unsigned base;	int len;	int size;	int pad;	while ((c = *f++) != '\0') {		if (c != '%') {			outc(c, dest);			continue;		}		flushleft = 0;		sharp = 0;		width = 0;		prec = -1;		islong = 0;		for (;;) {			if (*f == '-')				flushleft++;			else if (*f == '#')				sharp++;			else				break;			f++;		}		if (*f == '*') {			width = va_arg(ap, int);			f++;		} else {			while (is_digit(*f)) {				width = 10 * width + digit_val(*f++);			}		}		if (*f == '.') {			if (*++f == '*') {				prec = va_arg(ap, int);				f++;			} else {				prec = 0;				while (is_digit(*f)) {					prec = 10 * prec + digit_val(*f++);				}			}		}		if (*f == 'l') {			islong++;			f++;		}		switch (*f) {		case 'd':			if (islong)				l = va_arg(ap, long);			else				l = va_arg(ap, int);			sign = 0;			num = l;			if (l < 0) {				num = -l;				sign = 1;			}			base = 10;			goto number;		case 'u':			base = 10;			goto uns_number;		case 'o':			base = 8;			goto uns_number;		case 'x':			/* we don't implement 'x'; treat like 'X' */		case 'X':			base = 16;uns_number:	  /* an unsigned number */			sign = 0;			if (islong)				num = va_arg(ap, unsigned long);			else				num = va_arg(ap, unsigned int);number:		  /* process a number */			p = temp + TEMPSIZE - 1;			*p = '\0';			while (num) {				*--p = digit[num % base];				num /= base;			}			len = (temp + TEMPSIZE - 1) - p;			if (prec < 0)				prec = 1;			if (sharp && *f == 'o' && prec <= len)				prec = len + 1;			pad = 0;			if (width) {				size = len;				if (size < prec)					size = prec;				size += sign;				pad = width - size;				if (flushleft == 0) {					while (--pad >= 0)						outc(' ', dest);				}			}			if (sign)				outc('-', dest);			prec -= len;			while (--prec >= 0)				outc('0', dest);			while (*p)				outc(*p++, dest);			while (--pad >= 0)				outc(' ', dest);			break;		case 's':			p = va_arg(ap, char *);			pad = 0;			if (width) {				len = strlen(p);				if (prec >= 0 && len > prec)					len = prec;				pad = width - len;				if (flushleft == 0) {					while (--pad >= 0)						outc(' ', dest);				}			}			prec++;			while (--prec != 0 && *p)				outc(*p++, dest);			while (--pad >= 0)				outc(' ', dest);			break;		case 'c':			c = va_arg(ap, int);			outc(c, dest);			break;		default:			outc(*f, dest);			break;		}		f++;	}}/* * Version of write which resumes after a signal is caught. */intxwrite(fd, buf, nbytes)	int fd;	char *buf;	int nbytes;	{	int ntry;	int i;	int n;	n = nbytes;	ntry = 0;	for (;;) {		i = write(fd, buf, n);		if (i > 0) {			if ((n -= i) <= 0)				return nbytes;			buf += i;			ntry = 0;		} else if (i == 0) {			if (++ntry > 10)				return nbytes - n;		} else if (errno != EINTR) {			return -1;		}	}}/* * Version of ioctl that retries after a signal is caught. */intxioctl(fd, request, arg) {	int i;	while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR);	return i;}

⌨️ 快捷键说明

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