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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ для Linux. ΠŸΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 43

Автор ΠœΠ°Ρ€ΠΊ ΠœΠΈΡ‚Ρ‡Π΅Π»Π»

Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π° strace ΠΏΠΎΠΊΠ°Π·Π°Π»Π° ΠΌΠ΅Ρ‚ΠΊΠΈ ΠΏΠΎΠ»Π΅ΠΉ структуры, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ хранятся Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹. Π­Ρ‚Π° структура заполняСтся Π² систСмном Π²Ρ‹Π·ΠΎΠ²Π΅: Linux ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π² ΠΏΠΎΠ»Π΅ sys имя ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы, Π° Π² ΠΏΠΎΠ»Π΅ node β€” имя ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°. Ѐункция uname() Π±ΡƒΠ΄Π΅Ρ‚ описана Π½ΠΈΠΆΠ΅, Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 8.15. "Ѐункция uname()".

БистСмный Π²Ρ‹Π·ΠΎΠ² write() Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ Π½Π° экран. ВспомнитС, Ρ‡Ρ‚ΠΎ дСскриптор 1 соотвСтствуСт стандартному Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ. Π’Ρ€Π΅Ρ‚ΠΈΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ β€” это количСство ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΡ‹Ρ… символов. Ѐункция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ число Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ записанных символов.

write(1, "myhostname\n", 11) = 11

Π­Ρ‚Π° строка ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΡ‚ΡŒΡΡ искаТСнной, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π²Ρ‹Π²ΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ hostname ΡΠΌΠ΅ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ с Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°ΠΌΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ strace. Если запускаСмая ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° создаСт слишком ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…, Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π²Ρ‹Π²ΠΎΠ΄ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ strace Π² Ρ„Π°ΠΉΠ» с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΡ†ΠΈΠΈ -ΠΎ имя_Ρ„Π°ΠΉΠ»Π°.

8.2. Ѐункция access(): ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΡ€Π°Π² доступа ΠΊ Ρ„Π°ΠΉΠ»Ρƒ

Ѐункция access() опрСдСляСт, ΠΈΠΌΠ΅Π΅Ρ‚ Π»ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ Π΅Π΅ процСсс ΠΏΡ€Π°Π²ΠΎ доступа ΠΊ Π·Π°Π΄Π°Π½Π½ΠΎΠΌΡƒ Ρ„Π°ΠΉΠ»Ρƒ. Ѐункция способна ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π»ΡŽΠ±ΡƒΡŽ ΠΊΠΎΠΌΠ±ΠΈΠ½Π°Ρ†ΠΈΡŽ ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΠΉ чтСния, записи ΠΈ выполнСния, Π° Ρ‚Π°ΠΊΠΆΠ΅ Ρ„Π°ΠΊΡ‚ сущСствования Ρ„Π°ΠΉΠ»Π°.

Ѐункция access() ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π΄Π²Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°: ΠΏΡƒΡ‚ΡŒ ΠΊ провСряСмому Ρ„Π°ΠΉΠ»Ρƒ ΠΈ Π±ΠΈΡ‚ΠΎΠ²ΠΎΠ΅ объСдинСниС Ρ„Π»Π°Π³ΠΎΠ² R_OK, W_OK ΠΈ X_OK, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΏΡ€Π°Π²Π°ΠΌ чтСния, записи ΠΈ выполнСния. ΠŸΡ€ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ Ρƒ процСсса всСх Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Ρ… ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΠΉ функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ 0. Если Ρ„Π°ΠΉΠ» сущСствуСт, Π° Π½ΡƒΠΆΠ½Ρ‹Π΅ ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΠΈ Π½Π° доступ ΠΊ Π½Π΅ΠΌΡƒ Ρƒ процСсса ΠΎΡ‚ΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚, возвращаСтся -1 ΠΈ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ errno записываСтся ΠΊΠΎΠ΄ ошибки EACCES (ΠΈΠ»ΠΈ EROFS, Ссли провСряСтся ΠΏΡ€Π°Π²ΠΎ записи Π² Ρ„Π°ΠΉΠ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ располоТСн Π² Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС, смонтированной Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния).

