|
|
1.1 ! root 1: /* ! 2: * shell buffered IO and formatted output ! 3: */ ! 4: ! 5: static char *RCSid = "$Header: io.c,v 3.1 88/11/03 09:16:11 egisin Exp $"; ! 6: ! 7: #include <stddef.h> ! 8: #include <stdlib.h> ! 9: #include <stdio.h> ! 10: #include <errno.h> ! 11: #include <unistd.h> ! 12: #include <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: ! 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: if (fd < FDBASE) { ! 145: flushshf(fd); ! 146: nfd = fcntl(fd, F_DUPFD, FDBASE); ! 147: if (nfd < 0) ! 148: if (errno == EBADF) ! 149: return -1; ! 150: else ! 151: errorf("too many files open in shell\n"); ! 152: #if !COHERENT ! 153: (void) fcntl(nfd, F_SETFD, FD_CLEXEC); ! 154: #endif ! 155: close(fd); ! 156: } else ! 157: nfd = fd; ! 158: return nfd; ! 159: } ! 160: ! 161: void ! 162: restfd(fd, ofd) ! 163: int fd, ofd; ! 164: { ! 165: if (ofd == 0) /* not saved (e.savefd) */ ! 166: return; ! 167: flushshf(fd); ! 168: close(fd); ! 169: if (ofd < 0) /* original fd closed */ ! 170: return; ! 171: (void) fcntl(ofd, F_DUPFD, fd); ! 172: close(ofd); ! 173: } ! 174: ! 175: void ! 176: openpipe(pv) ! 177: register int *pv; ! 178: { ! 179: if (pipe(pv) < 0) ! 180: errorf("can't create pipe - try again\n"); ! 181: pv[0] = savefd(pv[0]); ! 182: pv[1] = savefd(pv[1]); ! 183: } ! 184: ! 185: void ! 186: closepipe(pv) ! 187: register int *pv; ! 188: { ! 189: close(pv[0]); ! 190: close(pv[1]); ! 191: } ! 192: ! 193: /* ! 194: * temporary files ! 195: */ ! 196: ! 197: struct temp * ! 198: maketemp(ap) ! 199: Area *ap; ! 200: { ! 201: register struct temp *tp; ! 202: static unsigned int inc = 0; ! 203: char path [PATH]; ! 204: ! 205: sprintf(path, "/tmp/sh%05u%02u", (unsigned)getpid(), inc++); ! 206: /* we could create the thing now with 600 mode */ ! 207: tp = (struct temp *) alloc(sizeof(struct temp), ap); ! 208: tp->next = NULL; ! 209: tp->name = strsave(path, ap); ! 210: return tp; ! 211: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.