aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2002-08-18 05:49:26 +0000
committerChristopher Faylor <me@cgf.cx>2002-08-18 05:49:26 +0000
commit8dca9e230217cc6f4ded94e5fa0ab3f63df941b9 (patch)
tree7eae73aeb5feb07bfb241edbd41134270d9867a5
parentd17ba05c1c9dbb15b846682fd98e65b80260623d (diff)
downloadnewlib-8dca9e230217cc6f4ded94e5fa0ab3f63df941b9.zip
newlib-8dca9e230217cc6f4ded94e5fa0ab3f63df941b9.tar.gz
newlib-8dca9e230217cc6f4ded94e5fa0ab3f63df941b9.tar.bz2
* 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.
-rw-r--r--winsup/cygwin/ChangeLog20
-rw-r--r--winsup/cygwin/cygwin.din1
-rw-r--r--winsup/cygwin/dcrt0.cc5
-rw-r--r--winsup/cygwin/fork.cc13
-rw-r--r--winsup/cygwin/include/cygwin/version.h3
-rw-r--r--winsup/cygwin/malloc.cc3
-rw-r--r--winsup/cygwin/perthread.h20
-rw-r--r--winsup/cygwin/spawn.cc8
-rw-r--r--winsup/cygwin/syscalls.cc45
9 files changed, 99 insertions, 19 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 2e8de61..0fa906e 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,25 @@
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.
2002-08-18 Christopher Faylor <cgf@redhat.com>
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index 2ebfd1c..99ff0a7 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 ac2c7e0..0384275 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 81ed6e2..e566bf0 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 b68c528..e945907 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 4407165..02832bb 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 48ad976..f8682ae 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 602c0af..8c1c18a 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 31eed42..f047cbd 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -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)
{