Как вы заставляете процесс сбрасывать данные, записанные в дескриптор открытого файла под Linux?

У меня есть двоичный процесс (без доступных источников), работающий на встроенной системе Linux. Процесс открывает файл журнала (/tmp/dmaosd.log), где он записывает, что он делает.

Проблема в том, что журнал обновляется порциями (около 1000 байт за раз), поэтому я не могу смотреть журнал в режиме реального времени с помощью tail -f.

Интересно, есть ли способ заставить работающий процесс сбрасывать свои данные (основываясь на доступе к /proc/1234/fd/3), не имея доступа к его источникам и не посылая ему никаких сигналов (я не уверен, какие сигналы он не поддерживает ни то, что они должны делать).

Рассматриваемый процесс - это экранное меню для медиаплеера, и информация в журнале обычно показывает, какие элементы выбраны / показаны на экране, поэтому было бы неплохо получить данные как можно быстрее.

Спасибо!

1 ответ

Решение

Это действительно зависит от того, где находится буфер: если приложение использует свой собственный буфер журналирования, то нет способа принудительно выполнить сброс.

Если буферизация выполняется библиотекой C, вы можете использовать LD_PRELOAD, чтобы отключить буферизацию. Предполагая, что программа использует fopen() чтобы открыть его файл журнала, вы можете сделать что-то вроде этого:

#define _GNU_SOURCE 1
#include <dlfcn.h>
#include <stdio.h>

static FILE* (*libc_fopen)(char const *, char const *);

FILE * fopen(char const *name, char const *mode) {
    FILE *ret;
    if (!libc_fopen)
        libc_fopen = dlsym(RTLD_NEXT, "fopen");

    ret = libc_fopen(name, mode);
    if (!ret)
        return ret;

    setvbuf(ret, NULL, _IONBF, 0);

    return ret;
}

Скомпилируйте как общую библиотеку, а затем используйте LD_PRELOAD, чтобы "внедрить" в программу:

LD_PRELOAD=./nobuffering.so myprogram

Если вы хотите, вы также можете проверить имя файла и изменить буферизацию только для интересующего вас файла журнала.

Другие вопросы по тегам