autoconf
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [autoconf] AmigaOS fork()


From: Rüdiger Kuhlmann
Subject: Re: [autoconf] AmigaOS fork()
Date: Thu, 31 May 2001 21:53:00 +0200
User-agent: Mutt/1.3.17i

>--[Akim Demaille]--<address@hidden>

> don't know enough about vfork and fork to speak intelligently here,
> but I seem to understand that using AC_REPLACE_FUNCS would be better
> suited then, no?  I mean, from the user point of view, not for the
> tests themselves.

What do you mean? If you don't have a fork(), you can't replace it.
To have a fork() on AmigaOS you'd need to write a new OS.

> s/FUN/FUNC/.
> Isn't it ditto?

Okay, there were even more typos...

> Independent comment: personally, I don't like this `feature' of
> Autoconf.  Maybe in the future we should move this #define vfork fork
> under the responsability of the user, say in system.h.

AOL

> Hm...  Do we really want _two_ macros here?

Actually, they're related anyway, so I put them into one macro,
obsoleting AC_FUNC_VFORK.

> Are you German?  :)  s/ist/is/.

Yes, I am. Damn! Usually I notice such stuff myself...

Btw, why does AC_FUNC_FNMATCH define HAVE_FNMATCH instead of
HAVE_WORKING_FNMATCH?

Next try:

2001-05-31 Rüdiger Kuhlmann <address@hidden>

        * acfunctions.m4: (AC_FUNC_FORK) New, check whether fork() isn't just
          a stub and define HAVE_WORKING_FORK if it works. Also, take over the
          work of AC_FUNC_VFORK, and define HAVE_WORKING_VFORK the same way.
          (AC_FUNC_VFORK) obsolete.
          (AC_FUNC_GETPGRP, AC_FUNC_WAIT3) Use AC_FUNC_FORK and #define fork
          to vfork if necessary.
        * acspecific.m4: (AC_SYS_RESTARTABLE_SYSCALLS) ditto.
        * acfunctions: add AC_FUNC_FORK.
        * doc/autoconf.texi: Document AC_FUNC_FORK. Give example to
          define forkvfork and vfork appropriately.

Index: acfunctions
===================================================================
RCS file: /cvs/autoconf/acfunctions,v
retrieving revision 1.13
diff -u -r1.13 acfunctions
--- acfunctions 2001/01/24 07:58:59     1.13
+++ acfunctions 2001/05/31 19:47:22
@@ -7,6 +7,7 @@
 error          AC_FUNC_ERROR_AT_LINE
 error_at_line  AC_FUNC_ERROR_AT_LINE
 fnmatch                AC_FUNC_FNMATCH
+fork           AC_FUNC_FORK     
 fseeko         AC_FUNC_FSEEKO
 ftello         AC_FUNC_FSEEKO
 getgroups      AC_FUNC_GETGROUPS
@@ -37,7 +38,7 @@
 strftime       AC_FUNC_STRFTIME
 strtod         AC_FUNC_STRTOD
 utime          AC_FUNC_UTIME_NULL
-vfork          AC_FUNC_VFORK
+vfork          AC_FUNC_FORK
 vfprintf       AC_FUNC_VPRINTF
 vprintf                AC_FUNC_VPRINTF
 vsprintf       AC_FUNC_VPRINTF
