how can I transform this:
FILE *f;
char in_buffer[80];
f=popen("command","r");
fgets(in_buffer,sizeof(in_buffer),f)
without using popen()
, but only pipe()
or other instruction?
The popen() function executes the command specified by the string command. It creates a pipe between the calling program and the executed command, and returns a pointer to a stream that can be used to either read from or write to the pipe.
popen - initiate pipe streams to or from a process.
The popen() function used to open a pipe to the program specified by the user using the command parameter. It returns a file pointer which is identical to that returned by fopen(), but it is unidirectional in nature i.e it can be only used for reading or writing.
Here's my simple implementation, with comments explaining what's being done.
#include <unistd.h>
#include <stdio.h>
FILE *
my_popen (const char *cmd)
{
int fd[2];
int read_fd, write_fd;
int pid;
/* First, create a pipe and a pair of file descriptors for its both ends */
pipe(fd);
read_fd = fd[0];
write_fd = fd[1];
/* Now fork in order to create process from we'll read from */
pid = fork();
if (pid == 0) {
/* Child process */
/* Close "read" endpoint - child will only use write end */
close(read_fd);
/* Now "bind" fd 1 (standard output) to our "write" end of pipe */
dup2(write_fd,1);
/* Close original descriptor we got from pipe() */
close(write_fd);
/* Execute command via shell - this will replace current process */
execl("/bin/sh", "sh", "-c", cmd, NULL);
/* Don't let compiler be angry with us */
return NULL;
} else {
/* Parent */
/* Close "write" end, not needed in this process */
close(write_fd);
/* Parent process is simpler - just create FILE* from file descriptor,
for compatibility with popen() */
return fdopen(read_fd, "r");
}
}
int main ()
{
FILE *p = my_popen ("ls -l");
char buffer[1024];
while (fgets(buffer, 1024, p)) {
printf (" => %s", buffer);
}
fclose(p);
}
Notes:
"r"
mode of popen
. Implementing other modes, namely "w"
mode is left as an exercise for the reader.pclose
is left as an exercise for the reader - see close
, waiptid
, and fclose
.If you want to look at real impementations, you can look into sources of OSX, GNU glibc and OpenSolaris, among others.
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With