Q: Is a pipe a file?
A: It's up to the operating system how it creates pipes, but pipes created with the pipe() function are not normally files.
Q: So pipes might be files?
A: It is possible to create pipes based on files, which are normally called named pipes or FIFO (first-in/first-out) files.
Q: Why would anyone want a pipe that uses a file?
A: Pipes based on files have names. That means they are useful if two processes need to talk to each other and they are not parent and child processes. As long as both processes know the name of the pipe, they can talk with it.
Q: Great! So how do I use named pipes?
A: Using the mkfifo() system call. For more information, see
http://tinyurl.com/cdf6ve5.
Q: If most pipes are not files, what are they?
A: Usually, they are just pieces of memory. Data is written at one point and read at another. In LINUX pipe capicity is 64KB, pipe buffer is 4096. (see man 7 pipe).
Since Linux 2.6.11, the pipe capacity is 65536 bytes.
(On Linux, PIPE_BUF is 4096 bytes.)
Q: What happens if I try to read from a pipe and there's nothing in there?
A: Your program will wait until something is there.
Q: How does the parent know when the child is finished?
A: When the child process dies, the pipe is closed and the fgets() command receives an end-of-file, which means the fgets() function returns 0, and the loop ends.
Q: Can parents speak to children?
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
void error(char * msg) {
fprintf(stderr, "%s: %s\n", msg, strerror(errno));
exit(1);
}
void open_url(char *url)
{
char launch[255];
sprintf(launch, "cmd /c start %s", url);
system(launch);
sprintf(launch, "x-www-browser '%s' &", url);
system(launch);
sprintf(launch, "open '%s'", url);
system(launch);
}
int main(int argc, char *argv[])
{
char *phrase = argv[1];
char *vars[] = {"RSS_FEED=http://www.cnn.com/rss/celebs.xml", NULL};
int fd[2];
if (pipe(fd) == -1) {
error("Can't create the pipe");
}
pid_t pid = fork();
if (pid == -1) {
error("Can't fork process");
}
if (!pid) {
dup2(fd[1], 1);
close(fd[0]);
if (execle("/usr/bin/python", "/usr/bin/python", "./rssgossip.py", "-u", phrase, NULL, vars) == -1) {
error("Can't run script");
}
}
dup2(fd[0], 0);
close(fd[1]);
char line[255];
while ( fgets(line, 255, stdin) ) {
if (line[0] == '\t')
open_url(line + 1);
}
return 0;
}
Q: Can parents speak to children?
A: Absolutely. There is no reason why you can't connect your pipes the other way around, so that the parent sends data to the child process.
Q: Can you have a pipe that works in both directions at once? That way, my parent and child processes could have a two-way conversation.
A: No, you can't do that. Pipes always work in only one direction. But you can create two pipes: one from the parent to the child, and one from the child to the parent. (or use mkfifo, shared pipe, can read write parallel with some processes)
【参考】
fgets
NAME
fgetc, fgets, getc, getchar, gets, ungetc - input of characters and strings
SYNOPSIS
#include <stdio.h>
int fgetc(FILE *stream);
char *fgets(char *s, int size, FILE *stream);
int getc(FILE *stream);
int getchar(void);
char *gets(char *s);
int ungetc(int c, FILE *stream);
DESCRIPTION
fgetc() reads the next character from stream and returns it as an unsigned char cast to an int, or EOF on end
of file or error.
getc() is equivalent to fgetc() except that it may be implemented as a macro which evaluates stream more than
once.
getchar() is equivalent to getc(stdin).
gets() reads a line from stdin into the buffer pointed to by s until either a terminating newline or EOF, which
it replaces with ’\0’. No check for buffer overrun is performed (see BUGS below).
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to
by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A ’\0’ is
stored after the last character in the buffer.
ungetc() pushes c back to stream, cast to unsigned char, where it is available for subsequent read operations.
Pushed-back characters will be returned in reverse order; only one pushback is guaranteed.
Calls to the functions described here can be mixed with each other and with calls to other input functions from
the stdio library for the same input stream.
For non-locking counterparts, see unlocked_stdio(3).
RETURN VALUE
fgetc(), getc() and getchar() return the character read as an unsigned char cast to an int or EOF on end of
file or error.
gets() and fgets() return s on success, and NULL on error or when end of file occurs while no characters have
been read.
ungetc() returns c on success, or EOF on error.
CONFORMING TO
C89, C99. LSB deprecates gets().
BUGS
Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters
gets() will read, and because gets() will continue to store characters past the end of the buffer, it is
extremely dangerous to use. It has been used to break computer security. Use fgets() instead.
It is not advisable to mix calls to input functions from the stdio library with low-level calls to read() for
the file descriptor associated with the input stream; the results will be undefined and very probably not what
you want.