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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ систСма UNIXΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 119

Автор АндрСй РобачСвский

ВзаимодСйствиС с ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½Ρ‹ΠΌΠΈ процСссами

РассмотрСнный Ρ€Π°Π½Π΅Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ интСрфСйс TLI ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ TPI. Π›Π΅Π³ΠΊΠΎ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ соотвСтствиС ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌΠΈ функциями TLI ΠΈ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π°ΠΌΠΈ TPI, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΌΠΈ Π² Ρ‚Π°Π±Π». 6.10. Π‘Ρ…Π΅ΠΌΠ° Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ TPI ΠΈ ΠΎΠ±ΠΌΠ΅Π½Π° ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π°ΠΌΠΈ TPI ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΠΎΠΌ ΠΈ сСрвСром для Ρ‚ΠΈΠΏΠΈΡ‡Π½ΠΎΠ³ΠΎ TCP-сСанса ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° Π½Π° рис. 6.32.

Рис. 6.32. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ TLI ΠΈ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Ρ‹ TPI

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ интСрфСйс ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π±Ρ‹Π» рассмотрСн Π² Π³Π»Π°Π²Π΅ 5 ΠΏΡ€ΠΈ обсуТдСнии подсистСмы STREAMS. ΠžΡΠ½ΠΎΠ²Π½Ρ‹ΠΌΠΈ функциями, ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‰ΠΈΠΌΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Ρƒ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ сообщСний, ΡΠ²Π»ΡΡŽΡ‚ΡΡ систСмныС Π²Ρ‹Π·ΠΎΠ²Ρ‹ putmsg(2) ΠΈ getmsg(2). Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ TLI, ΡΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΡ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ интСрфСйс доступа ΠΏΡ€ΠΈΠΊΠ»Π°Π΄Π½Ρ‹Ρ… процСссов ΠΊ транспортным ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π°ΠΌ, ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΡƒΠ΄ΠΎΠ±Π½ΠΎΠΉ ΠΎΠ±ΠΎΠ»ΠΎΡ‡ΠΊΠΎΠΉ (Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½ΠΎΠΉ Π² Π²ΠΈΠ΄Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, libnsl.so) Π±ΠΎΠ»Π΅Π΅ Ρ„ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΌ систСмным Π²Ρ‹Π·ΠΎΠ²Π°ΠΌ putmsg(2) ΠΈ getmsg(2).


Π’ качСствС ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° рассмотрим Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ t_connect(3N). Π•Π΅ рСализация ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²ΠΈΠ΄:

int t_connect(int fd, struct t_call *sndcall,

struct t_call *recvcall) {

 struct T_conn_req *connreq;

 struct T_conn_con* conncon;

 struct T_ok_ack *okack;

 struct T_error_ack *errack;

 struct strbuf connect, ack, confirm, m_data;

 struct netbuf addr, opt, udata;

 char *buf;

 int flags;

 ...


 /* Π‘ΠΎΡ…Ρ€Π°Π½ΠΈΠΌ адрСса Π±ΡƒΡ„Π΅Ρ€ΠΎΠ² netbuf запроса sndcall */

 addr = sndcall->addr; opt = sndcall->opt;

 udata = sndcall->udata;


 /* Π—Π°ΠΏΠΎΠ»Π½ΠΈΠΌ поля структуры strbuf для формирования

    ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰Π΅ΠΉ части (Π±Π»ΠΎΠΊ M_PROTO) сообщСния T_CONN_REQ */

 connect.len =

  sizeof(struct T_conn_req) + addr.len + opt.len;

 connect.maxlen =

  sizeof(struct Π’_conn_req) + addr.maxlen + opt.maxlen;

 buf = (char*)malloc(connect.maxlen);

 connect.buf = buf;


 /* Π—Π°ΠΏΠΎΠ»Π½ΠΈΠΌ поля Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Π±Π»ΠΎΠΊΠ° M_PROTO сообщСния T_CONN_REQ Π²

    соотвСтствии с Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠΌ структуры T_conn_req */

