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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π―Π·Ρ‹ΠΊ программирования Π‘ΠΈ. ИзданиС 3-Π΅, исправлСнноС». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 48

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

  error("cp: Π½Π΅ ΠΌΠΎΠ³Ρƒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡŒ Ρ„Π°ΠΉΠ» %s", argv[1]);

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

  error("cp: Π½Π΅ ΠΌΠΎΠ³Ρƒ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ» %s, Ρ€Π΅ΠΆΠΈΠΌ %03o", argv[2], PERMS);

 while ((n = read(f1, buf, BUFSIZ)) β€Ί 0)

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

   error ("cp: ошибка ΠΏΡ€ΠΈ записи Π² Ρ„Π°ΠΉΠ» %s", argv[2]);

 return 0;

}

Данная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° создаст Ρ„Π°ΠΉΠ» Π²Ρ‹Π²ΠΎΠ΄Π° с фиксированными ΠΏΡ€Π°Π²Π°ΠΌΠΈ доступа, опрСдСляСмыми ΠΊΠΎΠ΄ΠΎΠΌ 0666. Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ систСмного Π²Ρ‹Π·ΠΎΠ²Π° stat, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ описан Π² ΠΏΠ°Ρ€Π°Π³Ρ€Π°Ρ„Π΅ 8.6, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ Ρ€Π΅ΠΆΠΈΠΌ использования ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ Ρ„Π°ΠΉΠ»Π° ΠΈ Π·Π°Π΄Π°Ρ‚ΡŒ Ρ‚ΠΎΡ‚ ΠΆΠ΅ Ρ€Π΅ΠΆΠΈΠΌ для ΠΊΠΎΠΏΠΈΠΈ.

Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ функция error, вызываСмая с Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌ числом Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ², Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΌ ΠΏΠΎΡ…ΠΎΠΆΠ° Π½Π° printf. РСализация error ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚, ΠΊΠ°ΠΊ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌΠΈ сСмСйства printf. БиблиотСчная функция vprintf Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Π° printf, с Ρ‚ΠΎΠΉ лишь ΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΊΠΎΠΉ, Ρ‡Ρ‚ΠΎ пСрСмСнная Ρ‡Π°ΡΡ‚ΡŒ списка Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Π·Π°ΠΌΠ΅Π½Π΅Π½Π° Π² Π½Π΅ΠΉ ΠΎΠ΄Π½ΠΈΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ инициализируСтся макросом va_start. ΠŸΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΌ ΠΆΠ΅ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ соотносятся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ vfprinf с fprintf ΠΈ vsprintf с sprintf.

#include β€Ήstdio.hβ€Ί

#include β€Ήstdarg.hβ€Ί


/* error: ΠΏΠ΅Ρ‡Π°Ρ‚Π°Π΅Ρ‚ сообщСниС ΠΎΠ± ошибкС ΠΈ ΡƒΠΌΠΈΡ€Π°Π΅Ρ‚ */

void error(char *fmt, …) {

 va_list args;


 va_start(args, fmt);

 fprintf(stderr, "ошибка: ");

 vfprintf(stderr, fmt, args);

 fprintf(stderr, "\n");

 va_end(args);

 exit(1);

}

На количСство ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Ρ„Π°ΠΉΠ»ΠΎΠ² имССтся ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ (ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΡ… число колСблСтся ΠΎΠΊΠΎΠ»ΠΎ 20). ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ любая ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, которая намСрСваСтся Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с большим количСством Ρ„Π°ΠΉΠ»ΠΎΠ², Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ Π³ΠΎΡ‚ΠΎΠ²Π° ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… дСскрипторы. Ѐункция close(int fd) Ρ€Π°Π·Ρ€Ρ‹Π²Π°Π΅Ρ‚ связь ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΌ дСскриптором ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠΌ ΠΈ освобоТдаСт дСскриптор для Π΅Π³ΠΎ примСнСния с Π΄Ρ€ΡƒΠ³ΠΈΠΌ Ρ„Π°ΠΉΠ»ΠΎΠΌ. Она Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fclose с Ρ‚Π΅ΠΌ лишь Ρ€Π°Π·Π»ΠΈΡ‡ΠΈΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ очистки Π±ΡƒΡ„Π΅Ρ€Π° Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ‚. Π—Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ exit ΠΈΠ»ΠΈ return Π² Π³Π»Π°Π²Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ всС ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹.

