Prozesse und Pipes in C



  • Hallo!

    Erst einmal kurz zu mir, da ich ja neu hier bin. Studiere Informatik im 6. Semester und sollt mal bald fertig werden 😉

    So nun zu meinem Problem. Wie ihr sicher erahnen könnt, brauch ich es für die lieb Uni.

    Wir müssen in C ein kleine Programm schreiben, welches einen Vaterprozess besitzt, der von stdin liest und einen Kindprozess der das gelesene über eine Pipe bekommt und aus diesem String sämtliche Digits entfernt und wieder an den Vaterprozess über eine andere Pipe zurück schickt, wo sie dann auch ausgegeben werden soll.

    Im Prinzip ja einfach, allerdings schauts mit meinen C Kenntnissen traurig aus.

    Bitte um Hilfe... Ansätze, Codebeispiele, oder sogar fertige Programme sind herzlich willkommen.

    Hier darunter ist mal ein kleiner Ansatz von mir, den ich aus Büchern rausgenommen habe. Sorry für die Überlänge.

    /* INCLUDES */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <errno.h>
    #include <signal.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    /* DEFINES */
    #define MAXCHAR 80
    
    /* GLOBALS */
    const char *szCommand = "<not yet set";
    static int pPipe[2];
    static pid_t pid;
    static FILE *pStream = (FILE *) 0;
    
    /* PROTOTYPES */
    void BailOut(const char *szMessage);
    
    /* FUNCTIONS */
    
    void FreeResources(void)
    {
    /*
      if (pStream != (FILE *) 0)
      {
        if (fclose((FILE *) pStream) == EOF)
    	{
    	  pStream = (FILE *) 0;
    	  BailOut("Cannnot close pipe stream!");
    	}
    	pStream = (FILE *) 0;
      }
      */
    }
    
    void AllocateResources(void)
    {
    /*
      if (pipe(pPipe) == -1)
      {
        BailOut("Cannot create pipe!");
      }
      */
    }
    
    void Usage(void)
    {
      (void) fprintf(stderr,"USAGE: %s\n", szCommand);
    
      BailOut((const char *) 0);
    }
    
    void PrintError(const char *szMessage) 
    {
      if (errno != 0)
      {
        (void) fprintf(stderr, "%s: %s - %s\n", szCommand, szMessage, strerror(errno));
      }
      else
      {
        (void) fprintf( stderr, "%s: %s\n", szCommand, szMessage);
      }
    }
    
    void BailOut (const char *szMessage)
    {
      if (szMessage != (const char *) 0)
      {
        PrintError(szMessage);
      }
      FreeResources();
    
      exit(EXIT_FAILURE);
    }
    
    void FatherProcess(void)
    {
    char buffer[MAXCHAR + 1];
    
    BailOut("father");
    
      while(fgets(buffer, MAXCHAR, stdin) != NULL)
      {
        if (printf("%s",buffer) < 0)
    	{
    	  BailOut("Cannot print to stdout!");
    	}
    	if (fflush(stdout) == EOF)
    	{
    	  BailOut("Cannot flush stdout!");
    	}
      }
    
    /*  if (close(pPipe[0]) == -1)
      {
        BailOut("Error closing the read descriptor!");
      }
    
      if ((pStream = fdopen(pPipe[1], "w")) == (FILE *) NULL)
      {
        BailOut("Cannot open pipe for writing!");
      }
    
      if (fprintf(pStream, "Message from father\n") < 0)
      {
        BailOut("Can't write to pipe!");
      }
      */
      FreeResources();
    }
    
    void ChildProcess(void)
    {
    BailOut("child");
    /*
      char buffer[MAXCHAR + 1];
    
      if (close(pPipe[1]) == -1)
      {
        BailOut("Error closing the write descriptor!");
      }
    
      if ((pStream = fdopen(pPipe[0], "r")) == (FILE *) NULL)
      {
        BailOut("Cannot open pipe for reading!");
      }
    
      while(fgets(buffer, MAXCHAR, pStream) != NULL)
      {
        if (printf("%s",buffer) < 0)
    	{
    	  BailOut("Cannot print to stdout!");
    	}
    	if (fflush(stdout) == EOF)
    	{
    	  BailOut("Cannot flush stdout!");
    	}
      }
    
      if (ferror(pStream))
      {
        BailOut("Cannot read from pipe!");
      }
      */
      FreeResources();
    }
    
    void filter()
    {
    
    }
    
    /* main */
    int main(int argc, char **argv) 
    {
      pid_t wpid;
      int status;
    
      szCommand = argv[0];
    
      if (argc != 1)
      {
        Usage();
      }
    
      AllocateResources();
    
      switch (pid = fork())
      {
    	  case -1:
          BailOut("Fork failed!!");
    	  break;
    
    	  case 0:
          ChildProcess();
    	  break;
    
    	  default:
          FatherProcess();
    
          /*
          while((wpid = wait(&status)) != pid)
          {
            if (wpid != -1)
            {
              continue;
            }
            if (errno == EINTR)
            {
              continue;
            }
    
            BailOut("Error waiting for child process!");
          }*/
    	  break;
      }
    
      exit(EXIT_SUCCESS);
    }
    

    lg und big thx stefan



  • Hier schau dir zB den Sourcecode von popen aus der OpenBSD libc an: http://google.com/codesearch/p?hl=en#XAzRy8oK4zA/libc/unistd/popen.c&q=popen libc&sa=N&cd=1&ct=rc



  • #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/wait.h>
    
    #define LOLO_BUFFER_SIZE 8096
    
    typedef struct _lolo_pipe{
    	int pipe[2];
    }lolo_pipe;
    
    int createPipe(int p[]){
    	return pipe(p);
    }
    
    void setPipeRead(lolo_pipe p){
    	close(p.pipe[1]);
    }
    
    void setPipeWrite(lolo_pipe p){
    	close(p.pipe[0]);
    }
    
    int writePipe(lolo_pipe p, char *buffer, int len){
    	return write(p.pipe[1],buffer,len);
    }
    
    int readPipe(lolo_pipe p, char *buffer, int len){
    	return read(p.pipe[0],buffer,len);
    }
    
    int isTerminationCommand(char *str){
    	return (memcmp(str,"kill lolo",sizeof("kill lolo")-1)!=0);
    }
    
    int removeDigits(char *str,int bb){
    	char *ins=str;
    	int count=0;
    	while(bb--){
    		if(*ins<'0'
    		|| *ins>'9'){
    			*str++ = *ins++;
    			count++;
    		}else
    			ins++;
    	}
    	return  count;
    }
    
    void childProcess(lolo_pipe in,lolo_pipe out){
    	int bb;
    	int flag = 1;
    	char buffer[LOLO_BUFFER_SIZE+1];
    	setPipeWrite(in);
    	setPipeRead(out);
    	while(flag){
    		bb = readPipe(out,buffer,LOLO_BUFFER_SIZE);
    		if(bb<1)
    			continue;
    		flag = isTerminationCommand(buffer);
    		bb = removeDigits(buffer,bb);
    		writePipe(in,buffer,bb);
    	}
    }
    
    void parentProcess(lolo_pipe in,lolo_pipe out){
    	int bb;
    	int flag = 1;
    	char buffer[LOLO_BUFFER_SIZE+1];
    	setPipeWrite(out);
    	setPipeRead(in);
    	while(flag){
    		bb = read(STDIN_FILENO,buffer,LOLO_BUFFER_SIZE);
    		if(bb<1)
    			continue;
    		flag = isTerminationCommand(buffer);
    		writePipe(out,buffer,bb);
    		bb = readPipe(in,buffer,LOLO_BUFFER_SIZE);
    		if(bb<1)
    			continue;
    		write(STDOUT_FILENO,buffer,bb);
    	}
    }
    
    void waitForPid(int pid){
    	int status;
    	while(wait(&status)!=pid);
    	printf("pid %d is dead",pid);
    }
    
    int main(void){
    	pid_t pid;
    	lolo_pipe in;
    	lolo_pipe out;
    
    	if(createPipe(in.pipe) != 0
    	|| createPipe(out.pipe)!= 0){
    		printf("error creating pipes");
    		return 1;
    	}
    
    	switch (pid = fork()){
    		case -1:
    			printf("error forking process");
    		break;
    		case 0:
    			childProcess(in,out);
    		break;
    		default:
    			parentProcess(in,out);
    			waitForPid(pid);
    		break;
    	}
    	return 0;
    }
    

    na dann mal viel spaß damit 😉


Anmelden zum Antworten