0

I need to create a program that allows the user to execute a command passed as argument using execve in linux. I'm not sure about the syntax of the execve command. I wrote the program but it doesn't work with multiple arguments and I can't figure out why.

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc, char **argv)
{
int status;
pid_t pid;
if((pid = fork())>0)
{
    ///Father process
    wait(&status);
    printf("Process terminated with status = %d\n",status);
}
else
{
    ///son process
    int i;
    char param[100];

    printf("I'm the son woth PID= %d\n",getpid());
    printf("%s\n",argv[0]);
    printf("%s\n",argv[1]);
    printf("%s\n",argv[2]);
    strcpy(param,"/bin/");
    strcat(param,argv[1]);  

    execve(param,argv,NULL);
    exit(-1);
}


return 0;
}

A command that doesn't work using this code is

cp file1.txt file2.txt

Can someone help me?

  • 2
    What does "doesn't work" mean? Why don't you run your program on a test program that you control completely so you can verify your expectations first? – Kerrek SB May 07 '17 at 22:14
  • It doesn't execute the command. I pass the command and params and the execv should repeat the command using params passed to the main – Federico Zucchi May 07 '17 at 22:17
  • What is `argv[2]` for? Either you will get an error from `printf` or you fail to pass the argument along with the command `argv[1]`. – Weather Vane May 07 '17 at 22:25
  • The third argument of the main arguments. – Federico Zucchi May 07 '17 at 22:26
  • What output do you get? You say it "doesn't work", but you don't tell us what happens! Does it output anything? – David Schwartz May 07 '17 at 22:37
  • 1
    It seems to use the command, for example cp, as the first argument of cp itself – Federico Zucchi May 07 '17 at 22:42
  • Ah I didn't read the question properly. – Weather Vane May 07 '17 at 22:49
  • `execve(param,argv,NULL);` -->> `execve(param, argv+2,NULL);` – wildplasser May 07 '17 at 22:55
  • 1
    Note that `execve()` does no PATH-based search for the command to execute. If you don't have a binary `./cp` in your current directory, the command won't work because it can't find the executable. Not passing any environment is cruel and unusual punishment — though `cp` probably won't be adversely affected. Many other commands will be affected by no environment. You'd do better using `execv()` or `execvp()` — or even `execvpe()` if your platform supports it (Linux does; macOS and many other systems do not). – Jonathan Leffler May 07 '17 at 23:17

1 Answers1

1

This version is corrected:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc, char **argv)
{
int status;
pid_t pid;
if((pid = fork())>0)
{
    ///Father process
    wait(&status);
    printf("Process terminated with status = %d\n",status);
}
else
{
    ///son process
    int i;
    char program[100];

    printf("I'm the son woth PID= %d\n",getpid());
    strcpy(program,argv[1]);

    printf("Program: %s\n", program);

    execve(program, argv+1, NULL);
    exit(0);
}


return 0;
}

Example:

$ ./a.out /bin/cp a.txt b.txt
I'm the son woth PID= 1590
Program: /bin/cp
/bin/cp
a.txt
b.txt
Process terminated with status = 0

Example 2:

./a.out /bin/ls
I'm the son woth PID= 3021
Program: /bin/ls
/bin/ls
a.c a.out
Process terminated with status = 0

I've added #include <unistd.h> because I needed it.

I recommend you to do more printf in order to understand and troubleshoot.

Edit As @jonathan-leffler say, you can use execvp to be able to exec programs using PATH:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
int main(int argc, char **argv)
{
int status;
pid_t pid;
if((pid = fork())>0)
{
    ///Father process
    wait(&status);
    printf("Process terminated with status = %d\n",status);
}
else
{
    ///son process
    int i;
    char program[100];

    printf("I'm the son woth PID= %d\n",getpid());
    strcpy(program,argv[1]);

    printf("Program: %s\n", program);

    execvp(program, argv+1);
    exit(0);
}


return 0;
}

Example:

▶ ./a.out ls
I'm the son woth PID= 5056
Program: ls
a.c a.out
Process terminated with status = 0
Robert
  • 33,429
  • 8
  • 90
  • 94