The command argument is a pointer to a null-terminated string containing a shell command line. This command is passed to /bin/sh using the -c flag; interpretation, if any, is performed by the shell.
const char *type
Output
Return:
The return value from popen() is a normal standard I/O stream in all respects save that it must be closed with pclose() rather than fclose(3). Writing to such a stream writes to the standard input of the command; the command's standard output is the same as that of the process that called popen(), unless this is altered by the command itself. Conversely, reading from the stream reads the command's standard output, and the command's standard input is the same as that of the process that called popen().
#include <unistd.h>
int pipe(int pipefd[2]);
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <fcntl.h> /* Definition of O_* constants */
#include <unistd.h>
int pipe2(int pipefd[2], int flags);
/* On Alpha, IA-64, MIPS, SuperH, and SPARC/SPARC64, pipe() has the
following prototype; see NOTES */
#include <unistd.h>
struct fd_pair {
long fd[2];
};
struct fd_pair pipe(void);
Parameters:
Params
I/O
Details
int pipefd[2]
Input
pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe. Data written to the write end of the pipe is buffered by the kernel until it is read from the read end of the pipe.
Return:
On success, zero is returned. On error, -1 is returned, errno is set to indicate the error, and pipefd is left unchanged.
On Linux (and other systems), pipe() does not modify pipefd on failure. A requirement standardizing this behavior was added in POSIX.1-2008 TC2. The Linux-specific pipe2() system call likewise does not modify pipefd on failure.
**Example 1 **: 管道建立在同一个进程上面
int test_pipe_rw()
{
int ret = 0;
int data_process = 0;
int file_pipes[2];
const char some_data[] = "hello world";
char buffer[BUFSIZ + 1];
memset(buffer, '\0', sizeof buffer);
ret = pipe(file_pipes);
if (ret != 0) {
debug_log("pipe failed, ret = %d\n", ret);
goto exit;
}
// write some_data to pipe
data_process = write(file_pipes[1], some_data, strlen(some_data));
debug_log("Wrote the %d bytes\n", data_process);
// read buffer from pipe
data_process = read(file_pipes[0], buffer, BUFSIZ);
debug_log("read %d bytes: %s\n", data_process, buffer);
exit:
return ret;
}
**Example 2 **: 父进程和fork的子进程共用pipe,子进程写,父进程读。
这里要注意的是:
子进程故意延迟了5s的时间再写,会发现父进程会阻塞在read函数。
int test_pipe_rw_fork()
{
int ret = 0;
int data_process = 0;
int file_pipes[2];
const char some_data[] = "hello world";
char buffer[BUFSIZ + 1];
pid_t pid = 0;
memset(buffer, '\0', sizeof buffer);
ret = pipe(file_pipes);
if (ret != 0) {
debug_log("pipe failed, ret = %d\n", ret);
goto exit;
}
pid = fork();
if (pid == -1) {
debug_log("fork failed, ret = %d\n", ret);
goto exit;
}
// child process
else if (pid == 0) {
sleep(5);
data_process = write(file_pipes[1], some_data, strlen(some_data));
debug_log("child wrote the %d bytes\n", data_process);
}
// parent process
else {
data_process = read(file_pipes[0], buffer, BUFSIZ);
debug_log("parent read %d bytes: %s\n", data_process, buffer);
}
exit:
return ret;
}
The type argument is a pointer to a null-terminated string which must contain either the letter 'r' for reading or the letter 'w' for writing. Since glibc 2.9, this argument can additionally include the letter 'e', which causes the close-on-exec flag (FD_CLOEXEC) to be set on the underlying file descriptor; see the description of the O_CLOEXEC flag in for reasons why this may be useful.