Невозможно изменить размер буфера канала дочернего процесса.Linux

Ответить
Anonymous
 Невозможно изменить размер буфера канала дочернего процесса.

Сообщение Anonymous »

Я хочу запустить tcpdump на 5 секунд и получить его стандартный вывод. Проблема в том, что когда я читаю в неблокирующем режиме, все работает как положено. Но поскольку я не хочу застревать в чтении, я использую неблокирующее чтение. Когда я использую неблокирующее чтение, я получаю стандартный вывод tcpdump каждые 4096 байт. Я искал много раз и пробовал много вещей, но все равно безуспешно.
Пожалуйста, скажите мне, что я делаю неправильно. Как я могу читать в неблокирующем режиме из стандартного вывода дочернего процесса, не дожидаясь заполнения его буфера?
#include
#include
#include
#include
#include
#include
#include

#define PIPE_READ 0
#define PIPE_WRITE 1

// Function to set a file descriptor to non-blocking mode
void set_nonblocking(int fd) {
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
perror("fcntl F_GETFL");
exit(1);
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
perror("fcntl F_SETFL");
exit(1);
}
}

int main() {
int stdout_pipe[2], stderr_pipe[2];
pid_t pid;

// Create two pipes: one for stdout, one for stderr
if (pipe(stdout_pipe) == -1) {
perror("pipe stdout");
exit(1);
}
if (pipe(stderr_pipe) == -1) {
perror("pipe stderr");
exit(1);
}

// Fork the process
pid = fork();

if (pid == -1) {
// Error during fork
perror("fork");
exit(1);
}

if (pid == 0) { // Child process
// Close the unused ends of the pipes in the child
close(stdout_pipe[PIPE_READ]);
close(stderr_pipe[PIPE_READ]);

// Set stdout and stderr to be unbuffered
setvbuf(stdout, NULL, _IONBF, 0); // Unbuffered stdout
setvbuf(stderr, NULL, _IONBF, 0); // Unbuffered stderr

// Redirect stdout and stderr to the pipes
dup2(stdout_pipe[PIPE_WRITE], STDOUT_FILENO);
dup2(stderr_pipe[PIPE_WRITE], STDERR_FILENO);

// Close the pipe write ends since they're now redirected
close(stdout_pipe[PIPE_WRITE]);
close(stderr_pipe[PIPE_WRITE]);

// Child runs tcpdump (for example)
execlp("timeout", "timeout", "5s", "tcpdump", "src", "port", "41972", (char *)NULL);

// If execlp fails
perror("execlp");
exit(1);
} else { // Parent process
char buffer[256];
int status;
ssize_t nbytes;

// Close the unused ends of the pipes in the parent
close(stdout_pipe[PIPE_WRITE]);
close(stderr_pipe[PIPE_WRITE]);

// Set both pipe file descriptors to non-blocking
set_nonblocking(stdout_pipe[PIPE_READ]);
set_nonblocking(stderr_pipe[PIPE_READ]);

// Parent process reads from the pipes in non-blocking mode
printf("Parent is reading from child's stdout:\n");
while (1) {
// Try to read from stdout pipe
nbytes = read(stdout_pipe[PIPE_READ], buffer, sizeof(buffer) - 1);
if (nbytes > 0) {
buffer[nbytes] = '\0'; // Null-terminate the string
printf("%s", buffer);
} else if (nbytes == 0) {
// EOF reached (child process closed its end)
break;
} else if (errno != EAGAIN && errno != EWOULDBLOCK) {
// Handle other errors
perror("read stdout");
break;
}

// Try to read from stderr pipe
nbytes = read(stderr_pipe[PIPE_READ], buffer, sizeof(buffer) - 1);
if (nbytes > 0) {
buffer[nbytes] = '\0'; // Null-terminate the string
printf("%s", buffer);
} else if (nbytes == 0) {
// EOF reached (child process closed its end)
break;
} else if (errno != EAGAIN && errno != EWOULDBLOCK) {
// Handle other errors
perror("read stderr");
break;
}

// Sleep for a short time to avoid tight loop (can adjust as needed)
usleep(100000); // sleep for 100ms
}

// Wait for the child process to exit
waitpid(pid, &status, 0);

// Close the pipe read ends in the parent
close(stdout_pipe[PIPE_READ]);
close(stderr_pipe[PIPE_READ]);
}

return 0;
}


Подробнее здесь: https://stackoverflow.com/questions/792 ... uffer-size
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»