14b88c807SRodney W. Grimes /*- 24b88c807SRodney W. Grimes * Copyright (c) 1991, 1993 34b88c807SRodney W. Grimes * The Regents of the University of California. All rights reserved. 44b88c807SRodney W. Grimes * 54b88c807SRodney W. Grimes * This code is derived from software contributed to Berkeley by 64b88c807SRodney W. Grimes * Kenneth Almquist. 74b88c807SRodney W. Grimes * 84b88c807SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 94b88c807SRodney W. Grimes * modification, are permitted provided that the following conditions 104b88c807SRodney W. Grimes * are met: 114b88c807SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 124b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 134b88c807SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 144b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 154b88c807SRodney W. Grimes * documentation and/or other materials provided with the distribution. 164b88c807SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 174b88c807SRodney W. Grimes * must display the following acknowledgement: 184b88c807SRodney W. Grimes * This product includes software developed by the University of 194b88c807SRodney W. Grimes * California, Berkeley and its contributors. 204b88c807SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 214b88c807SRodney W. Grimes * may be used to endorse or promote products derived from this software 224b88c807SRodney W. Grimes * without specific prior written permission. 234b88c807SRodney W. Grimes * 244b88c807SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 254b88c807SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 264b88c807SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 274b88c807SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 284b88c807SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 294b88c807SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 304b88c807SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 314b88c807SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 324b88c807SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 334b88c807SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 344b88c807SRodney W. Grimes * SUCH DAMAGE. 3589730b29SDavid Greenman * 36aa9caaf6SPeter Wemm * $Id: output.c,v 1.2 1994/09/24 02:58:06 davidg Exp $ 374b88c807SRodney W. Grimes */ 384b88c807SRodney W. Grimes 394b88c807SRodney W. Grimes #ifndef lint 40aa9caaf6SPeter Wemm static char sccsid[] = "@(#)output.c 8.2 (Berkeley) 5/4/95"; 414b88c807SRodney W. Grimes #endif /* not lint */ 424b88c807SRodney W. Grimes 434b88c807SRodney W. Grimes /* 444b88c807SRodney W. Grimes * Shell output routines. We use our own output routines because: 454b88c807SRodney W. Grimes * When a builtin command is interrupted we have to discard 464b88c807SRodney W. Grimes * any pending output. 474b88c807SRodney W. Grimes * When a builtin command appears in back quotes, we want to 484b88c807SRodney W. Grimes * save the output of the command in a region obtained 494b88c807SRodney W. Grimes * via malloc, rather than doing a fork and reading the 504b88c807SRodney W. Grimes * output of the command via a pipe. 514b88c807SRodney W. Grimes * Our output routines may be smaller than the stdio routines. 524b88c807SRodney W. Grimes */ 534b88c807SRodney W. Grimes 54aa9caaf6SPeter Wemm #include <sys/ioctl.h> 55aa9caaf6SPeter Wemm 564b88c807SRodney W. Grimes #include <stdio.h> /* defines BUFSIZ */ 57aa9caaf6SPeter Wemm #include <string.h> 58aa9caaf6SPeter Wemm #ifdef __STDC__ 59aa9caaf6SPeter Wemm #include <stdarg.h> 60aa9caaf6SPeter Wemm #else 61aa9caaf6SPeter Wemm #include <varargs.h> 62aa9caaf6SPeter Wemm #endif 63aa9caaf6SPeter Wemm #include <errno.h> 64aa9caaf6SPeter Wemm #include <unistd.h> 65aa9caaf6SPeter Wemm #include <stdlib.h> 66aa9caaf6SPeter Wemm 674b88c807SRodney W. Grimes #include "shell.h" 684b88c807SRodney W. Grimes #include "syntax.h" 694b88c807SRodney W. Grimes #include "output.h" 704b88c807SRodney W. Grimes #include "memalloc.h" 714b88c807SRodney W. Grimes #include "error.h" 724b88c807SRodney W. Grimes 734b88c807SRodney W. Grimes 744b88c807SRodney W. Grimes #define OUTBUFSIZ BUFSIZ 754b88c807SRodney W. Grimes #define BLOCK_OUT -2 /* output to a fixed block of memory */ 764b88c807SRodney W. Grimes #define MEM_OUT -3 /* output to dynamically allocated memory */ 774b88c807SRodney W. Grimes #define OUTPUT_ERR 01 /* error occurred on output */ 784b88c807SRodney W. Grimes 794b88c807SRodney W. Grimes 804b88c807SRodney W. Grimes struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0}; 814b88c807SRodney W. Grimes struct output errout = {NULL, 0, NULL, 100, 2, 0};; 824b88c807SRodney W. Grimes struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0}; 834b88c807SRodney W. Grimes struct output *out1 = &output; 844b88c807SRodney W. Grimes struct output *out2 = &errout; 854b88c807SRodney W. Grimes 864b88c807SRodney W. Grimes 874b88c807SRodney W. Grimes 884b88c807SRodney W. Grimes #ifdef mkinit 894b88c807SRodney W. Grimes 904b88c807SRodney W. Grimes INCLUDE "output.h" 914b88c807SRodney W. Grimes INCLUDE "memalloc.h" 924b88c807SRodney W. Grimes 934b88c807SRodney W. Grimes RESET { 944b88c807SRodney W. Grimes out1 = &output; 954b88c807SRodney W. Grimes out2 = &errout; 964b88c807SRodney W. Grimes if (memout.buf != NULL) { 974b88c807SRodney W. Grimes ckfree(memout.buf); 984b88c807SRodney W. Grimes memout.buf = NULL; 994b88c807SRodney W. Grimes } 1004b88c807SRodney W. Grimes } 1014b88c807SRodney W. Grimes 1024b88c807SRodney W. Grimes #endif 1034b88c807SRodney W. Grimes 1044b88c807SRodney W. Grimes 1054b88c807SRodney W. Grimes #ifdef notdef /* no longer used */ 1064b88c807SRodney W. Grimes /* 1074b88c807SRodney W. Grimes * Set up an output file to write to memory rather than a file. 1084b88c807SRodney W. Grimes */ 1094b88c807SRodney W. Grimes 1104b88c807SRodney W. Grimes void 1114b88c807SRodney W. Grimes open_mem(block, length, file) 1124b88c807SRodney W. Grimes char *block; 1134b88c807SRodney W. Grimes int length; 1144b88c807SRodney W. Grimes struct output *file; 1154b88c807SRodney W. Grimes { 1164b88c807SRodney W. Grimes file->nextc = block; 1174b88c807SRodney W. Grimes file->nleft = --length; 1184b88c807SRodney W. Grimes file->fd = BLOCK_OUT; 1194b88c807SRodney W. Grimes file->flags = 0; 1204b88c807SRodney W. Grimes } 1214b88c807SRodney W. Grimes #endif 1224b88c807SRodney W. Grimes 1234b88c807SRodney W. Grimes 1244b88c807SRodney W. Grimes void 1254b88c807SRodney W. Grimes out1str(p) 126aa9caaf6SPeter Wemm const char *p; 1274b88c807SRodney W. Grimes { 1284b88c807SRodney W. Grimes outstr(p, out1); 1294b88c807SRodney W. Grimes } 1304b88c807SRodney W. Grimes 1314b88c807SRodney W. Grimes 1324b88c807SRodney W. Grimes void 1334b88c807SRodney W. Grimes out2str(p) 134aa9caaf6SPeter Wemm const char *p; 1354b88c807SRodney W. Grimes { 1364b88c807SRodney W. Grimes outstr(p, out2); 1374b88c807SRodney W. Grimes } 1384b88c807SRodney W. Grimes 1394b88c807SRodney W. Grimes 1404b88c807SRodney W. Grimes void 1414b88c807SRodney W. Grimes outstr(p, file) 142aa9caaf6SPeter Wemm register const char *p; 1434b88c807SRodney W. Grimes register struct output *file; 1444b88c807SRodney W. Grimes { 1454b88c807SRodney W. Grimes while (*p) 1464b88c807SRodney W. Grimes outc(*p++, file); 1474b88c807SRodney W. Grimes if (file == out2) 1484b88c807SRodney W. Grimes flushout(file); 1494b88c807SRodney W. Grimes } 1504b88c807SRodney W. Grimes 1514b88c807SRodney W. Grimes 1524b88c807SRodney W. Grimes char out_junk[16]; 1534b88c807SRodney W. Grimes 1544b88c807SRodney W. Grimes 1554b88c807SRodney W. Grimes void 1564b88c807SRodney W. Grimes emptyoutbuf(dest) 1574b88c807SRodney W. Grimes struct output *dest; 1584b88c807SRodney W. Grimes { 1594b88c807SRodney W. Grimes int offset; 1604b88c807SRodney W. Grimes 1614b88c807SRodney W. Grimes if (dest->fd == BLOCK_OUT) { 1624b88c807SRodney W. Grimes dest->nextc = out_junk; 1634b88c807SRodney W. Grimes dest->nleft = sizeof out_junk; 1644b88c807SRodney W. Grimes dest->flags |= OUTPUT_ERR; 1654b88c807SRodney W. Grimes } else if (dest->buf == NULL) { 1664b88c807SRodney W. Grimes INTOFF; 1674b88c807SRodney W. Grimes dest->buf = ckmalloc(dest->bufsize); 1684b88c807SRodney W. Grimes dest->nextc = dest->buf; 1694b88c807SRodney W. Grimes dest->nleft = dest->bufsize; 1704b88c807SRodney W. Grimes INTON; 1714b88c807SRodney W. Grimes } else if (dest->fd == MEM_OUT) { 1724b88c807SRodney W. Grimes offset = dest->bufsize; 1734b88c807SRodney W. Grimes INTOFF; 1744b88c807SRodney W. Grimes dest->bufsize <<= 1; 1754b88c807SRodney W. Grimes dest->buf = ckrealloc(dest->buf, dest->bufsize); 1764b88c807SRodney W. Grimes dest->nleft = dest->bufsize - offset; 1774b88c807SRodney W. Grimes dest->nextc = dest->buf + offset; 1784b88c807SRodney W. Grimes INTON; 1794b88c807SRodney W. Grimes } else { 1804b88c807SRodney W. Grimes flushout(dest); 1814b88c807SRodney W. Grimes } 1824b88c807SRodney W. Grimes dest->nleft--; 1834b88c807SRodney W. Grimes } 1844b88c807SRodney W. Grimes 1854b88c807SRodney W. Grimes 1864b88c807SRodney W. Grimes void 1874b88c807SRodney W. Grimes flushall() { 1884b88c807SRodney W. Grimes flushout(&output); 1894b88c807SRodney W. Grimes flushout(&errout); 1904b88c807SRodney W. Grimes } 1914b88c807SRodney W. Grimes 1924b88c807SRodney W. Grimes 1934b88c807SRodney W. Grimes void 1944b88c807SRodney W. Grimes flushout(dest) 1954b88c807SRodney W. Grimes struct output *dest; 1964b88c807SRodney W. Grimes { 1974b88c807SRodney W. Grimes 1984b88c807SRodney W. Grimes if (dest->buf == NULL || dest->nextc == dest->buf || dest->fd < 0) 1994b88c807SRodney W. Grimes return; 2004b88c807SRodney W. Grimes if (xwrite(dest->fd, dest->buf, dest->nextc - dest->buf) < 0) 2014b88c807SRodney W. Grimes dest->flags |= OUTPUT_ERR; 2024b88c807SRodney W. Grimes dest->nextc = dest->buf; 2034b88c807SRodney W. Grimes dest->nleft = dest->bufsize; 2044b88c807SRodney W. Grimes } 2054b88c807SRodney W. Grimes 2064b88c807SRodney W. Grimes 2074b88c807SRodney W. Grimes void 2084b88c807SRodney W. Grimes freestdout() { 2094b88c807SRodney W. Grimes INTOFF; 2104b88c807SRodney W. Grimes if (output.buf) { 2114b88c807SRodney W. Grimes ckfree(output.buf); 2124b88c807SRodney W. Grimes output.buf = NULL; 2134b88c807SRodney W. Grimes output.nleft = 0; 2144b88c807SRodney W. Grimes } 2154b88c807SRodney W. Grimes INTON; 2164b88c807SRodney W. Grimes } 2174b88c807SRodney W. Grimes 2184b88c807SRodney W. Grimes 2194b88c807SRodney W. Grimes #ifdef __STDC__ 2204b88c807SRodney W. Grimes void 2214b88c807SRodney W. Grimes outfmt(struct output *file, char *fmt, ...) { 2224b88c807SRodney W. Grimes va_list ap; 2234b88c807SRodney W. Grimes 2244b88c807SRodney W. Grimes va_start(ap, fmt); 2254b88c807SRodney W. Grimes doformat(file, fmt, ap); 2264b88c807SRodney W. Grimes va_end(ap); 2274b88c807SRodney W. Grimes } 2284b88c807SRodney W. Grimes 2294b88c807SRodney W. Grimes 2304b88c807SRodney W. Grimes void 2314b88c807SRodney W. Grimes out1fmt(char *fmt, ...) { 2324b88c807SRodney W. Grimes va_list ap; 2334b88c807SRodney W. Grimes 2344b88c807SRodney W. Grimes va_start(ap, fmt); 2354b88c807SRodney W. Grimes doformat(out1, fmt, ap); 2364b88c807SRodney W. Grimes va_end(ap); 2374b88c807SRodney W. Grimes } 2384b88c807SRodney W. Grimes 2394b88c807SRodney W. Grimes void 2404b88c807SRodney W. Grimes dprintf(char *fmt, ...) { 2414b88c807SRodney W. Grimes va_list ap; 2424b88c807SRodney W. Grimes 2434b88c807SRodney W. Grimes va_start(ap, fmt); 2444b88c807SRodney W. Grimes doformat(out2, fmt, ap); 2454b88c807SRodney W. Grimes va_end(ap); 2464b88c807SRodney W. Grimes flushout(out2); 2474b88c807SRodney W. Grimes } 2484b88c807SRodney W. Grimes 2494b88c807SRodney W. Grimes void 2504b88c807SRodney W. Grimes fmtstr(char *outbuf, int length, char *fmt, ...) { 2514b88c807SRodney W. Grimes va_list ap; 2524b88c807SRodney W. Grimes struct output strout; 2534b88c807SRodney W. Grimes 2544b88c807SRodney W. Grimes va_start(ap, fmt); 2554b88c807SRodney W. Grimes strout.nextc = outbuf; 2564b88c807SRodney W. Grimes strout.nleft = length; 2574b88c807SRodney W. Grimes strout.fd = BLOCK_OUT; 2584b88c807SRodney W. Grimes strout.flags = 0; 2594b88c807SRodney W. Grimes doformat(&strout, fmt, ap); 2604b88c807SRodney W. Grimes outc('\0', &strout); 2614b88c807SRodney W. Grimes if (strout.flags & OUTPUT_ERR) 2624b88c807SRodney W. Grimes outbuf[length - 1] = '\0'; 2634b88c807SRodney W. Grimes } 2644b88c807SRodney W. Grimes 2654b88c807SRodney W. Grimes #else /* not __STDC__ */ 2664b88c807SRodney W. Grimes 2674b88c807SRodney W. Grimes void 2684b88c807SRodney W. Grimes outfmt(va_alist) 2694b88c807SRodney W. Grimes va_dcl 2704b88c807SRodney W. Grimes { 2714b88c807SRodney W. Grimes va_list ap; 2724b88c807SRodney W. Grimes struct output *file; 2734b88c807SRodney W. Grimes char *fmt; 2744b88c807SRodney W. Grimes 2754b88c807SRodney W. Grimes va_start(ap); 2764b88c807SRodney W. Grimes file = va_arg(ap, struct output *); 2774b88c807SRodney W. Grimes fmt = va_arg(ap, char *); 2784b88c807SRodney W. Grimes doformat(file, fmt, ap); 2794b88c807SRodney W. Grimes va_end(ap); 2804b88c807SRodney W. Grimes } 2814b88c807SRodney W. Grimes 2824b88c807SRodney W. Grimes 2834b88c807SRodney W. Grimes void 2844b88c807SRodney W. Grimes out1fmt(va_alist) 2854b88c807SRodney W. Grimes va_dcl 2864b88c807SRodney W. Grimes { 2874b88c807SRodney W. Grimes va_list ap; 2884b88c807SRodney W. Grimes char *fmt; 2894b88c807SRodney W. Grimes 2904b88c807SRodney W. Grimes va_start(ap); 2914b88c807SRodney W. Grimes fmt = va_arg(ap, char *); 2924b88c807SRodney W. Grimes doformat(out1, fmt, ap); 2934b88c807SRodney W. Grimes va_end(ap); 2944b88c807SRodney W. Grimes } 2954b88c807SRodney W. Grimes 2964b88c807SRodney W. Grimes void 2974b88c807SRodney W. Grimes dprintf(va_alist) 2984b88c807SRodney W. Grimes va_dcl 2994b88c807SRodney W. Grimes { 3004b88c807SRodney W. Grimes va_list ap; 3014b88c807SRodney W. Grimes char *fmt; 3024b88c807SRodney W. Grimes 3034b88c807SRodney W. Grimes va_start(ap); 3044b88c807SRodney W. Grimes fmt = va_arg(ap, char *); 3054b88c807SRodney W. Grimes doformat(out2, fmt, ap); 3064b88c807SRodney W. Grimes va_end(ap); 3074b88c807SRodney W. Grimes flushout(out2); 3084b88c807SRodney W. Grimes } 3094b88c807SRodney W. Grimes 3104b88c807SRodney W. Grimes void 3114b88c807SRodney W. Grimes fmtstr(va_alist) 3124b88c807SRodney W. Grimes va_dcl 3134b88c807SRodney W. Grimes { 3144b88c807SRodney W. Grimes va_list ap; 3154b88c807SRodney W. Grimes struct output strout; 3164b88c807SRodney W. Grimes char *outbuf; 3174b88c807SRodney W. Grimes int length; 3184b88c807SRodney W. Grimes char *fmt; 3194b88c807SRodney W. Grimes 3204b88c807SRodney W. Grimes va_start(ap); 3214b88c807SRodney W. Grimes outbuf = va_arg(ap, char *); 3224b88c807SRodney W. Grimes length = va_arg(ap, int); 3234b88c807SRodney W. Grimes fmt = va_arg(ap, char *); 3244b88c807SRodney W. Grimes strout.nextc = outbuf; 3254b88c807SRodney W. Grimes strout.nleft = length; 3264b88c807SRodney W. Grimes strout.fd = BLOCK_OUT; 3274b88c807SRodney W. Grimes strout.flags = 0; 3284b88c807SRodney W. Grimes doformat(&strout, fmt, ap); 3294b88c807SRodney W. Grimes outc('\0', &strout); 3304b88c807SRodney W. Grimes if (strout.flags & OUTPUT_ERR) 3314b88c807SRodney W. Grimes outbuf[length - 1] = '\0'; 3324b88c807SRodney W. Grimes } 3334b88c807SRodney W. Grimes #endif /* __STDC__ */ 3344b88c807SRodney W. Grimes 3354b88c807SRodney W. Grimes 3364b88c807SRodney W. Grimes /* 3374b88c807SRodney W. Grimes * Formatted output. This routine handles a subset of the printf formats: 3384b88c807SRodney W. Grimes * - Formats supported: d, u, o, X, s, and c. 3394b88c807SRodney W. Grimes * - The x format is also accepted but is treated like X. 3404b88c807SRodney W. Grimes * - The l modifier is accepted. 3414b88c807SRodney W. Grimes * - The - and # flags are accepted; # only works with the o format. 3424b88c807SRodney W. Grimes * - Width and precision may be specified with any format except c. 3434b88c807SRodney W. Grimes * - An * may be given for the width or precision. 3444b88c807SRodney W. Grimes * - The obsolete practice of preceding the width with a zero to get 3454b88c807SRodney W. Grimes * zero padding is not supported; use the precision field. 3464b88c807SRodney W. Grimes * - A % may be printed by writing %% in the format string. 3474b88c807SRodney W. Grimes */ 3484b88c807SRodney W. Grimes 3494b88c807SRodney W. Grimes #define TEMPSIZE 24 3504b88c807SRodney W. Grimes 3514b88c807SRodney W. Grimes #ifdef __STDC__ 3524b88c807SRodney W. Grimes static const char digit[16] = "0123456789ABCDEF"; 3534b88c807SRodney W. Grimes #else 3544b88c807SRodney W. Grimes static const char digit[17] = "0123456789ABCDEF"; 3554b88c807SRodney W. Grimes #endif 3564b88c807SRodney W. Grimes 3574b88c807SRodney W. Grimes 3584b88c807SRodney W. Grimes void 3594b88c807SRodney W. Grimes doformat(dest, f, ap) 3604b88c807SRodney W. Grimes register struct output *dest; 3614b88c807SRodney W. Grimes register char *f; /* format string */ 3624b88c807SRodney W. Grimes va_list ap; 3634b88c807SRodney W. Grimes { 3644b88c807SRodney W. Grimes register char c; 3654b88c807SRodney W. Grimes char temp[TEMPSIZE]; 3664b88c807SRodney W. Grimes int flushleft; 3674b88c807SRodney W. Grimes int sharp; 3684b88c807SRodney W. Grimes int width; 3694b88c807SRodney W. Grimes int prec; 3704b88c807SRodney W. Grimes int islong; 3714b88c807SRodney W. Grimes char *p; 3724b88c807SRodney W. Grimes int sign; 3734b88c807SRodney W. Grimes long l; 3744b88c807SRodney W. Grimes unsigned long num; 3754b88c807SRodney W. Grimes unsigned base; 3764b88c807SRodney W. Grimes int len; 3774b88c807SRodney W. Grimes int size; 3784b88c807SRodney W. Grimes int pad; 3794b88c807SRodney W. Grimes 3804b88c807SRodney W. Grimes while ((c = *f++) != '\0') { 3814b88c807SRodney W. Grimes if (c != '%') { 3824b88c807SRodney W. Grimes outc(c, dest); 3834b88c807SRodney W. Grimes continue; 3844b88c807SRodney W. Grimes } 3854b88c807SRodney W. Grimes flushleft = 0; 3864b88c807SRodney W. Grimes sharp = 0; 3874b88c807SRodney W. Grimes width = 0; 3884b88c807SRodney W. Grimes prec = -1; 3894b88c807SRodney W. Grimes islong = 0; 3904b88c807SRodney W. Grimes for (;;) { 3914b88c807SRodney W. Grimes if (*f == '-') 3924b88c807SRodney W. Grimes flushleft++; 3934b88c807SRodney W. Grimes else if (*f == '#') 3944b88c807SRodney W. Grimes sharp++; 3954b88c807SRodney W. Grimes else 3964b88c807SRodney W. Grimes break; 3974b88c807SRodney W. Grimes f++; 3984b88c807SRodney W. Grimes } 3994b88c807SRodney W. Grimes if (*f == '*') { 4004b88c807SRodney W. Grimes width = va_arg(ap, int); 4014b88c807SRodney W. Grimes f++; 4024b88c807SRodney W. Grimes } else { 4034b88c807SRodney W. Grimes while (is_digit(*f)) { 4044b88c807SRodney W. Grimes width = 10 * width + digit_val(*f++); 4054b88c807SRodney W. Grimes } 4064b88c807SRodney W. Grimes } 4074b88c807SRodney W. Grimes if (*f == '.') { 4084b88c807SRodney W. Grimes if (*++f == '*') { 4094b88c807SRodney W. Grimes prec = va_arg(ap, int); 4104b88c807SRodney W. Grimes f++; 4114b88c807SRodney W. Grimes } else { 4124b88c807SRodney W. Grimes prec = 0; 4134b88c807SRodney W. Grimes while (is_digit(*f)) { 4144b88c807SRodney W. Grimes prec = 10 * prec + digit_val(*f++); 4154b88c807SRodney W. Grimes } 4164b88c807SRodney W. Grimes } 4174b88c807SRodney W. Grimes } 4184b88c807SRodney W. Grimes if (*f == 'l') { 4194b88c807SRodney W. Grimes islong++; 4204b88c807SRodney W. Grimes f++; 4214b88c807SRodney W. Grimes } 4224b88c807SRodney W. Grimes switch (*f) { 4234b88c807SRodney W. Grimes case 'd': 4244b88c807SRodney W. Grimes if (islong) 4254b88c807SRodney W. Grimes l = va_arg(ap, long); 4264b88c807SRodney W. Grimes else 4274b88c807SRodney W. Grimes l = va_arg(ap, int); 4284b88c807SRodney W. Grimes sign = 0; 4294b88c807SRodney W. Grimes num = l; 4304b88c807SRodney W. Grimes if (l < 0) { 4314b88c807SRodney W. Grimes num = -l; 4324b88c807SRodney W. Grimes sign = 1; 4334b88c807SRodney W. Grimes } 4344b88c807SRodney W. Grimes base = 10; 4354b88c807SRodney W. Grimes goto number; 4364b88c807SRodney W. Grimes case 'u': 4374b88c807SRodney W. Grimes base = 10; 4384b88c807SRodney W. Grimes goto uns_number; 4394b88c807SRodney W. Grimes case 'o': 4404b88c807SRodney W. Grimes base = 8; 4414b88c807SRodney W. Grimes goto uns_number; 4424b88c807SRodney W. Grimes case 'x': 4434b88c807SRodney W. Grimes /* we don't implement 'x'; treat like 'X' */ 4444b88c807SRodney W. Grimes case 'X': 4454b88c807SRodney W. Grimes base = 16; 4464b88c807SRodney W. Grimes uns_number: /* an unsigned number */ 4474b88c807SRodney W. Grimes sign = 0; 4484b88c807SRodney W. Grimes if (islong) 4494b88c807SRodney W. Grimes num = va_arg(ap, unsigned long); 4504b88c807SRodney W. Grimes else 4514b88c807SRodney W. Grimes num = va_arg(ap, unsigned int); 4524b88c807SRodney W. Grimes number: /* process a number */ 4534b88c807SRodney W. Grimes p = temp + TEMPSIZE - 1; 4544b88c807SRodney W. Grimes *p = '\0'; 4554b88c807SRodney W. Grimes while (num) { 4564b88c807SRodney W. Grimes *--p = digit[num % base]; 4574b88c807SRodney W. Grimes num /= base; 4584b88c807SRodney W. Grimes } 4594b88c807SRodney W. Grimes len = (temp + TEMPSIZE - 1) - p; 4604b88c807SRodney W. Grimes if (prec < 0) 4614b88c807SRodney W. Grimes prec = 1; 4624b88c807SRodney W. Grimes if (sharp && *f == 'o' && prec <= len) 4634b88c807SRodney W. Grimes prec = len + 1; 4644b88c807SRodney W. Grimes pad = 0; 4654b88c807SRodney W. Grimes if (width) { 4664b88c807SRodney W. Grimes size = len; 4674b88c807SRodney W. Grimes if (size < prec) 4684b88c807SRodney W. Grimes size = prec; 4694b88c807SRodney W. Grimes size += sign; 4704b88c807SRodney W. Grimes pad = width - size; 4714b88c807SRodney W. Grimes if (flushleft == 0) { 4724b88c807SRodney W. Grimes while (--pad >= 0) 4734b88c807SRodney W. Grimes outc(' ', dest); 4744b88c807SRodney W. Grimes } 4754b88c807SRodney W. Grimes } 4764b88c807SRodney W. Grimes if (sign) 4774b88c807SRodney W. Grimes outc('-', dest); 4784b88c807SRodney W. Grimes prec -= len; 4794b88c807SRodney W. Grimes while (--prec >= 0) 4804b88c807SRodney W. Grimes outc('0', dest); 4814b88c807SRodney W. Grimes while (*p) 4824b88c807SRodney W. Grimes outc(*p++, dest); 4834b88c807SRodney W. Grimes while (--pad >= 0) 4844b88c807SRodney W. Grimes outc(' ', dest); 4854b88c807SRodney W. Grimes break; 4864b88c807SRodney W. Grimes case 's': 4874b88c807SRodney W. Grimes p = va_arg(ap, char *); 4884b88c807SRodney W. Grimes pad = 0; 4894b88c807SRodney W. Grimes if (width) { 4904b88c807SRodney W. Grimes len = strlen(p); 4914b88c807SRodney W. Grimes if (prec >= 0 && len > prec) 4924b88c807SRodney W. Grimes len = prec; 4934b88c807SRodney W. Grimes pad = width - len; 4944b88c807SRodney W. Grimes if (flushleft == 0) { 4954b88c807SRodney W. Grimes while (--pad >= 0) 4964b88c807SRodney W. Grimes outc(' ', dest); 4974b88c807SRodney W. Grimes } 4984b88c807SRodney W. Grimes } 4994b88c807SRodney W. Grimes prec++; 5004b88c807SRodney W. Grimes while (--prec != 0 && *p) 5014b88c807SRodney W. Grimes outc(*p++, dest); 5024b88c807SRodney W. Grimes while (--pad >= 0) 5034b88c807SRodney W. Grimes outc(' ', dest); 5044b88c807SRodney W. Grimes break; 5054b88c807SRodney W. Grimes case 'c': 5064b88c807SRodney W. Grimes c = va_arg(ap, int); 5074b88c807SRodney W. Grimes outc(c, dest); 5084b88c807SRodney W. Grimes break; 5094b88c807SRodney W. Grimes default: 5104b88c807SRodney W. Grimes outc(*f, dest); 5114b88c807SRodney W. Grimes break; 5124b88c807SRodney W. Grimes } 5134b88c807SRodney W. Grimes f++; 5144b88c807SRodney W. Grimes } 5154b88c807SRodney W. Grimes } 5164b88c807SRodney W. Grimes 5174b88c807SRodney W. Grimes 5184b88c807SRodney W. Grimes 5194b88c807SRodney W. Grimes /* 5204b88c807SRodney W. Grimes * Version of write which resumes after a signal is caught. 5214b88c807SRodney W. Grimes */ 5224b88c807SRodney W. Grimes 5234b88c807SRodney W. Grimes int 5244b88c807SRodney W. Grimes xwrite(fd, buf, nbytes) 5254b88c807SRodney W. Grimes int fd; 5264b88c807SRodney W. Grimes char *buf; 5274b88c807SRodney W. Grimes int nbytes; 5284b88c807SRodney W. Grimes { 5294b88c807SRodney W. Grimes int ntry; 5304b88c807SRodney W. Grimes int i; 5314b88c807SRodney W. Grimes int n; 5324b88c807SRodney W. Grimes 5334b88c807SRodney W. Grimes n = nbytes; 5344b88c807SRodney W. Grimes ntry = 0; 5354b88c807SRodney W. Grimes for (;;) { 5364b88c807SRodney W. Grimes i = write(fd, buf, n); 5374b88c807SRodney W. Grimes if (i > 0) { 5384b88c807SRodney W. Grimes if ((n -= i) <= 0) 5394b88c807SRodney W. Grimes return nbytes; 5404b88c807SRodney W. Grimes buf += i; 5414b88c807SRodney W. Grimes ntry = 0; 5424b88c807SRodney W. Grimes } else if (i == 0) { 5434b88c807SRodney W. Grimes if (++ntry > 10) 5444b88c807SRodney W. Grimes return nbytes - n; 5454b88c807SRodney W. Grimes } else if (errno != EINTR) { 5464b88c807SRodney W. Grimes return -1; 5474b88c807SRodney W. Grimes } 5484b88c807SRodney W. Grimes } 5494b88c807SRodney W. Grimes } 5504b88c807SRodney W. Grimes 5514b88c807SRodney W. Grimes 5524b88c807SRodney W. Grimes /* 5534b88c807SRodney W. Grimes * Version of ioctl that retries after a signal is caught. 554aa9caaf6SPeter Wemm * XXX unused function 5554b88c807SRodney W. Grimes */ 5564b88c807SRodney W. Grimes 5574b88c807SRodney W. Grimes int 558aa9caaf6SPeter Wemm xioctl(fd, request, arg) 559aa9caaf6SPeter Wemm int fd; 560aa9caaf6SPeter Wemm unsigned long request; 561aa9caaf6SPeter Wemm char * arg; 562aa9caaf6SPeter Wemm { 5634b88c807SRodney W. Grimes int i; 5644b88c807SRodney W. Grimes 5654b88c807SRodney W. Grimes while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR); 5664b88c807SRodney W. Grimes return i; 5674b88c807SRodney W. Grimes } 568