|
Packit |
7cfc04 |
'\" et
|
|
Packit |
7cfc04 |
.TH POPEN "3P" 2013 "IEEE/The Open Group" "POSIX Programmer's Manual"
|
|
Packit |
7cfc04 |
.SH PROLOG
|
|
Packit |
7cfc04 |
This manual page is part of the POSIX Programmer's Manual.
|
|
Packit |
7cfc04 |
The Linux implementation of this interface may differ (consult
|
|
Packit |
7cfc04 |
the corresponding Linux manual page for details of Linux behavior),
|
|
Packit |
7cfc04 |
or the interface may not be implemented on Linux.
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
.SH NAME
|
|
Packit |
7cfc04 |
popen
|
|
Packit |
7cfc04 |
\(em initiate pipe streams to or from a process
|
|
Packit |
7cfc04 |
.SH SYNOPSIS
|
|
Packit |
7cfc04 |
.LP
|
|
Packit |
7cfc04 |
.nf
|
|
Packit |
7cfc04 |
#include <stdio.h>
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
FILE *popen(const char *\fIcommand\fP, const char *\fImode\fP);
|
|
Packit |
7cfc04 |
.fi
|
|
Packit |
7cfc04 |
.SH DESCRIPTION
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
function shall execute the command specified by the string
|
|
Packit |
7cfc04 |
.IR command .
|
|
Packit |
7cfc04 |
It shall create a pipe between the calling program and the executed
|
|
Packit |
7cfc04 |
command, and shall return a pointer to a stream that can be used to
|
|
Packit |
7cfc04 |
either read from or write to the pipe.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The environment of the executed command shall be as if a child process
|
|
Packit |
7cfc04 |
were created within the
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
call using the
|
|
Packit |
7cfc04 |
\fIfork\fR()
|
|
Packit |
7cfc04 |
function, and the child invoked the
|
|
Packit |
7cfc04 |
.IR sh
|
|
Packit |
7cfc04 |
utility using the call:
|
|
Packit |
7cfc04 |
.sp
|
|
Packit |
7cfc04 |
.RS 4
|
|
Packit |
7cfc04 |
.nf
|
|
Packit |
7cfc04 |
\fB
|
|
Packit |
7cfc04 |
execl(\fIshell path\fP, "sh", "-c", \fIcommand\fP, (char *)0);
|
|
Packit |
7cfc04 |
.fi \fR
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
.RE
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
where
|
|
Packit |
7cfc04 |
.IR "shell path"
|
|
Packit |
7cfc04 |
is an unspecified pathname for the
|
|
Packit |
7cfc04 |
.IR sh
|
|
Packit |
7cfc04 |
utility.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
function shall ensure that any streams from previous
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
calls that remain open in the parent process are closed in the new
|
|
Packit |
7cfc04 |
child process.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.IR mode
|
|
Packit |
7cfc04 |
argument to
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
is a string that specifies I/O mode:
|
|
Packit |
7cfc04 |
.IP " 1." 4
|
|
Packit |
7cfc04 |
If
|
|
Packit |
7cfc04 |
.IR mode
|
|
Packit |
7cfc04 |
is
|
|
Packit |
7cfc04 |
.IR r ,
|
|
Packit |
7cfc04 |
when the child process is started, its file descriptor STDOUT_FILENO
|
|
Packit |
7cfc04 |
shall be the writable end of the pipe, and the file descriptor
|
|
Packit |
7cfc04 |
\fIfileno\fR(\fIstream\fR) in the calling process, where
|
|
Packit |
7cfc04 |
.IR stream
|
|
Packit |
7cfc04 |
is the stream pointer returned by
|
|
Packit |
7cfc04 |
\fIpopen\fR(),
|
|
Packit |
7cfc04 |
shall be the readable end of the pipe.
|
|
Packit |
7cfc04 |
.IP " 2." 4
|
|
Packit |
7cfc04 |
If
|
|
Packit |
7cfc04 |
.IR mode
|
|
Packit |
7cfc04 |
is
|
|
Packit |
7cfc04 |
.IR w ,
|
|
Packit |
7cfc04 |
when the child process is started its file descriptor STDIN_FILENO
|
|
Packit |
7cfc04 |
shall be the readable end of the pipe, and the file descriptor
|
|
Packit |
7cfc04 |
\fIfileno\fR(\fIstream\fR) in the calling process, where
|
|
Packit |
7cfc04 |
.IR stream
|
|
Packit |
7cfc04 |
is the stream pointer returned by
|
|
Packit |
7cfc04 |
\fIpopen\fR(),
|
|
Packit |
7cfc04 |
shall be the writable end of the pipe.
|
|
Packit |
7cfc04 |
.IP " 3." 4
|
|
Packit |
7cfc04 |
If
|
|
Packit |
7cfc04 |
.IR mode
|
|
Packit |
7cfc04 |
is any other value, the result is unspecified.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
After
|
|
Packit |
7cfc04 |
\fIpopen\fR(),
|
|
Packit |
7cfc04 |
both the parent and the child process shall be capable of executing
|
|
Packit |
7cfc04 |
independently before either terminates.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
Pipe streams are byte-oriented.
|
|
Packit |
7cfc04 |
.SH "RETURN VALUE"
|
|
Packit |
7cfc04 |
Upon successful completion,
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
shall return a pointer to an open stream that can be used to read
|
|
Packit |
7cfc04 |
or write to the pipe. Otherwise, it shall return a null pointer and
|
|
Packit |
7cfc04 |
may set
|
|
Packit |
7cfc04 |
.IR errno
|
|
Packit |
7cfc04 |
to indicate the error.
|
|
Packit |
7cfc04 |
.SH ERRORS
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
function shall fail if:
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.BR EMFILE
|
|
Packit |
7cfc04 |
{STREAM_MAX}
|
|
Packit |
7cfc04 |
streams are currently open in the calling process.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
function may fail if:
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.BR EMFILE
|
|
Packit |
7cfc04 |
{FOPEN_MAX}
|
|
Packit |
7cfc04 |
streams are currently open in the calling process.
|
|
Packit |
7cfc04 |
.TP
|
|
Packit |
7cfc04 |
.BR EINVAL
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
.IR mode
|
|
Packit |
7cfc04 |
argument is invalid.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
function may also set
|
|
Packit |
7cfc04 |
.IR errno
|
|
Packit |
7cfc04 |
values as described by
|
|
Packit |
7cfc04 |
.IR "\fIfork\fR\^(\|)"
|
|
Packit |
7cfc04 |
or
|
|
Packit |
7cfc04 |
.IR "\fIpipe\fR\^(\|)".
|
|
Packit |
7cfc04 |
.LP
|
|
Packit |
7cfc04 |
.IR "The following sections are informative."
|
|
Packit |
7cfc04 |
.SH EXAMPLES
|
|
Packit |
7cfc04 |
.SS "Using popen(\|) to Obtain a List of Files from the ls Utility"
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The following example demonstrates the use of
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
\fIpclose\fR()
|
|
Packit |
7cfc04 |
to execute the command
|
|
Packit |
7cfc04 |
.IR ls *
|
|
Packit |
7cfc04 |
in order to obtain a list of files in the current directory:
|
|
Packit |
7cfc04 |
.sp
|
|
Packit |
7cfc04 |
.RS 4
|
|
Packit |
7cfc04 |
.nf
|
|
Packit |
7cfc04 |
\fB
|
|
Packit |
7cfc04 |
#include <stdio.h>
|
|
Packit |
7cfc04 |
\&...
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
FILE *fp;
|
|
Packit |
7cfc04 |
int status;
|
|
Packit |
7cfc04 |
char path[PATH_MAX];
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
fp = popen("ls *", "r");
|
|
Packit |
7cfc04 |
if (fp == NULL)
|
|
Packit |
7cfc04 |
/* Handle error */;
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
while (fgets(path, PATH_MAX, fp) != NULL)
|
|
Packit |
7cfc04 |
printf("%s", path);
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
status = pclose(fp);
|
|
Packit |
7cfc04 |
if (status == \(mi1) {
|
|
Packit |
7cfc04 |
/* Error reported by pclose() */
|
|
Packit |
7cfc04 |
...
|
|
Packit |
7cfc04 |
} else {
|
|
Packit |
7cfc04 |
/* Use macros described under wait() to inspect `status' in order
|
|
Packit |
7cfc04 |
to determine success/failure of command executed by popen() */
|
|
Packit |
7cfc04 |
...
|
|
Packit |
7cfc04 |
}
|
|
Packit |
7cfc04 |
.fi \fR
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
.RE
|
|
Packit |
7cfc04 |
.SH "APPLICATION USAGE"
|
|
Packit |
7cfc04 |
Since open files are shared, a mode
|
|
Packit |
7cfc04 |
.IR r
|
|
Packit |
7cfc04 |
command can be used as an input filter and a mode
|
|
Packit |
7cfc04 |
.IR w
|
|
Packit |
7cfc04 |
command as an output filter.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
Buffered reading before opening an input filter may leave the standard
|
|
Packit |
7cfc04 |
input of that filter mispositioned. Similar problems with an output
|
|
Packit |
7cfc04 |
filter may be prevented by careful buffer flushing; for example, with
|
|
Packit |
7cfc04 |
.IR "\fIfflush\fR\^(\|)".
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
A stream opened by
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
should be closed by
|
|
Packit |
7cfc04 |
\fIpclose\fR().
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The behavior of
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
is specified for values of
|
|
Packit |
7cfc04 |
.IR mode
|
|
Packit |
7cfc04 |
of
|
|
Packit |
7cfc04 |
.IR r
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.IR w .
|
|
Packit |
7cfc04 |
Other modes such as
|
|
Packit |
7cfc04 |
.IR rb
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.IR wb
|
|
Packit |
7cfc04 |
might be supported by specific implementations, but these would not be
|
|
Packit |
7cfc04 |
portable features. Note that historical implementations of
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
only check to see if the first character of
|
|
Packit |
7cfc04 |
.IR mode
|
|
Packit |
7cfc04 |
is
|
|
Packit |
7cfc04 |
.IR r .
|
|
Packit |
7cfc04 |
Thus, a
|
|
Packit |
7cfc04 |
.IR mode
|
|
Packit |
7cfc04 |
of
|
|
Packit |
7cfc04 |
.IR "robert the robot"
|
|
Packit |
7cfc04 |
would be treated as
|
|
Packit |
7cfc04 |
.IR mode
|
|
Packit |
7cfc04 |
.IR r ,
|
|
Packit |
7cfc04 |
and a
|
|
Packit |
7cfc04 |
.IR mode
|
|
Packit |
7cfc04 |
of
|
|
Packit |
7cfc04 |
.IR "anything else"
|
|
Packit |
7cfc04 |
would be treated as
|
|
Packit |
7cfc04 |
.IR mode
|
|
Packit |
7cfc04 |
.IR w .
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
If the application calls
|
|
Packit |
7cfc04 |
\fIwaitpid\fR()
|
|
Packit |
7cfc04 |
or
|
|
Packit |
7cfc04 |
\fIwaitid\fR()
|
|
Packit |
7cfc04 |
with a
|
|
Packit |
7cfc04 |
.IR pid
|
|
Packit |
7cfc04 |
argument greater than 0, and it still has a stream that was called with
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
open, it must ensure that
|
|
Packit |
7cfc04 |
.IR pid
|
|
Packit |
7cfc04 |
does not refer to the process started by
|
|
Packit |
7cfc04 |
\fIpopen\fR().
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
To determine whether or not the environment specified in the Shell and Utilities volume of POSIX.1\(hy2008 is
|
|
Packit |
7cfc04 |
present, use the function call:
|
|
Packit |
7cfc04 |
.sp
|
|
Packit |
7cfc04 |
.RS 4
|
|
Packit |
7cfc04 |
.nf
|
|
Packit |
7cfc04 |
\fB
|
|
Packit |
7cfc04 |
sysconf(_SC_2_VERSION)
|
|
Packit |
7cfc04 |
.fi \fR
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
.RE
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
(See
|
|
Packit |
7cfc04 |
.IR "\fIsysconf\fR\^(\|)").
|
|
Packit |
7cfc04 |
.SH RATIONALE
|
|
Packit |
7cfc04 |
The
|
|
Packit |
7cfc04 |
\fIpopen\fR()
|
|
Packit |
7cfc04 |
function should not be used by programs that have set user (or group)
|
|
Packit |
7cfc04 |
ID privileges. The
|
|
Packit |
7cfc04 |
\fIfork\fR()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
.IR exec
|
|
Packit |
7cfc04 |
family of functions (except
|
|
Packit |
7cfc04 |
\fIexeclp\fR()
|
|
Packit |
7cfc04 |
and
|
|
Packit |
7cfc04 |
\fIexecvp\fR()),
|
|
Packit |
7cfc04 |
should be used instead. This prevents any unforeseen manipulation of
|
|
Packit |
7cfc04 |
the environment of the user that could cause execution of commands not
|
|
Packit |
7cfc04 |
anticipated by the calling program.
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
If the original and
|
|
Packit |
7cfc04 |
\fIpopen\fR()ed
|
|
Packit |
7cfc04 |
processes both intend to read or write or read and write a common file,
|
|
Packit |
7cfc04 |
and either will be using FILE-type C functions (\c
|
|
Packit |
7cfc04 |
\fIfread\fR(),
|
|
Packit |
7cfc04 |
\fIfwrite\fR(),
|
|
Packit |
7cfc04 |
and so on), the rules for sharing file handles must be observed (see
|
|
Packit |
7cfc04 |
.IR "Section 2.5.1" ", " "Interaction of File Descriptors and Standard I/O Streams").
|
|
Packit |
7cfc04 |
.SH "FUTURE DIRECTIONS"
|
|
Packit |
7cfc04 |
None.
|
|
Packit |
7cfc04 |
.SH "SEE ALSO"
|
|
Packit |
7cfc04 |
.IR "Section 2.5" ", " "Standard I/O Streams",
|
|
Packit |
7cfc04 |
.IR "\fIfork\fR\^(\|)",
|
|
Packit |
7cfc04 |
.IR "\fIpclose\fR\^(\|)",
|
|
Packit |
7cfc04 |
.IR "\fIpipe\fR\^(\|)",
|
|
Packit |
7cfc04 |
.IR "\fIsysconf\fR\^(\|)",
|
|
Packit |
7cfc04 |
.IR "\fIsystem\fR\^(\|)",
|
|
Packit |
7cfc04 |
.IR "\fIwait\fR\^(\|)",
|
|
Packit |
7cfc04 |
.IR "\fIwaitid\fR\^(\|)"
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The Base Definitions volume of POSIX.1\(hy2008,
|
|
Packit |
7cfc04 |
.IR "\fB<stdio.h>\fP"
|
|
Packit |
7cfc04 |
.P
|
|
Packit |
7cfc04 |
The Shell and Utilities volume of POSIX.1\(hy2008,
|
|
Packit |
7cfc04 |
.IR "\fIsh\fR\^"
|
|
Packit |
7cfc04 |
.SH COPYRIGHT
|
|
Packit |
7cfc04 |
Portions of this text are reprinted and reproduced in electronic form
|
|
Packit |
7cfc04 |
from IEEE Std 1003.1, 2013 Edition, Standard for Information Technology
|
|
Packit |
7cfc04 |
-- Portable Operating System Interface (POSIX), The Open Group Base
|
|
Packit |
7cfc04 |
Specifications Issue 7, Copyright (C) 2013 by the Institute of
|
|
Packit |
7cfc04 |
Electrical and Electronics Engineers, Inc and The Open Group.
|
|
Packit |
7cfc04 |
(This is POSIX.1-2008 with the 2013 Technical Corrigendum 1 applied.) In the
|
|
Packit |
7cfc04 |
event of any discrepancy between this version and the original IEEE and
|
|
Packit |
7cfc04 |
The Open Group Standard, the original IEEE and The Open Group Standard
|
|
Packit |
7cfc04 |
is the referee document. The original Standard can be obtained online at
|
|
Packit |
7cfc04 |
http://www.unix.org/online.html .
|
|
Packit |
7cfc04 |
|
|
Packit |
7cfc04 |
Any typographical or formatting errors that appear
|
|
Packit |
7cfc04 |
in this page are most likely
|
|
Packit |
7cfc04 |
to have been introduced during the conversion of the source files to
|
|
Packit |
7cfc04 |
man page format. To report such errors, see
|
|
Packit |
7cfc04 |
https://www.kernel.org/doc/man-pages/reporting_bugs.html .
|