Note: I know I can achieve what I am describing by using fork
and maybe wait
but I want to understand how popen
works and how I can use it to communicate between processes.
I want to use popen
to create a child process, then in the child process I write to the pipe created by popen
and then, in the parent process, I read from the pipe and output the message.
This is what I have tried:
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#define BUFFER_SIZE 105
int main(int argc, const char * argv[])
{
FILE* fp;
int status;
char buffer[BUFFER_SIZE];
fp = popen("date", "r"); // returns `FILE *` object (the same as a "stream", I think)
if(fp == NULL) { printf("Eroare la deschidere cu `popen()`\n");} return -1; // or `EXIT_FAILURE`
fgets(buffer, BUFFER_SIZE, fp); // ????? is this where I am reading from the pipe?
// `popen` returns a pointer to a stream, thus is it a `FILE *` object?
// As such, is `fp` also the pipe? "pipe" == "stream" == `FILE *` object ?
printf("I have read: %s", buffer);
status = pclose(fp);
if(status == -1) { printf("`Eroare la inchiderea cu popen()`\n"); return -1;} // or `EXIT_FAILURE`
return 0; // or `EXIT_SUCCESS`?
}
Also, which is the pipe in such a context? Is fp
both a FILE *
object and "the pipe"? Can I access fp[0]
& fp[1]
?
Output:
I have read: Thu Apr 30 16:29:05 EEST 2020
I'm not entirely clear what you're asking here, so let me know if this answer misses the mark.
man popen
confirms that popen returns a FILE *
. It's not an array; there is no fp[0]
or fp[1]
.
A "pipe" is just a pair of connected file descriptors...one is available in the parent process (that's the return value from popen) and one is available in the child process. When you read from your fp
variable you are reading from one end of the pipe (and when the child process writes to stdout
it is writing to the other end of the pipe).
is the child reading from the stream or the parent
When you run fp = popen("date", "r")
, you are creating a uni-directional pipe. The parent can read, and the child can write (if you were to specify "w"
as the mode instead you'd have the opposite).
You are explicitly reading from the pip here:
fgets(buffer, BUFFER_SIZE, fp);
and how do I know what is executed by the sub-process
The subprocess executes what you told it to (in this case, date
).
Furthermore, how do we know which end is for read and which is for write
You control with the second argument to the popen
command.
is the whole purpose of popen (in my case, here) to redirect the output of a command to the parent process
The purpose of popen
is to permit communication between a child process and a parent process. It creates a unidirectional pipe, but you control whether that is parent -> child
or child -> parent
.
Is this what happens in the program I have provided? 1) popen opens a sub-process 2) The sub-process writes the output of the date command to the writing-end of the pipe 3) The parent process reads the read-end of the pipe(ie what the child has transmitted)?
That is correct.