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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [newlib/] [libc/] [posix/] [popen.c] - Blame information for rev 822

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

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

powered by: WebSVN 2.1.0

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