muto. Use this argument to construct static storage.
* cygheap.cc (cygheap_init): Reflect above change.
* exceptions.cc (events_init): Ditto.
* malloc.cc (malloc_init): Ditto.
* path.cc (cwdstuff::init): Ditto.
* cygheap.h (cwdstuff): Change name of lock element to make it less generic.
* path.cc (cwdstuff::get_hash): Ditto.
(cwdstuff::get_initial): Ditto.
(cwdstuff::set): Ditto.
(cwdstuff::get): Ditto.
* sigproc.cc (proc_subproc): Ditto.
* debug.cc (lock_debug): Change to method. Use method rather than macro
throughout.
* tty.h (tty_min::kill_pgrp): Declare new method.
* fhandler_termios.cc (tty_min::kill_pgrp): New method.
(fhandler_termios::line_edit): Use new method for killing process.
* dcrt0.cc (do_exit): Ditto.
* dtable.cc (dtable::get_debugger_info): New method for inheriting dtable info
from a debugger.
* tty.cc (tty_init): Attempt to grab file handle info from parent debugger, if
appropriate. # dtable.cc (dtable::stdio_init): Make this a method.
(dtable::init_std_file_from_handle): Don't set fd unless it's not open.
(dtable::build_fhandler_from_name): Move name setting to
dtable::build_fhandler.
(dtable::build_fhandler): Add win32 name parameter.
* dcrt0.cc (dll_crt0_1): Change to use dtable stdio_init.
* dtable.h (dtable): Reflect build_fhandler parameter change.
* mmap.cc (mmap_record::alloc_fh): Don't set name parameter in build_fhandler.
* net.cc (fdsock): Remove set_name call since it is now handled by
build_fhandler.
* sigproc.cc (proc_subproc): Release muto as early as possible.
+2002-02-22 Christopher Faylor <cgf@redhat.com>
+
+ * sync.h (new_muto): Just accept an argument which denotes the name of
+ the muto. Use this argument to construct static storage.
+ * cygheap.cc (cygheap_init): Reflect above change.
+ * exceptions.cc (events_init): Ditto.
+ * malloc.cc (malloc_init): Ditto.
+ * path.cc (cwdstuff::init): Ditto.
+ * cygheap.h (cwdstuff): Change name of lock element to make it less
+ generic.
+ * path.cc (cwdstuff::get_hash): Ditto.
+ (cwdstuff::get_initial): Ditto.
+ (cwdstuff::set): Ditto.
+ (cwdstuff::get): Ditto.
+ * sigproc.cc (proc_subproc): Ditto.
+
+ * debug.cc (lock_debug): Change to method. Use method rather than
+ macro throughout.
+
+ * tty.h (tty_min::kill_pgrp): Declare new method.
+ * fhandler_termios.cc (tty_min::kill_pgrp): New method.
+ (fhandler_termios::line_edit): Use new method for killing process.
+ * dcrt0.cc (do_exit): Ditto.
+
+ * dtable.cc (dtable::get_debugger_info): New method for inheriting
+ dtable info from a debugger.
+ * tty.cc (tty_init): Attempt to grab file handle info from parent
+ debugger, if appropriate.
+
+ # dtable.cc (dtable::stdio_init): Make this a method.
+ (dtable::init_std_file_from_handle): Don't set fd unless it's not open.
+ (dtable::build_fhandler_from_name): Move name setting to
+ dtable::build_fhandler.
+ (dtable::build_fhandler): Add win32 name parameter.
+ * dcrt0.cc (dll_crt0_1): Change to use dtable stdio_init.
+ * dtable.h (dtable): Reflect build_fhandler parameter change.
+ * mmap.cc (mmap_record::alloc_fh): Don't set name parameter in
+ build_fhandler.
+ * net.cc (fdsock): Remove set_name call since it is now handled by
+ build_fhandler.
+
+ * sigproc.cc (proc_subproc): Release muto as early as possible.
+
2001-02-22 Corinna Vinschen <corinna@vinschen.de>
* smallprint.c (rn): Allow long long values.
extern "C" void __stdcall
cygheap_init ()
{
- cygheap_protect = new_muto ("cygheap_protect");
+ new_muto (cygheap_protect);
_csbrk (0);
if (!cygheap->fdtab)
cygheap->fdtab.init ();
char *posix;
char *win32;
DWORD hash;
- muto *lock;
+ muto *cwd_lock;
char *get (char *buf, int need_posix = 1, int with_chroot = 0, unsigned ulen = MAX_PATH);
DWORD get_hash ();
void init ();
user_data->premain[i] (__argc, __argv, user_data);
/* Set up standard fds in file descriptor table. */
- stdio_init ();
+ cygheap->fdtab.stdio_init ();
/* Set up __progname for getopt error call. */
__progname = __argv[0];
}
}
-
/* Wrap the real one, otherwise gdb gets confused about
two symbols with the same name, but different addresses.
/* CGF FIXME: This can't be right. */
if (tp->getsid () == myself->sid)
- kill_pgrp (tp->getpgid (), SIGHUP);
+ tp->kill_pgrp (SIGHUP);
}
tty_terminate ();
void
threadname_init ()
{
- threadname_lock = new_muto ("threadname_lock");
+ new_muto (threadname_lock);
}
void __stdcall
static muto NO_COPY *debug_lock = NULL;
-#define lock_debug() \
- do {if (debug_lock) debug_lock->acquire (INFINITE); } while (0)
-
-#define unlock_debug() \
- do {if (debug_lock) debug_lock->release (); } while (0)
+struct lock_debug
+{
+ lock_debug () {if (debug_lock) debug_lock->acquire (INFINITE);}
+ void unlock () {if (debug_lock) debug_lock->release ();}
+ ~lock_debug () {unlock ();}
+};
static bool __stdcall mark_closed (const char *, int, HANDLE, const char *, BOOL);
void
debug_init ()
{
- debug_lock = new_muto ("debug_lock");
+ new_muto (debug_lock);
}
/* Find a registered handle in the linked list of handles. */
newh ()
{
handle_list *hl;
- lock_debug ();
+ lock_debug here;
+
for (hl = freeh; hl < freeh + NFREEH; hl++)
if (hl->name == NULL)
goto out;
}
out:
- unlock_debug ();
return hl;
}
add_handle (const char *func, int ln, HANDLE h, const char *name)
{
handle_list *hl;
- lock_debug ();
+ lock_debug here;
if ((hl = find_handle (h)))
{
ln, name, h);
system_printf (" previously allocated by %s:%d(%s<%p>)",
hl->func, hl->ln, hl->name, hl->h);
- goto out; /* Already did this once */
+ return;
}
if ((hl = newh ()) == NULL)
{
- unlock_debug ();
+ here.unlock ();
system_printf ("couldn't allocate memory for %s(%d): %s(%p)",
func, ln, name, h);
return;
endh->next = hl;
endh = hl;
-out:
- unlock_debug ();
+ return;
}
static void __stdcall
mark_closed (const char *func, int ln, HANDLE h, const char *name, BOOL force)
{
handle_list *hl;
- lock_debug ();
+ lock_debug here;
+
if ((hl = find_handle (h)) && !force)
{
hl = hl->next;
- unlock_debug (); // race here
+ here.unlock (); // race here
system_printf ("attempt to close protected handle %s:%d(%s<%p>)",
hl->func, hl->ln, hl->name, hl->h);
system_printf (" by %s:%d(%s<%p>)", func, ln, name, h);
if (hl)
delete_handle (hl);
- unlock_debug ();
return TRUE;
}
close_handle (const char *func, int ln, HANDLE h, const char *name, BOOL force)
{
BOOL ret;
- lock_debug ();
+ lock_debug here;
if (!mark_closed (func, ln, h, name, force))
return FALSE;
ret = CloseHandle (h);
- unlock_debug ();
#if 0 /* Uncomment to see CloseHandle failures */
if (!ret)
small_printf ("CloseHandle(%s) failed %s:%d\n", name, func, ln);
return ret;
}
-/* Add a handle to the linked list of known handles. */
int __stdcall
__set_errno (const char *func, int ln, int val)
{
#include "cygheap.h"
static const NO_COPY DWORD std_consts[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
- STD_ERROR_HANDLE};
+ STD_ERROR_HANDLE};
/* Set aside space for the table of fds */
void
return 1;
}
+void
+dtable::get_debugger_info ()
+{
+ if (IsDebuggerPresent ())
+ {
+ char std[3][sizeof ("/dev/ttyNNNN")];
+ std[0][0] = std[1][0] = std [2][0] = '\0';
+ char buf[sizeof ("cYgstd %x") + 32];
+ sprintf (buf, "cYgstd %x %x %x", (unsigned) &std, sizeof (std[0]), 3);
+ OutputDebugString (buf);
+ for (int i = 0; i < 3; i++)
+ if (std[i][0])
+ {
+ path_conv pc;
+ HANDLE h = GetStdHandle (std_consts[i]);
+ fhandler_base *fh = build_fhandler_from_name (i, std[i], NULL, pc);
+ if (!fh)
+ continue;
+ if (!fh->open (&pc, (i ? O_WRONLY : O_RDONLY) | O_BINARY, 0777))
+ release (i);
+ else
+ CloseHandle (h);
+ }
+ }
+}
+
/* Initialize the file descriptor/handle mapping table.
This function should only be called when a cygwin function is invoked
by a non-cygwin function, i.e., it should only happen very rarely. */
void
-stdio_init (void)
+dtable::stdio_init ()
{
extern void set_console_ctty ();
/* Set these before trying to output anything from strace.
Also, always set them even if we're to pick up our parent's fds
in case they're missed. */
- if (!myself->ppid_handle && NOTSTATE (myself, PID_CYGPARENT))
- {
- HANDLE in = GetStdHandle (STD_INPUT_HANDLE);
- HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
- HANDLE err = GetStdHandle (STD_ERROR_HANDLE);
+ if (myself->ppid_handle || ISSTATE (myself, PID_CYGPARENT))
+ return;
+
+ HANDLE in = GetStdHandle (STD_INPUT_HANDLE);
+ HANDLE out = GetStdHandle (STD_OUTPUT_HANDLE);
+ HANDLE err = GetStdHandle (STD_ERROR_HANDLE);
- cygheap->fdtab.init_std_file_from_handle (0, in, GENERIC_READ);
+ init_std_file_from_handle (0, in, GENERIC_READ);
- /* STD_ERROR_HANDLE has been observed to be the same as
- STD_OUTPUT_HANDLE. We need separate handles (e.g. using pipes
- to pass data from child to parent). */
- if (out == err)
+ /* STD_ERROR_HANDLE has been observed to be the same as
+ STD_OUTPUT_HANDLE. We need separate handles (e.g. using pipes
+ to pass data from child to parent). */
+ if (out == err)
+ {
+ /* Since this code is not invoked for forked tasks, we don't have
+ to worry about the close-on-exec flag here. */
+ if (!DuplicateHandle (hMainProc, out, hMainProc, &err, 0,
+ 1, DUPLICATE_SAME_ACCESS))
{
- /* Since this code is not invoked for forked tasks, we don't have
- to worry about the close-on-exec flag here. */
- if (!DuplicateHandle (hMainProc, out, hMainProc, &err, 0,
- 1, DUPLICATE_SAME_ACCESS))
- {
- /* If that fails, do this as a fall back. */
- err = out;
- system_printf ("couldn't make stderr distinct from stdout");
- }
+ /* If that fails, do this as a fall back. */
+ err = out;
+ system_printf ("couldn't make stderr distinct from stdout");
}
-
- cygheap->fdtab.init_std_file_from_handle (1, out, GENERIC_WRITE);
- cygheap->fdtab.init_std_file_from_handle (2, err, GENERIC_WRITE);
- /* Assign the console as the controlling tty for this process if we actually
- have a console and no other controlling tty has been assigned. */
- if (myself->ctty < 0 && GetConsoleCP () > 0)
- set_console_ctty ();
}
+
+ init_std_file_from_handle (1, out, GENERIC_WRITE);
+ init_std_file_from_handle (2, err, GENERIC_WRITE);
+ /* Assign the console as the controlling tty for this process if we actually
+ have a console and no other controlling tty has been assigned. */
+ if (myself->ctty < 0 && GetConsoleCP () > 0)
+ set_console_ctty ();
}
int
first_fd_for_open = 0;
+ if (!not_open (fd))
+ return;
+
if (!handle || handle == INVALID_HANDLE_VALUE)
{
fds[fd] = NULL;
return NULL;
}
- fhandler_base *fh = build_fhandler (fd, pc.get_devn (), name, pc.get_unitn ());
- fh->set_name (name, pc, pc.get_unitn ());
- return fh;
+ return build_fhandler (fd, pc.get_devn (), name, pc, pc.get_unitn ());
}
#define cnew(name) new ((void *) ccalloc (HEAP_FHANDLER, 1, sizeof (name))) name
fhandler_base *
-dtable::build_fhandler (int fd, DWORD dev, const char *name, int unit)
+dtable::build_fhandler (int fd, DWORD dev, const char *unix_name,
+ const char *win32_name, int unit)
{
fhandler_base *fh;
fh = NULL;
}
+ if (unix_name)
+ {
+ char new_win32_name[strlen (unix_name) + 1];
+ if (!win32_name)
+ {
+ char *p;
+ /* FIXME: ? Should we call win32_device_name here?
+ It seems like overkill, but... */
+ win32_name = strcpy (new_win32_name, unix_name);
+ for (p = (char *) win32_name; (p = strchr (p, '/')); p++)
+ *p = '\\';
+ }
+ fh->set_name (unix_name, win32_name, fh->get_unit ());
+ }
debug_printf ("fd %d, fh %p", fd, fh);
return fd >= 0 ? (fds[fd] = fh) : fh;
}
void fixup_before_exec (DWORD win_proc_id);
void fixup_before_fork (DWORD win_proc_id);
void fixup_after_fork (HANDLE);
- fhandler_base *build_fhandler (int fd, DWORD dev, const char *name,
- int unit = -1);
+ fhandler_base *build_fhandler (int fd, DWORD dev, const char *unix_name,
+ const char *win32_name = NULL, int unit = -1);
fhandler_base *build_fhandler_from_name (int fd, const char *name, HANDLE h,
path_conv& pc,
unsigned opts = PC_SYM_FOLLOW,
select_record *select_write (int fd, select_record *s);
select_record *select_except (int fd, select_record *s);
operator fhandler_base **() {return fds;}
+ void stdio_init ();
+ void get_debugger_info ();
};
void dtable_init (void);
api_fatal ("can't create title mutex, %E");
ProtectHandle (title_mutex);
- mask_sync = new_muto ("mask_sync");
+ new_muto (mask_sync);
windows_system_directory[0] = '\0';
(void) GetSystemDirectory (windows_system_directory, sizeof (windows_system_directory) - 2);
char *end = strchr (windows_system_directory, '\0');
}
void
+tty_min::kill_pgrp (int sig)
+{
+ int killself = 0;
+ winpids pids;
+ for (unsigned i = 0; i < pids.npids; i++)
+ {
+ _pinfo *p = pids[i];
+ if (!proc_exists (p) || p->ctty != ntty || p->pgid != pgid)
+ continue;
+ if (p == myself)
+ killself++;
+ else
+ (void) sig_send (p, sig);
+ }
+ if (killself)
+ sig_send (myself, sig);
+}
+
+void
tty_min::set_ctty (int ttynum, int flags)
{
if ((myself->ctty < 0 || myself->ctty == ttynum) && !(flags & O_NOCTTY))
termios_printf ("got interrupt %d, sending signal %d", c, sig);
eat_readahead (-1);
- kill_pgrp (tc->getpgid (), sig);
+ tc->kill_pgrp (sig);
tc->ti.c_lflag &= ~FLUSHO;
sawsig = 1;
goto restart_output;
termios_printf ("CloseHandle (ioctl_request_event), %E");
if (inuse && !CloseHandle (inuse))
termios_printf ("CloseHandle (inuse), %E");
- if (!ForceCloseHandle (output_mutex))
- termios_printf ("CloseHandle (output_mutex<%p>), %E", output_mutex);
if (!ForceCloseHandle (input_mutex))
termios_printf ("CloseHandle (input_mutex<%p>), %E", input_mutex);
+ if (!ForceCloseHandle (output_mutex))
+ termios_printf ("CloseHandle (output_mutex<%p>), %E", output_mutex);
/* Send EOF to slaves if master side is closed */
if (!get_ttyp ()->master_alive ())
void
malloc_init ()
{
- mprotect = new_muto ("mprotect");
+ new_muto (mprotect);
/* Check if mallock is provided by application. If so, redirect all
calls to export_malloc/free/realloc to application provided. This may
happen if some other dll calls cygwin's malloc, but main code provides
the call to fork(). This requires creating a fhandler
of the correct type to be sure to call the method of the
correct class. */
- return cygheap->fdtab.build_fhandler (-1, get_device (), "", 0);
+ return cygheap->fdtab.build_fhandler (-1, get_device (), NULL);
}
void
fhandler_socket *fh = (fhandler_socket *) cygheap->fdtab.build_fhandler (fd, FH_SOCKET, name);
fh->set_io_handle ((HANDLE) soc);
fh->set_flags (O_RDWR);
- fh->set_name (name, name);
debug_printf ("fd %d, name '%s', soc %p", fd, name, soc);
return fh;
}
cwdstuff::get_hash ()
{
DWORD hashnow;
- lock->acquire ();
+ cwd_lock->acquire ();
hashnow = hash;
- lock->release ();
+ cwd_lock->release ();
return hashnow;
}
void
cwdstuff::init ()
{
- lock = new_muto ("cwd");
+ new_muto (cwd_lock);
}
/* Get initial cwd. Should only be called once in a
bool
cwdstuff::get_initial ()
{
- lock->acquire ();
+ cwd_lock->acquire ();
if (win32)
return 1;
if (len == 0)
{
__seterrno ();
- lock->release ();
+ cwd_lock->release ();
debug_printf ("get_initial_cwd failed, %E");
- lock->release ();
+ cwd_lock->release ();
return 0;
}
set (NULL);
if (win32_cwd)
{
- lock->acquire ();
+ cwd_lock->acquire ();
win32 = (char *) crealloc (win32, strlen (win32_cwd) + 1);
strcpy (win32, win32_cwd);
}
hash = hash_path_name (0, win32);
if (win32_cwd)
- lock->release ();
+ cwd_lock->release ();
return;
}
strcpy (buf, "/");
}
- lock->release ();
+ cwd_lock->release ();
out:
syscall_printf ("(%s) = cwdstuff::get (%p, %d, %d, %d), errno %d",
if (hchildren[val] != pchildren[val]->hProcess)
{
sigproc_printf ("pid %d[%d], reparented old hProcess %p, new %p",
- pchildren[val]->pid, val, hchildren[val], pchildren[val]->hProcess);
- ForceCloseHandle1 (hchildren[val], childhProc);
+ pchildren[val]->pid, val, hchildren[val], pchildren[val]->hProcess);
+ HANDLE h = hchildren[val];
hchildren[val] = pchildren[val]->hProcess; /* Filled out by child */
+ sync_proc_subproc->release (); // Release the lock ASAP
+ ForceCloseHandle1 (h, childhProc);
ProtectHandle1 (pchildren[val]->hProcess, childhProc);
rc = 0;
- break; // This was an exec()
+ goto out; // This was an exec()
}
sigproc_printf ("pid %d[%d] terminated, handle %p, nchildren %d, nzombies %d",
/* sync_proc_subproc is used by proc_subproc. It serialises
* access to the children and zombie arrays.
*/
- sync_proc_subproc = new_muto ("sync_proc_subproc");
+ new_muto (sync_proc_subproc);
/* Initialize waitq structure for main thread. A waitq structure is
* allocated for each thread that executes a wait to allow multiple threads
/* Use a statically allocated buffer as the storage for a muto */
#define new_muto(__name) \
({ \
- static muto __mbuf __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy"))); \
- __mbuf.init (__name); \
+ static muto __name##_storage __attribute__((nocommon)) __attribute__((section(".data_cygwin_nocopy"))); \
+ __name = __name##_storage.init (#__name); \
})
void __stdcall
tty_init (void)
{
+ if (!myself->ppid_handle && NOTSTATE (myself, PID_CYGPARENT))
+ cygheap->fdtab.get_debugger_info ();
+
if (NOTSTATE (myself, PID_USETTY))
return;
if (myself->ctty == -1)
void __stdcall
create_tty_master (int ttynum)
{
- tty_master = (fhandler_tty_master *) cygheap->fdtab.build_fhandler (-1, FH_TTYM,
- "/dev/ttym", ttynum);
+ tty_master = (fhandler_tty_master *)
+ cygheap->fdtab.build_fhandler (-1, FH_TTYM, "/dev/ttym", NULL, ttynum);
if (tty_master->init (ttynum))
api_fatal ("Can't create master tty");
else
int getsid () {return sid;}
void setsid (pid_t tsid) {sid = tsid;}
void set_ctty (int ttynum, int flags);
+ void kill_pgrp (int sig);
struct termios ti;
struct winsize winsize;