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

📄 output.c

📁 Android 一些工具
💻 C
字号:
/*	$NetBSD: output.c,v 1.28 2003/08/07 09:05:36 agc Exp $	*//*- * Copyright (c) 1991, 1993 *	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. 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. */#include <sys/cdefs.h>#ifndef lint#if 0static char sccsid[] = "@(#)output.c	8.2 (Berkeley) 5/4/95";#else__RCSID("$NetBSD: output.c,v 1.28 2003/08/07 09:05:36 agc Exp $");#endif#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 <sys/types.h>		/* quad_t */#include <sys/param.h>		/* BSD4_4 */#include <sys/ioctl.h>#include <stdio.h>	/* defines BUFSIZ */#include <string.h>#include <errno.h>#include <unistd.h>#include <stdlib.h>#include "shell.h"#include "syntax.h"#include "output.h"#include "memalloc.h"#include "error.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(char *block, int length, struct output *file){	file->nextc = block;	file->nleft = --length;	file->fd = BLOCK_OUT;	file->flags = 0;}#endifvoidout1str(const char *p){	outstr(p, out1);}voidout2str(const char *p){	outstr(p, out2);}voidoutstr(const char *p, struct output *file){	while (*p)		outc(*p++, file);	if (file == out2)		flushout(file);}char out_junk[16];voidemptyoutbuf(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(void){	flushout(&output);	flushout(&errout);}voidflushout(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(void){	INTOFF;	if (output.buf) {		ckfree(output.buf);		output.buf = NULL;		output.nleft = 0;	}	INTON;}voidoutfmt(struct output *file, const char *fmt, ...){	va_list ap;	va_start(ap, fmt);	doformat(file, fmt, ap);	va_end(ap);}voidout1fmt(const char *fmt, ...){	va_list ap;	va_start(ap, fmt);	doformat(out1, fmt, ap);	va_end(ap);}voiddprintf(const char *fmt, ...){	va_list ap;	va_start(ap, fmt);	doformat(out2, fmt, ap);	va_end(ap);	flushout(out2);}voidfmtstr(char *outbuf, size_t length, const 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);}/* * Formatted output.  This routine handles a subset of the printf formats: * - Formats supported: d, u, o, p, X, s, and c. * - The x format is also accepted but is treated like X. * - The l, ll and q modifiers are 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 BSD4_4#define HAVE_VASPRINTF 1#endifvoiddoformat(struct output *dest, const char *f, va_list ap){#if	HAVE_VASPRINTF	char *s;	vasprintf(&s, f, ap);	outstr(s, dest);	free(s);     #else	/* !HAVE_VASPRINTF */	static const char digit[] = "0123456789ABCDEF";	char c;	char temp[TEMPSIZE];	int flushleft;	int sharp;	int width;	int prec;	int islong;	int isquad;	char *p;	int sign;#ifdef BSD4_4	quad_t l;	u_quad_t num;#else	long l;	u_long num;#endif	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;		isquad = 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') {			f++;			if (*f == 'l') {				isquad++;				f++;			} else				islong++;		} else if (*f == 'q') {			isquad++;			f++;		}		switch (*f) {		case 'd':#ifdef BSD4_4			if (isquad)				l = va_arg(ap, quad_t);			else#endif			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 'p':			outc('0', dest);			outc('x', dest);			/*FALLTHROUGH*/		case 'x':			/* we don't implement 'x'; treat like 'X' */		case 'X':			base = 16;uns_number:	  /* an unsigned number */			sign = 0;#ifdef BSD4_4			if (isquad)				num = va_arg(ap, u_quad_t);			else#endif			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++;	}#endif	/* !HAVE_VASPRINTF */}/* * Version of write which resumes after a signal is caught. */intxwrite(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. * XXX unused function */intxioctl(int fd, unsigned long request, char *arg){	int i;	while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR);	return i;}

⌨️ 快捷键说明

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