Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog24
-rw-r--r--winsup/cygwin/dtable.cc19
-rw-r--r--winsup/cygwin/exceptions.cc2
-rw-r--r--winsup/cygwin/path.cc4
-rw-r--r--winsup/cygwin/path.h3
-rw-r--r--winsup/cygwin/pinfo.cc1
-rw-r--r--winsup/cygwin/pinfo.h3
-rw-r--r--winsup/cygwin/sigproc.cc154
-rw-r--r--winsup/cygwin/spawn.cc60
9 files changed, 138 insertions, 132 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 7f3929614..cd766e5ee 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,27 @@
+Sun Oct 8 22:38:40 2000 Christopher Faylor <cgf@cygnus.com>
+
+ * dtable.cc (set_std_handle): Use std_consts array to control
+ SetStdHandle settings.
+ (dtable::fixup_after_fork): Ditto.
+ * exceptions.cc (set_sig_errno): Remove some debugging output.
+ * path.cc (path_conv::check): Don't OR need_directory with flags sent
+ to symlink_info::check.
+ (symlink_info::check): Use PATH_ALL_EXEC to determine when a file is
+ executable.
+ * path.h (path_types): Add PATH_ALL_EXEC.
+ (isexec): Use PATH_ALL_EXEC so that cygexec types will be considered
+ executable.
+ * pinfo.h (_pinfo): Add a process handle that is kept open throughout
+ the life of a cygwin pid.
+ * sigproc.cc (proc_exists): Remove hopefully obsolete stuff.
+ (proc_subproc): Set up process handle that is kept open throughout the
+ life of a cygwin pid. Reorganize PROC_WAIT stuff to use common code.
+ (proc_terminate): Close pid lifetime process handle.
+ (checkstate): Cleanup.
+ (stopped_or_terminated): Move zombie cleanup.
+ (remove_zombie): To here.
+ * spawn.cc (spawn_guts): Reorganize reparenting code for 1247th time.
+
Sat Oct 7 13:59:15 2000 Christopher Faylor <cgf@cygnus.com>
* fhandler.h (fhandler_base): Remove obsolete _rpos and _rsize
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index 5eff4fd66..f149d562b 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -33,6 +33,9 @@ details. */
dtable fdtab;
+static DWORD std_consts[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
+ STD_ERROR_HANDLE};
+
/* Set aside space for the table of fds */
void
dtable_init (void)
@@ -45,11 +48,9 @@ void __stdcall
set_std_handle (int fd)
{
if (fd == 0)
- SetStdHandle (STD_INPUT_HANDLE, fdtab[fd]->get_handle ());
- else if (fd == 1)
- SetStdHandle (STD_OUTPUT_HANDLE, fdtab[fd]->get_output_handle ());
- else if (fd == 2)
- SetStdHandle (STD_ERROR_HANDLE, fdtab[fd]->get_output_handle ());
+ SetStdHandle (std_consts[fd], fdtab[fd]->get_handle ());
+ else if (fd <= 2)
+ SetStdHandle (std_consts[fd], fdtab[fd]->get_output_handle ());
}
int
@@ -453,7 +454,13 @@ dtable::fixup_after_exec (HANDLE parent, size_t sz, fhandler_base **f)
if (fds[i]->get_close_on_exec ())
release (i);
else
- fds[i]->fixup_after_exec (parent);
+ {
+ fds[i]->fixup_after_exec (parent);
+ if (i == 0)
+ SetStdHandle (std_consts[i], fds[i]->get_io_handle ());
+ else if (i <= 2)
+ SetStdHandle (std_consts[i], fds[i]->get_output_handle ());
+ }
}
}
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 187e937a7..b536d6685 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -688,7 +688,7 @@ set_sig_errno (int e)
{
set_errno (e);
sigsave.saved_errno = e;
- debug_printf ("errno %d", e);
+ // sigproc_printf ("errno %d", e);
}
#define SUSPEND_TRIES 10000
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index fb8bcd5dd..41a0a7f16 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -257,7 +257,7 @@ path_conv::check (const char *src, unsigned opt,
else
{
suff = suffixes;
- sym.pflags = path_flags | need_directory;
+ sym.pflags = path_flags;
}
int len = sym.check (path_copy, suff);
@@ -2294,7 +2294,7 @@ symlink_info::check (const char *in_path, const suffix_info *suffixes)
else
{
/* Not a symlink, see if executable. */
- if (!(pflags & (PATH_EXEC | PATH_CYGWIN_EXEC)) && got >= 2 &&
+ if (!(pflags & PATH_ALL_EXEC) && got >= 2 &&
((cookie_buf[0] == '#' && cookie_buf[1] == '!') ||
(cookie_buf[0] == ':' && cookie_buf[1] == '\n') ||
(cookie_buf[0] == 'M' && cookie_buf[1] == 'Z')))
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index 4c7f2c0e2..3baa6a6cb 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -36,6 +36,7 @@ enum path_types
PATH_BINARY = MOUNT_BINARY,
PATH_EXEC = MOUNT_EXEC,
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
+ PATH_ALL_EXEC = PATH_CYGWIN_EXEC | PATH_EXEC,
PATH_SOCKET = 0x40000000,
PATH_HASACLS = 0x80000000
};
@@ -52,7 +53,7 @@ class path_conv
int isbinary () {return path_flags & PATH_BINARY;}
int issymlink () {return path_flags & PATH_SYMLINK;}
int issocket () {return path_flags & PATH_SOCKET;}
- int isexec () {return path_flags & PATH_EXEC;}
+ int isexec () {return path_flags & PATH_ALL_EXEC;}
int iscygexec () {return path_flags & PATH_CYGWIN_EXEC;}
void set_binary () {path_flags |= PATH_BINARY;}
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index f7c233da6..1ce6ace2c 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -258,6 +258,7 @@ pinfo::init (pid_t n, DWORD create, HANDLE in_h)
destroy = 1;
}
+
void
pinfo::release ()
{
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index 13eaa1de8..2c5b862c6 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -41,6 +41,9 @@ public:
#define PINFO_REDIR_SIZE ((DWORD) &(((_pinfo *)NULL)->hProcess) + sizeof (DWORD))
+ /* Handle associated with initial Windows pid which started it all. */
+ HANDLE pid_handle;
+
/* Parent process id. */
pid_t ppid;
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 99ed89ce9..f4929f109 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -236,6 +236,7 @@ proc_exists (_pinfo *p)
}
sigproc_printf ("it doesn't exist");
+#if 0
/* If the parent pid does not exist, clean this process out of the pinfo
* table. It must have died abnormally.
*/
@@ -244,6 +245,7 @@ proc_exists (_pinfo *p)
p->hProcess = NULL;
p->process_state = PID_NOT_IN_USE;
}
+#endif
return FALSE;
}
@@ -303,11 +305,15 @@ proc_subproc (DWORD what, DWORD val)
pchildren[nchildren] = vchild;
hchildren[nchildren] = vchild->hProcess;
ProtectHandle1 (vchild->hProcess, childhProc);
+ nchildren++;
+ if (!DuplicateHandle (hMainProc, vchild->hProcess, hMainProc, &vchild->pid_handle,
+ 0, 0, DUPLICATE_SAME_ACCESS))
+ system_printf ("Couldn't duplicate child handle for pid %d, %E", vchild->pid);
+ ProtectHandle1 (vchild->pid_handle, pid_handle);
sigproc_printf ("added pid %d to wait list, slot %d, winpid %p, handle %p",
vchild->pid, nchildren, vchild->dwProcessId,
vchild->hProcess);
- nchildren++;
wake_wait_subproc ();
break;
@@ -351,6 +357,38 @@ proc_subproc (DWORD what, DWORD val)
clearing = 0;
goto scan_wait;
+ /* Handle a wait4() operation. Allocates an event for the calling
+ * thread which is signaled when the appropriate pid exits or stops.
+ * (usually called from the main thread)
+ */
+ case PROC_WAIT:
+ wval->ev = NULL; // Don't know event flag yet
+
+ if (wval->pid <= 0)
+ child = NULL; // Not looking for a specific pid
+ else if (!mychild (wval->pid))
+ goto out; // invalid pid. flag no such child
+
+ wval->status = 0; // Don't know status yet
+ sigproc_printf ("wval->pid %d, wval->options %d", wval->pid, wval->options);
+
+ /* If the first time for this thread, create a new event, otherwise
+ * reset the event.
+ */
+ if ((wval->ev = wval->thread_ev) == NULL)
+ {
+ wval->ev = wval->thread_ev = CreateEvent (&sec_none_nih, TRUE,
+ FALSE, NULL);
+ ProtectHandle (wval->ev);
+ }
+
+ ResetEvent (wval->ev);
+ w = waitq_head.next;
+ waitq_head.next = wval; /* Add at the beginning. */
+ wval->next = w; /* Link in rest of the list. */
+ clearing = 0;
+ goto scan_wait;
+
/* Clear all waiting threads. Called from exceptions.cc prior to
* the main thread's dispatch to a signal handler function.
* (called from wait_sig thread)
@@ -371,12 +409,13 @@ proc_subproc (DWORD what, DWORD val)
{
if ((potential_match = checkstate (w)) > 0)
sigproc_printf ("released waiting thread");
- else if (!clearing && potential_match < 0)
+ else if (!clearing && !(w->next->options & WNOHANG) && potential_match < 0)
sigproc_printf ("only found non-terminated children");
else if (potential_match <= 0) // nothing matched
{
sigproc_printf ("waiting thread found no children");
HANDLE oldw = w->next->ev;
+ w->next->pid = 0;
if (clearing)
w->next->status = -1; /* flag that a signal was received */
else
@@ -397,75 +436,6 @@ proc_subproc (DWORD what, DWORD val)
sigproc_printf ("finished clearing");
}
break;
-
- /* Handle a wait4() operation. Allocates an event for the calling
- * thread which is signaled when the appropriate pid exits or stops.
- * (usually called from the main thread)
- */
- case PROC_WAIT:
- wval->ev = NULL; // Don't know event flag yet
-
- if (wval->pid <= 0)
- child = NULL; // Not looking for a specific pid
- else if (!mychild (wval->pid))
- goto out; // invalid pid. flag no such child
-
- wval->status = 0; // Don't know status yet
-
- /* Put waitq structure at the end of a linked list. */
- for (w = &waitq_head; w->next != NULL; w = w->next)
- if (w->next == wval && (w->next = w->next->next) == NULL)
- break;
-
- wval->next = NULL; /* This will be last in the list */
- sigproc_printf ("wval->pid %d, wval->options %d", wval->pid, wval->options);
-
- /* If the first time for this thread, create a new event, otherwise
- * reset the event.
- */
- if ((wval->ev = wval->thread_ev) == NULL)
- {
- wval->ev = wval->thread_ev = CreateEvent (&sec_none_nih, TRUE,
- FALSE, NULL);
- ProtectHandle (wval->ev);
- }
- ResetEvent (wval->ev);
-
- /* Scan list of children to see if any have died.
- * If so, the event flag is set so that the wait* ()
- * process will return immediately.
- *
- * If no children were found and the wait option was WNOHANG,
- * then set the pid to 0 and remove the waitq value from
- * consideration.
- */
- w->next = wval; /* set at end of wait queue */
- if ((potential_match = checkstate (w)) <= 0)
- {
- if (!potential_match)
- {
- w->next = NULL; // don't want to keep looking
- wval->ev = NULL; // flag that there are no children
- sigproc_printf ("no appropriate children, %p, %p",
- wval->thread_ev, wval->ev);
- }
- else if (wval->options & WNOHANG)
- {
- w->next = NULL; // don't want to keep looking
- wval->pid = 0; // didn't find a pid
- if (!SetEvent (wval->ev)) // wake up wait4 () immediately
- system_printf ("Couldn't wake up wait event, %E");
- sigproc_printf ("WNOHANG and no terminated children, %p, %p",
- wval->thread_ev, wval->ev);
- }
- }
- if (w->next != NULL)
- sigproc_printf ("wait activated %p, %p", wval->thread_ev, wval->ev);
- else if (wval->ev != NULL)
- sigproc_printf ("wait activated %p. Reaped zombie.", wval->ev);
- else
- sigproc_printf ("wait not activated %p, %p", wval->thread_ev, wval->ev);
- break;
}
out:
@@ -513,7 +483,7 @@ proc_terminate (void)
if (zombies[i]->hProcess)
{
ForceCloseHandle1 (zombies[i]->hProcess, childhProc);
- zombies[i]->hProcess = NULL;
+ ForceCloseHandle1 (zombies[i]->pid_handle, pid_handle);
}
zombies[i]->process_state = PID_NOT_IN_USE; /* CGF FIXME - still needed? */
zombies[i].release(); // FIXME: this breaks older gccs for some reason
@@ -530,7 +500,6 @@ proc_terminate (void)
else
{
ForceCloseHandle1 (pchildren[i]->hProcess, childhProc);
- pchildren[i]->hProcess = NULL;
if (!proc_exists (pchildren[i]))
{
sigproc_printf ("%d(%d) doesn't exist", pchildren[i]->pid,
@@ -937,21 +906,22 @@ init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready)
* terminated.
*/
static int __stdcall
-checkstate (waitq *w)
+checkstate (waitq *parent_w)
{
- int i, x, potential_match = 0;
- _pinfo *child;
+ int potential_match = 0;
sigproc_printf ("nchildren %d, nzombies %d", nchildren, nzombies);
/* Check already dead processes first to see if they match the criteria
* given in w->next.
*/
- for (i = 0; i < nzombies; i++)
- if ((x = stopped_or_terminated (w, child = zombies[i])) < 0)
- potential_match = -1;
- else if (x > 0)
+ for (int i = 0; i < nzombies; i++)
+ switch (stopped_or_terminated (parent_w, zombies[i]))
{
+ case -1:
+ potential_match = -1;
+ break;
+ case 1:
remove_zombie (i);
potential_match = 1;
goto out;
@@ -960,13 +930,15 @@ checkstate (waitq *w)
sigproc_printf ("checking alive children");
/* No dead terminated children matched. Check for stopped children. */
- for (i = 0; i < nchildren; i++)
- if ((x = stopped_or_terminated (w, pchildren[i])) < 0)
- potential_match = -1;
- else if (x > 0)
+ for (int i = 0; i < nchildren; i++)
+ switch (stopped_or_terminated (parent_w, pchildren[i]))
{
- potential_match = 1;
+ case -1:
+ potential_match = -1;
break;
+ case 1:
+ potential_match = 1;
+ goto out;
}
out:
@@ -1074,10 +1046,15 @@ static void __stdcall
remove_zombie (int ci)
{
sigproc_printf ("removing %d, pid %d, nzombies %d", ci, zombies[ci]->pid,
- nzombies);
+ nzombies);
if (zombies[ci])
- zombies[ci].release ();
+ {
+ ForceCloseHandle1 (zombies[ci]->hProcess, childhProc);
+ ForceCloseHandle1 (zombies[ci]->pid_handle, pid_handle);
+ zombies[ci]->process_state = PID_NOT_IN_USE; /* a reaped child */
+ zombies[ci].release ();
+ }
if (ci < --nzombies)
zombies[ci] = zombies[nzombies];
@@ -1146,9 +1123,6 @@ stopped_or_terminated (waitq *parent_w, _pinfo *child)
add_rusage ((struct rusage *) w->rusage, &child->rusage_children);
add_rusage ((struct rusage *) w->rusage, &child->rusage_self);
}
- ForceCloseHandle1 (child->hProcess, childhProc);
- child->hProcess = NULL;
- child->process_state = PID_NOT_IN_USE; /* a reaped child */
}
if (!SetEvent (w->ev)) /* wake up wait4 () immediately */
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 01a9cecd3..8542ecb1e 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -687,14 +687,11 @@ skip_arg_parsing:
/* We print the original program name here so the user can see that too. */
syscall_printf ("%d = spawn_guts (%s, %.132s)",
- rc ? cygpid : (unsigned int) -1,
- prog_arg, one_line.buf);
+ rc ? cygpid : (unsigned int) -1, prog_arg, one_line.buf);
- MALLOC_CHECK;
/* Name the handle similarly to proc_subproc. */
ProtectHandle1 (pi.hProcess, childhProc);
ProtectHandle (pi.hThread);
- MALLOC_CHECK;
if (mode == _P_OVERLAY)
{
@@ -785,20 +782,16 @@ skip_arg_parsing:
{
case WAIT_OBJECT_0:
sigproc_printf ("subprocess exited");
- if (!GetExitCodeProcess (pi.hProcess, &res))
- res = 1;
+ DWORD exitcode;
+ if (!GetExitCodeProcess (pi.hProcess, &exitcode))
+ exitcode = 1;
+ res |= exitcode;
exited = TRUE;
- if (nwait <= 2 || mode != _P_OVERLAY)
+ if (nwait <= 2 || (res & EXIT_REPARENTING) || (mode != _P_OVERLAY && mode != _P_VFORK))
/* nothing to do */;
else if (WaitForSingleObject (spr, 1) == WAIT_OBJECT_0)
goto reparent;
- else if (!(res & EXIT_REPARENTING))
- {
- MALLOC_CHECK;
- close_all_files ();
- MALLOC_CHECK;
- }
break;
case WAIT_OBJECT_0 + 1:
sigproc_printf ("signal arrived");
@@ -809,7 +802,6 @@ skip_arg_parsing:
{
reparent:
res |= EXIT_REPARENTING;
- close_all_files ();
if (!parent_alive)
{
nwait = 1;
@@ -848,33 +840,37 @@ skip_arg_parsing:
/* nothing */;
else
{
- int rc;
- HANDLE hP = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
- parent->dwProcessId);
- sigproc_printf ("parent handle %p, pid %d", hP, parent->dwProcessId);
- if (hP == NULL && GetLastError () == ERROR_INVALID_PARAMETER)
+ int rc = 0;
+ HANDLE oldh = myself->hProcess;
+ HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
+ parent->dwProcessId);
+ sigproc_printf ("parent handle %p, pid %d", h, parent->dwProcessId);
+ if (h == NULL && GetLastError () == ERROR_INVALID_PARAMETER)
rc = 1;
- else if (hP)
+ else if (h)
{
- ProtectHandle (hP);
- rc = DuplicateHandle (hMainProc, pi.hProcess, hP,
- &myself->hProcess, 0, FALSE,
+ ProtectHandle (h);
+ rc = DuplicateHandle (hMainProc, pi.hProcess,
+ h, &myself->hProcess, 0, FALSE,
DUPLICATE_SAME_ACCESS);
- sigproc_printf ("Dup hP %d", rc);
- ForceCloseHandle (hP);
+ sigproc_printf ("%d = DuplicateHandle, oldh %p, newh %p",
+ rc, oldh, myself->hProcess);
+ ForceCloseHandle (h);
}
- if (!res)
+ if (!rc)
{
- system_printf ("Reparent failed, parent handle %p, %E", hP);
+ system_printf ("Reparent failed, parent handle %p, %E", h);
system_printf ("my dwProcessId %d, myself->dwProcessId %d",
GetCurrentProcessId(), myself->dwProcessId);
- system_printf ("myself->process_state %x",
- myself->process_state);
- system_printf ("myself->hProcess %x", myself->hProcess);
+ system_printf ("old hProcess %p, hProcess %p", oldh, myself->hProcess);
}
}
- ForceCloseHandle1 (hExeced, childhProc);
- hExeced = INVALID_HANDLE_VALUE;
+ if (hExeced)
+ {
+ ForceCloseHandle1 (hExeced, childhProc);
+ hExeced = INVALID_HANDLE_VALUE;
+ close_all_files ();
+ }
}
else if (exited)
{