How to force a process to flush the data written to an open file descriptor under Linux

log-filesmax-file-descriptorsprocessrealtime

I have a binary process (with no sources available) running on an embedded Linux system. The process opens a log file (/tmp/dmaosd.log) where it logs what it's doing.

The problem is the log gets updated in chunks (about 1000 bytes at a time), so I can't watch the log in real time with tail -f.

I wonder if there is any way to force the running process to flush its data (based on accessing /proc/1234/fd/3) without having access to its sources and without sending any signals to it (I'm not sure what signals it supports nor what they are supposed to do).

The process in question is an OSD for a media player, and the log info usually shows what elements are selected/shown onscreen, so it would be nice to have the data as quickly as possible.

Thanks!

Best Answer

It really depends on where the buffer is: if the application uses its own logging buffer then there's no way of forcing a flush.

If the buffering is done by the C library then you can use LD_PRELOAD to disable the buffering. Assuming that the program is using fopen() to open its log file you can do something like this:

#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;
}

Compile as a shared library and then use LD_PRELOAD to "inject" into the program:

LD_PRELOAD=./nobuffering.so myprogram

If you want you can also check the name of the file and change the buffering only for the log file you're interested in.