Ѐункция unlink(char *name) удаляСт имя Ρ„Π°ΠΉΠ»Π° ΠΈΠ· Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмы. Она соотвСтствуСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ remove стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 8.1. ΠŸΠ΅Ρ€Π΅ΠΏΠΈΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ cat ΠΈΠ· Π³Π»Π°Π²Ρ‹ 7, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ read, write, open ΠΈ close. Π—Π°ΠΌΠ΅Π½ΠΈΡ‚Π΅ ΠΈΠΌΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ. ΠŸΠΎΡΠΊΡΠΏΠ΅Ρ€ΠΈΠΌΠ΅Π½Ρ‚ΠΈΡ€ΡƒΠΉΡ‚Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΡ€Π°Π²Π½ΠΈΡ‚ΡŒ быстродСйствиС Π΄Π²ΡƒΡ… вСрсий.

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

Π’Π²ΠΎΠ΄-Π²Ρ‹Π²ΠΎΠ΄ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π±Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ, Ρ‚. Π΅. каТдая новая опСрация чтСния-записи ΠΈΠΌΠ΅Π΅Ρ‚ Π΄Π΅Π»ΠΎ с ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ Ρ„Π°ΠΉΠ»Π°, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ Π·Π° Ρ‚ΠΎΠΉ, Ρ‡Ρ‚ΠΎ Π±Ρ‹Π»Π° Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ (чтСния-записи). ΠŸΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ, ΠΎΠ΄Π½Π°ΠΊΠΎ, Ρ„Π°ΠΉΠ» ΠΌΠΎΠΆΠ½ΠΎ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΈΠ»ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ΡŒ запись Π² Π½Π΅Π³ΠΎ Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠΌ порядкС. БистСмный Π²Ρ‹Π·ΠΎΠ² lseek прСдоставляСт способ ΠΏΠ΅Ρ€Π΅Π΄Π²ΠΈΠ³Π°Ρ‚ΡŒΡΡ ΠΏΠΎ Ρ„Π°ΠΉΠ»Ρƒ, Π½Π΅ читая ΠΈ Π½Π΅ записывая Π΄Π°Π½Π½Ρ‹Π΅. Π’Π°ΠΊ, функция

long lseek(int fd, long offset, int origin);

Π² Ρ„Π°ΠΉΠ»Π΅ с дСскриптором fd устанавливаСт Ρ‚Π΅ΠΊΡƒΡ‰ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ, смСщая Π΅Π΅ Π½Π° Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρƒ offset ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ мСста, Π·Π°Π΄Π°Π²Π°Π΅ΠΌΠΎΠ³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ origin. ЗначСния ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° origin 0, 1 ΠΈΠ»ΠΈ 2 ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ Π½Π° Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρƒ offset ΠΎΡ‚ΡΡ‚ΡƒΠΏΠ°ΡŽΡ‚ соотвСтствСнно ΠΎΡ‚ Π½Π°Ρ‡Π°Π»Π°, ΠΎΡ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ ΠΈΠ»ΠΈ ΠΎΡ‚ ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π°. НапримСр, Ссли трСбуСтся Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Ρ‡Ρ‚ΠΎ-Π»ΠΈΠ±ΠΎ Π² Ρ„Π°ΠΉΠ» (ΠΊΠΎΠ³Π΄Π° Π² ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΌ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ‚ΠΎΡ€Π΅ shell систСмы UNIX Π²Π²ΠΎΠ΄ ΠΏΠ΅Ρ€Π΅Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ β€Ίβ€Ί Π² Ρ„Π°ΠΉΠ» ΠΈΠ»ΠΈ ΠΊΠΎΠ³Π΄Π° Π² fopen Π·Π°Π΄Π°Π½ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ "a"), Ρ‚ΠΎ ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Ρ‡Ρ‚ΠΎ-Π»ΠΈΠ±ΠΎ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π½Π°ΠΉΡ‚ΠΈ ΠΊΠΎΠ½Π΅Ρ† Ρ„Π°ΠΉΠ»Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

