【发布时间】:2012-11-18 14:28:50
【问题描述】:
我正在读取另一个生成输出(缓慢且无限)的进程的输出。因为我想实时读取这些数据,所以我使用“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 在幕后所做的事情。
【问题讨论】:
-
getline() 中使用了什么函数?
-
该示例使用 GNU getline(可与 -std=gnu99 一起使用),但行为与 fread 相同。
-
你用strace看过了吗?
标签: c linux buffering setuid linux-capabilities