Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX β€” ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Π°Ρ срСда программирования». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 57

Автор Π‘Ρ€Π°ΠΉΠ°Π½ ΠšΠ΅Ρ€Π½ΠΈΠ³Π°Π½

 progname = argv[0];

 if (argc != 3)

  error("Usage: %s from to", progname);

 if ((f1 = open(argv[1], 0)) == -1)

  error("can't open %s", argv[1]);

 if ((f2 = creat(argv[2], PERMS)) == -1)

  error("can't create %s", argv[2]);

 while ((n = read(f1, buf, BUFSIZ)) > 0)

  if (write(f2, buf, n) != n)

 error("write error", (char*)0);

 exit(0);

}

error ΠΌΡ‹ обсудим Π½ΠΈΠΆΠ΅.

Число Ρ„Π°ΠΉΠ»ΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΎΠΉ, ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΎ (ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ порядка 20; см. NOFILE Π² <SYS/param.h>). ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ любая ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ прСдстоит ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»ΠΎΠ², Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ Π³ΠΎΡ‚ΠΎΠ²Π° Π½Π΅ΠΎΠ΄Π½ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΈ ΠΈ Ρ‚Π΅ ΠΆΠ΅ дСскрипторы Ρ„Π°ΠΉΠ»ΠΎΠ². БистСмный Π²Ρ‹Π·ΠΎΠ² close Ρ€Π°Π·Ρ€Ρ‹Π²Π°Π΅Ρ‚ связь ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΈΠΌΠ΅Π½Π΅ΠΌ ΠΈ дСскриптором Ρ„Π°ΠΉΠ»Π°, освобоТдая дСскриптор для использования с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π΄Ρ€ΡƒΠ³ΠΈΠΌ Ρ„Π°ΠΉΠ»ΠΎΠΌ. Π—Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ посрСдством exit ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ ΠΈΠ· основной ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π·Π°ΠΊΡ€Ρ‹Π²Π°ΡŽΡ‚ всС ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹. Π’Ρ‹Π·ΠΎΠ² систСмы unlink удаляСт Ρ„Π°ΠΉΠ» ΠΈΠ· Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмы.

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок: errno

ΠžΠ±ΡΡƒΠΆΠ΄Π°Π΅ΠΌΡ‹Π΅ здСсь систСмныС Π²Ρ‹Π·ΠΎΠ²Ρ‹, Π° ΠΏΠΎ сути всС систСмныС Π²Ρ‹Π·ΠΎΠ²Ρ‹, ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ошибки. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΎΠ½ΠΈ ΡΠΈΠ³Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ ΠΎΠ± ошибкС, возвращая Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ -1. Иногда ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π·Π½Π°Ρ‚ΡŒ, какая ΠΈΠΌΠ΅Π½Π½ΠΎ ошибка ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π°, поэтому систСмныС Π²Ρ‹Π·ΠΎΠ²Ρ‹, ΠΊΠΎΠ³Π΄Π° это ΠΏΡ€ΠΈΠ΅ΠΌΠ»Π΅ΠΌΠΎ, ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Π½ΠΎΠΌΠ΅Ρ€ ошибки Π²ΠΎ внСшнСй Ρ†Π΅Π»ΠΎΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠΉ errno. (Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Π½ΠΎΠΌΠ΅Ρ€ΠΎΠ² ошибок ΠΎΠ±ΡŠΡΡΠ½ΡΠ΅Ρ‚ΡΡ Π²ΠΎ Π²Π²Π΅Π΄Π΅Π½ΠΈΠΈ ΠΊ Ρ€Π°Π·Π΄. 2 справочного руководства ΠΏΠΎ UNIX.) Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ errno ваша ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‡Π΅ΠΌ Π²Ρ‹Π·Π²Π°Π½Π° Π½Π΅ΡƒΠ΄Π°Ρ‡Π° ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ Ρ„Π°ΠΉΠ»Π° β€” Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ сущСствуСт, ΠΈΠ»ΠΈ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Ρƒ вас Π½Π΅Ρ‚ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π½Π° Π΅Π³ΠΎ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Π΅ΡΡ‚ΡŒ массив ΡΠΈΠΌΠ²ΠΎΠ»ΡŒΠ½Ρ‹Ρ… строк sys_errlist, индСксируСмый errno, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ число Π² строку, ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‰ΡƒΡŽ смысл ошибки. Наша вСрсия error ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ эти структуры Π΄Π°Π½Π½Ρ‹Ρ…:

