mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-01-19 04:49:25 +08:00
* 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:
parent
d17ba05c1c
commit
8dca9e2302
@ -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.
|
||||
|
@ -394,6 +394,7 @@ getrusage
|
||||
_getrusage = getrusage
|
||||
gets
|
||||
_gets = gets
|
||||
getsid
|
||||
gettimeofday
|
||||
_gettimeofday = gettimeofday
|
||||
getuid
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 ------------------------------
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user