~ubuntu-branches/ubuntu/intrepid/dash/intrepid-updates

« back to all changes in this revision

Viewing changes to src/redir.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-07-18 15:38:47 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070718153847-pef1uwy72j9gs9pw
Tags: 0.5.4-1ubuntu1
* Merge with Debian; remaining changes:
  - Build against glibc instead of dietlibc
  - Change default answer for "Install dash as /bin/sh?" question to true.

Show diffs side-by-side

added added

removed removed

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