Если Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Ρ€Π°Π²Π΅Π½ F_OK, функция access() провСряСт лишь Ρ„Π°ΠΊΡ‚ сущСствования Ρ„Π°ΠΉΠ»Π°. Π’ случаС обнаруТСния Ρ„Π°ΠΉΠ»Π° возвращаСтся 0, ΠΈΠ½Π°Ρ‡Π΅ β€” -1 (Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ errno помСщаСтся Ρ‚Π°ΠΊΠΆΠ΅ ΠΊΠΎΠ΄ ошибки ENOENT). Когда ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ² Π½Π° ΠΏΡƒΡ‚ΠΈ ΠΊ Ρ„Π°ΠΉΠ»Ρƒ нСдоступСн, Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ errno Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠΌΠ΅Ρ‰Ρ‘Π½ ΠΊΠΎΠ΄ EACCES.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, показанная Π² листингС 8.1, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ access() провСряСт сущСствованиС Ρ„Π°ΠΉΠ»Π° ΠΈ опрСдСляСт, Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ Π»ΠΈ ΠΊ Π½Π΅ΠΌΡƒ доступ Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅/запись. Имя Ρ„Π°ΠΉΠ»Π° задаСтся Π² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строкС.

Листинг 8.1. (check-access.c) ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΡ€Π°Π² доступа ΠΊ Ρ„Π°ΠΉΠ»Ρƒ

#include <errno.h>

#include <stdio.h>

#include <unistd.h>


int main(int argc, char* argv[]) {

 char* path = argv[1];

 int rval;


 /* ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° сущСствования Ρ„Π°ΠΉΠ»Π°. */

 rval = access(path, F_OK);

 if (rval == 0)

  printf("%s exists\n", path);

 else {

  if (errno == ENOENT)

   printf("%s does not exist\n", path);

  else if (errno == EACCES)

   printf("%s is not accessible\n", path);

  return 0;

 }


 /* ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΡ€Π°Π²Π° доступа. */

 rval = access(path, R_OK);

 if (rval == 0)

  printf("%s is readable\n", path);

 else

  printf("%s is not readable (access denied)\n", path);


 /* ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° ΠΏΡ€Π°Π²Π° записи. */

 rval = access(path, W_OK);

 if (rval == 0)

  printf("%s is writable\n", path);

 else if (errno == EACCES)

  printf("%s is not writable (access denied)\n", path);

 else if (errno == EROFS)

  printf("%s is not writable (read-only filesystem)\n",

   path);

 return 0;

}

Π’ΠΎΡ‚ ΠΊΠ°ΠΊ, ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ ΠΏΡ€Π°Π²Π° доступа ΠΊ Ρ„Π°ΠΉΠ»Ρƒ README, располоТСнному Π½Π° ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚-дискС:

% ./check-access /mnt/cdrom/README

/mnt/cdrom/README exists

/mnt/cdrom/README is readable

/mnt/cdrom/README is not writable (read-only filesystem)

8.3. Ѐункция fcntl(): Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π°Π΄ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ

Ѐункция fcntl() β€” это Ρ‚ΠΎΡ‡ΠΊΠ° доступа ΠΊ нСскольким особым опСрациям Π½Π°Π΄ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ. ΠŸΠ΅Ρ€Π²Ρ‹ΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ являСтся дСскриптор Ρ„Π°ΠΉΠ»Π°, Π²Ρ‚ΠΎΡ€Ρ‹ΠΌ указываСтся ΠΊΠΎΠ΄ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. Для Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ трСбуСтся Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ, Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚. Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ описана Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ распространСнная опСрация, выполняСмая с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fcntl(): Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ².

Ѐункция fcntl() позволяСт ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π½Π° Ρ„Π°ΠΉΠ» Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ чтСния ΠΈΠ΄ΠΈ записи. Π­Ρ‚ΠΎ Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰ΠΈΡ… сСмафоров, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΠΈΡΡ‹Π²Π°Π»ΠΈΡΡŒ Π² Π³Π»Π°Π²Π΅ 5, "ВзаимодСйствиС процСссов". Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° чтСния ставится Π½Π° Ρ„Π°ΠΉΠ», доступный для чтСния. БоотвСтствСнно Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° записи ставится Π½Π° Ρ„Π°ΠΉΠ», доступный для записи. НСсколько процСссов ΠΌΠΎΠ³ΡƒΡ‚ ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ чтСния ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈ Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ Ρ„Π°ΠΉΠ»Π°, Π½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ процСссу Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΎ ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ записи. Π€Π°ΠΉΠ» Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ ΠΈ для чтСния, ΠΈ для записи. Π£Ρ‡Ρ‚ΠΈΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π½Π΅ ΠΌΠ΅ΡˆΠ°Π΅Ρ‚ Π΄Ρ€ΡƒΠ³ΠΈΠΌ процСссам ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ» ΠΈ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡ‚ΡŒ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅/запись Π΅Π³ΠΎ Π΄Π°Π½Π½Ρ‹Ρ…, Ссли Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ½ΠΈ сами Π½Π΅ ΠΏΠΎΠΏΡ‹Ρ‚Π°ΡŽΡ‚ΡΡ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ fcntl().

ΠŸΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ ΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ Π½Π° Ρ„Π°ΠΉΠ», Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΈ ΠΎΠ±Π½ΡƒΠ»ΠΈΡ‚ΡŒ структуру Ρ‚ΠΈΠΏΠ° flock. Π’ ΠΏΠΎΠ»Π΅ l_type Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ записана константа F_RDLCK Π² случаС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ чтСния ΠΈ константа F_WRLCK β€” Π² случаС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ записи. Π”Π°Π»Π΅Π΅ слСдуСт Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ fcntl(), ΠΏΠ΅Ρ€Π΅Π΄Π°Π² Π΅ΠΉ дСскриптор Ρ„Π°ΠΉΠ»Π°, ΠΊΠΎΠ΄ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ F_SETLCKW ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° структуру Ρ‚ΠΈΠΏΠ° flock. Если аналогичная Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° ΡƒΠΆΠ΅ Π±Ρ‹Π»Π° поставлСна Π΄Ρ€ΡƒΠ³ΠΈΠΌ процСссом, функция fcntl() ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Π΅Ρ‚ Π² Ρ€Π΅ΠΆΠΈΠΌ оТидания, ΠΏΠΎΠΊΠ° "ΠΌΠ΅ΡˆΠ°ΡŽΡ‰Π°Ρ" Π΅ΠΉ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ снята.

Π’ листингС 8.2 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, которая ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ для записи ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ», Π° Π·Π°Ρ‚Π΅ΠΌ ставит Π½Π° Π½Π΅Π³ΠΎ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ записи. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΆΠ΄Π΅Ρ‚ наТатия клавиши <Enter>, послС Ρ‡Π΅Π³ΠΎ снимаСт Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ ΠΈ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Ρ„Π°ΠΉΠ».

Листинг 8.2. (lock-file.c) Установка Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ записи с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fcntl()

#include <fcntl.h>

#include <stdio.h>

#include <string.h>

#include <unistd.h>


int main(int argc, char* argv[]) {

 char* file = argv[1];

 int fd;

 struct flock lock;


 printf("opening %s\n", file);

 /* ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π°. */

 fd = open(file, O_WRONLY);

 printf("locking\n");

 /* инициализация структуры flock. */

 memset(&lock, 0, sizeof(lock));

 lock.l_type = F_WRLCK;

 /* Установка Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ записи. */

 fcntl(fd, F_SETLKW, &lock);


 printf("locked; hit Enter to unlock... ");

 /* ОТиданиС наТатия клавиши <Enter>. */

 getchar();


 printf("unlocking\n");

 /* БнятиС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ. */

 lock.l_type = F_UNLCK;

 fcntl(fd, F_SETLKW, &lock);


 close(fd);

 return 0;

}

Π‘ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΈ запуститС Π΅Π΅ с ΠΊΠ°ΠΊΠΈΠΌ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ тСстовым Ρ„Π°ΠΉΠ»ΠΎΠΌ, скаТСм, /tmp/test-file:

% cc -o lock-file lock-file.с

% touch /tmp/test-file

% ./lock-file /tmp/test-file

opening /tmp/test-file

locking

locked; hit Enter to unlock...

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΎΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ ΠΈ Π²Ρ‹Π·ΠΎΠ²ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π΅Ρ‰Π΅ Ρ€Π°Π· с Ρ‚Π΅ΠΌ ΠΆΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠΌ:

% ./lock-file /tmp/test-file

opening /tmp/test-file

locking

ΠŸΡ‹Ρ‚Π°ΡΡΡŒ ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ Π½Π° Ρ„Π°ΠΉΠ», ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° сама окаТСтся Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΉ. Π’Π΅Ρ€Π½ΠΈΡ‚Π΅ΡΡŒ Π² ΠΏΠ΅Ρ€Π²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ ΠΈ Π½Π°ΠΆΠΌΠΈΡ‚Π΅ <Enter>:

