Я читаю вывод из другого процесса, который генерирует выходной (медленный и бесконечный). Поскольку я хочу читать эти данные в режиме реального времени, я использую "stdbuf -oL" (строка-буферизация, данные - текст). Я не контролирую процесс генерации, поэтому я не могу изменить источник для принудительной промывки.
Пока stdbuf работает отлично, однако процесс использует SOCK_RAW и должен либо запускаться как root, либо иметь setuid (0) или cap_net_raw
. При запуске как не-root с setuid или возможностями 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
ничего не отображается до заполнения буфера. Prepending 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)
Мне интересно понять, почему это происходит, и как я могу продолжать использовать stdbuf без запуска от root. Я признаю, что я не совсем понимаю, что делает setuid за кулисами.