From 97990e61d7dfa456efd573773a501343706662cb Mon Sep 17 00:00:00 2001 From: cgf Date: Sun, 18 Aug 2002 05:49:25 +0000 Subject: [PATCH] * perthread.h (vfork_save): Add ctty, sid, pgid, exitval fields. (vfork_save::restore_pid): New method. (vfork_save::restore_exit): New method. * fork.cc (vfork): Save ctty, sid, pgid and restore them when returning to "parent". Use exitval field if exiting but never created a new process. * syscalls.cc (setsid): Detect when in "vfork" and force an actual fork so that pid will be allocated (UGLY!). (getsid): New function. * dcrt0.cc (do_exit): Use vfork_save::restore_exit method for returning from a vfork. * spawn.cc (spawnve): Use vfork_save::{restore_pid,restore_exit} methods for returning from vfork. * cygwin.din: Export getsid. * include/cygwin/version.h: Bump api minor number. * malloc.cc: #ifdef sYSTRIm for when MORECORE_CANNOT_TRIM is true. --- winsup/cygwin/ChangeLog | 20 +++++++++++++++ winsup/cygwin/cygwin.din | 1 + winsup/cygwin/dcrt0.cc | 5 +--- winsup/cygwin/fork.cc | 13 +++++++--- winsup/cygwin/include/cygwin/version.h | 3 ++- winsup/cygwin/malloc.cc | 3 ++- winsup/cygwin/perthread.h | 20 +++++++++++++-- winsup/cygwin/spawn.cc | 8 +++--- winsup/cygwin/syscalls.cc | 45 +++++++++++++++++++++++++++++++--- 9 files changed, 99 insertions(+), 19 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 2e8de6145a..0fa906e0a8 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,25 @@ 2002-08-18 Christopher Faylor + * perthread.h (vfork_save): Add ctty, sid, pgid, exitval fields. + (vfork_save::restore_pid): New method. + (vfork_save::restore_exit): New method. + * fork.cc (vfork): Save ctty, sid, pgid and restore them when returning + to "parent". Use exitval field if exiting but never created a new + process. + * syscalls.cc (setsid): Detect when in "vfork" and force an actual fork + so that pid will be allocated (UGLY!). + (getsid): New function. + * dcrt0.cc (do_exit): Use vfork_save::restore_exit method for returning + from a vfork. + * spawn.cc (spawnve): Use vfork_save::{restore_pid,restore_exit} + methods for returning from vfork. + * cygwin.din: Export getsid. + * include/cygwin/version.h: Bump api minor number. + + * malloc.cc: #ifdef sYSTRIm for when MORECORE_CANNOT_TRIM is true. + +2002-08-18 Christopher Faylor + * cygmalloc.h (MORECORE_CANNOT_TRIM): Define. 2002-08-18 Christopher Faylor diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 2ebfd1ce9c..99ff0a7df2 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -394,6 +394,7 @@ getrusage _getrusage = getrusage gets _gets = gets +getsid gettimeofday _gettimeofday = gettimeofday getuid diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index ac2c7e0950..0384275b37 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -961,10 +961,7 @@ do_exit (int status) vfork_save *vf = vfork_storage.val (); if (vf != NULL && vf->pid < 0) - { - vf->pid = status < 0 ? status : -status; - longjmp (vf->j, 1); - } + vf->restore_exit (status); if (exit_state < ES_SIGNAL) { diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index 81ed6e21b0..e566bf0e68 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -687,8 +687,7 @@ get_vfork_val () } #endif -extern "C" -int +extern "C" int vfork () { #ifndef NEWVFORK @@ -711,9 +710,11 @@ vfork () for (pp = (char **)vf->frame, esp = vf->vfork_esp; esp <= vf->vfork_ebp + 2; pp++, esp++) *pp = *esp; + vf->ctty = myself->ctty; + vf->sid = myself->sid; + vf->pgid = myself->pgid; int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1; debug_printf ("%d = vfork()", res); - debug_printf ("exiting vfork, res %d", res); return res; } @@ -726,9 +727,13 @@ vfork () thisframe.init (mainthread); cygheap->fdtab.vfork_parent_restore (); + myself->ctty = vf->ctty; + myself->sid = vf->sid; + myself->pgid = vf->pgid; + if (vf->pid < 0) { - int exitval = -vf->pid; + int exitval = vf->exitval; vf->pid = 0; if ((vf->pid = fork ()) == 0) exit (exitval); diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index b68c528630..e9459070d3 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -157,12 +157,13 @@ details. */ 57: Export setgroups. 58: Export memalign, valloc, malloc_trim, malloc_usable_size, mallopt, malloc_stats + 59: getsid */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 58 +#define CYGWIN_VERSION_API_MINOR 59 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/malloc.cc b/winsup/cygwin/malloc.cc index 4407165290..02832bb994 100644 --- a/winsup/cygwin/malloc.cc +++ b/winsup/cygwin/malloc.cc @@ -3294,7 +3294,7 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; - +#ifndef MORECORE_CANNOT_TRIM /* sYSTRIm is an inverse of sorts to sYSMALLOc. It gives memory back to the system (via negative arguments to sbrk) if there is unused @@ -3360,6 +3360,7 @@ static int sYSTRIm(pad, av) size_t pad; mstate av; } return 0; } +#endif /*MORECORE_CANNOT_TRIM*/ /* ------------------------------ malloc ------------------------------ diff --git a/winsup/cygwin/perthread.h b/winsup/cygwin/perthread.h index 48ad97621f..f8682ae55b 100644 --- a/winsup/cygwin/perthread.h +++ b/winsup/cygwin/perthread.h @@ -48,14 +48,30 @@ public: }; #if defined (NEED_VFORK) -struct vfork_save +class vfork_save { - int pid; jmp_buf j; + int exitval; + public: + int pid; DWORD frame[100]; char **vfork_ebp; char **vfork_esp; + int ctty; + pid_t sid; + pid_t pgid; int is_active () { return pid < 0; } + void restore_pid (int val) + { + pid = val; + longjmp (j, 1); + } + void restore_exit (int val) + { + exitval = val; + longjmp (j, 1); + } + friend int vfork (); }; class per_thread_vfork : public per_thread diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 602c0af691..8c1c18adb2 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -907,11 +907,13 @@ spawnve (int mode, const char *path, const char *const *argv, case _P_DETACH: subproc_init (); ret = spawn_guts (path, argv, envp, mode); - if (vf && ret > 0) + if (vf) { debug_printf ("longjmping due to vfork"); - vf->pid = ret; - longjmp (vf->j, 1); + if (ret < 0) + vf->restore_exit (ret); + else + vf->restore_pid (ret); } break; default: diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 31eed42b2e..f047cbd1cb 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -36,6 +36,9 @@ details. */ #include #include "shared_info.h" #include "cygheap.h" +#define NEED_VFORK +#include +#include "perthread.h" SYSTEM_INFO system_info; @@ -265,11 +268,24 @@ getppid () extern "C" pid_t setsid (void) { - if (myself->pgid != _getpid ()) + vfork_save *vf = vfork_storage.val (); + /* This is a horrible, horrible kludge */ + if (vf && vf->pid < 0) { - if (myself->ctty == TTY_CONSOLE && - !cygheap->fdtab.has_console_fds () && - !check_pty_fds ()) + pid_t pid = fork (); + if (pid > 0) + { + syscall_printf ("longjmping due to vfork"); + vf->restore_pid (pid); + } + /* assuming that fork was successful */ + } + + if (myself->pgid != myself->pid) + { + if (myself->ctty == TTY_CONSOLE + && !cygheap->fdtab.has_console_fds () + && !check_pty_fds ()) FreeConsole (); myself->ctty = -1; myself->sid = _getpid (); @@ -277,10 +293,31 @@ setsid (void) syscall_printf ("sid %d, pgid %d, ctty %d", myself->sid, myself->pgid, myself->ctty); return myself->sid; } + set_errno (EPERM); return -1; } +extern "C" pid_t +getsid (pid_t pid) +{ + pid_t res; + if (!pid) + res = myself->sid; + else + { + pinfo p (pid); + if (p) + res = p->sid; + else + { + set_errno (ESRCH); + res = -1; + } + } + return res; +} + extern "C" ssize_t _read (int fd, void *ptr, size_t len) { -- 2.11.0