10: сообщение об ошибке и возвращает состояние успеха, что позволяет glob()
11: продолжить работу. */
12: int errfn(const char * pathname, int theerr) {
13: fprintf(stderr, 'ошибка при доступе к %s: %s
', pathname,
14: strerror(theerr));
15:
16: /* Операция универсализации должна продолжаться, поэтому вернуть 0 */
17: return 0;
18: }
19:
20: int main(int argc, const char ** argv) {
21: glob_t result;
22: int i, rc, flags;
23:
24: if (argc < 2) {
25: printf('необходимо передать хотя бы один аргумент
') ;
26: return 1;
27: }
28:
29: /* установить flags в 0; позже он будет изменен на GLOB_APPEND */
30: flags = 0;
31:
32: /* совершить проход по всем аргументам командной строки */
33: for (i = 1; i < argc; i++) {
34: rc = glob(argv[i], flags, errfn, &result);
35:
36: /* благодаря errfn, GLOB_ABEND не происходит */
37: if (rc == GLOB_NOSPACE) {
38: fprintf(stderr, 'не хватает памяти для выполнения универсализации
');
39: return 1;
40: }
41:
42: flags |= GLOB_APPEND;
43: }
44:
45: if (!result.gl_pathc) {
46: fprintf(stderr, 'соответствий нет
');
47: rc = 1;
48: } else {
49: for (i = 0; i < result.gl_pathc; i++)
50: puts(result.gl_pathv[i]);
51: rc = 0;
52: }
53:
54: /* структура glob_t занимает память из пула malloc(),
55: которая должна быть освобождена */
56: globfree(&result);
57:
58: return rc;
59: }
14.6. Добавление к ladsh
возможностей работы с каталогами и универсализацией
Продолжим эволюцию ladsh
, добавив к ladsh3.с
четыре новых возможности.
1. Встроенная команда cd
для смены каталогов.
2. Встроенная команда pwd
для отображения текущего каталога.
3. Универсализация файловых имен.
4. Отображение ряда новых сообщений, позволяющее воспользоваться преимуществами strsignal()
. Эти изменения обсуждались в главе 12.
14.6.1. Добавление встроенных команд cd
и pwd
Добавление встроенных команд является прямым применением вызовов chdir()
и getcwd()
. Код соответствует runProgram()
как раз там, где обрабатываются другие встроенные команды. Ниже показан раздел обработки встроенных команд в ladsh3.с
.
422: if (!strcmp(newJob.progs[0].argv[0], 'exit')) {
423: /* здесь должен возвращаться реальный код завершения */
424: exit(0);
425: } else if (!strcmp(newJob.progs[0].argv[0], 'pwd')) {
426: len = 50;
427: buf = malloc(len);
428: while (!getcwd(buf, len) && errno == ERANGE) {
429: len += 50;
430: buf = realloc(buf, len);
431: }
432: printf('%s
', buf);
433: free(buf);
434: return 0;
435: } else if (!strcmp(newJob.progs[0].argv[0], 'cd')) {
436: if (!new Job.progs[0].argv[1] == 1)
437: newdir = getenv('HOME');
438: else
439: newdir = newJob.progs[0].argv[1];
440: if (chdir(newdir))
441: printf('сбой при смене текущего каталога: %s
',
442: strerror(errno));
443: return 0;
444: } else if (!strcmp(newJob.progs[0].argv[0], 'jobs')) {
445: for (job = jobList->head; job; job = job->next)