|
|
1.1 ! root 1: /* ! 2: * shell buffered IO and formatted output ! 3: */ ! 4: ! 5: static char *RCSid = "$Header: /newbits/usr/bin/korn/RCS/io.c,v 1.2 91/08/01 12:40:33 bin Exp Locker: bin $"; ! 6: ! 7: #include <stddef.h> ! 8: #include <stdlib.h> ! 9: #include <stdio.h> ! 10: #include <errno.h> ! 11: #include <unistd.h> ! 12: #include <sys/fcntl.h> ! 13: #include <signal.h> ! 14: #include <setjmp.h> ! 15: #if __STDC__ ! 16: #include <stdarg.h> ! 17: #else ! 18: #include <varargs.h> ! 19: #endif ! 20: #include "sh.h" ! 21: #define TRACE printf ! 22: #if 0 ! 23: /* fputc with ^ escaping */ ! 24: static void ! 25: fzotc(c, f) ! 26: register int c; ! 27: register FILE *f; ! 28: { ! 29: if ((c&0x60) == 0) { /* C0|C1 */ ! 30: putc((c&0x80) ? '$' : '^', f); ! 31: putc((c&0x7F|0x40), f); ! 32: } else if ((c&0x7F) == 0x7F) { /* DEL */ ! 33: putc((c&0x80) ? '$' : '^', f); ! 34: putc('?', f); ! 35: } else ! 36: putc(c, f); ! 37: } ! 38: #endif ! 39: ! 40: /* ! 41: * formatted output functions ! 42: */ ! 43: ! 44: /* shellf(...); error() */ ! 45: int ! 46: #if COHERENT ! 47: errorf(fmt) ! 48: char *fmt; ! 49: { ! 50: fprintf(shlout, "%r", &fmt); ! 51: #else ! 52: #if __STDC__ ! 53: errorf(Const char *fmt, ...) { ! 54: #else ! 55: errorf(va_alist) va_dcl ! 56: { ! 57: char *fmt; ! 58: #endif ! 59: va_list va; ! 60: ! 61: #if __STDC__ ! 62: va_start(va, fmt); ! 63: #else ! 64: va_start(va); ! 65: fmt = va_arg(va, char *); ! 66: #endif ! 67: vfprintf(shlout, fmt, va); ! 68: va_end(va); ! 69: /*fflush(shlout);*/ ! 70: #endif ! 71: error(); ! 72: } ! 73: ! 74: /* printf to shlout (stderr) */ ! 75: int ! 76: #if COHERENT ! 77: shellf(fmt) ! 78: char *fmt; ! 79: { ! 80: fprintf(shlout, "%r", &fmt); ! 81: #else ! 82: #if __STDC__ ! 83: shellf(Const char *fmt, ...) { ! 84: #else ! 85: shellf(va_alist) va_dcl ! 86: { ! 87: char *fmt; ! 88: #endif ! 89: va_list va; ! 90: ! 91: #if __STDC__ ! 92: va_start(va, fmt); ! 93: #else ! 94: va_start(va); ! 95: fmt = va_arg(va, char *); ! 96: #endif ! 97: vfprintf(shlout, fmt, va); ! 98: va_end(va); ! 99: #endif ! 100: return 0; ! 101: } ! 102: ! 103: /* ! 104: * We have a stdio stream for any open shell file descriptors (0-9) ! 105: */ ! 106: FILE * shf [NUFILE]; /* map shell fd to FILE * */ ! 107: ! 108: /* open stream for shell fd */ ! 109: void ! 110: fopenshf(fd) ! 111: int fd; ! 112: { ! 113: if (shf[fd] != NULL) ! 114: return; ! 115: #if !COHERENT ! 116: if (fd <= 2) ! 117: _iob[fd]._flag = 0; /* re-use stdin, stdout, stderr */ ! 118: #endif ! 119: shf[fd] = fdopen(fd, "r+w"); ! 120: if (shf[fd] == NULL) ! 121: return; ! 122: setvbuf(shf[fd], (char*)NULL, _IOFBF, (size_t)BUFSIZ); ! 123: } ! 124: ! 125: /* flush stream assoc with fd */ ! 126: /* todo: either fseek (K&R) or fflush (ANSI) will "flush" IO streams */ ! 127: void ! 128: flushshf(fd) ! 129: int fd; ! 130: { ! 131: if (shf[fd] != NULL) ! 132: fseek(shf[fd], 0L, 1); /* questionable */ ! 133: } ! 134: ! 135: /* ! 136: * move fd from user space (0<=fd<10) to shell space (fd>=10) ! 137: */ ! 138: int ! 139: savefd(fd) ! 140: int fd; ! 141: { ! 142: int nfd; ! 143: ! 144: TRACE("savefd: received an fd value of %d\n",fd); ! 145: if (fd < FDBASE) { ! 146: flushshf(fd); ! 147: nfd = fcntl(fd, F_DUPFD, FDBASE); ! 148: /* nfd =3; */ ! 149: if (nfd < 0){ ! 150: TRACE("savefd: nfd = %d\n",nfd); ! 151: TRACE("savefd: errno is %d\n",errno); ! 152: if (errno == EBADF) ! 153: return -1; ! 154: else ! 155: errorf("too many files open in shell\n"); ! 156: } ! 157: #if !COHERENT ! 158: (void) fcntl(nfd, F_SETFD, FD_CLEXEC); ! 159: #endif ! 160: close(fd); ! 161: } else ! 162: nfd = fd; ! 163: return nfd; ! 164: } ! 165: ! 166: void ! 167: restfd(fd, ofd) ! 168: int fd, ofd; ! 169: { ! 170: if (ofd == 0) /* not saved (e.savefd) */ ! 171: return; ! 172: flushshf(fd); ! 173: close(fd); ! 174: if (ofd < 0) /* original fd closed */ ! 175: return; ! 176: (void) fcntl(ofd, F_DUPFD, fd); ! 177: close(ofd); ! 178: } ! 179: ! 180: void ! 181: openpipe(pv) ! 182: register int *pv; ! 183: { ! 184: if (pipe(pv) < 0) ! 185: errorf("can't create pipe - try again\n"); ! 186: pv[0] = savefd(pv[0]); ! 187: pv[1] = savefd(pv[1]); ! 188: } ! 189: ! 190: void ! 191: closepipe(pv) ! 192: register int *pv; ! 193: { ! 194: close(pv[0]); ! 195: close(pv[1]); ! 196: } ! 197: ! 198: /* ! 199: * temporary files ! 200: */ ! 201: ! 202: struct temp * ! 203: maketemp(ap) ! 204: Area *ap; ! 205: { ! 206: register struct temp *tp; ! 207: static unsigned int inc = 0; ! 208: char path [PATH]; ! 209: ! 210: sprintf(path, "/tmp/sh%05u%02u", (unsigned)getpid(), inc++); ! 211: /* we could create the thing now with 600 mode */ ! 212: tp = (struct temp *) alloc(sizeof(struct temp), ap); ! 213: tp->next = NULL; ! 214: tp->name = strsave(path, ap); ! 215: return tp; ! 216: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.