 connreq = (struct T_conn_req*)buf;

 connreq->PRIM_type = T_CONN_REQ;

 connreq->DEST_length = addr.len;

 connreq->DEST_offset = sizeof (struct T_conn_req);

 buf += sizeof(struct T_conn_req);

 memcpy(buf, addr.buf, addr.len);

 connreq->OPT_length = opt.len;

 connreq->OPT_offset = connreq->DEST_offset + opt.len;

 buf += addr.len;

 memcpy(buf, opt.buf, opt.len);


 /* Π—Π°ΠΏΠΎΠ»Π½ΠΈΠΌ поля структуры strbuf для формирования Π±Π»ΠΎΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ…

    (Π±Π»ΠΎΠΊ M_DATA) */

 m_data.len = udata.len;

 m_data.maxlen = udata.maxlen;

 m_data.buf = udata.buf;


 /* ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΠΌ запрос Π’_CONN_REQ поставщику транспортных услуг

    ΠΏΠΎ ΠΏΠΎΡ‚ΠΎΠΊΡƒ fd */

 putmsg(fd, &connect, &m_data, 0);

 /* ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΈΠΌΡΡ ΠΊ ΠΏΡ€ΠΈΠ΅ΠΌΡƒ подтвСрТдСния. Π’Ρ‹Π΄Π΅Π»ΠΈΠΌ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΉ

    Ρ€Π°Π·ΠΌΠ΅Ρ€ для получСния Π½Π΅Π³Π°Ρ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ подтвСрТдСния, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ

    ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² T_ERROR_ACK Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ большС мСста */

 ack.len = ack.maxlen = sizeof(struct T_error_ack);

 ack.buf = udata.buf;

 /* ΠŸΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ являСтся ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½Ρ‹ΠΌ, поэтому установим Ρ„Π»Π°Π³

    RS_HIPRI. Π”ΠΎ получСния подтвСрТдСния Π½Π΅ ΠΏΡ€Π΅Π΄ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌ

    Π½ΠΈΠΊΠ°ΠΊΠΈΡ… дСйствий */

 flags = RS_HIPRI;

 getmsg(fd, &ack, (struct strbuf*)0, &flags);

 free(connect.buf);

 okack = (struct T_ok_ack*)ack.buf;

 /* ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ Π»ΠΈ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΈΠ»ΠΈ

    Π½Π΅Π³Π°Ρ‚ΠΈΠ²Π½ΠΎΠ΅ ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ */

 if (okack->PRIM_type == T_OK_ACK) {

  /* Если ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅, подготовимся ΠΊ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΡŽ

     согласия ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π½Π° установлСниС связи

     (ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² T_CONN_CON) */

  free(ack.buf);

  if (recvcall != NULL) {

   addr = recvcall->addr;

   opt = recvcall->opt;

   udata = recvcall->udata;

   confirm.len = sizeof(struct T_conn_con) + addr.len + opt.len;

   confirm.maxlen =

    sizeof(struct T_conn_con) + addr.maxlen + opt.maxlen;

   buf = (char*)malloc(confirm.maxlen);

   confirm.buf = buf;

   m_data.len = udata.len;

   m_data.maxlen = udata.maxlen;

   m_data.buf = udata.buf;

   /* ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² T_CONN_CON */

   getmsg(fd, &confirm, &m_data, &flags);

   free(buf);


   conncon = (struct T_conn_con*)confirm.buf;

   if (conncon->PRIM_type == T_CONN_CON) {

    /* Если это Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ согласиС, Π·Π°ΠΏΠΎΠ»Π½ΠΈΠΌ

       структуру rcvcall для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ TLI */

    addr.len = conncon->OPT_length;

    opt.len = conncon->OPT_length;

    memcpy(addr.buf, conncon+conncon->RES_offset, addr.len);

    memcpy(opt.buf, conncon+conncon->OPT_offset, opt.len);

    free(confirm.buf);

    /* ВсС Π·Π°ΠΊΠΎΠ½Ρ‡ΠΈΠ»ΠΎΡΡŒ ΡƒΠ΄Π°Ρ‡Π½ΠΎ β€” Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ 0 */

    return 0;

   }

  } else {

   /* Π’ случаС ΠΎΡ‚ΠΊΠ°Π·Π° ΠΌΡ‹ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²

      T_DISCON_IND */

   ...

   return -1;

  }

 } else {

  /* Если ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² T_ERROR_ACK β€” ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π΅ΠΌ Π΅Π³ΠΎ */

  errack = (struct T_error_ack*)ack.buf;

  ...

  return -1;

 }

}

ΠŸΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ TLI. Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π² ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌ случаС использования транспортного ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° TCP ΠΏΡ€ΠΈΠ΅ΠΌ ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡŽΡ‚ΡΡ Π² Π²ΠΈΠ΄Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°, Π½Π΅ содСрТащСго ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ логичСских записСй. Π’ этом случаС Π½Π΅ трСбуСтся Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²ΠΎΠ² Ρ‚ΠΈΠΏΠ° T_DATA_REQ ΠΈ T_DATA_IND. Π’ Ρ‚ΠΎ ΠΆΠ΅ врСмя, для ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ ΠΈ получСния экстрСнных Π΄Π°Π½Π½Ρ‹Ρ… Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Π½Ρ‹ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Ρ‹ T_EXDATA_REQ ΠΈ T_EXDATA_IND. ΠŸΡ€ΠΈ использовании ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° UDP всС Π΄Π°Π½Π½Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²ΠΎΠ² T_UNITDATA_REQ ΠΈ T_UNITDATA_IND.

Описанная рСализация ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ интСрфСйса TLI ΠΈΠΌΠ΅Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ сущСствСнный нСдостаток β€” ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Π½Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½Ρ‹ΠΌΠΈ. Π”Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ t_connect(3N) ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€Π΅Ρ€Π²Π°Π½ΠΎ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ процСссами, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Ρ‚Π°ΠΊΠΆΠ΅ ΡΠ²ΡΠ·Ρ‹Π²Π°Ρ‚ΡŒΡΡ с ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΌ ΡƒΠ·Π»ΠΎΠΌ. Π­Ρ‚ΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ части ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ происходит Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Π·Π°Π΄Π°Ρ‡ΠΈ. Если для Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ t_connect(3N) Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ атомарности допустимо, Ρ‚ΠΎ ряд Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Ρ‚Π°ΠΊΠΈΡ…, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΊΠ°ΠΊ связываниС (t_bind(3N)), ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ (t_open(3N), t_getinfo(3N)) ΠΈ установка ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΎΠΏΡ†ΠΈΠΉ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° (t_optmgmt(3N)) Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Π·Π°Ρ‰ΠΈΡ‰Π΅Π½Ρ‹ ΠΎΡ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΠ³ΠΎ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ цСлостности Π΄Π°Π½Π½Ρ‹Ρ… ΠΏΠΎ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π΅ прСрывания ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. ЕдинствСнным способом Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π°Ρ‚ΠΎΠΌΠ°Ρ€Π½ΠΎΡΡ‚ΡŒ являСтся ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ выполнСния критичСских участков (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π° ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ΠΌ подтвСрТдСния ΠΎΡ‚ поставщика транспортных услуг) Π² Ρ€Π΅ΠΆΠΈΠΌ ядра. Для этого подсистСма STREAMS ΠΏΡ€Π΅Π΄Π»Π°Π³Π°Π΅Ρ‚ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ ΠΎΠ±ΠΌΠ΅Π½Π° ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠΌΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Π°ΠΌΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π²Ρ‹Π·ΠΎΠ²Π° ioctl(2).

