]> ruderich.org/simon Gitweb - coloredstderr/coloredstderr.git/commitdiff
Hook vfork() and replace it with fork().
authorSimon Ruderich <simon@ruderich.org>
Sun, 2 Jun 2013 16:25:49 +0000 (18:25 +0200)
committerSimon Ruderich <simon@ruderich.org>
Sun, 2 Jun 2013 16:25:49 +0000 (18:25 +0200)
.gitignore
src/coloredstderr.c
tests/Makefile.am
tests/example_vfork.c [new file with mode: 0644]
tests/example_vfork.expected [new file with mode: 0644]
tests/run.sh

index 0148b421e2edd83d9a409a08506e067bfea85416..bab1c5a07f1b62128c64e56075e0d534638e75fd 100644 (file)
@@ -23,6 +23,8 @@
 /tests/Makefile.in
 /tests/example
 /tests/example.o
+/tests/example_vfork
+/tests/example_vfork.o
 /tests/run.sh.log
 /tests/run.sh.trs
 /tests/test-suite.log
index b16633f8534b8b7d9a1e4fdc64532a185497c598..9ade423a4ed99c78000ab2a22de623ab5476074b 100644 (file)
@@ -326,3 +326,21 @@ int fclose(FILE *fp) {
     close_fd(fileno(fp));
     return real_fclose(fp);
 }
+
+
+/* Hook functions which are necessary for correct tracking. */
+
+pid_t vfork(void) {
+    /* vfork() is similar to fork() but the address space is shared between
+     * father and child. It's designed for fork()/exec() usage because it's
+     * faster than fork(). However according to the POSIX standard the "child"
+     * isn't allowed to perform any memory-modifications before the exec()
+     * (except the pid_t result variable of vfork()).
+     *
+     * As some programs don't adhere to the standard (e.g. the "child" closes
+     * or dups a descriptor before the exec()) and this breaks our tracking of
+     * file descriptors (e.g. it gets closed in the parent as well), we just
+     * fork() instead. This is in compliance with the POSIX standard and as
+     * most systems use copy-on-write anyway not a performance issue. */
+    return fork();
+}
index 9928cdc23de55b61d67f2d0235a76948a34294df..bfaaea2edaaecff34a4f127359c7037413d23c25 100644 (file)
@@ -1,9 +1,11 @@
 TESTS = run.sh
-check_PROGRAMS = example
+check_PROGRAMS = example example_vfork
 example_SOURCES = example.c
+example_vfork_SOURCES = example_vfork.c
 
 dist_check_SCRIPTS = run.sh lib.sh
 dist_check_DATA = example.expected \
+                  example_vfork.expected \
                   example-noforce.sh \
                   example-noforce.sh.expected \
                   example-redirects.sh \
diff --git a/tests/example_vfork.c b/tests/example_vfork.c
new file mode 100644 (file)
index 0000000..35ceaf4
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Test issues with vfork().
+ *
+ * Copyright (C) 2013  Simon Ruderich
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+    pid_t pid;
+
+    fprintf(stderr, "Before vfork().\n");
+
+    pid = vfork();
+    if (pid == 0) {
+        /* This violates the POSIX standard! The "child" is only allowed to
+         * modify the result of vfork(), e.g. the pid variable. Some programs
+         * (e.g. gdb) do it anyway so we have to workaround it. */
+        dup2(STDOUT_FILENO, STDERR_FILENO);
+
+        _exit(2);
+    }
+
+    fprintf(stderr, "After vfork().\n");
+    puts("");
+
+    return EXIT_SUCCESS;
+}
diff --git a/tests/example_vfork.expected b/tests/example_vfork.expected
new file mode 100644 (file)
index 0000000..0be6ad8
--- /dev/null
@@ -0,0 +1,3 @@
+>stderr>Before vfork().
+<stderr<>stderr>After vfork().
+<stderr<
index 1adadd5ec4815a2a2b3db9f50adf53284b26b634..1dc800f17af8110376153abe7411884d32a44209 100755 (executable)
@@ -33,3 +33,4 @@ force_write=1
 test_script example-simple.sh
 test_script example-redirects.sh
 test_program example
+test_program example_vfork