1

This program is called program.c. When I run ./program echo test, I would expect the program to print test, even if the command is run in a subshell. Why is the output an empty line? Does it have to do with filepath? When I try ./program /bin/echo test I still get an empty line output.

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

int function(char **argv) {
    execl("/bin/bash", "sh", "-c", *argv, argv, (char*)NULL);
}

int main(int argc, char **argv) {
    int return2;
    
    function(argv + 1);
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
JavaDumbell
  • 215
  • 2
  • 11
  • Maybe this helps: https://stackoverflow.com/questions/12596839/how-to-call-execl-in-c-with-the-proper-arguments – Jabberwocky Mar 15 '21 at 09:51

1 Answers1

5

There are two problems with your program.

The first problem is that the argument argv to execl() does not do what you think it does. The pointer argv is a pointer to a char * (i.e. a char **), and it is only permitted to pass a char * as an argument to execl(). That is, variable argument lists in C do not work how you are expecting them to.

In order to accomplish what you want, consider not using execl() and use execv() instead, passing an array of char *s which you have constructed yourself. You could do this in the following way, for example:

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

int function(char **argv) {
    // Consider passing `argc` as well to eliminate
    // the need for this loop.
    int len = 0;
    while(argv[len]) {
        len++;
    }
    
    char *new_argv[len + 3];
    new_argv[0] = "sh";
    new_argv[1] = "-c";
    for(int i = 0; i <= len; i++) {
        new_argv[i + 2] = argv[i];
    }
    
    execv("/bin/bash", new_argv);
}

int main(int argc, char **argv) {
     function(argv+1);
}

However, you still have a problem: ./program echo test will still print a blank line because if you execute sh -c echo test in a terminal you just get a blank line! In order to fix this, you need to do ./program 'echo test' (corresponding to sh -c 'echo test' at the terminal), which should then work.

Keeley Hoek
  • 543
  • 4
  • 18