diff options
author | Christopher Faylor <me@cgf.cx> | 2003-09-20 00:31:13 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2003-09-20 00:31:13 +0000 |
commit | d1fb625d2bbe16aeb77d403d62742b0240ca7024 (patch) | |
tree | 282edbea12074ba940905d8930168a69d63c3601 /winsup/cygwin/fhandler_fifo.cc | |
parent | 41946df6111b6daf93518b22ca49c54544c77599 (diff) | |
download | cygnal-d1fb625d2bbe16aeb77d403d62742b0240ca7024.tar.gz cygnal-d1fb625d2bbe16aeb77d403d62742b0240ca7024.tar.bz2 cygnal-d1fb625d2bbe16aeb77d403d62742b0240ca7024.zip |
* syscalls.cc (system): Strip signal considerations from here so that they are
not inherited by a child process.
* spawn.cc (spawn_guts): Handle system() signal stuff here.
* winsup.h (_P_SYSTEM): Define.
Diffstat (limited to 'winsup/cygwin/fhandler_fifo.cc')
-rw-r--r-- | winsup/cygwin/fhandler_fifo.cc | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc new file mode 100644 index 000000000..b717e9635 --- /dev/null +++ b/winsup/cygwin/fhandler_fifo.cc @@ -0,0 +1,207 @@ +/* fhandler_fifo.cc. See fhandler.h for a description of the fhandler classes. + + Copyright 2002 Red Hat, Inc. + + This file is part of Cygwin. + + This software is a copyrighted work licensed under the terms of the + Cygwin license. Please consult the file "CYGWIN_LICENSE" for + details. */ + +#include "winsup.h" +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> + +#include "cygerrno.h" +#include "perprocess.h" +#include "security.h" +#include "path.h" +#include "fhandler.h" +#include "dtable.h" +#include "cygheap.h" +#include "pinfo.h" + +fhandler_fifo::fhandler_fifo () + : fhandler_pipe (), output_handle (NULL), owner (NULL), upand (0), + read_use (0), write_use (0) +{ +} + +void +fhandler_fifo::set_use (int incr) +{ + long oread_use = read_use; + + if (get_flags () & (O_WRONLY | O_APPEND)) + write_use += incr; + else if (get_flags () & O_RDWR) + { + write_use += incr; + read_use += incr; + } + else + read_use += incr; + + if (incr >= 0) + return; + char buf[24]; + __small_sprintf (buf, "%x.%x", upand, myself->pid); + ATOM ant = GlobalFindAtom (buf); + if (!ant) + return; + if (read_use <= 0 && oread_use != read_use) + { + HANDLE h = get_handle (); + if (h) + { + set_io_handle (NULL); + CloseHandle (h); + } + DeleteAtom (ant); + } +} + +int +fhandler_fifo::close () +{ + fhandler_pipe::close (); + CloseHandle (get_output_handle ()); + set_use (-1); + return 0; +} + +#define DUMMY_O_RDONLY 4 +int +fhandler_fifo::open_not_mine (int flags) +{ + char buf[24]; + winpids pids; + static int flagtypes[] = {DUMMY_O_RDONLY | O_RDWR, O_WRONLY | O_APPEND | O_RDWR}; + HANDLE *usehandles[2] = {&(get_handle ()), &(get_output_handle ())}; + int res; + + for (unsigned i = 0; i < pids.npids; i++) + { + _pinfo *p = pids[i]; + __small_sprintf (buf, "%x.%x", upand, p->pid); + if (!GlobalFindAtom (buf)) + continue; + + HANDLE hp = OpenProcess (PROCESS_DUP_HANDLE, false, p->dwProcessId); + if (!hp) + { + __seterrno (); + goto err; + } + + HANDLE handles[2]; + commune_result r; + r = p->commune_send (PICOM_FIFO, upand); + flags = (flags & (O_RDWR | O_WRONLY | O_APPEND)) ?: DUMMY_O_RDONLY; + for (int i = 0; i < 2; i++) + { + if (!(flags & flagtypes[i])) + continue; + if (!DuplicateHandle (hp, r.handles[i], hMainProc, usehandles[i], 0, + false, DUPLICATE_SAME_ACCESS)) + { + debug_printf ("couldn't duplicate handle %d/%p, %E", i, handles[i]); + __seterrno (); + goto err; + } + + if (i == 0) + { + read_state = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); + set_need_fork_fixup (); + } + } + CloseHandle (hp); + + res = 1; + set_flags (flags); + goto out; + } + + set_errno (EAGAIN); + +err: + res = 0; + debug_printf ("failed"); + +out: + debug_printf ("res %d", res); + return res; +} + +int +fhandler_fifo::open (int flags, mode_t) +{ + int res = 1; + char buf[24]; + + upand = GlobalAddAtom (pc); + __small_sprintf (buf, "%x.owner", upand); + debug_printf ("mutex %s", buf); + + HANDLE h = CreateMutex (&sec_none, false, buf); + if (!h) + goto errnout; + + if (GetLastError () == ERROR_ALREADY_EXISTS) + { + CloseHandle (h); + return open_not_mine (flags); + } + + fhandler_pipe *fhs[2]; + if (create (fhs, 0, flags, true)) + { + CloseHandle (h); + goto errout; + } + + set_flags (fhs[0]->get_flags ()); + set_io_handle (fhs[0]->get_handle ()); + set_output_handle (fhs[1]->get_handle ()); + guard = fhs[0]->guard; + read_state = fhs[0]->read_state; + writepipe_exists = fhs[1]->writepipe_exists; + orig_pid = fhs[0]->orig_pid; + id = fhs[0]->id; + delete (fhs[0]); + delete (fhs[1]); + set_use (1); + __small_sprintf (buf, "%x.%x", upand, myself->pid); + (void) GlobalAddAtom (buf); + goto out; + +errnout: + __seterrno (); +errout: + res = 0; + +out: + debug_printf ("returning %d, errno %d", res, get_errno ()); + return res; +} + +int +fhandler_fifo::dup (fhandler_base * child) +{ + int res = fhandler_pipe::dup (child); + if (!res) + { + fhandler_fifo *ff = (fhandler_fifo *) child; + + if (!DuplicateHandle (hMainProc, get_output_handle (), hMainProc, + &ff->get_output_handle (), false, true, + DUPLICATE_SAME_ACCESS)) + { + child->close (); + res = -1; + } + } + return 0; +} |