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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π’Π²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² QNX/Neutrino 2. Руководство ΠΏΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π² QNX Realtime PlatformΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 77

Автор Π ΠΎΠ± ΠšΡ‘Ρ€Ρ‚Π΅Π½

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΎ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ Π²Π°ΠΆΠ½ΠΎΠΉ особСнности. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΠΊΠ°ΠΊ ΠΌΡ‹ использовали для выполнСния всСй нашСй Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ POSIX-уровня ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ! Ѐункция iofunc_open_default() ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ размСщаСтся Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ установлСния соСдинСния Π² Ρ‚ΠΎΠΉ ΠΆΠ΅ самой ячСйкС, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ сСйчас Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ наша функция my_open(). Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹ΠΉ Π½Π°Π±ΠΎΡ€ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²!

ВсС, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ β€” это Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊΡƒΡŽ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π½ΡƒΡŽ запись ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΡΠ²ΡΠ·Π°Ρ‚ΡŒ с OCB, создаваСмым Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ: Π»ΠΈΠ±ΠΎ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ²ΡƒΡŽ (Π² этом случаС ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ attr), Π»ΠΈΠ±ΠΎ ΠΎΠ΄Π½Ρƒ ΠΈΠ· 26 ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ…ΡΡ Ρƒ нас Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… (Ρ‚ΠΎΠ³Π΄Π° ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ элСмСнт atoz_attrs). Π­Ρ‚ΠΎ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚Π΅ Π² слот open Π² Ρ‚Π°Π±Π»ΠΈΡ†Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ установлСния соСдинСния, дСйствуСт ΠΊΠ°ΠΊ Β«ΡˆΠ²Π΅ΠΉΡ†Π°Ρ€Β» ΠΏΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡŽ ΠΊΠΎ всСм ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ запросам ΠΊ Π²Π°ΡˆΠ΅ΠΌΡƒ администратору рСсурса.

static int my_open(resmgr_context_t *ctp, io_open_t *msg,

 iofunc_attr_t *attr, void *extra) {

 if (msg->connect.path[0] == 0) {

  // ΠšΠ°Ρ‚Π°Π»ΠΎΠ³ (/dev/atoz)

  return (iofunc_open_default(ctp, msg, attr, extra));

 } else if (msg->connect.path[1] == 0 &&

  (msg->connect.path[0] >= 'a' &&

  msg->connect.path[0] <= 'z')) { // Π€Π°ΠΉΠ» (/dev/atoz/[a-z])

  return

   (iofunc_open_default(ctp, msg, atoz_attrs +

    msg->connect.path[0] - 'a', extra));

 } else {

  return (ENOENT);

 }

}

my_read()

