My program has a variable number of args and I need to make an execv
with a new path, so I want to change the value of argv[1]
in a different variable without changing it, but it won't let me.
char** arg_exec = malloc(argc * sizeof (char*));
int i;
for(i=0;i <= argc-1; i++)
arg_exec[i] = strdup(argv[i]);
arg_exec[argc] = NULL;
if( (pid = fork()) == 0){
arg_exec[1] = strcat(directory , dir_info->d_name); //some variables with the current path and a name
execv(arg_exec[0], arg_exec);
printf("Error in process %d\n", getpid());
return 1;
}
but after it runs this line arg_exec[1] = strcat(directory , dir_info->d_name);
it changes my value of argv[1], and my program fails..
It worked fine with execl
, since it was like execl(argv[0],strcat(directory , dir_info->d_name), ..., NULL);
but because I have a variable number of arguments to run it, it wouldn't be good to implement that way.
Edit1: Added NULL
at the end of the array
Edit2: I'm doing a version of the find
, so strcat will add to the current directory a folder to look into.
This is the initalization of the directory:
char *directory = strcat(argv[1],"/");
char *directory = strcat(argv[1],"/");
attemps to modify argv[1]
beyond its allocation, which is UB. @alk.
Modifying argv
itself may be UB. Is argv[n] writable?
So allocate memory for both.
Note: char** arg_exec = malloc(argc * sizeof (char*));
is insufficient as argv[argc]
must be NULL
. Need 1 more. Notice argc
is not passed to execv()
.
Step 1. Make a copy of the pointer array argv[]
char **argv_new;
size_t a_size = sizeof *argv_new * (argc + 1); // + 1 for the final NULL
argv_new = malloc(a_size);
memcpy(argv_new, argv, a_size);
Step 2. Form the new arg[1]
int size = 1 + snprintf(NULL, 0, "%s/%s", argv[1], dir_info->d_name);
argv_new[1] = malloc(size);
snprintf(argv_new[1], size, "%s/%s", argv[1], dir_info->d_name);
Use it
execv(arg_new[0], arg_new);
free(argv_new[1]);
free(argv_new);
TBD: Error checking to add for: argc > 1, malloc(), snprintf(), execv()