* 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.
This commit is contained in:
Christopher Faylor 2002-08-18 05:49:26 +00:00
parent d17ba05c1c
commit 8dca9e2302
9 changed files with 99 additions and 19 deletions

View File

@ -1,3 +1,23 @@
2002-08-18 Christopher Faylor <cgf@redhat.com>
* 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 <cgf@redhat.com>
* cygmalloc.h (MORECORE_CANNOT_TRIM): Define.

View File

@ -394,6 +394,7 @@ getrusage
_getrusage = getrusage
gets
_gets = gets
getsid
gettimeofday
_gettimeofday = gettimeofday
getuid

View File

@ -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)
{

View File

@ -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);

View File

@ -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

View File

@ -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 ------------------------------

View File

@ -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

View File

@ -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:

View File

@ -36,6 +36,9 @@ details. */
#include <unistd.h>
#include "shared_info.h"
#include "cygheap.h"
#define NEED_VFORK
#include <setjmp.h>
#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)
{