2017-02-12 10 views
0

私はZshモジュールを書いています。私はZshコマンドにマップされた組み込み関数を持っています。 oconf構造を取得し、その後、スレッドが生成されるdup(fileno(stdin))そして32スレッドの生成 - >入出力エラー

/* Duplicate standard input */ 
oconf->stream = fdopen(dup(fileno(stdin)), "r"); 

:この関数は、標準入力ファイル記述子を複製します。そのスレッドでは、私が行います

errno = 0; 

/* Read e.g. 5 characters, putting them after previous portion */ 
int count = fread(buf + index, 1, read_size, oconf->stream); 
/* Ensure that our whole data is a string - null terminated */ 
buf[ index + count ] = '\0'; 

if (errno) { 
    fprintf(oconf->err, "Read error (descriptor: %d): %s\n", fileno(oconf->stream), strerror(errno) > 
} 

私はzshの中に32件のスレッド産卵場合:2-3次に

for ((i=1; i<=32; i ++)); do 
    ls -R /Users/myuser/Documents | mybuiltin -A myhash_$i $i 
done 

をスレッドは例えば、上記fprintf()から報告されたI/Oエラーがあります。

読み取りエラー(記述子:7):入力/出力エラー

読み取りエラー(記述子:5):デバイスのための不適切IOCTL

読み取りエラー(記述子:14):デバイス

ための不適切なioctlのデバッガは、それらのスレッドは、複数の(5-20​​)のfread()繰り返した後、カーネルの__read_nocancel()にブロックされ得ることを述べています。だから、本当に悪いことがファイル記述子で起こっています。

これ以外の場合は、これが機能します。パイプは正しくls -Rのデータを渡し、カスタムの組み込み関数によって読み取られます。それで危険はどこですか?どのようにしてdup()がメインスレッドで実行されると、何かが読めなくなりますfread()?二次スレッドでdup()を実行するかどうか疑問に思うかもしれません。しかし、私はそれを安全な場所にとどめておきます。メインスレッドは、FILE *ストリームをセカンダリスレッドに渡します。また、POSIX open()read()およびclose()で試してみると、結果は同じです。

答えて

0

errnoを間違ってテストしています。 errnoを設定する関数がエラーを報告した場合にのみチェックする必要があります。標準のCまたはPOSIXライブラリの関数では、errnoがゼロに設定されることはありません。また、関数はエラーを報告することなくerrnoを非ゼロに設定することがあります。

たとえば、Solarisでは、ファイルストリームが端末ではない場合(たとえば、ファイルやパイプにリダイレクトされた場合)、書き込み操作後には大文字と小文字の区別がありました。問題はなかった。出力デバイスは端末ではないため、端末のみの操作は失敗し、errnoENOTTYに設定しました。

/* Read e.g. 5 characters, putting them after previous portion */ 
int count = fread(buf + index, 1, read_size, oconf->stream); 
/* Ensure that our whole data is a string - null terminated */ 
buf[ index + count ] = '\0'; 

if (errno) { 
    fprintf(oconf->err, "Read error (descriptor: %d): %s\n", fileno(oconf->stream), strerror(errno)); 
} 

あなたはより多くのようなものを使用する必要があります:あなたが現在持っている

あなたはおそらく他のいくつかのフロー制御の詳細必要があります(リターンまたは壊すか、設定されたフラグ)

int count = fread(buf + index, 1, read_size, oconf->stream); 
if (count == 0) 
{ 
    /* EOF or error — this might be a time to use feof() or ferror() */ 
    fprintf(oconf->err, "Read error (descriptor: %d): %s\n", fileno(oconf->stream), strerror(errno)); 
    …flow control?… 
} 
else 
    buf[index + count] = '\0'; 

でEOFとエラーパス。あなたの引用された断片からは、適切かもしれないものは明確ではありません。

関連する問題