OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [newlib/] [newlib/] [libc/] [posix/] [popen.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 39 lampret
/*      $NetBSD: popen.c,v 1.11 1995/06/16 07:05:33 jtc Exp $   */
2
 
3
/*
4
 * Copyright (c) 1988, 1993
5
 *      The Regents of the University of California.  All rights reserved.
6
 *
7
 * This code is derived from software written by Ken Arnold and
8
 * published in UNIX Review, Vol. 6, No. 8.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions
12
 * are met:
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in the
17
 *    documentation and/or other materials provided with the distribution.
18
 * 3. All advertising materials mentioning features or use of this software
19
 *    must display the following acknowledgement:
20
 *      This product includes software developed by the University of
21
 *      California, Berkeley and its contributors.
22
 * 4. Neither the name of the University nor the names of its contributors
23
 *    may be used to endorse or promote products derived from this software
24
 *    without specific prior written permission.
25
 *
26
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36
 * SUCH DAMAGE.
37
 */
38
 
39
#if defined(LIBC_SCCS) && !defined(lint)
40
#if 0
41
static char sccsid[] = "@(#)popen.c     8.1 (Berkeley) 6/4/93";
42
#else
43
static char rcsid[] = "$NetBSD: popen.c,v 1.11 1995/06/16 07:05:33 jtc Exp $";
44
#endif
45
#endif /* LIBC_SCCS and not lint */
46
 
47
#include <sys/param.h>
48
#include <sys/types.h>
49
#include <sys/wait.h>
50
 
51
#include <signal.h>
52
#include <errno.h>
53
#include <unistd.h>
54
#include <stdio.h>
55
#include <stdlib.h>
56
#include <string.h>
57
#include <paths.h>
58
 
59
static struct pid {
60
        struct pid *next;
61
        FILE *fp;
62
        pid_t pid;
63
} *pidlist;
64
 
65
FILE *
66
popen(program, type)
67
        const char *program;
68
        const char *type;
69
{
70
        struct pid *cur;
71
        FILE *iop;
72
        int pdes[2], pid;
73
 
74
        if (*type != 'r' && *type != 'w' || type[1]) {
75
                errno = EINVAL;
76
                return (NULL);
77
        }
78
 
79
        if ((cur = malloc(sizeof(struct pid))) == NULL)
80
                return (NULL);
81
 
82
        if (pipe(pdes) < 0) {
83
                free(cur);
84
                return (NULL);
85
        }
86
 
87
        switch (pid = vfork()) {
88
        case -1:                        /* Error. */
89
                (void)close(pdes[0]);
90
                (void)close(pdes[1]);
91
                free(cur);
92
                return (NULL);
93
                /* NOTREACHED */
94
        case 0:                          /* Child. */
95
                if (*type == 'r') {
96
                        if (pdes[1] != STDOUT_FILENO) {
97
                                (void)dup2(pdes[1], STDOUT_FILENO);
98
                                (void)close(pdes[1]);
99
                        }
100
                        (void) close(pdes[0]);
101
                } else {
102
                        if (pdes[0] != STDIN_FILENO) {
103
                                (void)dup2(pdes[0], STDIN_FILENO);
104
                                (void)close(pdes[0]);
105
                        }
106
                        (void)close(pdes[1]);
107
                }
108
                execl(_PATH_BSHELL, "sh", "-c", program, NULL);
109
#ifdef __CYGWIN32__
110
                /* On cygwin32, we may not have /bin/sh.  In that
111
                   case, try to find sh on PATH.  */
112
                execlp("sh", "sh", "-c", program, NULL);
113
#endif
114
                _exit(127);
115
                /* NOTREACHED */
116
        }
117
 
118
        /* Parent; assume fdopen can't fail. */
119
        if (*type == 'r') {
120
                iop = fdopen(pdes[0], type);
121
                (void)close(pdes[1]);
122
        } else {
123
                iop = fdopen(pdes[1], type);
124
                (void)close(pdes[0]);
125
        }
126
 
127
        /* Link into list of file descriptors. */
128
        cur->fp = iop;
129
        cur->pid =  pid;
130
        cur->next = pidlist;
131
        pidlist = cur;
132
 
133
        return (iop);
134
}
135
 
136
/*
137
 * pclose --
138
 *      Pclose returns -1 if stream is not associated with a `popened' command,
139
 *      if already `pclosed', or waitpid returns an error.
140
 */
141
int
142
pclose(iop)
143
        FILE *iop;
144
{
145
        register struct pid *cur, *last;
146
        int pstat;
147
        pid_t pid;
148
 
149
        (void)fclose(iop);
150
 
151
        /* Find the appropriate file pointer. */
152
        for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
153
                if (cur->fp == iop)
154
                        break;
155
        if (cur == NULL)
156
                return (-1);
157
 
158
        do {
159
                pid = waitpid(cur->pid, &pstat, 0);
160
        } while (pid == -1 && errno == EINTR);
161
 
162
        /* Remove the entry from the linked list. */
163
        if (last == NULL)
164
                pidlist = cur->next;
165
        else
166
                last->next = cur->next;
167
        free(cur);
168
 
169
        return (pid == -1 ? -1 : pstat);
170
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.