lseek(fd, 0L, 2);

Π§Ρ‚ΠΎΠ±Ρ‹ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ Π½Π°Π·Π°Π΄, Π² Π½Π°Ρ‡Π°Π»ΠΎ Ρ„Π°ΠΉΠ»Π°, Π½Π°Π΄ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ

lseek(fd, 0L, 0);

Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ 0L: вмСсто 0L ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ (long)0 ΠΈΠ»ΠΈ, Ссли функция lseek Π΄ΠΎΠ»ΠΆΠ½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ объявлСна, просто 0. Благодаря lseek с Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ Π±ΡƒΠ΄Ρ‚ΠΎ это большиС массивы, ΠΏΡ€Π°Π²Π΄Π°, с Π·Π°ΠΌΠ΅Π΄Π»Π΅Π½Π½Ρ‹ΠΌ доступом. НапримСр, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ функция Ρ‡ΠΈΡ‚Π°Π΅Ρ‚ любоС число Π±Π°ΠΉΡ‚ΠΎΠ² ΠΈΠ· любого мСста Ρ„Π°ΠΉΠ»Π°. Она Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ число ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½Π½Ρ‹Ρ… Π±Π°ΠΉΡ‚ΠΎΠ² ΠΈΠ»ΠΈ -1 Π² случаС ошибки.

#include "syscalls.h"

/* get: Ρ‡ΠΈΡ‚Π°Π΅Ρ‚ n Π±Π°ΠΉΡ‚ ΠΈΠ· ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ pos */

int get(int fd, long pos, char *buf, int n)

{

 if (lseek(fd, pos, 0) β€Ί= 0) /* установка ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ */

  return read(fd, buf, n);

 else

 return -1;

}

Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ lseek Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ long ΠΈ являСтся Π½ΠΎΠ²ΠΎΠΉ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠ΅ΠΉ Π² Ρ„Π°ΠΉΠ»Π΅ ΠΈΠ»ΠΈ, Π² случаС ошибки, Ρ€Π°Π²Π½ΠΎ -1. Ѐункция fseek ΠΈΠ· стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Π° lseek: ΠΎΡ‚ послСднСй ΠΎΠ½Π° отличаСтся Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π² случаС ошибки Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π° Π΅Π΅ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ FILE*.

8.5 ΠŸΡ€ΠΈΠΌΠ΅Ρ€. РСализация Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ fopen ΠΈ getc

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ fopen ΠΈ getc ΠΈΠ· стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ, ΠΊΠ°ΠΊ описанныС Π²Ρ‹ΡˆΠ΅ части ΡΠΎΠ³Π»Π°ΡΡƒΡŽΡ‚ΡΡ Π΄Ρ€ΡƒΠ³ с Π΄Ρ€ΡƒΠ³ΠΎΠΌ.

