* Copyright (c) 1991 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 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
/*static char sccsid[] = "from: @(#)output.c 5.1 (Berkeley) 3/7/91";*/
static char rcsid
[] = "output.c,v 1.4 1993/08/01 18:58:03 mycroft Exp";
* Shell output routines. We use our own output routines because:
* When a builtin command is interrupted we have to discard
* 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 */
#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
;
if (memout
.buf
!= NULL
) {
#ifdef notdef /* no longer used */
* Set up an output file to write to memory rather than a file.
open_mem(block
, length
, file
)
register struct output
*file
;
if (dest
->fd
== BLOCK_OUT
) {
dest
->nleft
= sizeof out_junk
;
dest
->flags
|= OUTPUT_ERR
;
} else if (dest
->buf
== NULL
) {
dest
->buf
= ckmalloc(dest
->bufsize
);
dest
->nleft
= dest
->bufsize
;
} else if (dest
->fd
== MEM_OUT
) {
dest
->buf
= ckrealloc(dest
->buf
, dest
->bufsize
);
dest
->nleft
= dest
->bufsize
- offset
;
dest
->nextc
= dest
->buf
+ offset
;
if (dest
->buf
== NULL
|| dest
->nextc
== dest
->buf
|| dest
->fd
< 0)
if (xwrite(dest
->fd
, dest
->buf
, dest
->nextc
- dest
->buf
) < 0)
dest
->flags
|= OUTPUT_ERR
;
dest
->nleft
= dest
->bufsize
;
outfmt(struct output
*file
, char *fmt
, ...) {
out1fmt(char *fmt
, ...) {
fmtstr(char *outbuf
, int length
, char *fmt
, ...) {
doformat(&strout
, fmt
, ap
);
if (strout
.flags
& OUTPUT_ERR
)
outbuf
[length
- 1] = '\0';
file
= va_arg(ap
, struct output
*);
fmt
= va_arg(ap
, char *);
fmt
= va_arg(ap
, char *);
outbuf
= va_arg(ap
, char *);
length
= va_arg(ap
, int);
fmt
= va_arg(ap
, char *);
doformat(&strout
, fmt
, ap
);
if (strout
.flags
& OUTPUT_ERR
)
outbuf
[length
- 1] = '\0';
* 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.
static const char digit
[16] = "0123456789ABCDEF";
static const char digit
[17] = "0123456789ABCDEF";
register struct output
*dest
;
register char *f
; /* format string */
while ((c
= *f
++) != '\0') {
width
= 10 * width
+ digit_val(*f
++);
prec
= 10 * prec
+ digit_val(*f
++);
/* we don't implement 'x'; treat like 'X' */
uns_number
: /* an unsigned number */
num
= va_arg(ap
, unsigned long);
num
= va_arg(ap
, unsigned int);
number
: /* process a number */
*--p
= digit
[num
% base
];
len
= (temp
+ TEMPSIZE
- 1) - p
;
if (sharp
&& *f
== 'o' && prec
<= len
)
if (prec
>= 0 && len
> prec
)
while (--prec
!= 0 && *p
)
* Version of write which resumes after a signal is caught.
} else if (errno
!= EINTR
) {
* Version of ioctl that retries after a signal is caught.
xioctl(fd
, request
, arg
) {
while ((i
= ioctl(fd
, request
, arg
)) == -1 && errno
== EINTR
);