error(s1, s2) /* print error message and die */

 char *s1, *s2;

{

 extern int errno, sys_nerr;

 extern char *sys_errlist[], *progname;


 if (progname)

  fprintf(stderr, "%s: ", progname);

 fprintf(stderr, s1, s2);

 if (errno > 0 && errno < sys_nerr)

  fprintf (stderr, " (%s)", sys_errlist[errno]);

 fprintf(stderr, "\n");

 exit(1);

}

Errno ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎ Ρ€Π°Π²Π½Π° Π½ΡƒΠ»ΡŽ ΠΈ всСгда Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ мСньшС, Ρ‡Π΅ΠΌ sys_herr. Она Π½Π΅ становится Π½ΡƒΠ»Π΅Π²ΠΎΠΉ вновь ΠΏΡ€ΠΈ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠΉ Ρ€Π°Π±ΠΎΡ‚Π΅, поэтому Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠ±Π½ΡƒΠ»ΡΡ‚ΡŒ Π΅Π΅ послС ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ошибки, Ссли ваша ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Ρ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ. БообщСния ΠΎΠ± ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ… Π² нашСй вСрсии cp ΠΏΠΎΡΠ²Π»ΡΡŽΡ‚ΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

$ cp foo bar

cp: can't open foo       (НСт Ρ‚Π°ΠΊΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° ΠΈΠ»ΠΈ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°)

$ date >foo; chmod 0 foo Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ Π½Π΅Ρ‡ΠΈΡ‚Π°Π΅ΠΌΡ‹ΠΉ Ρ„Π°ΠΉΠ»

$ cp too bar

cp: can't open foo       (Π’ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΈ ΠΎΡ‚ΠΊΠ°Π·Π°Π½ΠΎ)

$

ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ доступ: lseek

Π€Π°ΠΉΠ» Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π° ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ: ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ read ΠΈΠ»ΠΈ write Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ мСсто Π² Ρ„Π°ΠΉΠ»Π΅ нСпосрСдствСнно послС использованного ΠΏΡ€ΠΈ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅. Однако ΠΏΡ€ΠΈ нСобходимости Ρ„Π°ΠΉΠ» ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½ ΠΈΠ»ΠΈ записан Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠΌ порядкС. БистСмный Π²Ρ‹Π·ΠΎΠ² lseek позволяСт ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒΡΡ ΠΏΠΎ Ρ„Π°ΠΉΠ»Ρƒ, Π½Π΅ осущСствляя Π½ΠΈ чтСния, Π½ΠΈ записи:

int fd, origin;

long offset, pos, lseek();


pos = lseek(fd, offset, origin);

ВСкущая позиция Π² Ρ„Π°ΠΉΠ»Π΅ с дСскриптором fd пСрСмСщаСтся ΠΊ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ offset, которая отсчитываСтся ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ мСста, опрСдСляСмого origin. ΠŸΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ процСссы чтСния ΠΈΠ»ΠΈ записи Π±ΡƒΠ΄ΡƒΡ‚ Π½Π°Ρ‡ΠΈΠ½Π°Ρ‚ΡŒΡΡ с этой ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ. Origin ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ значСния 0, 1, 2, задавая Ρ‚Π΅ΠΌ самым Π½Π°Ρ‡Π°Π»ΠΎ отсчСта значСния offset β€” ΠΎΡ‚ Π½Π°Ρ‡Π°Π»Π°, ΠΎΡ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ»ΠΈ ΠΎΡ‚ ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π° соотвСтствСнно.

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π΅ΡΡ‚ΡŒ новая Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½Π°Ρ позиция ΠΈΠ»ΠΈ -1 ΠΏΡ€ΠΈ ошибкС. НапримСр, ΠΏΡ€ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π² Ρ„Π°ΠΉΠ» Π½ΡƒΠΆΠ½ΠΎ Π΄ΠΎΠΉΡ‚ΠΈ Π΄ΠΎ Π΅Π³ΠΎ ΠΊΠΎΠ½Ρ†Π°, Π° Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ запись:

