|
|
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.