开发者

Custom shell glob problem

开发者 https://www.devze.com 2023-03-25 17:14 出处:网络
I have to write a shell program in c that doesn\'t use the system() function. One of the features is that we have to be able to use wild cards. I can\'t seem to find a good example of how to use glob

I have to write a shell program in c that doesn't use the system() function. One of the features is that we have to be able to use wild cards. I can't seem to find a good example of how to use glob or this fnmatch functions that I have been running into so I have been messing around and so far I have a some what working blog feature (depending on how I have arranged my code).

If I have a glob variable declared as a global then the function partially works. However any command afterwards produces in error. example:

ls *.c
produce correct results
ls -l //no glob required
null passed through

so I tried making it a local variable. This is my code right now:

int runCommand(commandStruct * command1) {
if(!globbing)
    execvp(command1->cmd_path, command1->argv);
else{
    glob_t globbuf;
    printf("globChar: %s\n", globChar);
    glob(globChar, GLOB_DOOFFS, NULL, &globbuf);
    //printf("globbuf.gl_pathv[0]: %s\n", &globbuf.gl_pathv[0]);
    execvp(command1->cmd_path, &globbuf.gl_pathv[0]);
    //globfree(&globbuf);
    globbing = 0;
}
return 1;

}

When doing t开发者_Python百科his with the globbuf as a local, it produces a null for globbuf.gl_path[0]. Can't seem to figure out why. Anyone with a knowledge of how glob works know what might be the cause? Can post more code if necessary but this is where the problem lies.


this works for me:

...
glob_t glob_buffer;
const char * pattern = "/tmp/*";
int i;
int match_count;


glob( pattern , 0 , NULL , &glob_buffer ); 
match_count = glob_buffer.gl_pathc;
printf("Number of mathces: %d \n", match_count);

for (i=0; i < match_count; i++) 
    printf("match[%d] = %s \n",i,glob_buffer.gl_pathv[i]);

globfree( &glob_buffer );
...

Observe that the execvp function expects the argument list to end with a NULL pointer, i.e. I think it will be the easiest to create your own char ** argv copy with all the elements from the glob_buffer.gl_pathv[] and a NULL pointer at the end.


You are asking for GLOB_DOOFFS but you did not specify any number in globbuf.gl_offs saying how many slots to reserve.

Presumably as a global variable it gets initialized to 0.

Also this: &globbuf.gl_pathv[0] can simply be globbuf.gl_pathv.

And don't forget to run globfree(globbuf).

I suggest running your program under valgrind because it probably has a number of memory leaks, and/or access to uninitialized memory.


If you don't have to use * style wildcards I've always found it simpler to use opendir(), readdir() and strcasestr(). opendir() opens a directory (can be ".") like a file, readdir() reads an entry from it, returns NULL at the end. So use it like

struct dirent *de = NULL;
DIR *dirp = opendir(".");
while ((de = readdir(dirp)) != NULL) {
  if ((strcasestr(de->d_name,".jpg") != NULL) {
  // do something with your JPEG
  }
}

Just remember to closedir() what you opendir(). A struct dirent has the d_type field if you want to use it, most files are type DT_REG (not dirs, pipes, symlinks, sockets, etc.).

It doesn't make a list like glob does, the directory is the list, you just use criteria to control what you select from it.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号