8672 proc_t changes broke genunix dmods and walker
[unleashed.git] / usr / src / cmd / sh / io.c
blob46f394429b31477ba57d0c871ec265f57da962d1
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * UNIX shell
34 #include "defs.h"
35 #include "dup.h"
36 #include <stdio.h>
37 #include <fcntl.h>
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <errno.h>
42 short topfd;
44 /* ======== input output and file copying ======== */
46 void
47 initf(int fd)
49 struct fileblk *f = standin;
51 f->fdes = fd;
52 f->fsiz = ((flags & oneflg) == 0 ? BUFFERSIZE : 1);
53 f->fnxt = f->fend = f->fbuf;
54 f->nxtoff = f->endoff = 0;
55 f->feval = 0;
56 f->flin = 1;
57 f->feof = FALSE;
60 int
61 estabf(unsigned char *s)
63 struct fileblk *f;
65 (f = standin)->fdes = -1;
66 f->fend = length(s) + (f->fnxt = s);
67 f->nxtoff = 0;
68 f->endoff = length(s);
69 f->flin = 1;
70 return (f->feof = (s == 0));
73 void
74 push(struct fileblk *af)
76 struct fileblk *f;
78 (f = af)->fstak = standin;
79 f->feof = 0;
80 f->feval = 0;
81 standin = f;
84 int
85 pop(void)
87 struct fileblk *f;
89 if ((f = standin)->fstak) {
90 if (f->fdes >= 0)
91 close(f->fdes);
92 standin = f->fstak;
93 return (TRUE);
94 } else
95 return (FALSE);
98 struct tempblk *tmpfptr;
100 void
101 pushtemp(int fd, struct tempblk *tb)
103 tb->fdes = fd;
104 tb->fstak = tmpfptr;
105 tmpfptr = tb;
109 poptemp(void)
111 if (tmpfptr) {
112 close(tmpfptr->fdes);
113 tmpfptr = tmpfptr->fstak;
114 return (TRUE);
115 } else
116 return (FALSE);
119 void
120 chkpipe(int *pv)
122 if (pipe(pv) < 0 || pv[INPIPE] < 0 || pv[OTPIPE] < 0)
123 error(piperr);
127 chkopen(unsigned char *idf, int mode)
129 int rc;
131 if ((rc = open((char *)idf, mode, 0666)) < 0)
132 failed(idf, badopen);
133 else
134 return (rc);
138 * Make f2 be a synonym (including the close-on-exec flag) for f1, which is
139 * then closed. If f2 is descriptor 0, modify the global ioset variable
140 * accordingly.
142 void
143 renamef(int f1, int f2)
145 #ifdef RES
146 if (f1 != f2) {
147 dup(f1 | DUPFLG, f2);
148 close(f1);
149 if (f2 == 0)
150 ioset |= 1;
152 #else
153 int fs;
155 if (f1 != f2) {
156 fs = fcntl(f2, 1, 0);
157 close(f2);
158 fcntl(f1, 0, f2);
159 close(f1);
160 if (fs == 1)
161 fcntl(f2, 2, 1);
162 if (f2 == 0)
163 ioset |= 1;
165 #endif
169 create(unsigned char *s)
171 int rc;
173 if ((rc = creat((char *)s, 0666)) < 0)
174 failed(s, badcreate);
175 else
176 return (rc);
181 tmpfil(struct tempblk *tb)
183 int fd;
184 int len;
185 size_t size_left = TMPOUTSZ - tmpout_offset;
187 /* make sure tmp file does not already exist. */
188 do {
189 len = snprintf((char *)&tmpout[tmpout_offset], size_left,
190 "%u", serial);
191 fd = open((char *)tmpout, O_RDWR|O_CREAT|O_EXCL, 0600);
192 serial++;
193 if ((serial >= UINT_MAX) || (len >= size_left)) {
195 * We've already cycled through all the possible
196 * numbers or the tmp file name is being
197 * truncated anyway (although TMPOUTSZ should be
198 * big enough), so start over.
200 serial = 0;
201 break;
203 } while ((fd == -1) && (errno == EEXIST));
204 if (fd != -1) {
205 pushtemp(fd, tb);
206 return (fd);
208 else
209 failed(tmpout, badcreate);
213 * set by trim
215 extern BOOL nosubst;
216 #define CPYSIZ 512
218 void
219 copy(struct ionod *ioparg)
221 unsigned char *cline;
222 unsigned char *clinep;
223 struct ionod *iop;
224 unsigned int c;
225 unsigned char *ends;
226 unsigned char *start;
227 int fd;
228 int i;
229 int stripflg;
230 unsigned char *pc;
233 if (iop = ioparg) {
234 struct tempblk tb;
235 copy(iop->iolst);
236 ends = mactrim(iop->ioname);
237 stripflg = iop->iofile & IOSTRIP;
238 if (nosubst)
239 iop->iofile &= ~IODOC_SUBST;
240 fd = tmpfil(&tb);
242 if (fndef)
243 iop->ioname = (char *)make(tmpout);
244 else
245 iop->ioname = (char *)cpystak(tmpout);
247 iop->iolst = iotemp;
248 iotemp = iop;
250 cline = clinep = start = locstak();
251 if (stripflg) {
252 iop->iofile &= ~IOSTRIP;
253 while (*ends == '\t')
254 ends++;
256 for (;;) {
257 chkpr();
258 if (nosubst) {
259 c = readwc();
260 if (stripflg)
261 while (c == '\t')
262 c = readwc();
264 while (!eolchar(c)) {
265 pc = readw(c);
266 while (*pc) {
267 if (clinep >= brkend)
268 growstak(clinep);
269 *clinep++ = *pc++;
271 c = readwc();
273 } else {
274 c = nextwc();
275 if (stripflg)
276 while (c == '\t')
277 c = nextwc();
279 while (!eolchar(c)) {
280 pc = readw(c);
281 while (*pc) {
282 if (clinep >= brkend)
283 growstak(clinep);
284 *clinep++ = *pc++;
286 if (c == '\\') {
287 pc = readw(readwc());
288 /* *pc might be NULL */
289 /* BEGIN CSTYLED */
290 if (*pc) {
291 while (*pc) {
292 if (clinep >= brkend)
293 growstak(clinep);
294 *clinep++ = *pc++;
296 } else {
297 if (clinep >= brkend)
298 growstak(clinep);
299 *clinep++ = *pc;
301 /* END CSTYLED */
303 c = nextwc();
307 if (clinep >= brkend)
308 growstak(clinep);
309 *clinep = 0;
310 if (eof || eq(cline, ends)) {
311 if ((i = cline - start) > 0)
312 write(fd, start, i);
313 break;
314 } else {
315 if (clinep >= brkend)
316 growstak(clinep);
317 *clinep++ = NL;
320 if ((i = clinep - start) < CPYSIZ)
321 cline = clinep;
322 else
324 write(fd, start, i);
325 cline = clinep = start;
330 * Pushed in tmpfil -- bug fix for problem
331 * deleting in-line script.
333 poptemp();
337 void
338 link_iodocs(struct ionod *i)
340 int r;
341 int len;
342 size_t size_left = TMPOUTSZ - tmpout_offset;
344 while (i) {
345 free(i->iolink);
347 /* make sure tmp file does not already exist. */
348 do {
349 len = snprintf((char *)&tmpout[tmpout_offset],
350 size_left, "%u", serial);
351 serial++;
352 r = link(i->ioname, (char *)tmpout);
353 if ((serial >= UINT_MAX) || (len >= size_left)) {
355 * We've already cycled through all the possible
356 * numbers or the tmp file name is being
357 * truncated anyway, so start over.
359 serial = 0;
360 break;
362 } while (r == -1 && errno == EEXIST);
364 if (r != -1) {
365 i->iolink = (char *)make(tmpout);
366 i = i->iolst;
367 } else
368 failed(tmpout, badcreate);
373 void
374 swap_iodoc_nm(struct ionod *i)
376 while (i) {
377 free(i->ioname);
378 i->ioname = i->iolink;
379 i->iolink = 0;
381 i = i->iolst;
386 savefd(int fd)
388 int f;
390 f = fcntl(fd, F_DUPFD, 10);
391 /* this saved fd should not be found in an exec'ed cmd */
392 (void) fcntl(f, F_SETFD, FD_CLOEXEC);
393 return (f);
396 void
397 restore(int last)
399 int i;
400 int dupfd;
402 for (i = topfd - 1; i >= last; i--) {
403 if ((dupfd = fdmap[i].dup_fd) > 0)
404 renamef(dupfd, fdmap[i].org_fd);
405 else
406 close(fdmap[i].org_fd);
408 topfd = last;