有効な読み込み用ストリームのファイルディスクリプタfdがあり、これは、ファイルであるか、ソケットであるか、パイプであるか分かりません。
このとき、fdに対して、peek操作(一文字読み込むが、ストリームの位置は変えない)を実行することは可能でしょうか?
> fdに対して、peek操作(一文字読み込むが、ストリームの位置は変えない)を実行することは可能でしょうか?
結論から言うとファイルディスクリプタ「だけ」では無理です。
何故ならファイルディスクリプタに対してread(2)してしまった時点でストリーム位置が変更されてしまい、
その後、一部のファイルはlseek(2)を使って戻すことはできますが、ソケット、パイプは戻せません
# 一部のファイルとはテープデバイスとかのseekが面倒なデバイスです
この場合のpeekの実装方法ですが、fdopen(3C)でファイルディスクリプタから
ファイルストリームを生成して、
fgetc(3C), ungetc(3C)を行えばファイルストリーム上の位置を変えずにデータの読み出しは可能です
# でも、ファイルディスクリプタの位置は変更されます
なので、以降の処理はファイルストリームに対して読み書きを行う必要があり、
うっかりファイルディスクリプタに対して読み書きを行うとおかしなことになります。
> ファイルディスクリプタfdがあり、これは、ファイルであるか、
> ソケットであるか、パイプであるか分かりません。
↓こうすればわかるはず.
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> struct stat st; int fd = (謎のファイルディスクリプタ); if(fstat(fd, &st) < 0) goto Error; switch(st.st_mode & S_IFMT) { case S_IFREG: // fd は通常のファイル : : break; case S_IFSOCK: // fd はソケット : : break; case S_IFIFO: // fd は名前付パイプ : : break; // 以下略 }
fstat() のマニュアル
http://www.linux.or.jp/JM/html/LDP_man-pages/man2/fstat.2.html
ありがとうございます。
なるほど、こんな方法があったんですね。
これなら、最大限の柔軟性を実現できますね。
ありがとうございます。
ファイルストリームで統一的に扱う方向で検討中です。