s-kitaの日記 このページをアンテナに追加 RSSフィード

2008-05-21

isfdtypeの実装


ファイルディスクリプタが、ある特定の型であるかどうかを検査する「isfdtype()」の実装

#include <unistd.h>

/* 
S_IFMT
ファイル種別を示すビット領域を表すビットマスク
int
isfdtype(int fd, int fdtype)
{
  struct stat buf;
  if (fstat(fd, &buf) < 0)
    return -1;
  if ((buf.st_mode & S_IFMT) == fdtype)
    return 1;
  else
    return 0;
}

int
main()
{
  int fd = open("isfdtype.c", "r");
  if (isfdtype(fd, S_IFREG) == 1) {
    printf("Regular File\n");
  } else {
    printf("Not regular file\n");
  }

  return 0;
}







参考文献

  • UNIXネットワークプログラミング スティーブンズ
  • ソケットAPI

    プロトコル群は、それぞれsockaddr_で始まるソケットアドレス構造体を定義している。



    IPv4ソケットアドレス構造体(インターネットソケットアドレス構造体)

    #include <netinet/in.h>
    
    struct in_addr {
      in_addr_t s_addr;
    };
    
    struct sockaddr_in {
      uint8_t sin_len;//構造体の大きさ
      sa_family_t sin_family;//アドレスファミリ(AF_INET)
      in_port_t sin_port;//ポート番号(ネットワークバイトオーダー)
      struct in_addr sin_addr;//IPv4アドレス(ネットワークバイトオーダー)
      char sin_zero[8];//未使用
    };
    





    総称ソケットアドレス構造体 sockaddr

    struct sockaddr {
      uint8_t sa_len;
      sa_family_t sa_family;//アドレスファミリ
      char sa_data[14];//プロトコル依存アドレス
    };
    




    値-結果引数

    bind, connect, sendtoは、プロセスからカーネルへソケットアドレスを渡す。


    accept, recvfrom, getsockname, getpeernameは、カーネルからプロセスにソケットアドレスを渡す。これら関数をコールするときは、構造体サイズを示す値をポインタで引数として渡し、関数から返るときは、結果を受け取る(値-結果引数)。

    他の値-結果引数の例

    select

    getsockopt

    recvmsg

    ifconf構造体のifc_lenメンバ

    sysctl


    バイト順序関数

    16ビットの整数にて、

    低位バイトを最初のアドレスに格納する:リトルエンディアン

    高位バイトを最初のアドレスに格納する:ビッグエンディアン

    16ビットの最左端:LSB(Least Significant Bit)

    16ビットの最右端:MSB(Most Significant Bit)


    /* ビッグエンディアン/リトルエンディアン判定プログラム */
    #include <stdio.h>
    #include <stdlib.h>
    
    int
    main(int argc, char *argv[])
    {
      union {
        short s;
        char c[sizeof(short)];
      } un;
    
      un.s = 0x1122;
      if (sizeof(short) == 2) {
        if (un.c[0] == 0x11 && un.c[1] == 0x22)
          printf("big endian\n");
        else if (un.c[0] == 0x22 && un.c[1] == 0x11)
          printf("little endian\n");
        else
          printf("unknown\n");
      } else {
        printf("sizeof(short) = %d\n", sizeof(short));
      }
    
      exit(0);
    }
    
    


    ソケットアドレス構造体には、IPアドレス、ポート番号などをネットワークバイトオーダーで格納する必要がある。

    よって、ホストバイトオーダーとネットワークバイトオーダーを相互に変換する必要がある。

    #include <netinet/in.h>
    uint16_t htons(uint16_t host16bitvalue);
    uint32_t htonl(uint32_t host32bitvalue);
    uint16_t ntohs(uint16_t net16bitvalue);
    uint32_t ntohl(uint32_t net32bitvalue);
    



    バイト列操作関数

    #include <string.h>
    void bzero(void *dest, size_t nbytes);
    void bcopy(const void *src, void *dest, size_t nbytes);
    int bcmp(const void *ptrl, const void *ptr2, size_t nbytes);
    


    #include <string.h>
    #include <stdio.h>
    
    int
    main()
    {
      int i;
      char p1[8];
    
      /* void bzero(void *dest, size_t nbytes) */
      bzero(p1, sizeof(p1));
      for (i = 0; i < sizeof(p1); i++)
        printf("%0x", p1[i]);
      putchar('\n');
    
      /* void bcopy(const void *src, void *dest, size_t nbytes)  */
      char p2[] = {"0123456789"};
      char p3[16];
      bcopy(p2, p3, sizeof(p2));
      for (i = 0; i < strlen(p3); i++)
        printf("%0x ", p3[i]);
      putchar('\n');
    
      /* int bcmp(const void *ptrl, const void *ptr2, size_t nbytes) */
      int ret = bcmp(p2, p3, sizeof(p2));
      if (ret == 0)
        printf("equal\n");
      else if (ret > 0)
        printf("p2 > p3\n");
      else
        printf("p3 < p2");
    
      return 0;
    }
    


    アドレス変換関数

    #include <arpa/inet.h>
    
    int inet_aton(const char *strptr, struct in_addr *addptr);
    in_addr_t inet_addr(const char *strptr);
    char *inet_ntoa(struct in_addr inaddr);
    


    #include <stdio.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    
    int
    main()
    {
      const char *ip = "192.168.1.2";
      struct in_addr addr;
    
      /* inet_aton */
      if (inet_aton(ip, &addr) == 1) /* success */
        printf("%d\n", addr);
      else /* fail */
        printf("inet_aton(): failed\n");
    
      /* inet_addr */
      in_addr_t iat = inet_addr("192.168.1.2");
      printf("%d\n", iat);
     
      /* inet_ntoa */
      printf("%s\n",  inet_ntoa(addr));
     
      return 0;
    }
    
    


    参考文献

  • UNIXネットワークプログラミング スティーブンズ