| | |
Pipe() and Execve() Problem
![]() |
•
•
Join Date: Feb 2009
Posts: 2
Reputation:
Solved Threads: 0
Hi guys, i'm working on trying to pass commands from the console from one program to another program by using pipes() and the execve() system calls.
I'm pretty much stuck right now, because I can't seem to determine what i'm doing wrong.
Here are my code listings
That is the first program that handles taking in the input from the console. This next one is the program that processes the command that is passed through the pipe.
Also, the text file which contains the inputs :
Both codes are incomplete at the moment because I am still trying to figure out how to fix it part by part.
My question is, what am I doing wrong? How do I take in input from the console and pass it through the pipes to invoke a function in the "server.c" program. I understand that you can only pass strings, hence my sscanf() and sprintf() functions. Also am I utilizing execve() the right way?
I understand that the community does not generally solve people's homework for them, and yes this is a project for a class, but I am not asking for an actual program, I just need some help in figuring out where i'm going wrong and what it is I should look at.
It'd be great if someone could guide me in the right direction.
Thank you
I'm pretty much stuck right now, because I can't seem to determine what i'm doing wrong.
Here are my code listings
C Syntax (Toggle Plain Text)
#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #define BUFLEN 100 #define MESSAGE "shit" int main(int argc, char *argv[]) { extern int errno; char buffer[BUFLEN]; char result[BUFLEN+1]; char *param[3]; float *fnum; int toServer[2]; int fromServer[2]; int pid; int err; char input[BUFLEN]; /*scanf("%s,%s\n",mpg, input);//fix this to call mpg function*/ /* Create a pipe */ err=pipe(toServer); /*For reading*/ err=pipe(fromServer); /*For writing*/ if(err==-1) { printf("Error on pipe creation: %d\n",errno); exit(1); } pid=fork(); if(pid==0) { /* Child process */ close(fromServer[1]); /*Close output*/ err=read(fromServer[0], buffer, BUFLEN);/*store from fromServer[0] into buffer*/ if(err==-1) { printf("Error on read from pipe: %d\n", errno); exit(2); } sscanf(buffer, "%f", &fnum);//convert buffer to float printf("response: Average MPG = %f\n", fnum);/*print from sprintf*/ exit(0); } else if (pid>0) { /* Parent process */ close(toServer[0]);/*Close input*/ err=write(toServer[1],result,strlen(result)+1);/*write char[] to fd[1]*/ if(err==-1) { printf("Error on write to pipe: %d\n", errno); exit(3); } sprintf(result, "%f", *fnum); param[0]=result; err = execve ("./server.c", param,0); if (err == -1) printf ("error on execve: %d\n", errno); exit(0); } else exit(4); }
That is the first program that handles taking in the input from the console. This next one is the program that processes the command that is passed through the pipe.
C Syntax (Toggle Plain Text)
#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> typedef struct { char id[8]; int odometer; float gallons; }Records; int main(int argc, char *argv[]) { FILE *finput; int i, n; //extern int errno; //char buffer[BUFLEN]; //char result[100]; Records r[20]; finput = fopen("proj3.txt", "r"); for (i = 0; i < 13; i++ ) { fscanf(finput, "%s %d %f", &r[i].id, &r[i].odometer, &r[i].gallons); if (feof(finput)) { printf("end-of-file detected on file proj3.txt\n"); exit (1); } printf("element = %d, id = %s,odometer = %d, gallons = %f\n", i, r[i].id, r[i].odometer, r[i].gallons); } /*parameters passed to Server program via execve call, take in arguments as console, and calculate them using the mpg<id> function that calculates the avg use fromServer[], toServer[] to pass response back to Interface program to print create text file that stores in all the values listed in the project 3 description just numbers. use fprintf(), fscanf() to read and write from files must use fopen() and fclose() to handle open and close of files */ }
Also, the text file which contains the inputs :
C Syntax (Toggle Plain Text)
987654 201200 4.000000 red 89114 0.000000 red 89712 13.500000 red 90229 15.300000 987654 201001 0.000000 987654 201111 5.200000 987654 201612 25.299999 red 89300 7.100000 green 16 0.000000 green 216 20.000000 green 518 61.000000 green 879 50.000000
Both codes are incomplete at the moment because I am still trying to figure out how to fix it part by part.
My question is, what am I doing wrong? How do I take in input from the console and pass it through the pipes to invoke a function in the "server.c" program. I understand that you can only pass strings, hence my sscanf() and sprintf() functions. Also am I utilizing execve() the right way?
I understand that the community does not generally solve people's homework for them, and yes this is a project for a class, but I am not asking for an actual program, I just need some help in figuring out where i'm going wrong and what it is I should look at.
It'd be great if someone could guide me in the right direction.
Thank you
Last edited by otterfreak; Feb 19th, 2009 at 8:56 pm.
•
•
Join Date: Feb 2009
Posts: 2
Reputation:
Solved Threads: 0
Hey, thanks for the reply, I have changed a bit of my code but now I'm getting an errno error: 14 when it tries to call the execve() system call. I have changed it to execute the executable function, my makefile has already compiled the server program, i've been trying to figure out what my problem is by altering the code and testing it part by part by i'm still at a complete loss.
C Syntax (Toggle Plain Text)
#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #define STD_INPUT 0 #define STD_OUTPUT 1 #define BUFLEN 100 #define MESSAGE "shit" int main(int argc, char *argv[]) { extern int errno; char buffer[BUFLEN]; char result[BUFLEN]; char *param[2]; float fnum=15.05; int toServer[2]; int fromServer[2]; int pid; int err; char input[BUFLEN]; //int input; /*scanf("%s,%s\n",mpg, input);//fix this to call mpg function*/ //printf("Please enter your input\n"); //scanf("%d",input); /* Create a pipe */ err=pipe(&toServer[1]); /*For reading*/ err=pipe(&fromServer[0]); /*For writing*/ if(err==-1) { printf("Error on pipe creation: %d\n",errno); exit(1); } pid=fork(); if(pid==0) { /* Child process */ close(fromServer[1]); /*Close output*/ close(STD_OUTPUT); dup(fromServer[0]); err=read(fromServer[0], buffer, BUFLEN);/*store from fromServer[0] into buffer*/ if(err==-1) { printf("Error on read from pipe: %d\n", errno); exit(2); } sscanf(buffer, "%f", fnum);//convert buffer to float printf("response: Average MPG = %f\n", fnum);/*print from sprintf*/ exit(0); } else if (pid>0) { /* Parent process * close(toServer[0]);/*Close input*/ close(STD_INPUT); dup(toServer[1]); sprintf(result,"%d",12345); err=write(toServer[1],result,strlen(result)+1);/*write char[] to fd[1]*/ if(err==-1) { printf("Error on write to pipe: %d\n", errno); exit(3); } param[0]=result; err = execve ("./server",param,NULL); if (err == -1) printf ("error on execve: %d\n", errno); exit(0); } else exit(4); }
C Syntax (Toggle Plain Text)
#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define BUFLEN 100 typedef struct { char id[8]; int odometer; float gallons; }Records; int main(int argc, char *argv[]) { extern int errno; int err; int fromInterface=atoi(argv[1]); int toInterface=atoi(argv[2]); int i, n; char buffer[BUFLEN]; FILE *finput; Records r[20]; err = read(fromInterface,buffer,BUFLEN); printf ("String read from interface = %s\n", buffer); if(err == -1) { printf("server read errno=%d\n", errno); exit(7); } /*finput = fopen("proj3.txt", "r"); for (i = 0; i < 13; i++ ) { fscanf(finput, "%s %d %f", &r[i].id, &r[i].odometer, &r[i].gallons); if (feof(finput)) { printf("end-of-file detected on file proj3.txt\n"); exit (1); } printf("element = %d, id = %s,odometer = %d, gallons = %f\n", i, r[i].id, r[i].odometer, r[i].gallons); } /*parameters passed to Server program via execve call, take in arguments as console, and calculate them using the mpg<id> function that calculates the avg use fromServer[], toServer[] to pass response back to Interface program to print create text file that stores in all the values listed in the project 3 description just numbers. */ }
Sadly I haven't used unix in many years, so hopefully a real unix person will come along to help you. A couple of points, though.
You should pass the base pointer of the 2-element int array to pipe. Also, try cleaning up your error handling, something like this, although I haven't included any cleanup like closing fd's.
You need to remember when to pass the value and when the address to the scanf functions:
Try not closing STD_OUTPUT and STD_INPUT for now; I don't see why that's necessary in this particular case (although maybe it is). And presumably you should be saving and using the file descriptors returned from dup:
I'm already overstepping my knowledge so I'll stop there.
You should pass the base pointer of the 2-element int array to pipe. Also, try cleaning up your error handling, something like this, although I haven't included any cleanup like closing fd's.
C Syntax (Toggle Plain Text)
void die(const char *msg) { perror(msg); exit(1); } ... if (pipe(toServer) == -1) die("pipe to"); if (pipe(fromServer) == -1) die("pipe from"); if ((pid = fork()) == -1) die("fork"); // use same err-handling method elsewhere too
// You need to add an ampersand here since fnum is a float.
sscanf(buffer, "%f", &fnum);
...
// And remove one here, since id is a string.
fscanf(finput, "%s %d %f",
&r[i].id, &r[i].odometer, &r[i].gallons); C Syntax (Toggle Plain Text)
if ((fd = dup(fromServer[0])) == -1) die("dup fromServer");
Last edited by nucleon; Feb 22nd, 2009 at 10:04 pm.
> param[0]=result;
And what of param[1], is that NULL (it should be)
> printf ("error on execve: %d\n", errno);
Use perror(), and it will give you a wordy description, and not just "error 14".
And what of param[1], is that NULL (it should be)
> printf ("error on execve: %d\n", errno);
Use perror(), and it will give you a wordy description, and not just "error 14".
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
--
If your code lacks code tags, you will be IGNORED
--
If your code lacks code tags, you will be IGNORED
![]() |
Similar Threads
- syntax question (C)
Other Threads in the C Forum
- Previous Thread: something recursive...
- Next Thread: C - graphics pgms
Views: 1419 | Replies: 4
| Thread Tools | Search this Thread |
Tag cloud for C
api array arrays binary binarysearch bit c++ centimeter char character code coke command conversion convert createcopyoffile csyntax database decimal dice directory do-not-use drawing dude dumpandrun dynamic error exec executable factorial fgets file fork free function functions givemetehcode givemetehcodez grade graphics highest histogram homework i/o initialization input insert int integer kernel lazy line linked linkedlist linux linuxsegmentationfault list lists loop malloc matrix memory mysql no-effort output parallel path pointer pointers precedence problem process profile program programming question read recursion recursive recursiveloop recv research reverse scanf simple socket socketprograming source spoonfeeding string strings strtok structures student system turbo-c unix user variable windows






