2

I am using execvp for execing a new process for the command grep -l night *. Here is my code:

char * argument[5];
char keyword[] = "night";

argument[0] = (char *) malloc (sizeof(char)*25);
argument[1] = (char *) malloc (sizeof(char)*25);
argument[2] = (char *) malloc (sizeof(char)*25);
argument[3] = (char *) malloc (sizeof(char)*25);
argument[4] = (char *) malloc (sizeof(char)*25);

argument[0] = "grep";
argument[1] = "-l";
strcpy(argument[2],keyword);
argument[3] = "*";
argument[4] = NULL;

execvp ("grep", argument);

But I am getting the output from this program as "grep: *: No such file or directory" which is incorrect as executing the same command from the shell results in the list of files which contain the text "night". I do suspect that the * in the command list is being sent as a string with quotes to exec. Is my assumption correct? If so how can I rectify this problem? Any help would be highly appreciated.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
sragvuw
  • 33
  • 5
  • 1
    Notice that your code is leaking memory; you allocate space, but then you ignore the allocated space with the assignments. You have to use `strcpy()` or something similar to use the allocated memory. Of course, there's no great harm done; the `execvp()` will clean up for you, and the exit that occurs after it if the command fails altogether also cleans up. But don't get into the habit of throwing memory away as you do - it will hurt you in due course. – Jonathan Leffler Mar 09 '12 at 06:32

1 Answers1

2

Grep does not understand the "*" argument. Usually the shell expands such arguments (it's called globbing). Of course, since exec functions don't start a shell, you don't get that functionality.

You can:

  • Use functions which do start a shell (system(3), popen(3))
  • Use glob(3), essentially doing the shells job

EDIT

You could probably write it as this (untested):

glob_t globbuf;
globbuf.gl_offs = 3;

/* Globbing magic. */
glob("*", GLOB_DOOFFS, NULL, &globbuf);

/* That's what the 3 was for. */
globbuf.gl_pathv[0] = "grep";
globbuf.gl_pathv[1] = "-l";
globbuf.gl_pathv[2] = "night";

/* Conveniently, the list is NULL-terminated. */
execvp("grep", globbuf.gl_pathv);
Community
  • 1
  • 1
cnicutar
  • 178,505
  • 25
  • 365
  • 392