Проблема нестабильности оболочки - PullRequest
0 голосов
/ 03 августа 2011

Мне нужно написать программу на языке c, чтобы не использовал функцию system (). Одна из особенностей заключается в том, что мы должны иметь возможность использовать подстановочные знаки. Кажется, я не могу найти хороший пример того, как использовать функции glob или fnmatch, с которыми я сталкивался, поэтому я возился и пока у меня есть кое-какая работающая функция блога (в зависимости от того, как я организовал свой код).

Если у меня есть переменная glob, объявленная как глобальная, то функция частично работает. Однако любая команда впоследствии выдает ошибку. Пример:

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

поэтому я попытался сделать его локальной переменной. Это мой код прямо сейчас:

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;

}

Когда вы делаете это с globbuf как локальным, он выдает null для globbuf.gl_path [0]. Не могу понять почему. Любой, кто знает, как работает глобус, знает, что может быть причиной? При необходимости может опубликовать больше кода, но именно в этом проблема.

Ответы [ 3 ]

1 голос
/ 03 августа 2011

это работает для меня:

...
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 );
...

Заметьте, что функция execvp ожидает, что список аргументов заканчивается указателем NULL, т.е. я думаю, что будет проще всего создать свой собственный char ** argvскопируйте все элементы из glob_buffer.gl_pathv[] и указатель NULL в конце.

1 голос
/ 03 августа 2011

Вы запрашиваете GLOB_DOOFFS, но в globbuf.gl_offs вы не указали ни одного числа, указывающего, сколько слотов нужно резервировать.

Предположительно, как глобальная переменная, она инициализируется значением 0.

Также это: &globbuf.gl_pathv[0] может быть просто globbuf.gl_pathv.

И не забудьте запустить globfree(globbuf).

Я предлагаю запустить вашу программу под valgrind, потому что она, вероятно, имеет ряд утечек памяти и / или доступ к неинициализированной памяти.

0 голосов
/ 20 июня 2018

Если вам не нужно использовать подстановочные знаки стиля *, мне всегда было проще использовать opendir (), readdir () и strcasestr ().opendir () открывает каталог (может быть ".") как файл, readdir () читает запись из него, возвращает NULL в конце.Так что используйте это как

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

Просто запомните closedir (), что вы opendir ().Структура struct имеет поле d_type, если вы хотите его использовать, большинство файлов имеют тип DT_REG (не каталоги, каналы, символические ссылки, сокеты и т.каталог - это список, вы просто используете критерии для управления тем, что вы выбираете из него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...