lseek(fd, 0L, 2);

Π§Ρ‚ΠΎΠ±Ρ‹ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΊ Π½Π°Ρ‡Π°Π»Ρƒ ("ΠΏΠ΅Ρ€Π΅ΠΌΠΎΡ‚Π°Ρ‚ΡŒ"), Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ

lseek(fd, 0L, 0);

Для опрСдСлСния Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ слСдуСт Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ

pos = lseek(fd, 0L, 1);

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ 0L: смСщСниС Π΅ΡΡ‚ΡŒ Π΄Π»ΠΈΠ½Π½ΠΎΠ΅ Ρ†Π΅Π»ΠΎΠ΅. ('l' Π² lseek ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚ 'long' β€” Π΄Π»ΠΈΠ½Π½Ρ‹ΠΉ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΎΡ‚ систСмного Π²Ρ‹Π·ΠΎΠ²Π° seek Π² ΡˆΠ΅ΡΡ‚ΠΎΠΉ вСрсии, Π³Π΄Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΠ΅ Ρ†Π΅Π»Ρ‹Π΅.)

Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ lseek ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ ΠΊΠ°ΠΊ с большими массивами, ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΏΡ€ΠΈ этом врСмя доступа ΠΊ Π½ΠΈΠΌ возрастаСт. НапримСр, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ функция Ρ‡ΠΈΡ‚Π°Π΅Ρ‚ любоС число Π±Π°ΠΉΡ‚ΠΎΠ² ΠΈΠ· любого мСста Π² Ρ„Π°ΠΉΠ»Π΅:

get(fd, pos, buf, n) /* read n bytes from position pos */

 int fd, n;

 long pos;

 char *buf;

{

 if (lseek(fd, pos, 0) == -1) /* get to pos */

  return -1;

 return read(fd, buf, n);

}

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 7.3

ΠœΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠΉΡ‚Π΅ readslow Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ имя Ρ„Π°ΠΉΠ»Π° Π² качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°, Ссли ΠΎΠ½ΠΎ присутствуСт. Π”ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ -Π΅:

$ readslow -Π΅

заставляСт readslow ΠΈΡΠΊΠ°Ρ‚ΡŒ ΠΊΠΎΠ½Π΅Ρ† Π²Ρ…ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Π½Π°Ρ‡Π°Ρ‚ΡŒ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅. ΠšΠ°ΠΊΠΎΠ²Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ lseek ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΌ ΠΊΠ°Π½Π°Π»ΠΎΠΌ?

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 7.4

ΠŸΠ΅Ρ€Π΅ΠΏΠΈΡˆΠΈΡ‚Π΅ efopen ΠΈΠ· Π³Π». 6, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ error.

7.2 Ѐайловая систСма: ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ

Наша ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ Ρ‚Π΅ΠΌΠ° β€” ΠΊΠ°ΠΊ ΠΎΡ€ΠΈΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² ΠΈΠ΅Ρ€Π°Ρ€Ρ…ΠΈΠΈ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ². ΠŸΡ€ΠΈ этом ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ Π½ΠΎΠ²Ρ‹Π΅ систСмныС Π²Ρ‹Π·ΠΎΠ²Ρ‹, Π° лишь нСсколько старых Π² Π½ΠΎΠ²ΠΎΠΌ контСкстС. Π’ качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ spname, которая пытаСтся ΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒΡΡ с Π½Π΅Π²Π΅Ρ€Π½ΠΎ написанными ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ². Ѐункция

n = spname(name, newname);

