For runtest-writev.
authorJan Kratochvil <jan.kratochvil@redhat.com>
Sun, 6 Nov 2011 15:34:13 +0000 (16:34 +0100)
committerJan Kratochvil <jan.kratochvil@redhat.com>
Sun, 6 Nov 2011 15:34:13 +0000 (16:34 +0100)
redhat/my/writew.c [new file with mode: 0644]

diff --git a/redhat/my/writew.c b/redhat/my/writew.c
new file mode 100644 (file)
index 0000000..3206161
--- /dev/null
@@ -0,0 +1,94 @@
+#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;
+}