Рейтинговые книги
Читем онлайн Разработка приложений в среде Linux. Второе издание - Майкл Джонсон

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 39 40 41 42 43 44 45 46 47 ... 150

44:   if (flags & EXT3_APPEND_FL) printf("Append");

45:   if (flags & EXT3_IMMUTABLE_FL) printf("Immutable");

46:   if (flags & EXT3_SYNC_FL) printf("Sync");

47:   if (flags & EXT3_NODUMP_FL) printf("Nodump");

48:

49:   printf("n");

50:   close(fd);

51:  }

52:

53:  return 0;

54: }

Ниже приведена похожая программа, которая устанавливает расширенные атрибуты ext3 для указанного списка файлов. Первый параметр должен быть списком флагов, которые нужно установить. Каждый флаг представляется в списке в виде одной буквы: А — только для добавления (append only), I — неизменяемый (immutable), S — синхронизированный (sync), N — недампированный (nodump). Эта программа не модифицирует существующие флаги файла; она только устанавливает флаги, переданные в командной строке.

 1: /* setflags.c */

 2:

 3: /* Первый параметр этой программы — строка, состоящая из

 4:    0 (допускается пустая) или более букв из набора I, A, S,

 5:    N. Эта строка указывает, какие из атрибутов ext3 должны

 6:    быть включены для файлов, указанных в остальных

 7:    параметрах командной строки — остальные атрибуты выключаются

 8:    буквы обозначают соответственно: immutable, append-only, sync и nodump.

 9:

10:    Например, команда "setflags IN file1, file2" включает

11:    флаги immutable и nodump для файлов file1 и file2, но отключает

12:    флаги sync и append-only для этих файлов. */

13:

14: #include <errno.h>

15: #include <fcntl.h>

16: #include <linux/ext3_fs.h>

17: #include <stdio.h>

18: #include <string.h>

19: #include <sys/ioctl.h>

20: #include <unistd.h>

21:

22: int main(int argc, const char **argv) {

23:  const char **filename = argv + 1;

24:  int fd;

25:  int flags = 0;

26:

27:  /* Убедиться, что указаны устанавливаемые флаги, вместе

28:     с именами файлов. Позволить установить "0", как признак

29:     того, что все флаги должны быть сброшены. */

30:  if (argc<3){

31:   fprintf(stderr, "Использование setflags: [0][I][A][S][N]"

32:    "<filenames>n");

33:   return 1;

34:  }

35:

36:  /* каждая буква представляет флаг; установить

37:     флаг, которые указаны */

38:  if (strchr(argv[1], 'I') ) flags |= EXT3_IMMUTABLE_FL;

39:  if (strchr(argv[1], 'A') ) flags |= EXT3_APPEND_FL;

40:  if (strchr(argv[1], 'S') ) flags |= EXT3_SYNC_FL;

41:  if (strchr(argv[1], 'N') ) flags |= EXT3_NODUMP_FL;

42:

43:  /* пройти по всем именам в argv[] */

44:  while (*(++filename)) {

45:   /* В отличие от нормальных атрибутов, атрибута ext3 можно опрашивать,

46:      только если есть файловый дескриптор (имя файла не годится).

47:      Для выполнения запроса атрибутов ext3 нам не нужен доступ на запись,

48:      поэтому O_RDONLY подойдет. */

49:   fd = open(*filename, O_RDONLY);

50:   if (fd < 0) {

51:    fprintf(stderr, "невозможно открыть %s:%sn", *filename,

52:     strerror(errno));

53:    return 1;

54:   }

55:

56:   /* Установить атрибуты в соответствии с переданными

57:      флагами. */

58:   if (ioctl(fd, EXT3_IOC_SETFLAGS, &flags)) {

59:    fprintf(stderr, "Сбой ioctl в %s:%sn", *filename,

60:     strerror(errno));

61:    return 1;

62:   }

63:   close(fd);

64:  }

65:

66:  return 0;

67: }

11.4. Манипулирование содержимым каталогов

Вспомните, что компоненты каталогов (имена файлов) — это ни что иное, как указатели на дисковые информационные узлы (on-disk inodes); почти вся важная информация, касающаяся файла, хранится в его inode. Вызов open() позволяет процессу создавать компоненты каталогов, которые являются обычными файлами, но для создания файлов других типов и для манипулирования компонентами каталогов могут понадобиться другие функции. Функции, которые позволяют создавать, удалять и выполнять поиск каталогов, описаны в главе 14; файлы сокетов — в главе 17. В настоящем разделе раскрываются символические ссылки, файлы устройств и FIFO.

