I’m trying to execute this simple command ls -1 *.c using the execv() function.
#include<stdio.h>
#include<fcntl.h>
int main(int argc,char* argv[]){
char *arr[3]={"ls","-1","*.c"};
execv("/bin/ls",arr);
}
The output I’m getting is
ls: cannot access *.c: No such file or directory
Advertisement
Answer
There’s a big problem in your code: execv can’t tell how big the array you’re passing it is. You absolutely need a terminating NULL element to mark the end:
char *arr[] = { "ls", "-1", "*.c", NULL };
OK, now that we have a valid execv invocation, we can deal with the ls error.
Calling execv like this is equivalent to running
'ls' '-1' '*.c'
on the command line (which would produce the same error).
When you do
ls -1 *.c
on the command line, ls never sees *.c because the shell expands wildcards and passes a list of matching filenames to ls.
If you want to replicate that in your C code, you have to do the same thing manually. See e.g. man glob for a function that does most of the work. Here’s an adapted example from the man page that shows the general principle:
glob_t globbuf;
globbuf.gl_offs = 2;
glob("*.c", GLOB_DOOFFS, NULL, &globbuf);
globbuf.gl_pathv[0] = "ls";
globbuf.gl_pathv[1] = "-1";
execv("/bin/ls", globbuf.gl_pathv);