Ah, so that happens in check_file_stream(), here in particular if the file changed underneath:
if (old_stats.st_ino != new_stats.st_ino || old_stats.st_dev != new_stats.st_dev) { g_debug ("File %s has been replaced; writing to end of new file", event_logger->priv->log_filename); reopen_file_stream (event_logger);
I just checked the code, and priv->file is only ever fdopen()'ed from priv->fd. Now man fdopen explains the crash: "The file descriptor is not dup’ed, and will be closed when the stream created by fdopen() is closed.".
Thus it seems this crash is due to close()ing priv->fd twice in reopen_file_stream():
close (event_logger->priv->fd);
fclose (event_logger->priv->file);
I confirmed that by instrumenting reopen_file_stream():
g_debug ("Reopening %s", event_logger->priv->log_filename);
close (event_logger->priv->fd);
if (fclose (event_logger->priv->file) != 0) perror("fclose");
started the daemon, did a "rm /var/log/ConsoleKit/history; touch /var/log/ConsoleKit/history; ck-launch-session" and got
console-kit-daemon[15108]: DEBUG: Reopening /var/log/ConsoleKit/history
fclose: Bad file descriptor
Now I'm unclear why this actually causes a segfault at times, and not just a failed close() call, but that's something for the glibc developers to ask, I think.
In any case it is correct to remove the first close(). fclose() will flush the stream and call close() on priv->fd.
Ah, so that happens in check_file_ stream( ), here in particular if the file changed underneath:
if (old_stats.st_ino != new_stats.st_ino || old_stats.st_dev != new_stats.st_dev) {
g_debug ("File %s has been replaced; writing to end of new file", event_logger- >priv-> log_filename) ;
reopen_ file_stream (event_logger);
I just checked the code, and priv->file is only ever fdopen()'ed from priv->fd. Now man fdopen explains the crash: "The file descriptor is not dup’ed, and will be closed when the stream created by fdopen() is closed.".
Thus it seems this crash is due to close()ing priv->fd twice in reopen_ file_stream( ):
close (event_ logger- >priv-> fd); logger- >priv-> file);
fclose (event_
I confirmed that by instrumenting reopen_ file_stream( ):
g_debug ("Reopening %s", event_logger- >priv-> log_filename) ; logger- >priv-> fd); logger- >priv-> file) != 0)
perror( "fclose" );
close (event_
if (fclose (event_
started the daemon, did a "rm /var/log/ ConsoleKit/ history; touch /var/log/ ConsoleKit/ history; ck-launch-session" and got
console- kit-daemon[ 15108]: DEBUG: Reopening /var/log/ ConsoleKit/ history
fclose: Bad file descriptor
Now I'm unclear why this actually causes a segfault at times, and not just a failed close() call, but that's something for the glibc developers to ask, I think.
In any case it is correct to remove the first close(). fclose() will flush the stream and call close() on priv->fd.