Index: acfunctions.m4
===================================================================
RCS file: /cvs/autoconf/acfunctions.m4,v
retrieving revision 1.33
diff -u -r1.33 acfunctions.m4
--- acfunctions.m4      2001/04/22 12:50:07     1.33
+++ acfunctions.m4      2001/05/31 19:47:25
@@ -599,7 +599,8 @@
 # AC_FUNC_GETPGRP
 # ---------------
 AC_DEFUN([AC_FUNC_GETPGRP],
-[AC_CACHE_CHECK(whether getpgrp takes no argument, ac_cv_func_getpgrp_void,
+[AC_REQUIRE([AC_FUNC_FORK])dnl
+AC_CACHE_CHECK(whether getpgrp takes no argument, ac_cv_func_getpgrp_void,
 [AC_RUN_IFELSE([AC_LANG_SOURCE([[
 /*
  * If this system has a BSD-style getpgrp(),
@@ -609,6 +610,9 @@
  */
 #include <stdio.h>
 #include <sys/types.h>
+#if !HAVE_WORKING_FORK
+# define fork vfork
+#endif
 
 int     pid;
 int     pg1, pg2, pg3, pg4;
@@ -1442,118 +1446,169 @@
 AU_ALIAS([AC_UTIME_NULL], [AC_FUNC_UTIME_NULL])
 
 
-# AC_FUNC_VFORK
+# AC_FUNC_FORK
 # -------------
-AC_DEFUN([AC_FUNC_VFORK],
-[AC_REQUIRE([AC_TYPE_PID_T])dnl
-AC_CHECK_HEADERS(unistd.h vfork.h)
-AC_CACHE_CHECK(for working vfork, ac_cv_func_vfork_works,
-[AC_TRY_RUN([/* Thanks to Paul Eggert for this test.  */
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#if HAVE_VFORK_H
-# include <vfork.h>
-#endif
-/* On some sparc systems, changes by the child to local and incoming
-   argument registers are propagated back to the parent.  The compiler
-   is told about this with #include <vfork.h>, but some compilers
-   (e.g. gcc -O) don't grok <vfork.h>.  Test for this by using a
-   static variable whose address is put into a register that is
-   clobbered by the vfork.  */
-static
-#ifdef __cplusplus
-sparc_address_test (int arg)
-# else
-sparc_address_test (arg) int arg;
-#endif
-{
-  static pid_t child;
-  if (!child) {
-    child = vfork ();
-    if (child < 0) {
-      perror ("vfork");
-      _exit(2);
-    }
-    if (!child) {
-      arg = getpid();
-      write(-1, "", 0);
-      _exit (arg);
-    }
-  }
-}
-
-int
-main ()
-{
-  pid_t parent = getpid ();
-  pid_t child;
-
-  sparc_address_test ();
-
-  child = vfork ();
+AC_DEFUN([AC_FUNC_FORK],
+  [AC_REQUIRE([AC_TYPE_PID_T])dnl
+  AC_CHECK_HEADERS(unistd.h vfork.h)
+  AC_CHECK_FUNCS(fork vfork)
+  ac_cv_func_fork_works=$ac_cv_func_fork
+  if test "x$ac_cv_func_fork" = xyes; then
+    AC_CACHE_CHECK(for working fork, ac_cv_func_fork_works,
+      [AC_RUN_IFELSE([/* By Rüdiger Kuhlmann. */
+        #include <sys/types.h>
+        #if HAVE_UNISTD_H
+        # include <unistd.h>
+        #endif
+        /* Some systems only have a dummy stub for fork() */
+        int main ()
+        {
+          if (fork() < 0)
+            exit (1);
+          exit (0);
+        }],
+      [ac_cv_func_fork_works=yes],
+      [ac_cv_func_fork_works=no],
+      [ac_cv_func_fork_works=cross])])
+  fi
+  if test "x$ac_cv_func_fork_works" = xcross"; then
+    case "$host" in
+      *-*-amigaos* | *-*-msdosdjgpp*)
+        # Override, as these systems have only a dummy fork() stub
+        ac_cv_func_fork_works=no
+        ;;
+      *)
+        ac_cv_func_fork_works=yes
+        ;;
+    esac
+    AC_MSG_WARN(CROSS: Result $ac_cv_func_fork_works guessed due to 
cross-compiling.)
+  fi
+  ac_cv_func_vfork_works=$ac_cv_func_vfork
+  if test "x$ac_cv_func_vfork" = xyes; then
+    AC_CACHE_CHECK(for working vfork, ac_cv_func_vfork_works,
+      [AC_RUN_IFELSE([/* Thanks to Paul Eggert for this test.  */
+        #include <stdio.h>
+        #include <sys/types.h>
+        #include <sys/stat.h>
+        #if HAVE_UNISTD_H
+        # include <unistd.h>
+        #endif
+        #if HAVE_VFORK_H
+        # include <vfork.h>
+        #endif
+        /* On some sparc systems, changes by the child to local and incoming
+           argument registers are propagated back to the parent.  The compiler
+           is told about this with #include <vfork.h>, but some compilers
+           (e.g. gcc -O) don't grok <vfork.h>.  Test for this by using a
+           static variable whose address is put into a register that is
+           clobbered by the vfork.  */
+        static
+        #ifdef __cplusplus
+        sparc_address_test (int arg)
+        # else
+        sparc_address_test (arg) int arg;
+        #endif
+        {
+          static pid_t child;
+          if (!child) {
+            child = vfork ();
+            if (child < 0) {
+              perror ("vfork");
+              _exit(2);
+            }
+            if (!child) {
+              arg = getpid();
+              write(-1, "", 0);
+              _exit (arg);
+            }
+          }
+        }
+
+        int
+        main ()
+        {
+          pid_t parent = getpid ();
+          pid_t child;
+
+          sparc_address_test ();
+
+          child = vfork ();
+
+          if (child == 0) {
+            /* Here is another test for sparc vfork register problems.  This
+               test uses lots of local variables, at least as many local
+               variables as main has allocated so far including compiler
+               temporaries.  4 locals are enough for gcc 1.40.3 on a Solaris
+               4.1.3 sparc, but we use 8 to be safe.  A buggy compiler should
+               reuse the register of parent for one of the local variables,
+               since it will think that parent can't possibly be used any more
+               in this routine.  Assigning to the local variable will thus
+               munge parent in the parent process.  */
+            pid_t
+              p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+              p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+            /* Convince the compiler that p..p7 are live; otherwise, it might
+               use the same hardware register for all 8 local variables.  */
+            if (p != p1 || p != p2 || p != p3 || p != p4
+                || p != p5 || p != p6 || p != p7)
+              _exit(1);
+
+            /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
+               from child file descriptors.  If the child closes a descriptor
+               before it execs or exits, this munges the parent's descriptor
+               as well.  Test for this by closing stdout in the child.  */
+            _exit(close(fileno(stdout)) != 0);
+          } else {
+            int status;
+            struct stat st;
+
+            while (wait(&status) != child)
+              ;
+            exit(
+                 /* Was there some problem with vforking?  */
+                 child < 0
+
+                 /* Did the child fail?  (This shouldn't happen.)  */
+                 || status
+
+                 /* Did the vfork/compiler bug occur?  */
+                 || parent != getpid()
+
+                 /* Did the file descriptor bug occur?  */
+                 || fstat(fileno(stdout), &st) != 0
+                 );
+          }
+        }],
+        [ac_cv_func_vfork_works=yes],
+        [ac_cv_func_vfork_works=no],
+        [ac_cv_func_vfork_works=cross])])
+  fi;
+  if test "x$ac_cv_func_fork_works" = xcross"; then
+    ac_cv_func_vfork_works=ac_cv_func_vfork
+    AC_MSG_WARN(CROSS: Result $ac_cv_func_vfork_works guessed due to 
cross-compiling.)
+  fi
+  
+  if test "x${ac_cv_func_fork_works}${ac_cv_func_vfork_works}" = xnono; then
+    AC_MSG_WARN(Neither working `fork' nor `vfork' found.)
+  fi
+  if test "x$ac_cv_func_vfork_works" = xyes; then
+    AC_DEFINE(HAVE_WORKING_VFORK, 1, [Define if `vfork' works.])
+  else
+    AC_DEFINE(vfork, fork, [Define as `fork' if `vfork' does not work.])
+  fi
+  if test "x$ac_cv_func_fork_works" = xyes; then
+    AC_DEFINE(HAVE_WORKING_FORK, 1, [Define if `fork' works.])
+  endif
+])# AC_FUNC_FORK
 
-  if (child == 0) {
-    /* Here is another test for sparc vfork register problems.  This
-       test uses lots of local variables, at least as many local
-       variables as main has allocated so far including compiler
-       temporaries.  4 locals are enough for gcc 1.40.3 on a Solaris
-       4.1.3 sparc, but we use 8 to be safe.  A buggy compiler should
-       reuse the register of parent for one of the local variables,
-       since it will think that parent can't possibly be used any more
-       in this routine.  Assigning to the local variable will thus
-       munge parent in the parent process.  */
-    pid_t
-      p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
-      p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
-    /* Convince the compiler that p..p7 are live; otherwise, it might
-       use the same hardware register for all 8 local variables.  */
-    if (p != p1 || p != p2 || p != p3 || p != p4
-       || p != p5 || p != p6 || p != p7)
-      _exit(1);
-
-    /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
-       from child file descriptors.  If the child closes a descriptor
-       before it execs or exits, this munges the parent's descriptor
-       as well.  Test for this by closing stdout in the child.  */
-    _exit(close(fileno(stdout)) != 0);
-  } else {
-    int status;
-    struct stat st;
-
-    while (wait(&status) != child)
-      ;
-    exit(
-        /* Was there some problem with vforking?  */
-        child < 0
-
-        /* Did the child fail?  (This shouldn't happen.)  */
-        || status
-
-        /* Did the vfork/compiler bug occur?  */
-        || parent != getpid()
-
-        /* Did the file descriptor bug occur?  */
-        || fstat(fileno(stdout), &st) != 0
-        );
-  }
-}],
-            [ac_cv_func_vfork_works=yes],
-            [ac_cv_func_vfork_works=no],
-            [AC_CHECK_FUNC(vfork)
-ac_cv_func_vfork_works=$ac_cv_func_vfork])])
-if test "x$ac_cv_func_vfork_works" = xno; then
-  AC_DEFINE(vfork, fork, [Define as `fork' if `vfork' does not work.])
-fi
-])# AC_FUNC_VFORK
 
+# AU::AC_FUNC_VFORK
+# ------------
+AU_ALIAS([AC_FUNC_VFORK], [AC_FUNC_FORK])
 
 # AU::AC_VFORK
 # ------------
-AU_ALIAS([AC_VFORK], [AC_FUNC_VFORK])
+AU_ALIAS([AC_VFORK], [AC_FUNC_FORK])
 
 
 # AC_FUNC_VPRINTF
@@ -1577,12 +1632,16 @@
 # AC_FUNC_WAIT3
 # -------------
 AC_DEFUN([AC_FUNC_WAIT3],
-[AC_CACHE_CHECK(for wait3 that fills in rusage, ac_cv_func_wait3_rusage,
+[AC_REQUIRE([AC_FUNC_FORK])dnl
+AC_CACHE_CHECK(for wait3 that fills in rusage, ac_cv_func_wait3_rusage,
 [AC_TRY_RUN(
 [#include <sys/types.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <stdio.h>
+#if !HAVE_WORKING_FORK
+# define fork vfork
+#endif
 /* HP-UX has wait3 but does not fill in rusage at all.  */
 int
 main ()
Index: acspecific.m4
===================================================================
RCS file: /cvs/autoconf/acspecific.m4,v
retrieving revision 1.338
diff -u -r1.338 acspecific.m4
--- acspecific.m4       2001/04/15 16:20:30     1.338
+++ acspecific.m4       2001/05/31 19:47:29
@@ -495,6 +495,7 @@
 # interrupted by a signal, define `HAVE_RESTARTABLE_SYSCALLS'.
 AC_DEFUN([AC_SYS_RESTARTABLE_SYSCALLS],
 [AC_REQUIRE([AC_HEADER_SYS_WAIT])dnl
+AC_REQUIRE([AC_FUNC_FORK])dnl
 AC_CHECK_HEADERS(unistd.h)
 AC_CACHE_CHECK(for restartable system calls, ac_cv_sys_restartable_syscalls,
 [AC_RUN_IFELSE([AC_LANG_SOURCE(
@@ -510,6 +511,9 @@
 #if HAVE_SYS_WAIT_H
 # include <sys/wait.h>
 #endif
+#if !HAVE_WORKING_FORK
+# define fork vfork
+#endif
 
 /* Some platforms explicitly require an extern "C" signal handler
    when using C++. */
Index: doc/autoconf.texi
===================================================================
RCS file: /cvs/autoconf/doc/autoconf.texi,v
retrieving revision 1.452
diff -u -r1.452 autoconf.texi
--- doc/autoconf.texi   2001/05/31 07:32:27     1.452
+++ doc/autoconf.texi   2001/05/31 19:47:46
@@ -3226,6 +3226,44 @@
 SunOS 5.4), define @code{HAVE_FNMATCH}.
 @end defmac
 
address@hidden AC_FUNC_FORK
address@hidden FUNC_FORK
address@hidden HAVE_VFORK_H
address@hidden HAVE_WORKING_FORK
address@hidden HAVE_WORKING_VFORK
address@hidden vfork
+This macro checks for the @code{fork} and @code{vfork} functions. If a
+working @code{fork} is found, define @code{HAVE_WORKING_FORK}. This macro
+only checks whether @code{fork} is just a stub.
+
+If @file{vfork.h} is found, define @code{HAVE_VFORK_H}. If a working
address@hidden is not found, define @code{vfork} to be @code{fork}, and define
address@hidden  This macro checks for several known errors in
+implementations of @code{vfork} and considers the system to not have a
+working @code{vfork} if it detects any of them.  It is not considered to be
+an implementation error if a child's invocation of @code{signal} modifies
+the parent's signal handler, since child processes rarely change their
+signal handlers.
+
+Typically, use
address@hidden
address@hidden
+#if HAVE_WORKING_FORK
+# define forkvfork fork
+#else
+# define forkvfork vfork
+#endif
+#if !HAVE_WORKING_VFORK
+# define vfork fork
+#endif
address@hidden group
address@hidden example
+and do not rely on @code{vfork} being defined to @code{fork} in later
+versions. This will give you a @code{forkvfork} function for calls
+to @code{fork} that can be replaced by calls to @code{vfork} if the
+former is just a stub.
address@hidden defmac
+
 @defmac AC_FUNC_FSEEKO
 @maindex FUNC_FSEEKO
 @cvindex _LARGEFILE_SOURCE
@@ -3456,19 +3494,6 @@
 the present, define @code{HAVE_UTIME_NULL}.
 @end defmac
 
address@hidden AC_FUNC_VFORK
address@hidden FUNC_VFORK
address@hidden HAVE_VFORK_H
address@hidden vfork
-If @file{vfork.h} is found, define @code{HAVE_VFORK_H}.  If a working
address@hidden is not found, define @code{vfork} to be @code{fork}.  This
-macro checks for several known errors in implementations of @code{vfork}
-and considers the system to not have a working @code{vfork} if it
-detects any of them.  It is not considered to be an implementation error
-if a child's invocation of @code{signal} modifies the parent's signal
-handler, since child processes rarely change their signal handlers.
address@hidden defmac
-
 @defmac AC_FUNC_VPRINTF
 @maindex FUNC_VPRINTF
 @cvindex HAVE_VPRINTF
@@ -9446,6 +9471,11 @@
 @defmac AC_FUNC_CHECK
 @maindex FUNC_CHECK
 @code{AC_CHECK_FUNC}
address@hidden defmac
+
address@hidden AC_FUNC_VFORK
address@hidden FUNC_VFORK
address@hidden
 @end defmac
 
 @defmac AC_GCC_TRADITIONAL


-- 
A "No" uttered from deepest conviction is better and greater than a
"Yes" merely uttered to please, or what is worse, to avoid trouble.
                -- Mahatma Ghandi



reply via email to

[Prev in Thread] Current Thread [Next in Thread]