4
0
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:
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> 2002-08-18 Christopher Faylor <cgf@redhat.com>
* cygmalloc.h (MORECORE_CANNOT_TRIM): Define. * cygmalloc.h (MORECORE_CANNOT_TRIM): Define.

View File

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

View File

@ -961,10 +961,7 @@ do_exit (int status)
vfork_save *vf = vfork_storage.val (); vfork_save *vf = vfork_storage.val ();
if (vf != NULL && vf->pid < 0) if (vf != NULL && vf->pid < 0)
{ vf->restore_exit (status);
vf->pid = status < 0 ? status : -status;
longjmp (vf->j, 1);
}
if (exit_state < ES_SIGNAL) if (exit_state < ES_SIGNAL)
{ {

View File

@ -687,8 +687,7 @@ get_vfork_val ()
} }
#endif #endif
extern "C" extern "C" int
int
vfork () vfork ()
{ {
#ifndef NEWVFORK #ifndef NEWVFORK
@ -711,9 +710,11 @@ vfork ()
for (pp = (char **)vf->frame, esp = vf->vfork_esp; for (pp = (char **)vf->frame, esp = vf->vfork_esp;
esp <= vf->vfork_ebp + 2; pp++, esp++) esp <= vf->vfork_ebp + 2; pp++, esp++)
*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; int res = cygheap->fdtab.vfork_child_dup () ? 0 : -1;
debug_printf ("%d = vfork()", res); debug_printf ("%d = vfork()", res);
debug_printf ("exiting vfork, res %d", res);
return res; return res;
} }
@ -726,9 +727,13 @@ vfork ()
thisframe.init (mainthread); thisframe.init (mainthread);
cygheap->fdtab.vfork_parent_restore (); cygheap->fdtab.vfork_parent_restore ();
myself->ctty = vf->ctty;
myself->sid = vf->sid;
myself->pgid = vf->pgid;
if (vf->pid < 0) if (vf->pid < 0)
{ {
int exitval = -vf->pid; int exitval = vf->exitval;
vf->pid = 0; vf->pid = 0;
if ((vf->pid = fork ()) == 0) if ((vf->pid = fork ()) == 0)
exit (exitval); exit (exitval);

View File

@ -157,12 +157,13 @@ details. */
57: Export setgroups. 57: Export setgroups.
58: Export memalign, valloc, malloc_trim, malloc_usable_size, mallopt, 58: Export memalign, valloc, malloc_trim, malloc_usable_size, mallopt,
malloc_stats malloc_stats
59: getsid
*/ */
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0 #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 /* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible 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 sYSTRIm is an inverse of sorts to sYSMALLOc. It gives memory back
to the system (via negative arguments to sbrk) if there is unused 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; return 0;
} }
#endif /*MORECORE_CANNOT_TRIM*/
/* /*
------------------------------ malloc ------------------------------ ------------------------------ malloc ------------------------------

View File

@ -48,14 +48,30 @@ public:
}; };
#if defined (NEED_VFORK) #if defined (NEED_VFORK)
struct vfork_save class vfork_save
{ {
int pid;
jmp_buf j; jmp_buf j;
int exitval;
public:
int pid;
DWORD frame[100]; DWORD frame[100];
char **vfork_ebp; char **vfork_ebp;
char **vfork_esp; char **vfork_esp;
int ctty;
pid_t sid;
pid_t pgid;
int is_active () { return pid < 0; } 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 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: case _P_DETACH:
subproc_init (); subproc_init ();
ret = spawn_guts (path, argv, envp, mode); ret = spawn_guts (path, argv, envp, mode);
if (vf && ret > 0) if (vf)
{ {
debug_printf ("longjmping due to vfork"); debug_printf ("longjmping due to vfork");
vf->pid = ret; if (ret < 0)
longjmp (vf->j, 1); vf->restore_exit (ret);
else
vf->restore_pid (ret);
} }
break; break;
default: default:

View File

@ -36,6 +36,9 @@ details. */
#include <unistd.h> #include <unistd.h>
#include "shared_info.h" #include "shared_info.h"
#include "cygheap.h" #include "cygheap.h"
#define NEED_VFORK
#include <setjmp.h>
#include "perthread.h"
SYSTEM_INFO system_info; SYSTEM_INFO system_info;
@ -265,11 +268,24 @@ getppid ()
extern "C" pid_t extern "C" pid_t
setsid (void) 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 && pid_t pid = fork ();
!cygheap->fdtab.has_console_fds () && if (pid > 0)
!check_pty_fds ()) {
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 (); FreeConsole ();
myself->ctty = -1; myself->ctty = -1;
myself->sid = _getpid (); myself->sid = _getpid ();
@ -277,10 +293,31 @@ setsid (void)
syscall_printf ("sid %d, pgid %d, ctty %d", myself->sid, myself->pgid, myself->ctty); syscall_printf ("sid %d, pgid %d, ctty %d", myself->sid, myself->pgid, myself->ctty);
return myself->sid; return myself->sid;
} }
set_errno (EPERM); set_errno (EPERM);
return -1; 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 extern "C" ssize_t
_read (int fd, void *ptr, size_t len) _read (int fd, void *ptr, size_t len)
{ {