Однако с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ioctl(2), ΠΊΠ°ΠΊ Π±Ρ‹Π»ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ "ΠŸΠΎΠ΄ΡΠΈΡΡ‚Π΅ΠΌΠ° STREAMS" Π³Π»Π°Π²Ρ‹ 5, ΠΌΠΎΠΆΠ½ΠΎ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ лишь сообщСния Ρ‚ΠΈΠΏΠ° M_IOCTL. Для прСобразования этих сообщСний Π² ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Ρ‹ TPI слуТит Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ timod(7M), встраиваСмый Π² ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠ΅ΠΆΠ΄Ρƒ Π³ΠΎΠ»ΠΎΠ²Π½Ρ‹ΠΌ ΠΈ транспортным модулями. На рис. 6.33 ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ мСстополоТСниС модуля timod(7M) ΠΈ схСматичСски ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Ρ‹ Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

Рис. 6.33. АрхитСктура доступа ΠΊ транспортным услугам

Для всСх сообщСний STREAMS, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ сообщСний M_IOCTL, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π³ΠΎΠ»ΠΎΠ²Π½Ρ‹ΠΌ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΌ Π² ΠΎΡ‚Π²Π΅Ρ‚ Π½Π° систСмный Π²Ρ‹Π·ΠΎΠ² ioctl(fd, I_STR, ...), ΠΌΠΎΠ΄ΡƒΠ»ΡŒ timod(7M) являСтся ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹ΠΌ, Ρ‚.Π΅. ΠΎΠ½ просто ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ эти сообщСния ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ ΠΌΠΎΠ΄ΡƒΠ»ΡŽ Π²Π½ΠΈΠ· ΠΏΠΎ ΠΏΠΎΡ‚ΠΎΠΊΡƒ Π±Π΅Π· ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ. НСсколько сообщСний M_IOCTL ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΌ ΠΈ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΡŽΡ‚ΡΡ Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Ρ‹ TPI.

ΠŸΡ€ΠΈ этом Π²Ρ‹Π·ΠΎΠ² ioctl(2) ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ„ΠΎΡ€ΠΌΠ°Ρ‚:

#include <sys/stropts.h>


struct strioctl my_strioctl

...

strioctl.ic_cmd = cmd;

strioctl.ic_timeout = INFTIM;

strioctl.ic_len = size;

strioctl.ic_dp = (char*)buf;

ioctl(fd, I_STR, &my_strioctl);

ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ ioctl(2) ΠΏΠΎΠ»Π΅ size устанавливаСтся Ρ€Π°Π²Π½Ρ‹ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρƒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π° TPI, ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ»Π΅ΠΌ cmd ΠΈ располоТСнного Π² Π±ΡƒΡ„Π΅Ρ€Π΅ buf. ΠŸΡ€ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π΅ ΠΈΠ· Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΎΠ»Π΅ size содСрТит Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Π°, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½Π½ΠΎΠ³ΠΎ поставщиком транспортных услуг ΠΈ располоТСнного Π² Π±ΡƒΡ„Π΅Ρ€Π΅ buf.

ΠœΠΎΠ΄ΡƒΠ»ΡŒ timod(7M) слуТит для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… ΠΊΠΎΠΌΠ°Π½Π΄ cmd:

Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ cmd ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΌΠΎΠ΄ΡƒΠ»Π΅ΠΌ timod(7M) TI_BIND Команда прСобразуСтся Π² ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² T_BIND_REQ. ΠŸΡ€ΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ioctl(2) Π² Π±ΡƒΡ„Π΅Ρ€Π΅ buf находится ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² T_BIND_ACK. TI_UNBIND Команда прСобразуСтся Π² ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² T_UNBIND_REQ. ΠŸΡ€ΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ioctl(2) Π² Π±ΡƒΡ„Π΅Ρ€Π΅ buf находится ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² T_OK_ACK. TI_GETINFO Команда прСобразуСтся Π² ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² T_INFO_REQ. ΠŸΡ€ΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ioctl(2) Π² Π±ΡƒΡ„Π΅Ρ€Π΅ buf находится ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² T_INFO_ACK. TI_OPTMGMT Команда прСобразуСтся Π² ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² T_OPTMT_REQ. ΠŸΡ€ΠΈ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ioctl(2) Π² Π±ΡƒΡ„Π΅Ρ€Π΅ buf находится ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ² T_OPTMGMT_ACK.

Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ DLPI