出力を生成する別のプロセスからの出力を読み取っています(低速で無限)。このデータをリアルタイムで読み取りたいので、「stdbuf -oL」(行バッファー、データはテキスト)を使用します。生成プロセスを制御できないため、ソースを変更して強制的にフラッシュすることはできません。
これまでのところ、stdbufは問題なく動作しますが、プロセスはSOCK_RAWを使用し、rootとして実行するか、setuid(0)またはcap_net_raw
機能を備えている必要があります。setuidまたは機能を使用して非rootとして実行している場合、stdbufは無視されるようです。問題を説明しましょう:
これは単純なライターです。
#include <stdio.h>
#include <unistd.h>
int main(){
int i;
for ( i = 0;; i++){
fprintf(stdout, "%d\n", i);
sleep(1);
}
}
そして簡単な読者:
#include <stdio.h>
int main(){
char* line = NULL;
size_t n = 0;
while (getline(&line, &n, stdin) != -1 ) {
fputs(line, stdout);
}
}
予想通り、実行./writer | ./reader
してもバッファがいっぱいになるまで何も表示されません。プリペンディングstdbuf -oL
はラインバッファリングを有効にし、リーダーにラインを取得します。
% stdbuf -oL ./writer | ./reader
0
1
2
...
しかし、追加すると機能cap_net_raw+ep
しなくなります。
% sudo setcap cap_net_raw+ep ./writer
% stdbuf -oL ./writer | ./reader
(no output)
setuidを使用した場合も、同じ動作が見られます。
% sudo chown root:root ./writer
% sudo chmod +s ./writer
% stdbuf -oL ./writer | ./reader
(no output)
これが発生する理由と、rootとして実行せずにstdbufを引き続き使用する方法を理解することに興味があります。setuidが舞台裏で何をしているのか完全には理解していないことを認めます。