Pipe() and Execve() Problem

Reply

Join Date: Feb 2009
Posts: 2
Reputation: otterfreak is an unknown quantity at this point 
Solved Threads: 0
otterfreak otterfreak is offline Offline
Newbie Poster

Pipe() and Execve() Problem

 
0
  #1
Feb 19th, 2009
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

  1. #include <errno.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <unistd.h>
  7. #define BUFLEN 100
  8. #define MESSAGE "shit"
  9.  
  10. int main(int argc, char *argv[])
  11. {
  12. extern int errno;
  13. char buffer[BUFLEN];
  14. char result[BUFLEN+1];
  15. char *param[3];
  16. float *fnum;
  17. int toServer[2];
  18. int fromServer[2];
  19. int pid;
  20. int err;
  21. char input[BUFLEN];
  22.  
  23. /*scanf("%s,%s\n",mpg, input);//fix this to call mpg function*/
  24.  
  25. /* Create a pipe */
  26. err=pipe(toServer); /*For reading*/
  27. err=pipe(fromServer); /*For writing*/
  28. if(err==-1)
  29. {
  30. printf("Error on pipe creation: %d\n",errno);
  31. exit(1);
  32. }
  33.  
  34. pid=fork();
  35. if(pid==0)
  36. {
  37. /* Child process */
  38. close(fromServer[1]); /*Close output*/
  39. err=read(fromServer[0], buffer, BUFLEN);/*store from fromServer[0] into buffer*/
  40. if(err==-1)
  41. {
  42. printf("Error on read from pipe: %d\n", errno);
  43. exit(2);
  44. }
  45. sscanf(buffer, "%f", &fnum);//convert buffer to float
  46. printf("response: Average MPG = %f\n", fnum);/*print from sprintf*/
  47. exit(0);
  48. }
  49. else if (pid>0)
  50. {
  51. /* Parent process */
  52. close(toServer[0]);/*Close input*/
  53. err=write(toServer[1],result,strlen(result)+1);/*write char[] to fd[1]*/
  54. if(err==-1)
  55. {
  56. printf("Error on write to pipe: %d\n", errno);
  57. exit(3);
  58. }
  59. sprintf(result, "%f", *fnum);
  60. param[0]=result;
  61. err = execve ("./server.c", param,0);
  62. if (err == -1)
  63. printf ("error on execve: %d\n", errno);
  64. exit(0);
  65. }
  66. else
  67. exit(4);
  68. }

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.

  1. #include <errno.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6.  
  7. typedef struct
  8. {
  9. char id[8];
  10. int odometer;
  11. float gallons;
  12. }Records;
  13.  
  14. int main(int argc, char *argv[])
  15. {
  16. FILE *finput;
  17. int i, n;
  18. //extern int errno;
  19. //char buffer[BUFLEN];
  20. //char result[100];
  21. Records r[20];
  22.  
  23. finput = fopen("proj3.txt", "r");
  24.  
  25. for (i = 0; i < 13; i++ )
  26. {
  27. fscanf(finput, "%s %d %f", &r[i].id, &r[i].odometer, &r[i].gallons);
  28. if (feof(finput))
  29. {
  30. printf("end-of-file detected on file proj3.txt\n");
  31. exit (1);
  32. }
  33. printf("element = %d, id = %s,odometer = %d, gallons = %f\n", i, r[i].id, r[i].odometer, r[i].gallons);
  34. }
  35.  
  36. /*parameters passed to Server program via execve call, take in arguments as console,
  37. and calculate them using the mpg<id> function that calculates the avg
  38. use fromServer[], toServer[] to pass response back to Interface program to print
  39. create text file that stores in all the values listed in the project 3 description
  40.   just numbers.
  41. use fprintf(), fscanf() to read and write from files
  42. must use fopen() and fclose() to handle open and close of files
  43. */
  44. }

Also, the text file which contains the inputs :
  1. 987654 201200 4.000000
  2. red 89114 0.000000
  3. red 89712 13.500000
  4. red 90229 15.300000
  5. 987654 201001 0.000000
  6. 987654 201111 5.200000
  7. 987654 201612 25.299999
  8. red 89300 7.100000
  9. green 16 0.000000
  10. green 216 20.000000
  11. green 518 61.000000
  12. 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.
Reply With Quote Quick reply to this message  
Join Date: Oct 2008
Posts: 476
Reputation: nucleon has a spectacular aura about nucleon has a spectacular aura about 
Solved Threads: 91
nucleon's Avatar
nucleon nucleon is offline Offline
Posting Pro in Training

Re: Pipe() and Execve() Problem

 
0
  #2
Feb 19th, 2009
err = execve ("./server.c", param, 0);
You are trying to run the C file! You have to run the executable.
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 2
Reputation: otterfreak is an unknown quantity at this point 
Solved Threads: 0
otterfreak otterfreak is offline Offline
Newbie Poster

Re: Pipe() and Execve() Problem

 
0
  #3
