]> git.pld-linux.org Git - packages/ash.git/blame - ash-redir.patch
- dropped pre-cvs changelog
[packages/ash.git] / ash-redir.patch
CommitLineData
cf7098dd
MM
1diff -ur netbsd-sh/eval.c netbsd-sh-/eval.c
2--- netbsd-sh/eval.c Tue May 23 12:03:18 2000
3+++ netbsd-sh-/eval.c Mon Apr 23 23:33:34 2001
4@@ -442,6 +442,7 @@
5 case NFROM:
6 case NTO:
7 case NAPPEND:
8+ case NTOOV:
9 expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
10 redir->nfile.expfname = fn.list->text;
11 break;
12diff -ur netbsd-sh/exec.c netbsd-sh-/exec.c
13--- netbsd-sh/exec.c Fri Jan 12 17:50:35 2001
14+++ netbsd-sh-/exec.c Mon Apr 23 23:33:34 2001
15@@ -125,6 +125,10 @@
16 char *cmdname;
17 int e;
18
19+ if (fd2 >= 0 && fd2 != 2) {
20+ close(fd2);
21+ }
22+
23 if (strchr(argv[0], '/') != NULL) {
24 tryexec(argv[0], argv, envp);
25 e = errno;
26diff -ur netbsd-sh/jobs.c netbsd-sh-/jobs.c
27--- netbsd-sh/jobs.c Mon Apr 23 23:34:53 2001
28+++ netbsd-sh-/jobs.c Mon Apr 23 23:34:30 2001
29@@ -129,9 +129,9 @@
30 if (on) {
31 do { /* while we are in the background */
32 #ifdef OLD_TTY_DRIVER
33- if (ioctl(2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
34+ if (ioctl(fd2, TIOCGPGRP, (char *)&initialpgrp) < 0) {
35 #else
36- initialpgrp = tcgetpgrp(2);
37+ initialpgrp = tcgetpgrp(fd2);
38 if (initialpgrp < 0) {
39 #endif
40 out2str("sh: can't access tty; job control turned off\n");
41@@ -146,7 +146,7 @@
42 }
43 } while (0);
44 #ifdef OLD_TTY_DRIVER
45- if (ioctl(2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
46+ if (ioctl(fd2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) {
47 out2str("sh: need new tty driver to run job control; job control turned off\n");
48 mflag = 0;
49 return;
50@@ -157,16 +157,16 @@
51 setsignal(SIGTTIN);
52 setpgid(0, rootpid);
53 #ifdef OLD_TTY_DRIVER
54- ioctl(2, TIOCSPGRP, (char *)&rootpid);
55+ ioctl(fd2, TIOCSPGRP, (char *)&rootpid);
56 #else
57- tcsetpgrp(2, rootpid);
58+ tcsetpgrp(fd2, rootpid);
59 #endif
60 } else { /* turning job control off */
61 setpgid(0, initialpgrp);
62 #ifdef OLD_TTY_DRIVER
63- ioctl(2, TIOCSPGRP, (char *)&initialpgrp);
64+ ioctl(fd2, TIOCSPGRP, (char *)&initialpgrp);
65 #else
66- tcsetpgrp(2, initialpgrp);
67+ tcsetpgrp(fd2, initialpgrp);
68 #endif
69 setsignal(SIGTSTP);
70 setsignal(SIGTTOU);
71@@ -206,9 +206,9 @@
72 error("job not created under job control");
73 pgrp = jp->ps[0].pid;
74 #ifdef OLD_TTY_DRIVER
75- ioctl(2, TIOCSPGRP, (char *)&pgrp);
76+ ioctl(fd2, TIOCSPGRP, (char *)&pgrp);
77 #else
78- tcsetpgrp(2, pgrp);
79+ tcsetpgrp(fd2, pgrp);
80 #endif
81 restartjob(jp);
82 INTOFF;
83@@ -612,10 +612,10 @@
84 if (mode == FORK_FG) {
85 /*** this causes superfluous TIOCSPGRPS ***/
86 #ifdef OLD_TTY_DRIVER
87- if (ioctl(2, TIOCSPGRP, (char *)&pgrp) < 0)
88+ if (ioctl(fd2, TIOCSPGRP, (char *)&pgrp) < 0)
89 error("TIOCSPGRP failed, errno=%d", errno);
90 #else
91- if (tcsetpgrp(2, pgrp) < 0)
92+ if (tcsetpgrp(fd2, pgrp) < 0)
93 error("tcsetpgrp failed, errno=%d", errno);
94 #endif
95 }
96@@ -734,10 +734,10 @@
97 #if JOBS
98 if (jp->jobctl) {
99 #ifdef OLD_TTY_DRIVER
100- if (ioctl(2, TIOCSPGRP, (char *)&mypgrp) < 0)
101+ if (ioctl(fd2, TIOCSPGRP, (char *)&mypgrp) < 0)
102 error("TIOCSPGRP failed, errno=%d\n", errno);
103 #else
104- if (tcsetpgrp(2, mypgrp) < 0)
105+ if (tcsetpgrp(fd2, mypgrp) < 0)
106 error("tcsetpgrp failed, errno=%d\n", errno);
107 #endif
108 }
109@@ -1092,6 +1092,8 @@
110 p = ">>"; i = 1; goto redir;
111 case NTOFD:
112 p = ">&"; i = 1; goto redir;
113+ case NTOOV:
114+ p = ">|"; i = 1; goto redir;
115 case NFROM:
116 p = "<"; i = 0; goto redir;
117 case NFROMFD:
118Only in netbsd-sh-: jobs.c.orig
119diff -ur netbsd-sh/nodetypes netbsd-sh-/nodetypes
120--- netbsd-sh/nodetypes Fri Feb 5 13:04:52 1999
121+++ netbsd-sh-/nodetypes Mon Apr 23 23:33:34 2001
122@@ -119,6 +119,7 @@
123 NFROM nfile # fd< fname
124 NFROMTO nfile # fd<> fname
125 NAPPEND nfile # fd>> fname
126+NTOOV nfile # fd>| fname
127 type int
128 next nodeptr # next redirection in list
129 fd int # file descriptor being redirected
130diff -ur netbsd-sh/parser.c netbsd-sh-/parser.c
131--- netbsd-sh/parser.c Fri Jan 12 17:50:39 2001
132+++ netbsd-sh-/parser.c Mon Apr 23 23:33:34 2001
133@@ -1125,6 +1125,8 @@
134 np->type = NAPPEND;
135 else if (c == '&')
136 np->type = NTOFD;
137+ else if (c == '|')
138+ np->type = NTOOV;
139 else {
140 np->type = NTO;
141 pungetc();
142diff -ur netbsd-sh/redir.c netbsd-sh-/redir.c
143--- netbsd-sh/redir.c Tue May 23 12:03:19 2000
144+++ netbsd-sh-/redir.c Mon Apr 23 23:33:34 2001
145@@ -45,6 +45,7 @@
146 #endif
147 #endif /* not lint */
148
149+#include <sys/stat.h>
150 #include <sys/types.h>
151 #include <sys/param.h> /* PIPE_BUF */
152 #include <signal.h>
153@@ -66,6 +67,7 @@
154 #include "output.h"
155 #include "memalloc.h"
156 #include "error.h"
157+#include "options.h"
158
159
160 #define EMPTY -2 /* marks an unused slot in redirtab */
161@@ -92,8 +94,15 @@
162 */
163 int fd0_redirected = 0;
164
165-STATIC void openredirect __P((union node *, char[10 ]));
166+/*
167+ * We also keep track of where fd2 goes.
168+ */
169+int fd2 = 2;
170+
171+STATIC int openredirect __P((union node *));
172+STATIC void dupredirect __P((union node *, int, char[10 ]));
173 STATIC int openhere __P((union node *));
174+STATIC int noclobberopen __P((const char *));
175
176
177 /*
178@@ -113,6 +122,7 @@
179 struct redirtab *sv = NULL;
180 int i;
181 int fd;
182+ int newfd;
183 int try;
184 char memory[10]; /* file descriptors to write to memory */
185
186@@ -133,36 +143,47 @@
187 n->ndup.dupfd == fd)
188 continue; /* redirect from/to same file descriptor */
189
190- if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
191- INTOFF;
192-again:
193- if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
194+ INTOFF;
195+ newfd = openredirect(n);
196+ if (((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) ||
197+ (fd == fd2)) {
198+ if (newfd == fd) {
199+ try++;
200+ } else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
201 switch (errno) {
202 case EBADF:
203 if (!try) {
204- openredirect(n, memory);
205+ dupredirect(n, newfd, memory);
206 try++;
207- goto again;
208+ break;
209 }
210 /* FALLTHROUGH*/
211 default:
212+ if (newfd >= 0) {
213+ close(newfd);
214+ }
215 INTON;
216 error("%d: %s", fd, strerror(errno));
217 /* NOTREACHED */
218 }
219 }
220 if (!try) {
221- sv->renamed[fd] = i;
222 close(fd);
223+ if (flags & REDIR_PUSH) {
224+ sv->renamed[fd] = i;
225+ }
226+ if (fd == fd2) {
227+ fd2 = i;
228+ }
229 }
230- INTON;
231- } else {
232+ } else if (fd != newfd) {
233 close(fd);
234 }
235 if (fd == 0)
236 fd0_redirected++;
237 if (!try)
238- openredirect(n, memory);
239+ dupredirect(n, newfd, memory);
240+ INTON;
241 }
242 if (memory[1])
243 out1 = &memout;
244@@ -171,22 +192,13 @@
245 }
246
247
248-STATIC void
249-openredirect(redir, memory)
250+STATIC int
251+openredirect(redir)
252 union node *redir;
253- char memory[10];
254 {
255- int fd = redir->nfile.fd;
256 char *fname;
257 int f;
258
259- /*
260- * We suppress interrupts so that we won't leave open file
261- * descriptors around. This may not be such a good idea because
262- * an open of a device or a fifo can block indefinitely.
263- */
264- INTOFF;
265- memory[fd] = 0;
266 switch (redir->nfile.type) {
267 case NFROM:
268 fname = redir->nfile.expfname;
269@@ -199,6 +211,14 @@
270 goto ecreate;
271 break;
272 case NTO:
273+ /* Take care of noclobber mode. */
274+ if (Cflag) {
275+ fname = redir->nfile.expfname;
276+ if ((f = noclobberopen(fname)) < 0)
277+ goto ecreate;
278+ break;
279+ }
280+ case NTOOV:
281 fname = redir->nfile.expfname;
282 #ifdef O_CREAT
283 if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
284@@ -222,32 +242,48 @@
285 break;
286 case NTOFD:
287 case NFROMFD:
288+ f = -1;
289+ break;
290+ case NHERE:
291+ case NXHERE:
292+ f = openhere(redir);
293+ break;
294+ default:
295+ abort();
296+ }
297+
298+ return f;
299+ecreate:
300+ error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
301+eopen:
302+ error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
303+}
304+
305+
306+STATIC void
307+dupredirect(redir, f, memory)
308+ union node *redir;
309+ int f;
310+ char memory[10];
311+ {
312+ int fd = redir->nfile.fd;
313+
314+ memory[fd] = 0;
315+ if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
316 if (redir->ndup.dupfd >= 0) { /* if not ">&-" */
317 if (memory[redir->ndup.dupfd])
318 memory[fd] = 1;
319 else
320 copyfd(redir->ndup.dupfd, fd);
321 }
322- INTON;
323 return;
324- case NHERE:
325- case NXHERE:
326- f = openhere(redir);
327- break;
328- default:
329- abort();
330 }
331
332 if (f != fd) {
333 copyfd(f, fd);
334 close(f);
335 }
336- INTON;
337 return;
338-ecreate:
339- error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
340-eopen:
341- error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
342 }
343
344
345@@ -304,6 +340,7 @@
346 struct redirtab *rp = redirlist;
347 int i;
348
349+ INTOFF;
350 for (i = 0 ; i < 10 ; i++) {
351 if (rp->renamed[i] != EMPTY) {
352 if (i == 0)
353@@ -313,9 +350,11 @@
354 copyfd(rp->renamed[i], i);
355 close(rp->renamed[i]);
356 }
357+ if (rp->renamed[i] == fd2) {
358+ fd2 = i;
359+ }
360 }
361 }
362- INTOFF;
363 redirlist = rp->next;
364 ckfree(rp);
365 INTON;
366@@ -359,6 +398,9 @@
367 for (i = 0 ; i < 10 ; i++) {
368 if (rp->renamed[i] >= 0) {
369 close(rp->renamed[i]);
370+ if (rp->renamed[i] == fd2) {
371+ fd2 = -1;
372+ }
373 }
374 rp->renamed[i] = EMPTY;
375 }
376@@ -388,4 +430,63 @@
377 error("%d: %s", from, strerror(errno));
378 }
379 return newfd;
380+}
381+
382+/*
383+ * Open a file in noclobber mode.
384+ * The code was copied from bash.
385+ */
386+int
387+noclobberopen(fname)
388+ const char *fname;
389+{
390+ int r, fd;
391+ struct stat finfo, finfo2;
392+
393+ /*
394+ * If the file exists and is a regular file, return an error
395+ * immediately.
396+ */
397+ r = stat(fname, &finfo);
398+ if (r == 0 && S_ISREG(finfo.st_mode)) {
399+ errno = EEXIST;
400+ return -1;
401+ }
402+
403+ /*
404+ * If the file was not present (r != 0), make sure we open it
405+ * exclusively so that if it is created before we open it, our open
406+ * will fail. Make sure that we do not truncate an existing file.
407+ * Note that we don't turn on O_EXCL unless the stat failed -- if the
408+ * file was not a regular file, we leave O_EXCL off.
409+ */
410+ if (r != 0)
411+ return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666);
412+ fd = open(fname, O_WRONLY|O_CREAT, 0666);
413+
414+ /* If the open failed, return the file descriptor right away. */
415+ if (fd < 0)
416+ return fd;
417+
418+ /*
419+ * OK, the open succeeded, but the file may have been changed from a
420+ * non-regular file to a regular file between the stat and the open.
421+ * We are assuming that the O_EXCL open handles the case where FILENAME
422+ * did not exist and is symlinked to an existing file between the stat
423+ * and open.
424+ */
425+
426+ /*
427+ * If we can open it and fstat the file descriptor, and neither check
428+ * revealed that it was a regular file, and the file has not been
429+ * replaced, return the file descriptor.
430+ */
431+ if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) &&
432+ finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)
433+ return fd;
434+
435+ /* The file has been replaced. badness. */
436+ close(fd);
437+ errno = EEXIST;
438+ return -1;
439 }
440Only in netbsd-sh-: redir.c.orig
441diff -ur netbsd-sh/redir.h netbsd-sh-/redir.h
442--- netbsd-sh/redir.h Tue May 23 12:03:19 2000
443+++ netbsd-sh-/redir.h Mon Apr 23 23:33:34 2001
444@@ -42,6 +42,8 @@
445 #define REDIR_PUSH 01 /* save previous values of file descriptors */
446 #define REDIR_BACKQ 02 /* save the command output in memory */
447
448+extern int fd2;
449+
450 union node;
451 void redirect __P((union node *, int));
452 void popredir __P((void));
453diff -ur netbsd-sh/show.c netbsd-sh-/show.c
454--- netbsd-sh/show.c Sat Oct 9 13:02:09 1999
455+++ netbsd-sh-/show.c Mon Apr 23 23:33:34 2001
456@@ -155,6 +155,7 @@
457 case NTO: s = ">"; dftfd = 1; break;
458 case NAPPEND: s = ">>"; dftfd = 1; break;
459 case NTOFD: s = ">&"; dftfd = 1; break;
460+ case NTOOV: s = ">|"; dftfd = 1; break;
461 case NFROM: s = "<"; dftfd = 0; break;
462 case NFROMFD: s = "<&"; dftfd = 0; break;
463 case NFROMTO: s = "<>"; dftfd = 0; break;
This page took 0.155104 seconds and 5 git commands to generate.