Π’ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ my_read(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π°Π΄ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ, ΠΌΡ‹ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ ΠΏΠΎΠ»Π΅ mode Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π½ΠΎΠΉ записи. Если макрос S_ISDIR() Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚, Ρ‡Ρ‚ΠΎ это ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³, ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ my_read_dir(); Ссли макрос S_ISREG() Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚, Ρ‡Ρ‚ΠΎ это Ρ„Π°ΠΉΠ», ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ my_read_file(). (ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ссли ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ это Ρ‚Π°ΠΊΠΎΠ΅, ΠΌΡ‹ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ EBADF, указывая Π΅ΠΌΡƒ этим, Ρ‡Ρ‚ΠΎ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ здСсь Π½Π΅ Ρ‚Π°ΠΊ.)

ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ Π½ΠΈΠΆΠ΅ ΠΊΠΎΠ΄ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π·Π½Π°Π΅Ρ‚ ΠΎ Π½Π°ΡˆΠΈΡ… ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Ρ‹Ρ… устройствах, Π΄Π° Π΅ΠΌΡƒ, собствСнно, ΠΈ Π΄Π΅Π»Π° Π΄ΠΎ Π½ΠΈΡ… Π½Π΅Ρ‚ β€” ΠΎΠ½ просто ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π½Π° основС стандартных общСизвСстных Π΄Π°Π½Π½Ρ‹Ρ….

static int my_read(resmgr_context_t *ctp, io_read_t *msg,

 iofunc_ocb_t *ocb) {

 int sts;


 // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ

 // коррСктности

 if ((sts =

  iofunc_read_verify(ctp, msg, ocb, NULL)) != EOK) {

   return (sts);

 }


 // Π Π΅ΡˆΠΈΡ‚ΡŒ, Π½Π°Π΄ΠΎ Π»ΠΈ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Β«Ρ„Π°ΠΉΠ»Β» ΠΈΠ»ΠΈ Β«ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Β»

 if (S_ISDIR(ocb->attr->mode)) {

  return (my_read_dir(ctp, msg, ocb));

 } else if (S_ISREG(ocb->attr->mode)) {

  return (my_read_file(ctp, msg, ocb));

 } else {

  return (EBADF);

 }

}

my_read_dir()

Π’ΠΎΡ‚ Ρ‚ΡƒΡ‚-Ρ‚ΠΎ всС вСсСльС ΠΈ начинаСтся. Π‘ Ρ‚ΠΎΡ‡ΠΊΠΈ зрСния высокого уровня, ΠΌΡ‹ выдСляСм Π±ΡƒΡ„Π΅Ρ€ (ΠΎΠ½ называСтся reply_msg), Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ собираСмся Ρ€Π°Π·ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ dp, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Β«ΠΏΡ€ΠΎΠ³ΡƒΠ»ΡΡ‚ΡŒΡΡΒ» ΠΏΠΎ Π±ΡƒΡ„Π΅Ρ€Ρƒ, заполняя Π΅Π³ΠΎ ΠΏΠΎ Ρ…ΠΎΠ΄Ρƒ Π΄Π΅Π»Π° элСмСнтами struct dirent. Π’ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Π°Ρ ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° dirent_size() примСняСтся, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, Π΅ΡΡ‚ΡŒ Π»ΠΈ Ρƒ нас мСсто Π² Π±ΡƒΡ„Π΅Ρ€Π΅ для Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ элСмСнта. Π’ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Π°Ρ ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° dirent_fill() ΠΊΠ»Π°Π΄Π΅Ρ‚ элСмСнт Π² Π±ΡƒΡ„Π΅Ρ€. (ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ эти ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½Π΅ входят Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ администратора рСсурсов; ΠΌΡ‹ обсудим ΠΈΡ… Π½ΠΈΠΆΠ΅.)

На ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд этот ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ нСэффСктивным; ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ sprintf() для создания Π΄Π²ΡƒΡ…Π±Π°ΠΉΡ‚ΠΎΠ²ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ Ρ„Π°ΠΉΠ»Π° (символ ΠΈΠΌΠ΅Π½ΠΈ Ρ„Π°ΠΉΠ»Π° ΠΈ ΠΏΡ€ΠΈΠ·Π½Π°ΠΊ ΠΊΠΎΠ½Ρ†Π° строки NULL) Π² Π±ΡƒΡ„Π΅Ρ€Π΅ Π΄Π»ΠΈΠ½ΠΎΠΉ _POSIX_PATH_MAX (Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ 256) Π±Π°ΠΉΡ‚. Π­Ρ‚ΠΎ дСлаСтся для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ ΠΏΠΎ возмоТности ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½Ρ‹ΠΌ.

НаконСц, ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΏΠΎΠ»Π΅ offset Π² OCB для указания, для ΠΊΠ°ΠΊΠΎΠ³ΠΎ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° ΠΌΡ‹ Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ структуру struct dirent. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ»Π΅ offset всякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅.

Π’ΠΎΠ·Π²Ρ€Π°Ρ‚ Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ осущСствляСтся Β«ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌΒ» способом ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ MsgReply(). Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»Π΅ состояния (status) Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ MsgReply() ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для указания числа ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Π½Ρ‹Ρ… ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ Π±Π°ΠΉΡ‚.

static int my_read_dir(resmgr_context_t *ctp,

 io_read_t *msg, iofunc_ocb_t *ocb) {

 int nbytes;

 int nleft;

 struct dirent *dp;

 char *reply_msg;

 char fname[_POSIX_PATH_MAX];

 // Π’Ρ‹Π΄Π΅Π»ΠΈΡ‚ΡŒ Π±ΡƒΡ„Π΅Ρ€ для ΠΎΡ‚Π²Π΅Ρ‚Π°

 reply_msg = calloc(1, msg->i.nbytes);

 if (reply_msg == NULL) {

  return (ENOMEM);

 }


 // ΠΠ°Π·Π½Π°Ρ‡ΠΈΡ‚ΡŒ Π²Ρ‹Ρ…ΠΎΠ΄Π½ΠΎΠΉ Π±ΡƒΡ„Π΅Ρ€

 dp = (struct dirent *)reply_msg;


 // ΠžΡΡ‚Π°Π»ΠΎΡΡŒ Β«nleftΒ» Π±Π°ΠΉΡ‚

 nleft = msg->i.nbytes;

 while (ocb->offset < NUM_ENTS) {

  // Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ имя Ρ„Π°ΠΉΠ»Π°

  sprintf(fname, "%с", ocb->offset + "a");

  // ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ, насколько Π²Π΅Π»ΠΈΠΊ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚

  nbytes = dirent_size(fname);

  // Π•ΡΡ‚ΡŒ мСсто?

  if (nleft - nbytes >= 0) {

   // Π—Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ элСмСнт ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° ΠΈ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ

   dp =

    dirent_fill(dp, ocb->offset + 1, ocb->offset, fname);

   // Π£Π²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ смСщСниС OCB

   ocb->offset++;

   // Π£Ρ‡Π΅ΡΡ‚ΡŒ, сколько Π±Π°ΠΉΡ‚ ΠΌΡ‹ использовали

   nleft -= nbytes;

  } else {

   // ΠœΠ΅ΡΡ‚Π° большС Π½Π΅Ρ‚, ΠΎΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒΡΡ

   break;

  }

 }


 // ВозвращаСмся ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ ΠΊ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ

 MsgReply(ctp->rcvid, (char*)dp - reply_msg, reply_msg,

  (char*)dp β€” reply_msg);


 // ΠžΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ Π±ΡƒΡ„Π΅Ρ€

 free(reply_msg);

 // Π‘ΠΊΠ°Π·Π°Ρ‚ΡŒ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΡƒΠΆΠ΅ ΠΎΡ‚Π²Π΅Ρ‚ΠΈΠ»ΠΈ сами

 return (_RESMGR_NOREPLY);

}

my_read_file()

Π’ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ my_read_file() ΠΌΡ‹ Π²ΠΈΠ΄ΠΈΠΌ ΠΊΠΎΠ΄, ΠΏΠΎΡ‡Ρ‚ΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹ΠΉ простому ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ чтСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π²Ρ‹ΡˆΠ΅ Π² Π΄Π°Π½Π½ΠΎΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅. ЕдинствСнная странная Π²Π΅Ρ‰ΡŒ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΌΡ‹ здСсь Π΄Π΅Π»Π°Π΅ΠΌ β€” ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ возвращаСтся всСгда Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Π±Π°ΠΉΡ‚ Π΄Π°Π½Π½Ρ‹Ρ…, Π·Π½Π°Ρ‡ΠΈΡ‚, Ссли ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ nbytes Π½Π΅ Ρ€Π°Π²Π΅Π½ Π½ΡƒΠ»ΡŽ, Ρ‚ΠΎ ΠΎΠ½ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π²Π΅Π½ Π΅Π΄ΠΈΠ½ΠΈΡ†Π΅ (ΠΈ Π½ΠΈΡ‡Π΅ΠΌΡƒ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ). Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅, ΠΏΠΎΠ΄Π»Π΅ΠΆΠ°Ρ‰ΠΈΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Ρƒ, нСпосрСдствСнным Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ символьной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ string. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΠΊΠ°ΠΊ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΏΠΎΠ»Π΅ inode Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π½ΠΎΠΉ записи для опрСдСлСния, ΠΊΠ°ΠΊΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ. Π­Ρ‚ΠΎ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠ΅ΠΌ для администраторов, ΠΎΠ±ΡΠ»ΡƒΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΡ… нСсколько рСсурсов. Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ‚Ρ€ΡŽΠΊΠΎΠΌ Π±Ρ‹Π»ΠΎ Π±Ρ‹ Ρ€Π°ΡΡˆΠΈΡ€ΠΈΡ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π½ΡƒΡŽ запись (ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΈ ΠΎΠ± этом Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ Β«Π Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π½ΠΎΠΉ записи») ΠΈ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ нСпосрСдствСнно Π² Π½Π΅ΠΉ Π»ΠΈΠ±ΠΎ сами Π΄Π°Π½Π½Ρ‹Π΅, Π»ΠΈΠ±ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π½ΠΈΡ….

static int my_read_file(resmgr_context_t *ctp,

 io_read_t *msg, iofunc_ocb_t *ocb) {

 int nbytes;

 int nleft;

 char string;


 // Π’ΡƒΡ‚ Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… xtype...

 if ((msg->i.xtype & _IO_XTYPE_MASK) != _IO_XTYPE_NONE) (

  return (ENOSYS);

 }


 // Π’Ρ‹ΡΡΠ½ΠΈΡ‚ΡŒ, сколько Π±Π°ΠΉΡ‚ ΠΎΡΡ‚Π°Π»ΠΎΡΡŒ...

 nleft = ocb->attr->nbytes β€” ocb->offset;


 // ...ΠΈ сколько ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ

 nbytes = min(nleft, msg->i.nbytes);

 if (nbytes) {

  // Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΎΡ‚Π²Π΅Ρ‚Π½ΡƒΡŽ строку

  string = ocb->attr->inode - 1 + "A";

  // Π’ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π΅Π΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Ρƒ

  MsgReply(ctp->rcvid, nbytes, &string + ocb->offset,

   nbytes);

  // ΠžΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ Ρ„Π»Π°Π³ΠΈ ΠΈ смСщСниС

  ocb->attr->flags |=

   IOFUNC_ATTR_ATIME | IOFUNC_ATTR_DIRTY_TIME;

  ocb->offset += nbytes;

 } else {

  // Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ Π½Π΅Ρ‡Π΅Π³ΠΎ, ΠΈΠ½Π΄ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ½Π΅Ρ† Ρ„Π°ΠΉΠ»Π°

  MsgReply(ctp->rcvid, EOK, NULL, 0);

 }


 // Π£ΠΆΠ΅ ΠΎΡ‚Π²Π΅Ρ‚ΠΈΠ»ΠΈ сами

 return (_RESMGR_NOREPLY);

}

dirent_size()

Π’ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Π°Ρ ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° dirent_size() просто вычисляСт число Π±Π°ΠΉΡ‚, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠ΅ для структуры struct dirent, с ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ ΠΏΠΎ Π²Ρ‹Ρ€Π°Π²Π½ΠΈΠ²Π°Π½ΠΈΡŽ. ΠžΠΏΡΡ‚ΡŒ ΠΆΠ΅, для нашСго простого администратора рСсурсов здСсь ΠΈΠΌΠ΅Π΅Ρ‚ мСсто нСбольшоС искусствСнноС ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½ΠΈΠ΅, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ Ρ‚ΠΎΡ‡Π½ΠΎ Π·Π½Π°Π΅ΠΌ, ΠΊΠ°ΠΊΠΎΠ² Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ элСмСнта ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° β€” всС ΠΈΠΌΠ΅Π½Π° Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΈΠΌΠ΅ΡŽΡ‚ Π΄Π»ΠΈΠ½Ρƒ Ρ€ΠΎΠ²Π½ΠΎ ΠΎΠ΄ΠΈΠ½ Π±Π°ΠΉΡ‚. Однако, ΠΊΠ°ΠΊ Π±Ρ‹ Ρ‚Π°ΠΌ Π½ΠΈ Π±Ρ‹Π»ΠΎ, это всС Ρ€Π°Π²Π½ΠΎ полСзная слуТСбная ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°.

int dirent_size(char *fname) {

return (ALIGN(sizeof(struct dirent) - 4 + strlen(fname)));

}

dirent_fill()

И, Π½Π°ΠΊΠΎΠ½Π΅Ρ†, Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Π°Ρ ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° dirent_fill() примСняСтся для помСщСния ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… Π΅ΠΉ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ (Π° ΠΈΠΌΠ΅Π½Π½ΠΎ β€” ΠΏΠΎΠ»Π΅ΠΉ inode, offset ΠΈ fname) Π² Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹ΠΉ Π΅ΠΉ элСмСнт ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°. Π’ порядкС щСдрости ΠΎΠ½Π° Ρ‚Π°ΠΊΠΆΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° адрСс (с ΡƒΡ‡Π΅Ρ‚ΠΎΠΌ выравнивания), с ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π½Π°Ρ‡ΠΈΠ½Π°Ρ‚ΡŒΡΡ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ элСмСнт ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°.

struct dirent* dirent_fill(struct dirent *dp, int inode,

 int offset, char *fname) {

 dp->d_ino = inode;

 dp->d_offset = offset;