[centos-users 1658] 疑似デバイス制御について

藤原 昭宏 fujiwaraa @ topix.co.jp
2014年 10月 17日 (金) 20:29:18 JST


初めまして。藤原と申します。

疑似デバイスの制御で困っておりますので、お知恵を拝借させて頂けないでしょう
か。

<現象>
疑似デバイスからデータをread後、EOFとなっているはずのデバイスに対して
Select文が読取可能と判断してしまう。
その後のreadでEIOエラーとなる。

<環境>
サーバ:HP ml310e
OS:CentOS6.4
コンパイラ:gcc version 4.4.7

<プログラム仕様>
疑似デバイスをOPENし、selectにて読取可となった際にreadし、
データを16進表示する。
その後、selectでの読取待ちに戻る。

<プログラム>
〜〜〜〜〜〜以下、tstprg.c〜〜〜〜〜〜〜
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>
#include <term.h>
#include <termio.h>

extern  char *ptsname(int fd1);

int
main(int argc, char *argv[])
{
    unsigned char buf[64*1024];
    int fd1;
    int m;
    int r;
    int i;
    fd_set rdfs;

    printf("start\n");

    if((fd1 = open("/dev/ptmx", O_RDWR | O_NOCTTY)) < 0)
    {
            perror("open");
            return(1);
    }
    grantpt(fd1);
    unlockpt(fd1);
    printf("fd1 %s\n", ptsname(fd1));

    while(1)
    {
            m = fd1;

            FD_ZERO(&rdfs);
            FD_SET(fd1, &rdfs);

            r = select(m+1, &rdfs, NULL, NULL, NULL);
            printf("select sts=%d max=%d fd1=%d\n", r, m, fd1);

            if(r<0)
            {
                    perror("select");
                    return(1);
            }

            if(r)
            {
                    r = read(fd1, buf, sizeof(buf));
                    printf("read1 sts=%d\n", r);
                    if(r<0)
                    {
                            perror("read");
                            return(1);
                    }

                    for(i=0;i<r;i++)
                    {
                            printf("%02x",buf[i]);
                    }
                    fputs("\n",stdout);
            }
    }

    return(0);
}
〜〜〜〜〜〜以上、tstprg.c〜〜〜〜〜〜〜
※いろいろ設定していたためincludeに不要なものも含まれておりますがご容赦くだ
さい

<コンパイル>
cc -o tstprg tstprg.c

<実行結果>
# tstprg
start
fd1 /dev/pts/1              ←ここで別端末より echo "12345" > /dev/pts/1 を
実行
select sts=1 max=3 fd1=3
read1 sts=7
31323334350d0a
select sts=1 max=3 fd1=3    ←全データread済だがselectにて読取可と判断
read1 sts=-1                ←readにてEIOエラー
read: Input/output error
#

<上記プログラム内容以外で試したこと>
以下のロケールでのコンパイル&実行
 Ja_JP.SJIS, ja_JP.UTF8
Fcntlでの設定
 O_NDELAY, O_NONBLOCK, O_DIRECT
Ioctlでの設定
 ICRNL, INLCR, IGNCR
 -ICANON, VMIN=1, VTIME=1
CentOS5.8環境でのコンパイル&実行
→以上すべて同様の結果
初回read後、select前に再度readを実行
→read時、同様にEIOエラー


CentOS5.8でも同様の現象がでますのでおそらく自分の設定の問題だとは思います
が、
自分なりに調べてはみたものの、スキル不足もあり原因不明の状態です。
原因、もしくは調査のヒントなどをご教示頂けると助かります。

以上、恐縮ですが宜しくお願い致します。



centos-users メーリングリストの案内