Напомним, Ρ‡Ρ‚ΠΎ Ρ„Π°ΠΉΠ»Ρ‹ Π² стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΌΠΈ указатСлями, Π° Π½Π΅ дСскрипторами. Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Ρ„Π°ΠΉΠ»Π° - это ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° структуру, ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‰ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ„Π°ΠΉΠ»Π΅: ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π±ΡƒΡ„Π΅Ρ€, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ» большими кусками: число нСзанятых Π±Π°ΠΉΡ‚ΠΎΠ² Π±ΡƒΡ„Π΅Ρ€Π°; ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ Π² Π±ΡƒΡ„Π΅Ρ€Π΅; дСскриптор Ρ„Π°ΠΉΠ»Π°; Ρ„Π»Π°ΠΆΠΊΠΈ, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰ΠΈΠ΅ Ρ€Π΅ΠΆΠΈΠΌ (Ρ‡Ρ‚Π΅Π½ΠΈΠ΅/запись), ΠΎΡˆΠΈΠ±ΠΎΡ‡Π½Ρ‹Π΅ состояния ΠΈ Ρ‚. Π΄.

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° Π΄Π°Π½Π½Ρ‹Ρ…, ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‰Π°Ρ Ρ„Π°ΠΉΠ», содСрТится Π² β€Ήstdio.hβ€Ί, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒ (с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ #include) Π² любой исходный Ρ„Π°ΠΉΠ», Ссли Π² Ρ‚ΠΎΠΌ осущСствляСтся стандартный Π²Π²ΠΎΠ΄-Π²Ρ‹Π²ΠΎΠ΄. Π­Ρ‚ΠΎΡ‚ ΠΆΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ ΠΈ Π² исходныС тСксты Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°.

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π΅, Ρ‚ΠΈΠΏΠΈΡ‡Π½ΠΎΠΌ для Ρ„Π°ΠΉΠ»Π° β€Ήstdio.hβ€Ί, ΠΈΠΌΠ΅Π½Π°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½Ρ‹Ρ… функциях, Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ΡΡ с подчСркивания. Π­Ρ‚ΠΎ сдСлано для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΈ случайно Π½Π΅ совпали с ΠΈΠΌΠ΅Π½Π°ΠΌΠΈ, Ρ„ΠΈΠ³ΡƒΡ€ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΌΠΈ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ. Π’Π°ΠΊΠΎΠ΅ соглашСниС ΡΠΎΠ±Π»ΡŽΠ΄Π°Π΅Ρ‚ΡΡ Π²ΠΎ всСх ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ… стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ.

#define NULL 0

#define EOF (-1)

#define BUFSIZ 1024

#define OPEN_MAX 20 /* max число ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ² */

typedef struct _iobuf {

 int cnt; /* количСство ΠΎΡΡ‚Π°Π²ΡˆΠΈΡ…ΡΡ символов */

 char *ptr; /* позиция ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ символа */

 char *base; /* адрСс Π±ΡƒΡ„Π΅Ρ€Π° */

 int flag; /* Ρ€Π΅ΠΆΠΈΠΌ доступа */

 int fd; /* дСскриптор Ρ„Π°ΠΉΠ»Π° */

} FILE;


extern FILE _iob[OPEN_MAX];


#define stdin (&iob[0])

#define stdout (&_iob[1])

#define stderr (&_iob[2])


enum _flags {

 _READ = 01, /* Ρ„Π°ΠΉΠ» ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ */

 _WRITE = 02, /* Ρ„Π°ΠΉΠ» ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ Π½Π° запись */

 _UNBUF = 04, /* Ρ„Π°ΠΉΠ» Π½Π΅ буфСризируСтся */

 _EOF = 010, /* Π² Π΄Π°Π½Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ встрСтился EOF */

 _ERR = 020 /* Π² Π΄Π°Π½Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ Π²ΡΡ‚Ρ€Π΅Ρ‚ΠΈΠ»Π°ΡΡŒ ошибка */

};


int _fillbuf(FILE *);

int _flushbuf(int, FILE *);


#define feof(p) (((p)-β€Ίflag & _EOF) != 0)

#define ferror(p) (((p)-β€Ίflag & _ERR) != 0)

#define fileno(p) ((p)-β€Ίfd)


#define getc(p) (--(p)-β€Ίcnt β€Ί= 0 \

 ? (unsigned char) *(p)-β€Ίptr++ : _fillbuf(p))

