Magellan Linux

Diff of /trunk/mkinitrd-magellan/klibc/usr/dash/redir.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 814 by niro, Sat Sep 1 22:45:15 2007 UTC revision 815 by niro, Fri Apr 24 18:32:46 2009 UTC
# Line 57  Line 57 
57  #include "error.h"  #include "error.h"
58    
59    
60    #define REALLY_CLOSED -3 /* fd that was closed and still is */
61  #define EMPTY -2 /* marks an unused slot in redirtab */  #define EMPTY -2 /* marks an unused slot in redirtab */
62    #define CLOSED -1 /* fd opened for redir needs to be closed */
63    
64  #ifndef PIPE_BUF  #ifndef PIPE_BUF
65  # define PIPESIZE 4096 /* amount of buffering in a pipe */  # define PIPESIZE 4096 /* amount of buffering in a pipe */
66  #else  #else
# Line 116  redirect(union node *redir, int flags) Line 119  redirect(union node *redir, int flags)
119   }   }
120   sv = NULL;   sv = NULL;
121   INTOFF;   INTOFF;
122   if (flags & REDIR_PUSH) {   if (likely(flags & REDIR_PUSH)) {
123   struct redirtab *q;   struct redirtab *q;
124   q = ckmalloc(sizeof (struct redirtab));   q = ckmalloc(sizeof (struct redirtab));
125   q->next = redirlist;   q->next = redirlist;
# Line 129  redirect(union node *redir, int flags) Line 132  redirect(union node *redir, int flags)
132   }   }
133   n = redir;   n = redir;
134   do {   do {
  fd = n->nfile.fd;  
  if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&  
     n->ndup.dupfd == fd)  
  continue; /* redirect from/to same file descriptor */  
   
135   newfd = openredirect(n);   newfd = openredirect(n);
136   if (fd == newfd)   if (newfd < -1)
137   continue;   continue;
138   if (sv && *(p = &sv->renamed[fd]) == EMPTY) {  
139   int i = fcntl(fd, F_DUPFD, 10);   fd = n->nfile.fd;
140   if (i == -1) {  
141   i = errno;   if (sv) {
142   if (i != EBADF) {   p = &sv->renamed[fd];
143   const char *m = strerror(i);   i = *p;
144   close(newfd);  
145   sh_error("%d: %s", fd, m);   if (likely(i == EMPTY)) {
146   /* NOTREACHED */   i = CLOSED;
147     if (fd != newfd) {
148     i = savefd(fd);
149     fd = -1;
150   }   }
  } else {  
  *p = i;  
  close(fd);  
151   }   }
152   } else {  
153   close(fd);   if (i == newfd)
154     /* Can only happen if i == newfd == CLOSED */
155     i = REALLY_CLOSED;
156    
157     *p = i;
158   }   }
159    
160     if (fd == newfd)
161     continue;
162    
163  #ifdef notyet  #ifdef notyet
164   dupredirect(n, newfd, memory);   dupredirect(n, newfd, memory);
165  #else  #else
# Line 167  redirect(union node *redir, int flags) Line 173  redirect(union node *redir, int flags)
173   if (memory[2])   if (memory[2])
174   out2 = &memout;   out2 = &memout;
175  #endif  #endif
176   if (flags & REDIR_SAVEFD2 && sv && sv->renamed[2] >= 0)   if (flags & REDIR_SAVEFD2 && sv->renamed[2] >= 0)
177   preverrout.fd = sv->renamed[2];   preverrout.fd = sv->renamed[2];
178  }  }
179    
# Line 208  openredirect(union node *redir) Line 214  openredirect(union node *redir)
214   if ((f = open64(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)   if ((f = open64(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
215   goto ecreate;   goto ecreate;
216   break;   break;
217     case NTOFD:
218     case NFROMFD:
219     f = redir->ndup.dupfd;
220     if (f == redir->nfile.fd)
221     f = -2;
222     break;
223   default:   default:
224  #ifdef DEBUG  #ifdef DEBUG
225   abort();   abort();
226  #endif  #endif
227   /* Fall through to eliminate warning. */   /* Fall through to eliminate warning. */
  case NTOFD:  
  case NFROMFD:  
  f = -1;  
  break;  
228   case NHERE:   case NHERE:
229   case NXHERE:   case NXHERE:
230   f = openhere(redir);   f = openhere(redir);
# Line 244  dupredirect(redir, f) Line 252  dupredirect(redir, f)
252  #endif  #endif
253   {   {
254   int fd = redir->nfile.fd;   int fd = redir->nfile.fd;
255     int err = 0;
256    
257  #ifdef notyet  #ifdef notyet
258   memory[fd] = 0;   memory[fd] = 0;
259  #endif  #endif
260   if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {   if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) {
261   if (redir->ndup.dupfd >= 0) { /* if not ">&-" */   /* if not ">&-" */
262     if (f >= 0) {
263  #ifdef notyet  #ifdef notyet
264   if (memory[redir->ndup.dupfd])   if (memory[f])
265   memory[fd] = 1;   memory[fd] = 1;
266   else   else
267  #endif  #endif
268   copyfd(redir->ndup.dupfd, fd);   if (dup2(f, fd) < 0) {
269     err = errno;
270     goto err;
271     }
272     return;
273   }   }
274   return;   f = fd;
275   }   } else if (dup2(f, fd) < 0)
276     err = errno;
277    
278     close(f);
279     if (err < 0)
280     goto err;
281    
  if (f != fd) {  
  copyfd(f, fd);  
  close(f);  
  }  
282   return;   return;
283    
284    err:
285     sh_error("%d: %s", f, strerror(err));
286  }  }
287    
288    
# Line 326  popredir(int drop) Line 344  popredir(int drop)
344   INTOFF;   INTOFF;
345   rp = redirlist;   rp = redirlist;
346   for (i = 0 ; i < 10 ; i++) {   for (i = 0 ; i < 10 ; i++) {
347   if (rp->renamed[i] != EMPTY) {   switch (rp->renamed[i]) {
348   if (!drop) {   case CLOSED:
349     if (!drop)
350   close(i);   close(i);
351   copyfd(rp->renamed[i], i);   break;
352   }   case EMPTY:
353     case REALLY_CLOSED:
354     break;
355     default:
356     if (!drop)
357     dup2(rp->renamed[i], i);
358   close(rp->renamed[i]);   close(rp->renamed[i]);
359     break;
360   }   }
361   }   }
362   redirlist = rp->next;   redirlist = rp->next;
# Line 349  popredir(int drop) Line 374  popredir(int drop)
374  INCLUDE "redir.h"  INCLUDE "redir.h"
375    
376  RESET {  RESET {
377   clearredir(0);   /*
378  }   * Discard all saved file descriptors.
379     */
 #endif  
   
 /*  
  * Discard all saved file descriptors.  
  */  
   
 void  
 clearredir(int drop)  
 {  
380   for (;;) {   for (;;) {
381   nullredirs = 0;   nullredirs = 0;
382   if (!redirlist)   if (!redirlist)
383   break;   break;
384   popredir(drop);   popredir(0);
385   }   }
386  }  }
387    
388    #endif
389    
390    
391    
392  /*  /*
393   * Copy a file descriptor to be >= to.  Returns -1   * Move a file descriptor to > 10.  Invokes sh_error on error unless
394   * if the source file descriptor is closed, EMPTY if there are no unused   * the original file dscriptor is not open.
  * file descriptors left.  
395   */   */
396    
397  int  int
398  copyfd(int from, int to)  savefd(int from)
399  {  {
400   int newfd;   int newfd;
401     int err;
402    
403   newfd = fcntl(from, F_DUPFD, to);   newfd = fcntl(from, F_DUPFD, 10);
404   if (newfd < 0) {   err = newfd < 0 ? errno : 0;
405   int errno2 = errno;   if (err != EBADF) {
406   if (errno2 == EMFILE)   close(from);
407   return EMPTY;   if (err)
408     sh_error("%d: %s", from, strerror(err));
409   else   else
410   sh_error("%d: %s", from, strerror(errno2));   fcntl(newfd, F_SETFD, FD_CLOEXEC);
411   }   }
412    
413   return newfd;   return newfd;
414  }  }
415    

Legend:
Removed from v.814  
changed lines
  Added in v.815