简体   繁体   中英

execve() different program output printing

I've recently been working with the execve() system call and I've been trying to figure out why it would print the full path of the function I called.

For example, when calling ls with execve :

/usr/bin/ls: cannot access 'nofile': No such file or directory

I mean, if I think about it, it's quite logical. If I call /usr/bin/ls as filename in execve , this is what the pathname actually is.

But why is the ls system call output like this:

ls: cannot access[...]

and not like mine?

I was wondering if there was any solution to find out the "name" of the program I just called, not to print the full path of the program.

As it's execve 's choice and not mine, at least I guess it is, I'm not sure about it.

Thanks.

I used of execvp function in the following code and built it:

#include  <stdio.h>
#include  <sys/types.h>

void  parse(char *line, char **argv)
{
     while (*line != '\0') {       /* if not the end of line ....... */ 
          while (*line == ' ' || *line == '\t' || *line == '\n')
               *line++ = '\0';     /* replace white spaces with 0    */
          *argv++ = line;          /* save the argument position     */
          while (*line != '\0' && *line != ' ' && 
                 *line != '\t' && *line != '\n') 
               line++;             /* skip the argument until ...    */
     }
     *argv = '\0';                 /* mark the end of argument list  */
}

void  execute(char **argv)
{
     pid_t  pid;
     int    status;

     if ((pid = fork()) < 0) {     /* fork a child process           */
          printf("*** ERROR: forking child process failed\n");
          exit(1);
     }
     else if (pid == 0) {          /* for the child process:         */
          if (execvp(*argv, argv) < 0) {     /* execute the command  */
               printf("*** ERROR: exec failed\n");
               exit(1);
          }
     }
     else {                                  /* for the parent:      */
          while (wait(&status) != pid)       /* wait for completion  */
               ;
     }
}

void  main(void)
{
     char  line[1024];             /* the input line                 */
     char  *argv[64];              /* the command line argument      */

     while (1) {                   /* repeat until done ....         */
          printf("Shell -> ");     /*   display a prompt             */
          gets(line);              /*   read in the command line     */
          printf("\n");
          parse(line, argv);       /*   parse the line               */
          if (strcmp(argv[0], "exit") == 0)  /* is it an "exit"?     */
               exit(0);            /*   exit if it is                */
          execute(argv);           /* otherwise, execute the command */
     }
}

Now, when i run the program in terminal , the result is something like this (I tried with ls command):

msi@ubuntu:~/Desktop$ ./output
Shell -> ls

1.txt
2.jpg
Qt-Creator.run
.
.
.

It also does worked with this parameter (Full path of ls program):

Shell -> /bin/ls
1.txt
2.jpg
Qt-Creator.run
.
.
.

I found out the issue, but as It's in an answer to BattleTested - закалённый в бо , I figured that answering it here would be better for anyone having this issue.

Basically, to call execve , I needed a pathname (here /usr/bin/ls ), an array of arguments (which contains the program name as first argument, not just the arguments or a NULL array if none) and the environment.

Here for ls with the -l should've been:

pathname: "/usr/bin/ls"

arguments: {"/usr/bin/ls", "-l", NULL};

and your environment (NULL terminated).

The thing is, execve() will use the first argument of your arguments array , which here is /usr/bin/ls . Simply modifying it to the program's name, and not path, fixed it.

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