#define putc(x,p) (--(p)-β€Ίcnt β€Ί= 0 \

 ? *(p)-β€Ίptr++ = (x) : _flushbuf((x),p))


#define getchar() getc(stdin)

#define putchar(x) putc((x), stdout)

ΠœΠ°ΠΊΡ€ΠΎΡ getc ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ счСтчик числа символов, находящихся Π² Π±ΡƒΡ„Π΅Ρ€Π΅, ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ символ, послС Ρ‡Π΅Π³ΠΎ ΠΏΡ€ΠΈΡ€Π°Ρ‰ΠΈΠ²Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ. (Напомним, Ρ‡Ρ‚ΠΎ Π΄Π»ΠΈΠ½Π½Ρ‹Π΅ #define с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΉ Π½Π°ΠΊΠ»ΠΎΠ½Π½ΠΎΠΉ Ρ‡Π΅Ρ€Ρ‚Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… строках.) Когда Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика становится ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ, getc Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ _fillbuf, Ρ‡Ρ‚ΠΎΠ±Ρ‹ снова Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Π±ΡƒΡ„Π΅Ρ€, ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ содСрТимоС структуры ΠΈ Π²Ρ‹Π΄Π°Ρ‚ΡŒ символ. Π’ΠΈΠΏΡ‹ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Ρ… символов приводятся ΠΊ unsigned; это Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ всС ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ.

Π₯отя Π² дСталях Π²Π²ΠΎΠ΄-Π²Ρ‹Π²ΠΎΠ΄ здСсь Π½Π΅ рассматриваСтся, ΠΌΡ‹ всС ΠΆΠ΅ ΠΏΡ€ΠΈΠ²Π΅Π»ΠΈ ΠΏΠΎΠ»Π½ΠΎΠ΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ putc. Π‘Π΄Π΅Π»Π°Π½ΠΎ это, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½Π° дСйствуСт Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΌ Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ getc, вызывая Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ _flushbuf, ΠΊΠΎΠ³Π΄Π° Π±ΡƒΡ„Π΅Ρ€ ΠΏΠΎΠ»ΠΎΠ½. Π’ тСкстС ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ макросы, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ доступ ΠΊ Ρ„Π»Π°ΠΆΠΊΠ°ΠΌ ошибки ΠΈ ΠΊΠΎΠ½Ρ†Π° Ρ„Π°ΠΉΠ»Π°, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΊ Π΅Π³ΠΎ дСскриптору.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ fopen. Π‘ΠΎΠ»ΡŒΡˆΠ°Ρ Ρ‡Π°ΡΡ‚ΡŒ инструкций fopen относится ΠΊ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΡŽ Ρ„Π°ΠΉΠ»Π°, ΠΊ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ Π΅Π³ΠΎ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ ΠΈ ΠΊ установкС Ρ„Π»Π°ΠΆΠΊΠΎΠ²Ρ‹Ρ… Π±ΠΈΡ‚ΠΎΠ², ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹Ρ… для ΠΈΠ½Π΄ΠΈΠΊΠ°Ρ†ΠΈΠΈ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ состояния. Π‘Π°ΠΌΠ° fopen Π½Π΅ ΠΎΡ‚Π²ΠΎΠ΄ΠΈΡ‚ мСста для Π±ΡƒΡ„Π΅Ρ€Π°; это Π΄Π΅Π»Π°Π΅Ρ‚ _fillbuf ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ Ρ„Π°ΠΉΠ»Π°.

#include <fcntl.h>

#include "syscalls.h"

#define PERMS 0666 /* RW для собствСнника, Π³Ρ€ΡƒΠΏΠΏΡ‹ ΠΈ ΠΏΡ€ΠΎΡ‡. */


/* fopen: ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Ρ„Π°ΠΉΠ», Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ */