简体   繁体   中英

fork() & execl - unable to run external process

All, I'm running the program below and receiving the output at the end of the question. I'm not sure if this is a gap in my understanding of execl, or if I'm doing something completely incorrectly here. The code is pretty straight forward, and the arguments/output are noted below:

Edit: Fixed sizeof(arg) to reflect actual size of arg; though, as you can see it returns a puzzling '1', though it should be of size 2.

int shell (int argc, char *argv[]) {
  char *s;          /* user input string */
  tok_t *t;         /* tokens parsed from input */
  int lineNum = 0;
  int fundex = -1;
  pid_t pid = getpid();     /* get current processes PID */
  pid_t ppid = getppid();   /* get parents PID */

  printf("%s running as PID %d under %d\n",argv[0],pid,ppid);
  lineNum=0;
  fprintf(stdout,"%d: ",lineNum);
  while ((s = freadln(stdin))) {
    t = getToks(s);     /* Break the line into tokens */
    fundex = lookup(t[0]);  /* Is first token a shell literal */
    if (fundex >= 0) cmd_table[fundex].fun(&t[1]);
    else {          /* Treat it as a file to exec */
      cmd_fork(t);
    }
    fprintf(stdout,"%d: ",++lineNum);
  }
  return 0;
}

int cmd_fork(tok_t arg[]) {
  size_t size = 120;
  int i, status = 0;
  pid_t childPid;
  char *nargs = (char *) malloc(size);

    printf("sizeof arg: %lu\n", (sizeof(arg)/sizeof(tok_t))); // returns 1?
    if ((sizeof(arg)/sizeof(tok_t)) >= 2) {
    printf("arg0: %s, arg1: %s\n", arg[0], arg[1]);
    if (sizeof(arg) > 2) {
      for (i=1; i < sizeof(arg); i++) {
        if (i > 1) {
          strcat(nargs, " ");
        }
        strcat(nargs, arg[i]);
        printf("Nargs: %s\n", nargs);
      }
    } 
    execl(arg[0], arg[0], nargs, NULL);
    _exit(127);
  }

  if (childPid > 0) {
    waitpid(childPid, &status, 0);    
    printf("Exit status of process was %d\n", status);
  } else {

    printf("Child failed");
  }

  return 0;
}

Output:

./shell running as PID 3595 under 1833
0: /usr/bin/wc /home/vagrant/example
T0: /usr/bin/wc, T1: /home/vagrant/example
arg0: /usr/bin/wc, arg1: /home/vagrant/example
sizeof arg: 1
/usr/bin/wc: invalid zero-length file name
Exit status of process was 256

I'm not quite sure what's going wrong, but would really appreciate any pointers in the right direction.

Thank you,

Mo

As @5gon12eder pointed out, I had my sizes and thus loops borked. Final resolution looked like the below. Shame on me for not looking at the parse.c belonging to the parse.h sooner.

int cmd_fork(tok_t arg[]) {
  size_t size = 120;
  int i, status = 0;
  pid_t childPid;
  char *nargs = (char *) malloc(size);

  if ((childPid = fork()) == 0) {
    printf("arg0: %s, arg1: %s\n", arg[0], arg[1]);
    for (i=1; i < MAXTOKS && arg[i]; i++) {
      if (i > 1) {
        strcat(nargs, " ");
      }
      strcat(nargs, arg[i]);
      printf("Nargs: %s\n", nargs);
    }
    execl(arg[0], arg[0], nargs, NULL);
    _exit(127);
  }

  if (childPid > 0) {
    waitpid(childPid, &status, 0);    
    printf("Exit status of process was %d\n", status);
  } else {

    printf("Child failed");
  }

  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM