G
Greg
I am trying to implement the UNIX pipe command using C but with the
"->" operator. Everything works fine with 1 pipe, but when I try to
use 2 or more, it hangs up when reading the pipe_in filestream. If
ANYONE could offer ANY suggestion as to why this is happening it would
be much appreciated.
Thanks in advance!
#define MAX_PIPES 5
#define MAX_CMD_LEN 255
#include <string.h>
#include <stdio.h>
// global vars
char piped_cmds [MAX_PIPES][MAX_CMD_LEN] ;
int numPipes ;
// fcn prototypes
int pipeCmds (int cmd1, int cmd2) ;
char *stripFirstChar (char *str) ;
char *stripLastChar (char *str) ;
void splitPipes (char *toSplit) ;
int isPipe (char *cmd) ;
int main () {
int i ;
char command [] = "ps aux -> grep greg -> wc" ;
//char command [] = "cat .bash_profile -> tail -15 -> tail -10 ->
tail -5 -> tail -3" ;
//char command [] = "ps aux -> grep greg -> grep 5 -> grep 3 -> less"
;
char *noPipe = "ps aux" ;
//numPipes = 0 ;
if (isPipe (command)) {
splitPipes (command) ;
for (i = 0; i < numPipes - 1; i++) {
if (!pipeCmds (i, i + 1))
printf ("Pipe failed\n") ;
else
printf ("Pipe succeeded\n") ;
}
}
printf ("Exit\n") ;
}
int pipeCmds (int cmd1, int cmd2) {
FILE *pipe_in ;
FILE *pipe_out ;
char *my_string ;
int nbytes = 100;
int bytes_read;
char readbuf[MAX_CMD_LEN];
printf ("Piping [%i] %s -> [%i] %s\n", cmd1, piped_cmds [cmd1], cmd2,
piped_cmds [cmd2]) ;
// open pipes
pipe_in = popen (piped_cmds [cmd1], "r") ;
printf ("Input pipe open\n") ;
pipe_out = popen (piped_cmds [cmd2], "w") ;
printf ("Output pipe open\n") ;
if ((!pipe_in) || (!pipe_out)) {
fprintf (stderr, "One or both pipes failed.\n") ;
return 0 ;
}
printf ("Transferring file contents...\n") ;
// while(fgets(readbuf, 250, pipe_in))
// fputs(readbuf, pipe_out);
while (!feof (pipe_in)) {
printf ("Reading input pipe...\n") ;
/****************program hangs here**************************/
fgets (readbuf, MAX_CMD_LEN, pipe_in);
if(feof(pipe_in))
break;
printf("%s", readbuf) ;
fputs (readbuf, pipe_out) ;
}
pclose (pipe_in) ;
pclose (pipe_out) ;
printf ("Pipes closed\n") ;
return 1 ;
}
char *stripFirstChar (char *str) {
str++ ;
return str ;
}
char *stripLastChar (char *str) {
char *temp = str ;
while (*temp != '\0') {
temp++ ;
}
temp-- ;
*temp = '\0' ;
//printf ("\"%s\"\n", temp) ;
return str ;
}
void splitPipes (char *toSplit) {
char *tokenPtr = NULL ;
int i ;
for (tokenPtr = strtok (toSplit, "->"); tokenPtr != NULL;
tokenPtr = strtok (NULL, "->"))
{
strcpy (piped_cmds [numPipes], tokenPtr) ;
numPipes++ ;
}
for (i = 1; i < numPipes; i++) {
strcpy (piped_cmds , stripFirstChar (piped_cmds )) ;
}
for (i = 0; i < numPipes - 1; i++) {
strcpy (piped_cmds , stripLastChar (piped_cmds )) ;
}
for (i = 0; i < numPipes; i++) {
printf ("[%i] \"%s\"\n", i, piped_cmds ) ;
}
}
int isPipe (char *cmd) {
if (strchr (cmd, '>')) {
printf ("%s contains at least 1 pipe\n", cmd) ;
return 1 ;
}
else
printf ("%s contains no pipes\n", cmd) ;
return 0 ;
}
"->" operator. Everything works fine with 1 pipe, but when I try to
use 2 or more, it hangs up when reading the pipe_in filestream. If
ANYONE could offer ANY suggestion as to why this is happening it would
be much appreciated.
Thanks in advance!
#define MAX_PIPES 5
#define MAX_CMD_LEN 255
#include <string.h>
#include <stdio.h>
// global vars
char piped_cmds [MAX_PIPES][MAX_CMD_LEN] ;
int numPipes ;
// fcn prototypes
int pipeCmds (int cmd1, int cmd2) ;
char *stripFirstChar (char *str) ;
char *stripLastChar (char *str) ;
void splitPipes (char *toSplit) ;
int isPipe (char *cmd) ;
int main () {
int i ;
char command [] = "ps aux -> grep greg -> wc" ;
//char command [] = "cat .bash_profile -> tail -15 -> tail -10 ->
tail -5 -> tail -3" ;
//char command [] = "ps aux -> grep greg -> grep 5 -> grep 3 -> less"
;
char *noPipe = "ps aux" ;
//numPipes = 0 ;
if (isPipe (command)) {
splitPipes (command) ;
for (i = 0; i < numPipes - 1; i++) {
if (!pipeCmds (i, i + 1))
printf ("Pipe failed\n") ;
else
printf ("Pipe succeeded\n") ;
}
}
printf ("Exit\n") ;
}
int pipeCmds (int cmd1, int cmd2) {
FILE *pipe_in ;
FILE *pipe_out ;
char *my_string ;
int nbytes = 100;
int bytes_read;
char readbuf[MAX_CMD_LEN];
printf ("Piping [%i] %s -> [%i] %s\n", cmd1, piped_cmds [cmd1], cmd2,
piped_cmds [cmd2]) ;
// open pipes
pipe_in = popen (piped_cmds [cmd1], "r") ;
printf ("Input pipe open\n") ;
pipe_out = popen (piped_cmds [cmd2], "w") ;
printf ("Output pipe open\n") ;
if ((!pipe_in) || (!pipe_out)) {
fprintf (stderr, "One or both pipes failed.\n") ;
return 0 ;
}
printf ("Transferring file contents...\n") ;
// while(fgets(readbuf, 250, pipe_in))
// fputs(readbuf, pipe_out);
while (!feof (pipe_in)) {
printf ("Reading input pipe...\n") ;
/****************program hangs here**************************/
fgets (readbuf, MAX_CMD_LEN, pipe_in);
if(feof(pipe_in))
break;
printf("%s", readbuf) ;
fputs (readbuf, pipe_out) ;
}
pclose (pipe_in) ;
pclose (pipe_out) ;
printf ("Pipes closed\n") ;
return 1 ;
}
char *stripFirstChar (char *str) {
str++ ;
return str ;
}
char *stripLastChar (char *str) {
char *temp = str ;
while (*temp != '\0') {
temp++ ;
}
temp-- ;
*temp = '\0' ;
//printf ("\"%s\"\n", temp) ;
return str ;
}
void splitPipes (char *toSplit) {
char *tokenPtr = NULL ;
int i ;
for (tokenPtr = strtok (toSplit, "->"); tokenPtr != NULL;
tokenPtr = strtok (NULL, "->"))
{
strcpy (piped_cmds [numPipes], tokenPtr) ;
numPipes++ ;
}
for (i = 1; i < numPipes; i++) {
strcpy (piped_cmds , stripFirstChar (piped_cmds )) ;
}
for (i = 0; i < numPipes - 1; i++) {
strcpy (piped_cmds , stripLastChar (piped_cmds )) ;
}
for (i = 0; i < numPipes; i++) {
printf ("[%i] \"%s\"\n", i, piped_cmds ) ;
}
}
int isPipe (char *cmd) {
if (strchr (cmd, '>')) {
printf ("%s contains at least 1 pipe\n", cmd) ;
return 1 ;
}
else
printf ("%s contains no pipes\n", cmd) ;
return 0 ;
}