Feb 22nd, 2009
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.

  1. #include <errno.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <unistd.h>
  7. #define STD_INPUT 0
  8. #define STD_OUTPUT 1
  9. #define BUFLEN 100
  10. #define MESSAGE "shit"
  11.  
  12. int main(int argc, char *argv[])
  13. {
  14. extern int errno;
  15. char buffer[BUFLEN];
  16. char result[BUFLEN];
  17. char *param[2];
  18. float fnum=15.05;
  19. int toServer[2];
  20. int fromServer[2];
  21. int pid;
  22. int err;
  23. char input[BUFLEN];
  24. //int input;
  25. /*scanf("%s,%s\n",mpg, input);//fix this to call mpg function*/
  26. //printf("Please enter your input\n");
  27. //scanf("%d",input);
  28. /* Create a pipe */
  29. err=pipe(&toServer[1]); /*For reading*/
  30. err=pipe(&fromServer[0]); /*For writing*/
  31. if(err==-1)
  32. {
  33. printf("Error on pipe creation: %d\n",errno);
  34. exit(1);
  35. }
  36.  
  37. pid=fork();
  38. if(pid==0)
  39. {
  40. /* Child process */
  41. close(fromServer[1]); /*Close output*/
  42. close(STD_OUTPUT);
  43. dup(fromServer[0]);
  44. err=read(fromServer[0], buffer, BUFLEN);/*store from fromServer[0] into buffer*/
  45. if(err==-1)
  46. {
  47. printf("Error on read from pipe: %d\n", errno);
  48. exit(2);
  49. }
  50. sscanf(buffer, "%f", fnum);//convert buffer to float
  51. printf("response: Average MPG = %f\n", fnum);/*print from sprintf*/
  52. exit(0);
  53. }
  54.  
  55. else if (pid>0)
  56. {
  57. /* Parent process *
  58. close(toServer[0]);/*Close input*/
  59. close(STD_INPUT);
  60. dup(toServer[1]);
  61. sprintf(result,"%d",12345);
  62.  
  63. err=write(toServer[1],result,strlen(result)+1);/*write char[] to fd[1]*/
  64. if(err==-1)
  65. {
  66. printf("Error on write to pipe: %d\n", errno);
  67. exit(3);
  68. }
  69. param[0]=result;
  70. err = execve ("./server",param,NULL);
  71. if (err == -1)
  72. printf ("error on execve: %d\n", errno);
  73. exit(0);
  74. }
  75. else
  76. exit(4);
  77.  
  78. }

  1. #include <errno.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #define BUFLEN 100
  7.  
  8. typedef struct
  9. {
  10. char id[8];
  11. int odometer;
  12. float gallons;
  13. }Records;
  14.  
  15. int main(int argc, char *argv[])
  16. {
  17. extern int errno;
  18. int err;
  19. int fromInterface=atoi(argv[1]);
  20. int toInterface=atoi(argv[2]);
  21. int i, n;
  22. char buffer[BUFLEN];
  23. FILE *finput;
  24.  
  25. Records r[20];
  26.  
  27. err = read(fromInterface,buffer,BUFLEN);
  28. printf ("String read from interface = %s\n", buffer);
  29.  
  30. if(err == -1)
  31. {
  32. printf("server read errno=%d\n", errno);
  33. exit(7);
  34. }
  35.  
  36. /*finput = fopen("proj3.txt", "r");
  37.  
  38. for (i = 0; i < 13; i++ )
  39. {
  40. fscanf(finput, "%s %d %f", &r[i].id, &r[i].odometer, &r[i].gallons);
  41. if (feof(finput))
  42. {
  43. printf("end-of-file detected on file proj3.txt\n");
  44. exit (1);
  45. }
  46. printf("element = %d, id = %s,odometer = %d, gallons = %f\n", i, r[i].id, r[i].odometer, r[i].gallons);
  47. }
  48.  
  49.  
  50.  
  51.  
  52. /*parameters passed to Server program via execve call, take in arguments as console,
  53. and calculate them using the mpg<id> function that calculates the avg
  54. use fromServer[], toServer[] to pass response back to Interface program to print
  55. create text file that stores in all the values listed in the project 3 description
  56.   just numbers.
  57. */
  58. }
Reply With Quote Quick reply to this message  
Join Date: Oct 2008
Posts: 476
Reputation: nucleon has a spectacular aura about nucleon has a spectacular aura about 
Solved Threads: 91
nucleon's Avatar
nucleon nucleon is offline Offline
Posting Pro in Training

Re: Pipe() and Execve() Problem

 
0
  #4
Feb 22nd, 2009
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.
  1. void die(const char *msg)
  2. {
  3. perror(msg);
  4. exit(1);
  5. }
  6. ...
  7. if (pipe(toServer) == -1) die("pipe to");
  8. if (pipe(fromServer) == -1) die("pipe from");
  9. if ((pid = fork()) == -1) die("fork");
  10. // use same err-handling method elsewhere too
You need to remember when to pass the value and when the address to the scanf functions:
// 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);
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:
  1. if ((fd = dup(fromServer[0])) == -1) die("dup fromServer");
I'm already overstepping my knowledge so I'll stop there.
Last edited by nucleon; Feb 22nd, 2009 at 10:04 pm.
Reply With Quote Quick reply to this message  
Join Date: Dec 2005
Posts: 6,555
Reputation: Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute Salem has a reputation beyond repute 
Solved Threads: 841
Team Colleague
Salem's Avatar
Salem Salem is offline Offline
Void main'ers are DOOMed

Re: Pipe() and Execve() Problem

 
0
  #5
Feb 23rd, 2009
> 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".
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
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the C Forum


Views: 1419 | Replies: 4
Thread Tools Search this Thread



Tag cloud for C
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2010 DaniWeb® LLC