This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: getpid/vfork broken


On Sun, Mar 07, 2004 at 06:37:33PM -0800, Roland McGrath wrote:
> The new specification for vfork where you can't even call dup2 is very
> close to useless.  The origin of vfork and true standard for its behavior
> that applications have been written for is 4.2BSD, where simple system
> calls were always safe, and getpid has always been the simplest system
> call.  The modern BSD specification remains that the address space is
> shared, with all that entails, but since getpid has never relied on data
> contents in the address space before, citing that as license to make it do
> the wrong thing is dubious at best.  Since the useless specification has
> been enshrined in POSIX, where vfork in fact never belonged at all, it is
> likely that every historical program will be broken and people will just
> have to adapt to giving up vfork entirely.  Progress.

Here is what would be needed to make vfork & getpid work together:

1) vfork needs to:
   struct pthread *pd = THREAD_SELF;
   int oldval = THREAD_GETMEM (pd, pid);
   int newval = oldval ? -oldval : INT_MIN;
   THREAD_SETMEM (pd, pid) = newval;
   actual vfork syscall (oldval must be saved in a register
			 preserved accross the syscall)
   THREAD_SETMEM (pd, pid) = oldval;
2) raise would need:
    /* raise is an async-safe function.  It could be called while the
       fork function temporarily invalidated the PID field.  Adjust for
       that.  */
    if (__builtin_expect (pid <= 0, 0))
-      pid = pid == 0 ? selftid : -pid;
+      pid = (pid & INT_MAX) == 0 ? selftid : -pid;

vfork is written in assembly for each architecture, so so that would need to
be coded for each architecture.

->pid field seems to be only accessed in raise, getpid and fork from libc.so
functions, when libpthread is loaded, THREAD_SELF->pid will always be
non-zero, getpid with THREAD_SELF->pid == INT_MIN will always do the real
syscall and while vfork is running, the same program certainly shouldn't
call fork() (neither in a signal handler nor in the vfork child).

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]