+++ /dev/null
-#define _GNU_SOURCE 1
-#include <dlfcn.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-static int (*fputs2) (const char *s, FILE *stream) = NULL;
-static size_t (*fwrite2) (const void *ptr, size_t size, size_t nmemb,
- FILE *stream);
-static int is_gdb;
-
-static void __attribute__((constructor))
-init (void)
-{
- if (getenv ("WRITEW_IS_GDB"))
- {
- /* GDB */
- unsetenv ("LD_PRELOAD");
- is_gdb = 1;
- }
- else
- {
- /* expect */
- setenv ("WRITEW_IS_GDB", "1", 1);
- }
- fputs2 = dlsym (RTLD_NEXT, "fputs");
- assert (fputs2 != NULL);
- fwrite2 = dlsym (RTLD_NEXT, "fwrite");
- assert (fwrite2 != NULL);
-}
-
-static int
-pid_is_sleeping (pid_t pid)
-{
- FILE *status_file;
- char buf[100];
- int retval = 0;
-
- snprintf (buf, sizeof (buf), "/proc/%d/status", (int) pid);
- status_file = fopen (buf, "r");
- if (status_file != NULL)
- {
- int have_state = 0;
-
- while (fgets (buf, sizeof (buf), status_file))
- {
- if (strncmp (buf, "State:", 6) == 0)
- {
- have_state = 1;
- break;
- }
- }
- if (have_state && strstr (buf, "S (sleeping)") != NULL)
- retval = 1;
- fclose (status_file);
- }
- return retval;
-}
-
-static void
-delay (void)
-{
- pid_t expect_pid = getppid ();
-
- do
- usleep (1000 * 1000 / 100);
- while (!pid_is_sleeping (expect_pid));
-}
-
-int
-fputs (const char *s, FILE *stream)
-{
- int retval = fputs2 (s, stream);
-
- if (is_gdb && fileno (stream) == STDOUT_FILENO && strchr (s, '\n'))
- delay ();
-
- return retval;
-}
-
-size_t
-fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
- size_t retval = fwrite2 (ptr, size, nmemb, stream);
-
- if (is_gdb && fileno (stream) == STDOUT_FILENO
- && memchr (ptr, '\n', size * nmemb))
- delay ();
-
- return retval;
-}