* Copyright (c) 1991 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)output.c 5.1 (Berkeley) %G%";
* 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
);