ΠΈΡ‰Π΅Ρ‚ Ρ„Π°ΠΉΠ» с ΠΈΠΌΠ΅Π½Π΅ΠΌ, "достаточно Π±Π»ΠΈΠ·ΠΊΠΈΠΌ" ΠΊ name. Если Ρ‚Π°ΠΊΠΎΠ΅ имя Π½Π°ΠΉΠ΄Π΅Π½ΠΎ, ΠΎΠ½ΠΎ копируСтся Π² newname. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ n, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ spname, Ρ€Π°Π²Π½ΠΎ -1, Ссли Π½ΠΈΡ‡Π΅Π³ΠΎ достаточно Π±Π»ΠΈΠ·ΠΊΠΎΠ³ΠΎ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½ΠΎ, 0 β€” ΠΏΡ€ΠΈ Ρ‚ΠΎΡ‡Π½ΠΎΠΌ совпадСнии ΠΈ 1, Ссли Π±Ρ‹Π»Π° сдСлана коррСкция.

Spname являСтся ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΌ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ ΠΊ ΠΊΠΎΠΌΠ°Π½Π΄Π΅ p: Ссли Π²Ρ‹ ΠΏΡ‹Ρ‚Π°Π΅Ρ‚Π΅ΡΡŒ ΠΏΠ΅Ρ‡Π°Ρ‚Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ», Π½ΠΎ Π½Π΅Π²Π΅Ρ€Π½ΠΎ написали имя, p спросит вас, Π½Π΅ ΠΈΠΌΠ΅Π»ΠΈ Π»ΠΈ Π²Ρ‹ Π² Π²ΠΈΠ΄Ρƒ Ρ‡Ρ‚ΠΎ-Π»ΠΈΠ±ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠ΅:

$ p /urs/srx/ccmd/p/spnam.с  ΠžΡ‡Π΅Π½ΡŒ ΠΏΠ»ΠΎΡ…ΠΎΠ΅ имя

"/usr/src/cmd/p/spname.с"? y ΠŸΡ€Π΅Π΄Π»ΠΎΠΆΠ΅Π½Π½Π°Ρ коррСкция принята


/* spname: Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π²Π΅Ρ€Π½ΠΎ написанноС имя Ρ„Π°ΠΉΠ»Π° */

...

Пока ΠΌΡ‹ пишСм имя Ρ„Π°ΠΉΠ»Π°, spname пытаСтся ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ Π΅Π³ΠΎ ΡΠΎΡΡ‚Π°Π²Π½ΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ нСсовпавшая Π±ΡƒΠΊΠ²Π° Π±Ρ‹Π»Π° ΠΎΠΏΡƒΡ‰Π΅Π½Π°, оказалась лишнСй, просто Π½Π΅Π²Π΅Ρ€Π½Π° ΠΈΠ»ΠΈ помСнялась мСстами с Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π±ΡƒΠΊΠ²ΠΎΠΉ. Π­Ρ‚ΠΎ ΡƒΠ΄ΠΎΠ±Π½ΠΎΠ΅ срСдство рассчитано Π½Π° Ρ‚ΠΎΠ³ΠΎ, ΠΊΡ‚ΠΎ ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π΅Ρ‚ Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½ΠΎ.

ΠŸΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, умСстно ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΠΉ ΠΎΠ±Π·ΠΎΡ€ структуры Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмы. ΠšΠ°Ρ‚Π°Π»ΠΎΠ³ прСдставляСт собой Ρ„Π°ΠΉΠ», содСрТащий список ΠΈΠΌΠ΅Π½ Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈ ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅, Π³Π΄Π΅ ΠΎΠ½ΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Ρ‹. ΠœΠ΅ΡΡ‚ΠΎ размСщСния опрСдСляСтся индСксом Π² Ρ‚Π°ΠΊ Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΠΎΠΉ индСксной Ρ‚Π°Π±Π»ΠΈΡ†Π΅ Ρ„Π°ΠΉΠ»ΠΎΠ². Π’ записи индСксной Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹ содСрТится вся информация ΠΎ Ρ„Π°ΠΉΠ»Π΅, ΠΊΡ€ΠΎΠΌΠ΅ Π΅Π³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ. Π‘Ρ‚Ρ€ΠΎΠΊΠ° ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°, Ρ‚Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, состоит ΠΈΠ· Π΄Π²ΡƒΡ… элСмСнтов β€” индСкса Ρ„Π°ΠΉΠ»Π° ΠΈ Π΅Π³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ. Π’ΠΎΡ‡Π½ΠΎΠ΅ описаниС ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π² Ρ„Π°ΠΉΠ»Π΅ <sys/dir.h>:

