Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Pipes and waitpid

Status
Not open for further replies.

jurros

Programmer
Feb 14, 2005
13
NO
Hello, i have done a script that is supposed to read urls from the SOURCE. When a user types in vg.no in stdin or read a file that contains vg.no it gets the last 5/6 topics from the newspaper. the problem here is that from pipe 0 to write pipe 1 somthing goes wrong and it doenst do the cut,grep or sed ? can any 1 help me out here ?

Code:
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>

#define SOURCE "[URL unfurl="true"]http://startsiden.no/sport/nyheter/"[/URL]
#define LESFRA 0 //read from
#define SKRIVTIL 1 //write to

#define STDIN 0 
#define STDOUT 1
#define STDERR 2


int lesURL(char* URL); //url from stdinn

int main(int argc,char *argv[]){
	int antall;
   	int omFil = open(argv[1], O_RDONLY);
	char buffer[256];

   
  if (omFil >= 0)
  { /* argument er fil */ //if file
     while ( (antall=read(omFil, buffer, 254)) ) {
	     buffer[antall-1]=0;	
	     lesURL(buffer);
     }
    
     return 0; 
exit(0);

  } 
  else
  { /* Les argumenter fra stdin */ if stdin
      while ( (antall = read(0, buffer, 254)) )
      {
	   buffer[antall-1]=0;
	   lesURL(buffer);
      }
  }    

return 0;
exit(0);
}

int lesURL(char* URL) {
	pid_t nyPid[4];
	//int nyPid[4];
	int piper[4][3];
	
	/* lynx SOURCE*/
	pipe(piper[0]);
	nyPid[1] = fork();
	if (nyPid[1]==0) {
		dup2(piper[0][SKRIVTIL],STDOUT);
		execl( "/usr/bin/lynx", "lynx", "-dump", SOURCE, 0);

	}

	/* grep URL */
	pipe(piper[2]);
	nyPid[2]=fork();
	if(nyPid[2]==0) {
		dup2(piper[0][LESFRA], STDIN);
		dup2(piper[2][SKRIVTIL], STDOUT);
		execlp("grep", "grep", URL, 0);
	
	}

	/* cut -d '.' -f1 */
	pipe(piper[2]);
	nyPid[3] = fork();
	if (nyPid[3]==0) {
		dup2(piper[1][LESFRA],STDIN);
		dup2(piper[2][SKRIVTIL], STDOUT);
		execlp("cut", "cut","-d", ".", "-f1",0);

	}

/* sed -e s/\ //g */
/* pipe(piper[3]);*/
nyPid[4] = fork();
if (nyPid[4] == 0) {
dup2(piper[2][LESFRA], STDIN);
execlp("sed", "sed", "-e", "s/\\ //g", 0);
}

waitpid(nyPid[1], NULL, 0);
waitpid(nyPid[2], NULL, 0);
waitpid(nyPid[3], NULL, 0);
waitpid(nyPid[4], NULL, 0);

return (0);
}
 
sorry about this but this is the code that compiles, but it dont use cut sed etc :(
Code:
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>

#define SOURCE "[URL unfurl="true"]http://startsiden.no/sport/nyheter/"[/URL]
#define LESFRA 0 //read from
#define SKRIVTIL 1 //write to

#define STDIN 0
#define STDOUT 1
#define STDERR 2


int lesURL(char* URL); //url from stdinn

int main(int argc,char *argv[]){
    int antall;
       int omFil = open(argv[1], O_RDONLY);
    char buffer[256];

   
  if (omFil >= 0)
  { /* argument er fil */ //if file
     while ( (antall=read(omFil, buffer, 254)) ) {
         buffer[antall-1]=0;    
         lesURL(buffer);
     }
    
     return 0;
exit(0);

  }
  else
  { /* Les argumenter fra stdin if stdin */ 
      while ( (antall = read(0, buffer, 254)) )
      {
       buffer[antall-1]=0;
       lesURL(buffer);
      }
  }    

return 0;
exit(0);
}

int lesURL(char* URL) {
    pid_t nyPid[4];
    //int nyPid[4];
    int piper[4][3];
    
    /* lynx SOURCE*/
    pipe(piper[0]);
    nyPid[1] = fork();
    if (nyPid[1]==0) {
        dup2(piper[0][SKRIVTIL],STDOUT);
        execl( "/usr/bin/lynx", "lynx", "-dump", SOURCE, 0);

    }

    /* grep URL */
    pipe(piper[1]);
    nyPid[2]=fork();
    if(nyPid[2]==0) {
        dup2(piper[0][LESFRA], STDIN);
        dup2(piper[2][SKRIVTIL], STDOUT);
        execlp("grep", "grep", URL, 0);
    
    }

    /* cut -d '.' -f1 */
    pipe(piper[2]);
    nyPid[3] = fork();
    if (nyPid[3]==0) {
        dup2(piper[1][LESFRA],STDIN);
        dup2(piper[2][SKRIVTIL], STDOUT);
        execlp("cut", "cut","-d", ".", "-f1",0);

    }

/* sed -e s/\ //g */
/* pipe(piper[3]);*/
nyPid[4] = fork();
if (nyPid[4] == 0) {
dup2(piper[2][LESFRA], STDIN);
execlp("sed", "sed", "-e", "s/\\ //g", 0);
}

waitpid(nyPid[1], NULL, 0);
waitpid(nyPid[2], NULL, 0);
waitpid(nyPid[3], NULL, 0);
waitpid(nyPid[4], NULL, 0);

return (0);
}
 
How about libcurl?
..and the posix or pcre libraries? Elegant and extensible
in C.

This convoluted use of pipes for IPC between processes,
and for this purpose, makes my head hurt. The most
complicated you should get with pipes for ipc IMHO is coprocesses.
This multiple legged implemetation needs to be a shell
script making use of netcat or sock.

My .02 cents
 
:) i see but still i need it as pipes and forkes...
:(
 
> i see but still i need it as pipes and forkes...
Can you write it out as a shell program (which excells at this sort of stuff).
Code:
/usr/bin/lynx -dump [URL unfurl="true"]http://startsiden.no/sport/nyheter/[/URL] |
  grep $url |
  cut -d . -f1 |
  sed -e "s/\\ //g"
At least then you can verify that you're doing the right thing.
Personally, I'd leave it like that if it works, you're not getting anything out of it by writing it as a C program.

--
 
yes this is my shell

Code:
IFS=`echo -e "\n\r"`
for I in `cut -f1 $1`
do
source="[URL unfurl="true"]http://startsiden.no/sport/nyheter/"[/URL]
echo "Kilde: $source"

lynx -dump $source > /tmp/nyhet

hva=$(cat /tmp/nyhet |grep $I | cut -d'.' -f1 | sed -e s/\ //g)

for nr in $hva; do
	 over=$(cat /tmp/nyhet | grep -G "\W$nr\W" | head -n 1| cut -d']' -f2)
	 url=$(cat /tmp/nyhet | grep -G "\W$nr\W" | tail -n 1 | cut -d' ' -f4)
	
echo "<a href=\"$url\">$over</a><br>"
done
done
rm /tmp/nyhet
 
Of course its possible (how do you think the shell manages it?), but I see no reason to do it given a perfectly adequate shell script.

I mean, your shell script is complicated enough that I would write a parser to read a file. Simply hard-coding a long sequence of pipe(), fork() and execl() calls together in that particular arrangement seems hard work for no gain IMO.

Damn, I thought this post was familiar...

--
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top