unlocking

Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, запущСнная Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΌ ΠΎΠΊΠ½Π΅, Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ свою Ρ€Π°Π±ΠΎΡ‚Ρƒ. Если Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ функция fcntl() Π½Π΅ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠ»Π° Π² Ρ€Π΅ΠΆΠΈΠΌ оТидания Π² случаС, ΠΊΠΎΠ³Π΄Π° Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π·Π°Π΄Π°ΠΉΡ‚Π΅ Π² качСствС ΠΊΠΎΠ΄Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ константу F_SETLCK, Π° Π½Π΅ F_SETLKW. Если функция ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚, Ρ‡Ρ‚ΠΎ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌΡ‹ΠΉ Ρ„Π°ΠΉΠ» ΡƒΠΆΠ΅ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½, ΠΎΠ½Π° Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ Π²Π΅Ρ€Π½Π΅Ρ‚ -1.

Π’ Linux имССтся систСмный Π²Ρ‹Π·ΠΎΠ² flock(), Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ блокирования Ρ„Π°ΠΉΠ»Π°. Но Ρƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fcntl() Π΅ΡΡ‚ΡŒ большоС прСимущСство: ΠΎΠ½Π° Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΌΠΈ систСмами NFS[28] (ΠΏΡ€ΠΈ условии, Ρ‡Ρ‚ΠΎ сСрвСр NFS ΠΈΠΌΠ΅Π΅Ρ‚ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ нСдавнюю Π²Π΅Ρ€ΡΠΈΡŽ ΠΈ сконфигурирован ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ). Π’Π°ΠΊ Ρ‡Ρ‚ΠΎ. имСя доступ ΠΊ Π΄Π²ΡƒΠΌ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π°ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ½Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ ΠΎΠ΄Π½Ρƒ ΠΈ Ρ‚Ρƒ ΠΆΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ²ΡƒΡŽ систСму Ρ‡Π΅Ρ€Π΅Π· NFS, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΈΡ‚ΡŒ ΠΏΠΎΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ Π²Ρ‹ΡˆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π½Π° Π΄Π²ΡƒΡ… Ρ€Π°Π·Π½Ρ‹Ρ… ΠΌΠ°ΡˆΠΈΠ½Π°Ρ….

8.4. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ fsync() ΠΈ fdatasync(): очистка дисковых Π±ΡƒΡ„Π΅Ρ€ΠΎΠ²

Π’ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… систСм ΠΏΡ€ΠΈ записи Π² Ρ„Π°ΠΉΠ» Π΄Π°Π½Π½Ρ‹Π΅ Π½Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π½Π° диск Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ. ВмСсто этого опСрационная систСма ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ ΠΈΡ… Π² Ρ€Π΅Π·ΠΈΠ΄Π΅Π½Ρ‚Π½Ρ‹ΠΉ кэш-Π±ΡƒΡ„Π΅Ρ€ с Ρ†Π΅Π»ΡŒΡŽ сокращСния числа ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠΉ ΠΊ диску ΠΈ ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½ΠΈΡ опСративности ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Когда Π±ΡƒΡ„Π΅Ρ€ заполнится ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ ΠΊΠ°ΠΊΠΎΠ΅-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ событиС (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, истСчСт ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΠΊ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ), систСма Π·Π°ΠΏΠΈΡˆΠ΅Ρ‚ содСрТимоС Π±ΡƒΡ„Π΅Ρ€Π° Π½Π° диск Π² Ρ…ΠΎΠ΄Π΅ ΠΎΠ΄Π½ΠΎΠΉ Π½Π΅ΠΏΡ€Π΅Ρ€Ρ‹Π²Π½ΠΎΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ.

Π’ Linux Ρ‚ΠΎΠΆΠ΅ поддСрТиваСтся Ρ‚Π°ΠΊΠΎΠΉ Ρ‚ΠΈΠΏ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΎΠ½ способствуСт сущСствСнному ΠΏΠΎΠ²Ρ‹ΡˆΠ΅Π½ΠΈΡŽ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. Но ΠΎΠ½ ΠΆΠ΅ Π΄Π΅Π»Π°Π΅Ρ‚ Π½Π΅Π½Π°Π΄Π΅ΠΆΠ½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, зависящиС ΠΎΡ‚ цСлостности дисковых Π΄Π°Π½Π½Ρ‹Ρ…. Если систСма Π²Π½Π΅Π·Π°ΠΏΠ½ΠΎ Π²Ρ‹ΠΉΠ΄Π΅Ρ‚ ΠΈΠ· строя, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ вслСдствиС сбоя ядра ΠΈΠ»ΠΈ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ питания, Π»ΡŽΠ±Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, находящиСся Π² памяти ΠΈ Π΅Ρ‰Π΅ Π½Π΅ записанныС Π½Π° диск, Π±ΡƒΠ΄ΡƒΡ‚ потСряны.