TEDIA会員に登録したメールアドレスとパスワードを入力してください

メールアドレス:

     パスワード:


パスワードを忘れた方はパスワードの確認を行ってください。

TEDIA会員へのご登録がお済みで無い方はこちらで登録ができます


>> テクノロジーポータル TEDIA トップページへ戻る <<

Think IT Software Developer's Think IT Find-IT 失敗しないソフト選び Find-IT TEDIA テクノロジーポータル TEDIA インストールマニアックス2008 インストールマニアックス2008

TEDIA SponsorsOpen Source Web Development Tutorials - Dev Shed

Linux I/Oファイルのシステムコール
(2009/03/03公開)

readv()例

 ここで、プログラムの1例を考えてみましょう。readv()システムコールを使い、前節で生成したテキストファイルからベクター型I/Oで読み出しを行うプログラムです。この例も自給的で、シンプルであると同時に完結しています。


  #include <stdio.h>
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <fcntl.h>
  #include <sys/uio.h> 
  int main () 
  {
          char foo[48], bar[51], baz[49]; 
          struct iovec iov[3];
          ssize_t nr;
          int fd, i; 
          fd = open ("buccaneer.txt", O_RDONLY);
          if (fd == -1) {
                  perror ("open");
                  return 1; 
          }
          /* set up our iovec structures */
          iov[0].iov_base = foo;
          iov[0].iov_len = sizeof (foo);
          iov[1].iov_base = bar;
          iov[1].iov_len = sizeof (bar);
          iov[2].iov_base = baz;
          iov[2].iov_len = sizeof (baz); 
          /* read into the structures with a single call */
          nr = readv (fd, iov, 3);
          if (nr == -1) { 
                  perror ("readv");
                  return 1;
          } 
          for (i = 0; i < 3; i++)
                  printf ("%d: %s", i, (char *) iov[i].iov_base);
          if (close (fd)) {
                  perror ("close");
                  return 1; 
          }
          return 0;
  } 



 前のプログラムを実行した後にこのプログラムを実行すると、以下が出力されます。


  $ ./readv 
  0: The term buccaneer comes from the word boucan.
  1: A boucan is a wooden frame used for cooking meat.
  2: Buccaneer is the West Indies name for a pirate.

実装

 readv()およびwritev()の素朴な実装は、シンプルなループとして、ユーザースペースで行えます。大体、以下のようになります。


  #include <unistd.h>
  #include <sys/uio.h> 
  ssize_t naive_writev (int fd, const struct iovec *iov, int count)
  {
          ssize_t ret = 0;
          int i; 
          for (i = 0; i < count; i++) {
                  ssize_t nr; 
                  nr = write (fd, iov[i].iov_base, iov[i].iov_len);
                  if (nr == -1) {
                          ret = -1;
                          break; 
                  }
                  ret += nr; 
          }
          return ret;
  } 



 ありがたいことに、これはLinux実装ではありません。Linuxはreadv()およびwritev()をシステムコールとして実装し、内的にスキャタ/ギャザーI/Oを実行します。事実、Linuxカーネル内のすべてのI/Oはベクター型I/Oです。read()およびwrite()は、単一のセグメントから成るベクターのベクター型I/Oとして実行されます。
 次回に続きます。

(編集部より:次回は、2009年3月10日に公開予定です)

(著者: O'Reilly Media)

原文へのリンク


前のページ     1    2    3    4   

Copyright © 2008 Ziff Davis Enterprise, Inc.
Originally appearing in the U.S. Edition of Dev Shed. All Rights Reserved.