1

My apologies if this seems duplicate but I can't find the answer I'm looking for. What I'm trying to do is create a super simple function in my C program that calls an app that I also made with C, waits for it to finish, then receives the return value from the app.

This is my source code of the app:

int main(){
    return 777;
}

I compiled it and renamed it to b.out and placed it in the root folder so the program can execute it. As you can see, all the app does is return 777 to the system.

This is the program that is calling the app:

  #include <stdio.h>
  #include <string.h>
  #include <stdlib.h>
  #include <wait.h>
  #include <unistd.h>

  int rcode=0;

  int run(char* dir,char* mainapp,char *par1,char *par2){
  int f=fork();
  if (f==-1){
      printf("Fork call error\n");
      return -1;
  }
  if (f==0){ //child
      char cmdline[1000];
      memset(cmdline,0,1000); //command line = directory + / + appname
      strcat(cmdline,dir);
      strcat(cmdline,"/");
      strcat(cmdline,mainapp);
      //par1,par2 = parameters to program
      char *args[5]={cmdline,par1,par2,NULL};
      execve(cmdline,args,NULL);
      return 1; //this is child here
    }else{
      int waitstat;
      waitpid(f,&waitstat,0); //let child finish
      rcode=WEXITSTATUS(waitstat); //get return code from child
    }
  return 0;
  }

  int main(){
  if (run("/","b.out","","")==1){
      return 0; //exit if this is child
  };
  printf("Child returns %d\n",rcode); //only parent prints this
  return rcode;
  }

When I execute everything, the return value reported is 9 (rcode=9) but it should equal 777 because my program made it equal that.

Am I supposed to replace return 777 with exit(777) or is there a better code I can use to get the return value from the child that the child sets?

Mike -- No longer here
  • 2,064
  • 1
  • 15
  • 37
  • 10
    Exit codes are 8 bits. If you truncate 777 to 8 bits you get 9. – user253751 Mar 06 '18 at 04:01
  • 1
    ^ that's a reasonable answer to me – Mike -- No longer here Mar 06 '18 at 04:34
  • I think `execve(cmdline, args, NULL);` is an error; you're invoking the program with a completely empty environment. (Worse, than that, you're invoking it with a NULL pointer, not with a NULL-terminated array; an empty environment should be an array of char* consisting of a single NULL.) Generally, programs won't work with a completely empty environment, although of course the program you're running doesn't do anything at all. But unless you have specific security concerns, you would normally want to pass your environment through to the new process, by just using `execv`. – rici Mar 06 '18 at 04:51
  • And: `char cmdline[1000]; snprintf(cmdline, sizeof(cmdline), "%s/%s", dir, mainapp);` is safer, faster and easier to read than all those `strcat` calls. (But it needs a feature-test macro: `#define _XOPEN_SOURCE 700` should do it.) – rici Mar 06 '18 at 04:54
  • Note the answers at [ExitCodes bigger than 255 — possible?](https://stackoverflow.com/questions/179565/) – Jonathan Leffler Mar 06 '18 at 04:57
  • 1
    See **man 3 exit**. see description. `The exit() function causes normal process termination and the value of status & 0377 is returned to the parent.` – kangmj37 Mar 06 '18 at 13:55

1 Answers1

2

The exit code is 8 bits.

Truncating 777 to 8 bits gives the value 9.

user253751
  • 57,427
  • 7
  • 48
  • 90