I'm trying to make a program that will prompt the user for a command, then use exec to execute that command.
For instance if they gave me "ls -la" I would have to execute that command. I've tried the following code:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int ret, num_args;
printf("Enter number of arguments (Example: \"ls -la\" has 1 argument): ");
scanf("%d", &num_args);
char *cmd[num_args];
printf("Enter command name: ");
scanf("%s", &cmd[0]);
int i;
for (i = 0; i < num_args; i++)
{
printf("Enter parameter: ");
scanf("%s", &cmd[i]);
}
execvp(cmd[0], cmd);
}
However, when I tried the following run it gave me a "segmentation fault"
$ ./a.out
Enter number of arguments (Example: "ls -la" has 1 argument): 2
Enter command name: ls
Enter parameter: -la
Enter parameter: .
Segmentation fault
$
Any ideas?
You need to allocate memory for your strings. The following line only allocates num_args
worth of pointers to char
:
char *cmd[num_args];
First of all, you'll be getting num_args + 1
strings (don't forget that the command itself is cmd[0]
). The easiest way is to statically allocate the memory as an array of character buffers:
const unsigned int MAX_LEN = 512; // Arbitrary number
char cmd[num_args + 1][MAX_LEN];
However, now you can't use scanf
to read in a line because the user could input a string that's longer than your character buffer. Instead, you'll have to use fgets
, which can limit the number of characters the user can input:
fgets(cmd[i], MAX_LEN, stdin);
Keep in mind that fgets
also reads newline characters, so make sure to strip any stray ones that show up (but don't assume that they're there).