Thread: cont of IPC using PIPE

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    20

    cont of IPC using PIPE

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <string.h>
    
    /*
     *Decimal number is taken in through standard input and
     *output to a file called bin.txt
     */
    int main(int argc, char* argv[]){
    	pid_t pid1, pid2;
    	int rv;
    	int	D2Bcommpipe[2];		/* This holds the fd for the input & output of the pipe */
    	int D2Hcommpipe[2];
    	char input[32] = "00";
    	FILE *inputfile;
    	FILE *outputfile;
    	inputfile = fopen("dec.txt", "r");
    	outputfile = fopen("bin.txt", "w");
    	
    	if(inputfile == NULL) fprintf(stderr, "dec.dat NOT opened successfully\n");
    	else fprintf(stderr, "dec.dat opened successfully\n");
    	
    	if(outputfile == NULL) fprintf(stderr, "bin.dat NOT created successfully\n");
    	else fprintf(stderr, "bin.dat created successfully\n");
    	
    	/* Setup communication pipeline first */
    	if(pipe(D2Bcommpipe)){
    		fprintf(stderr,"Pipe not opened. terminating...\n");
    		exit(1);
    	}
    	if(pipe(D2Hcommpipe)){
    		fprintf(stderr, "Pipe not opened. terminating...\n");
    		exit(1);
    	}
    
    	
    	/* Attempt to fork and check for errors */
    	if( (pid1=fork()) == -1){
    		fprintf(stderr,"Fork error. terminating....\n");  /* something went wrong */
    		exit(1);        
    	}
    	/*pid1 Child Process*/
    	if(pid1 == 0){
    		dup2(D2Bcommpipe[0], 0);			//Dup child into reading stdin from pipe
    		close(D2Bcommpipe[1]);
    		dup2(D2Hcommpipe[1], 1);			//Dup Child into piping its stdout
    		close(D2Hcommpipe[0]);
    		
    		setvbuf(stdout, (char*) NULL, _IONBF, 0);	/* Set non-buffered output on stdout */
    		if(execl("dectohex","dectohex",NULL) == -1){
    			fprintf(stderr,"dectohex NOT found by execlp, terminating...\n");
    			exit(1);
    		}
    		
    	}
    	/***********************
    	 *pid1 Parent process
    	 ***********************/
    	else{		
    		if((pid2=fork()) == -1){
    			fprintf(stderr,"Fork error. terminating....\n");  /* something went wrong */
    			exit(1);        
    		}
    		/*pid2 child Process*/
    		if(pid2 == 0){
    			dup2(D2Hcommpipe[0], 0);
    			close(D2Hcommpipe[1]);
    			
    			if(execl("hextobin", "hextobin", NULL) == -1){
    			   fprintf(stderr, "hextobin NOT found by execlp, terminating...\n");
    			}
    		}
    		/***********************
    		 *pid2 Parent process
    		 ***********************/
    		else{
    			dup2(D2Bcommpipe[1],1);
    			close(D2Bcommpipe[0]);	
    			setvbuf(stdout, (char*) NULL, _IONBF, 0);	/* Set non-buffered output on stdout */
    			
    			while(fscanf(inputfile, "%s", &input) != EOF){
    				printf("%s\n", input);
    				memset(input, 0, 32);
    			}
    			
    			close(D2Bcommpipe[1]);
    			close(1);
    		}
    		//wait(&rv);				/* Wait for child process to end */
    		if(!WIFEXITED(rv))
    			fprintf(stderr, "Message for dectobin.c child process not found\n");
    		else
    			if(WEXITSTATUS(rv))
    				fprintf(stderr, "One or more errors in child process of dectobin.c\n");
    	}
    	return 0;
    	
    }
    I want to make this code generate 1 parent and 2 child processes
    the parent will push its stdout through pipe1 into the process dectohex.c
    dectohex.c will be duped into reading stdin via pipe 1 and pushings its stdout through pipe2
    hextobin.c will be duped into reading stdin via pipe 2 and then push its stdout through pipe3 where the parent will finally read from pipe 3 and get what it wants.


    In general, I am converting a number from decimal to binary by first piping the number to a process that converts it to hex then piping to process that converts the hex to binary then piping that number BACK to the parent process.

    Problem: I can pipe from the parent to child1 just fine but when I try to pipe from child1 to child2 and have child2 just output to the terminal I get nothing. I think there is some fluke in the way I am forking my processes and duping the children. Would anyone care to take a look?

    Also, any tips on better practices I could be using in this code are appreciated.
    Last edited by BMathis; 03-15-2009 at 05:42 PM.

  2. #2
    Registered User
    Join Date
    Feb 2009
    Posts
    20
    Here are the children

    dectohex.c
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <string.h>
    
    void tohex(int num, char* hex)
    {
    	char *hlookup = "0123456789ABCDEF";
    	int hindex[16];
    	int index=-1;
    	int subindex;
    		
    	do{
    		index++;
    		hindex[index] = num%16;
    		num /= 16;
    	}while(num!=0);
    	
    	subindex=0;
    	
    	for( index; index>=0; index--){
    		hex[subindex]=hlookup[hindex[index]];
    		subindex++;
    	}
    }	
    /*
     *Will take a decimal number from the stantard input and
     *output the hexidecimal version to hex.txt
     */
    int main(int argc, char* argv[]){
    	char input[16]={'\0'};
    	char hex[16]={'\0'};	
    	char *pch;
    	fprintf(stderr, "RAAAAAAW\n");
    		while(fgets(input, sizeof(input), stdin)!=NULL){
    			pch=strchr(input, '\n');
    			input[pch-input]='\0';
    			tohex(atoi(input), hex);
    			printf("%s\n", hex);
    			memset(hex, 0, 16);
    		}
    	exit(0);
    }
    hextobin.c
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <string.h>
    
    int indexof(char* str, char c){
    	int x;
    	for(x=0; x<strlen(str); x++){
    		if(c == str[x]) return x;
    	}
    	return -1;
    }
    
    void tobin(char* hex, char* bin){
    	char *binlookup[16] =   {"0000", "0001", "0010", "0011",
    							 "0100", "0101", "0110", "0111", 
    							 "1000", "1001", "1010", "1011", 
    							 "1100", "1101", "1110", "1111"};
    	char* hlookup= "0123456789ABCDEF";
    	int index;
    	int i;
    	char posvalue;
    	
    	for(i=0; i<strlen(hex); i++){
    		posvalue = hex[i];
    		index = (posvalue<='9') ? atoi(&posvalue): indexof(hlookup, posvalue);
    		strcat(bin, binlookup[index]);
    	}
    }
    
    int main(int argc, char* argv[]){
    	char input[16]={'\0'};
    	char bin[16*4]={'\0'};	
    	char *pch;
    	int compipe[2];	
    	printf("VROOOOOM\n");
    	while(fgets(input, sizeof(input), stdin)!=NULL){
    		pch=strchr(input, '\n');
    		input[pch-input]='\0';
    		tobin(input, bin);
    		printf("%s\n", bin);
    		memset(bin, 0, 16);
    	}
    	exit(0);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault - IPC
    By kbfirebreather in forum C Programming
    Replies: 7
    Last Post: 02-01-2009, 03:17 PM
  2. Pipe class.
    By eXeCuTeR in forum Linux Programming
    Replies: 8
    Last Post: 08-21-2008, 03:44 AM
  3. Pipe(): Interprocess or Intraprocess comm?
    By @nthony in forum C Programming
    Replies: 2
    Last Post: 03-28-2007, 07:27 PM
  4. Clearing a pipe used in IPC
    By cbgb in forum C Programming
    Replies: 5
    Last Post: 09-26-2006, 03:59 PM
  5. 2 way ipc
    By mmnoname in forum C Programming
    Replies: 2
    Last Post: 03-25-2006, 10:39 AM