$ cat /usr/include/sys/dir.h

#define DIRSIZ 14 /* максимальная Π΄Π»ΠΈΠ½Π° ΠΈΠΌΠ΅Π½ΠΈ Ρ„Π°ΠΉΠ»Π° */


struct direct /* структура строки ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° */

{

 ino_t d_ino; /* Π½ΠΎΠΌΠ΅Ρ€ индСксного дСскриптора */

 char d_name[DIRSIZ]; /* имя Ρ„Π°ΠΉΠ»Π° */

};

$

"Π’ΠΈΠΏ" ino_t это typedef, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠΉ индСкс Π² индСксной Ρ‚Π°Π±Π»ΠΈΡ†Π΅. Он являСтся ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΠΌ Ρ†Π΅Π»Ρ‹ΠΌ Π±Π΅Π· Π·Π½Π°ΠΊΠ° (unsigned short) Π² вСрсиях систСмы для PDP-11 ΠΈ VAX ΠΈ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒΡΡ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ½Ρ‹ΠΌ Π½Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ машинС. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΌΡ‹ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ Ρ‚ΠΈΠΏΠ° typedef. ΠŸΠΎΠ»Π½Ρ‹ΠΉ Π½Π°Π±ΠΎΡ€ "систСмных" Ρ‚ΠΈΠΏΠΎΠ² находится Π² <sys/types.h>, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ Π΄ΠΎ <sys/dir.h>.

ДСйствия spname достаточно прямолинСйны, хотя ΠΈ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ выполнСния Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π³Ρ€Π°Π½ΠΈΡ‡Π½Ρ‹Ρ… условий. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ имя Ρ„Π°ΠΉΠ»Π° /d1/d2/f. Основная идСя состоит Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ: ΠΎΡ‚Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ (/), Π½Π°ΠΉΡ‚ΠΈ Π² ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅ имя, Π±Π»ΠΈΠ·ΠΊΠΎΠ΅ ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π΅ (d1), Π·Π°Ρ‚Π΅ΠΌ Π½Π°ΠΉΡ‚ΠΈ имя, Π±Π»ΠΈΠ·ΠΊΠΎΠ΅ ΠΊ d2, ΠΈ Ρ‚.Π΄. Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ достигнуто ΠΏΠΎΠ»Π½ΠΎΠ΅ совпадСниС для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ составной части. Если Π½Π° ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ стадии Π² ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅ Π½Π΅ окаТСтся подходящСго ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ‚Π°, поиск прСкратится.

ΠœΡ‹ Ρ€Π°Π·Π±ΠΈΠ»ΠΈ процСсс Π½Π° Ρ‚Ρ€ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π‘Π°ΠΌΠ° spname выдСляСт ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΏΡƒΡ‚ΠΈ ΠΈ составляСт ΠΈΠ· Π½ΠΈΡ… имя Ρ„Π°ΠΉΠ»Π°, Π½Π°ΠΈΠ»ΡƒΡ‡ΡˆΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‰Π΅Π΅ с исходным. Ѐункция mindist ΠΈΡ‰Π΅Ρ‚ Π² Π΄Π°Π½Π½ΠΎΠΌ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅ Ρ„Π°ΠΉΠ» с ΠΈΠΌΠ΅Π½Π΅ΠΌ, блиТайшим ΠΊ составлСнному Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ spname. Ѐункция spdist вычисляСт "расстояниС" ΠΌΠ΅ΠΆΠ΄Ρƒ двумя ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ.

/* spname: return correctly spelled filename */

/*

 * spname(oldname, newname) char *oldname, *newname;

 * returns -1 if no reasonable match to oldname,

 * 0 if exact match,

 *1 if corrected.

 * stores corrected name in newname.

 */

#include <sys/types.h>

#include <sys/dir.h>


spname(oldname, newname)

 char *oldname, *newname;

{