11.4.1. Создание входных точек устройств и именованных каналов

Процессы создают файлы устройств и именованных каналов в файловой системе с помощью вызова mknod().

#include <fcntl.h>

#include <unistd.h>

int mknod(const char *pathname, mode_t mode, dev_t dev);

pathname — это имя файла, который нужно создать, mode — это и режим доступа (который модифицируется текущим umask), и тип нового файла (S_IFIFO, S_IFBLK, S_IFCHR). Последний параметр, dev, содержит старший (major) и младший (minor) номера создаваемого устройства. Тип устройства (символьное или блочное) и старший номер устройства сообщают ядру, какой драйвер устройств отвечает за операции с этим файлом устройства. Младший номер используется внутри драйвером устройства, чтобы различать отдельные устройства среди многих, которыми он управляет. Только пользователю root разрешено создавать файлы устройств; именованные же каналы могут создавать все пользователи.

Заголовочный файл <sys/sysmacros.h> представляет три макроса для манипулирования значениями типа dev_t. Макрос makedev() принимает старшие номера в первом аргументе, младшие — во втором и возвращает значение dev_t, ожидаемое mknod(). Макросы major() и minor() принимают значение типа dev_t в качестве единственного аргумента и возвращают, соответственно, старший и младший номер устройства.

Программа mknod, доступная в Linux, предоставляет пользовательский интерфейс к системному вызову mknod() (подробности см. в man 1 mknod). Ниже приведена упрощенная реализация mknod для иллюстрации системного вызова mknod(). Следует отметить, что программа создает файл с режимом доступа 0666 (предоставляя право на чтение и запись всем пользователям) и зависит от системной установки umask процесса для получения прав доступа.

 1: /* mknod.с */

 2:

 3: /* Создать устройство или именованный канал, указанный в командной строке.

 4:    См. подробности о параметрах командной строки

 5:    на man-странице mknod(1). */

 6:

 7: #include <errno.h>

 8: #include <stdio.h>

 9: #include <stdlib.h>

10: #include <string.h>

11: #include <sys/stat.h>

12: #include <sys/sysmacros.h>

13: #include <unistd.h>

14:

15: void usage(void) {

16:  fprintf (stderr, "использование: mknod <путь> [b | с | u | p]"

17:   "<старший> <младший>n");

18:  exit(1);

19: }

20:

21: int main(int argc, const char **argv) {

22:  int major = 0, minor = 0;

23:  const char *path;

24:  int mode = 0666;

25:  char *end;

26:  int args;

27:

28:  /* Всегда необходимы, как минимум, тип создаваемого inode

29:     и путь к нему. */

30:  if (argc < 3) usage();

31:

32:  path = argv[1];

33:

34:  /* второй аргумент указывает тип создаваемого узла */

35:  if (!strcmp(argv[2], "b")) {

36:   mode | = S_IFBLK;

37:   args = 5;

38:  } else if (!strcmp(argv[2] , "с") || !strcmp(argv[2], "u")) {

39:   mode |= S_IFCHR;

40:   args = 5;

41:  } else if(!strcmp(argv[2], "p")) {

42:   mode |= S_IFIFO;

43:   args = 3;

44:  } else {

45:   fprintf(stderr, "неизвестный тип узла %sn", argv[2]);

46:   return 1;

47:  }

48:

49:  /* args сообщает, сколько аргументов ожидается, поскольку нам нужно

50:    больше информации при создания устройств, чем именованных каналов*/

51:  if (argc != args) usage();

52:

53:  if (args == 5) {

54:   /* получить старший и младший номера файла устройств,

55:      который нужно создать */

56:   major = strtol(argv[3], &end, 0);

57:   if (*end) {

58:    fprintf(stderr,"неверный старший номер %sn", argv[3]);

59:    return 1;

60:   }

61:

62:   minor = strtol(argv[4], &end, 0);

63:   if (*end) {

64:    fprintf(stderr, "неверный младший номер %sn", argv[4]);

65:    return 1;

66:   }

67:  }

68:

69:  /* если создается именованный канал, то финальный параметр

70:     игнорируется */

71:  if (mknod(path, mode, makedev(major, minor))) {

72:   fprintf(stderr, "вызов mknod не удался : %sn", strerror(errno));

1 ... 39 40 41 42 43 44 45 46 47 ... 150
На этой странице вы можете бесплатно читать книгу Разработка приложений в среде Linux. Второе издание - Майкл Джонсон бесплатно.
Похожие на Разработка приложений в среде Linux. Второе издание - Майкл Джонсон книги

Оставить комментарий