Hi Johan, Thanks for the added details.
> The code actually works fine on FreeBSD 7.2 machines. It's also > fine on OpenBSD (4.7) and MacOS (Darwin 8.11). So it seems something was > changed / broken in FreeBSD 8.0. FreeBSD 8.0 has its own, new implementation of the posix_spawn* functions, whereas on the other platforms the gnulib replacement is used. > > This quickly identifies a problem: > > > > 2143 gm4 CALL sigprocmask(SIG_BLOCK,0x545a20,0) > > 2143 gm4 RET sigprocmask 0 > > 2143 gm4 CALL vfork > > 2144 gm4 RET fork 0 > > 2144 gm4 CALL sched_setscheduler(0,<invalid=0>,0x800a0e918) > > 2144 gm4 RET sched_setscheduler -1 errno 1 Operation not permitted > > 2144 gm4 CALL exit(0x7f) > > 2143 gm4 RET vfork 2144/0x860 > > 2143 gm4 CALL sigprocmask(SIG_UNBLOCK,0x545a20,0) > > 2143 gm4 RET sigprocmask 0 How come that sched_setscheduler is called? The only use of posix_spawn and posix_spawnp that is made by m4 1.4.14 (see lib/execute.c and lib/pipe.c) is with a flags value of POSIX_SPAWN_SETSIGMASK. Whereas in the native FreeBSD posix_spawn[p] (as well as in the gnulib replacement), sched_setscheduler is only called if the flags word contains the POSIX_SPAWN_SETSCHEDULER bit. FreeBSD's POSIX_SPAWN_SETSIGMASK is 0x20, FreeBSD's POSIX_SPAWN_SETSCHEDULER is 0x08. Whereas the gnulib replacement value for POSIX_SPAWN_SETSIGMASK is 0x08. It seems gnulib's replacement value is in use when it should not. I'm applying this fix. 2010-03-02 Bruno Haible <br...@clisp.org> spawn: Don't override the system defined values on FreeBSD 8. * lib/spawn.in.h (POSIX_SPAWN_RESETIDS, POSIX_SPAWN_SETPGROUP, POSIX_SPAWN_SETSIGDEF, POSIX_SPAWN_SETSIGMASK, POSIX_SPAWN_SETSCHEDPARAM, POSIX_SPAWN_SETSCHEDULER): Don't redefine if HAVE_POSIX_SPAWN is 1. Reported by Johan van Selst <joh...@stack.nl> via Eric Blake. *** lib/spawn.in.h.orig Tue Mar 2 11:53:02 2010 --- lib/spawn.in.h Tue Mar 2 11:48:54 2010 *************** *** 110,126 **** /* Flags to be set in the `posix_spawnattr_t'. */ ! #if @REPLACE_POSIX_SPAWN@ /* Use the values from the system, for better compatibility. */ /* But this implementation does not support AIX extensions. */ ! # undef POSIX_SPAWN_FORK_HANDLERS ! #else ! # define POSIX_SPAWN_RESETIDS 0x01 ! # define POSIX_SPAWN_SETPGROUP 0x02 ! # define POSIX_SPAWN_SETSIGDEF 0x04 ! # define POSIX_SPAWN_SETSIGMASK 0x08 ! # define POSIX_SPAWN_SETSCHEDPARAM 0x10 ! # define POSIX_SPAWN_SETSCHEDULER 0x20 #endif /* A GNU extension. Use the next free bit position. */ #define POSIX_SPAWN_USEVFORK \ --- 110,128 ---- /* Flags to be set in the `posix_spawnattr_t'. */ ! #if !...@have_posix_spawn@ ! # if @REPLACE_POSIX_SPAWN@ /* Use the values from the system, for better compatibility. */ /* But this implementation does not support AIX extensions. */ ! # undef POSIX_SPAWN_FORK_HANDLERS ! # else ! # define POSIX_SPAWN_RESETIDS 0x01 ! # define POSIX_SPAWN_SETPGROUP 0x02 ! # define POSIX_SPAWN_SETSIGDEF 0x04 ! # define POSIX_SPAWN_SETSIGMASK 0x08 ! # define POSIX_SPAWN_SETSCHEDPARAM 0x10 ! # define POSIX_SPAWN_SETSCHEDULER 0x20 ! # endif #endif /* A GNU extension. Use the next free bit position. */ #define POSIX_SPAWN_USEVFORK \