diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 7a4707064..b81f856e2 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,29 @@ +2002-10-08 Christopher Faylor + + * cygheap.cc (dup_now): Make fatal error a little more informative. + (cygheap_setup_for_child): Detect when default size of shared region is + less than the current size and allocate that much. + (_cbrk): Just return NULL on inability to allocate. + (_cmalloc): Ditto. + * cygheap.h (CYGHEAPSIZE): Change size to reflect newer, tinier + fhandler sizes. + * spawn.cc (av::error): New element, reflects potential errno from cmalloc. + (av::~av): Don't free NULL pointers. + (av::replace0_maybe): Detect out-of-memory conditions. + (av::dup_maybe): Ditto. + (av::dup_all): Ditto. + (av::unshift): Ditto. + (spawn_guts): Set errno and return if argv creation ran into problems. + + * fhandler.h (fhandler_union): Change member names to something safer. + + * fhandler_console.cc (fhandler_console::get_tty_stuff): Always set + fhandler_console::dev_state regardless of whether shared region is + initialized. + + * cygthread.cc (cygthread::runner): Use ExitThread rather than return + (planning for future). + 2002-10-08 Christopher Faylor * fhandler.h (dev_console): New class. diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 60eafcd44..d3d1bd610 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -63,12 +63,13 @@ init_cheap () cygheap_max = cygheap; } -static void dup_now (void *, child_info *, unsigned) __attribute__ ((regparm(3))); +// static void dup_now (void *, child_info *, unsigned) __attribute__ ((regparm(3))); static void dup_now (void *newcygheap, child_info *ci, unsigned n) { if (!VirtualAlloc (newcygheap, n, MEM_COMMIT, PAGE_READWRITE)) - api_fatal ("couldn't allocate new cygwin heap for child, %E"); + api_fatal ("couldn't allocate new cygwin heap %p, %d for child, %E", + newcygheap, n); memcpy (newcygheap, cygheap, n); } @@ -77,9 +78,15 @@ cygheap_setup_for_child (child_info *ci, bool dup_later) { void *newcygheap; cygheap_protect->acquire (); +if (!ci) try_to_debug (); unsigned n = (char *) cygheap_max - (char *) cygheap; + unsigned size = CYGHEAPSIZE; + if (size < n) + size = n + (128 * 1024); ci->cygheap_h = CreateFileMapping (INVALID_HANDLE_VALUE, &sec_none, - CFMAP_OPTIONS, 0, CYGHEAPSIZE, NULL); + CFMAP_OPTIONS, 0, size, NULL); + if (!ci->cygheap_h) + api_fatal ("Couldn't create heap for child, size %d, %E", CYGHEAPSIZE); newcygheap = MapViewOfFileEx (ci->cygheap_h, MVMAP_OPTIONS, 0, 0, 0, NULL); ProtectHandle1INH (ci->cygheap_h, passed_cygheap_h); if (!dup_later) @@ -177,7 +184,12 @@ _csbrk (int sbs) if (!sbs || (prebrk != prebrka && prebrka == pagetrunc (cygheap_max))) /* nothing to do */; else if (!VirtualAlloc (prebrk, (DWORD) sbs, MEM_COMMIT, PAGE_READWRITE)) - api_fatal ("couldn't commit memory for cygwin heap, %E"); + { + malloc_printf ("couldn't commit memory for cygwin heap, %E"); + __seterrno (); + (char *) cygheap_max -= sbs; + return NULL; + } return prebrk; } @@ -222,6 +234,11 @@ _cmalloc (int size) { size = sz + sizeof (_cmalloc_entry); rvc = (_cmalloc_entry *) _csbrk (size); + if (!rvc) + { + cygheap_protect->release (); + return NULL; + } rvc->b = b; rvc->prev = cygheap->chain; diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 6f81eaa41..fd784ae95 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -224,7 +224,7 @@ struct init_cygheap bool etc_changed (); }; -#define CYGHEAPSIZE (sizeof (init_cygheap) + (4000 * sizeof (fhandler_union)) + (2 * 65536)) +#define CYGHEAPSIZE (sizeof (init_cygheap) + (16000 * sizeof (fhandler_union)) + (4 * 65536)) extern init_cygheap *cygheap; extern void *cygheap_max; diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index c3b74dfb0..c6e5d173b 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -86,10 +86,10 @@ cygthread::runner (VOID *arg) &threads[i], CREATE_SUSPENDED, &threads[i].avail); else - return 0; + ExitThread (0); initialized ^= 1; - return 0; + ExitThread (0); } /* Start things going. Called from dll_crt0_1. */ diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index b0dbb7d26..6611b487d 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -725,7 +725,6 @@ enum ansi_intensity #define eattitle 7 #define MAXARGS 10 -class fhandler_console; class dev_console { WORD default_color, underline_color, dim_color; @@ -1160,30 +1159,32 @@ class fhandler_process: public fhandler_proc typedef union { - char base[sizeof(fhandler_base)]; - char console[sizeof(fhandler_console)]; - char dev_clipboard[sizeof(fhandler_dev_clipboard)]; - char dev_dsp[sizeof(fhandler_dev_dsp)]; - char dev_floppy[sizeof(fhandler_dev_floppy)]; - char dev_mem[sizeof(fhandler_dev_mem)]; - char dev_null[sizeof(fhandler_dev_null)]; - char dev_random[sizeof(fhandler_dev_random)]; - char dev_raw[sizeof(fhandler_dev_raw)]; - char dev_tape[sizeof(fhandler_dev_tape)]; - char dev_zero[sizeof(fhandler_dev_zero)]; - char disk_file[sizeof(fhandler_disk_file)]; - char pipe[sizeof(fhandler_pipe)]; - char proc[sizeof(fhandler_proc)]; - char process[sizeof(fhandler_process)]; - char pty_master[sizeof(fhandler_pty_master)]; - char registry[sizeof(fhandler_registry)]; - char serial[sizeof(fhandler_serial)]; - char socket[sizeof(fhandler_socket)]; - char termios[sizeof(fhandler_termios)]; - char tty_common[sizeof(fhandler_tty_common)]; - char tty_master[sizeof(fhandler_tty_master)]; - char tty_slave[sizeof(fhandler_tty_slave)]; - char windows[sizeof(fhandler_windows)]; + char __base[sizeof (fhandler_base)]; + char __console[sizeof (fhandler_console)]; + char __cygdrive[sizeof (fhandler_cygdrive)]; + char __dev_clipboard[sizeof (fhandler_dev_clipboard)]; + char __dev_dsp[sizeof (fhandler_dev_dsp)]; + char __dev_floppy[sizeof (fhandler_dev_floppy)]; + char __dev_mem[sizeof (fhandler_dev_mem)]; + char __dev_null[sizeof (fhandler_dev_null)]; + char __dev_random[sizeof (fhandler_dev_random)]; + char __dev_raw[sizeof (fhandler_dev_raw)]; + char __dev_tape[sizeof (fhandler_dev_tape)]; + char __dev_zero[sizeof (fhandler_dev_zero)]; + char __disk_file[sizeof (fhandler_disk_file)]; + char __pipe[sizeof (fhandler_pipe)]; + char __proc[sizeof (fhandler_proc)]; + char __process[sizeof (fhandler_process)]; + char __pty_master[sizeof (fhandler_pty_master)]; + char __registry[sizeof (fhandler_registry)]; + char __serial[sizeof (fhandler_serial)]; + char __socket[sizeof (fhandler_socket)]; + char __termios[sizeof (fhandler_termios)]; + char __tty_common[sizeof (fhandler_tty_common)]; + char __tty_master[sizeof (fhandler_tty_master)]; + char __tty_slave[sizeof (fhandler_tty_slave)]; + char __virtual[sizeof (fhandler_virtual)]; + char __windows[sizeof (fhandler_windows)]; } fhandler_union; struct select_record diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index 953e9c5c5..4b7c2daef 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -100,12 +100,14 @@ dev_console NO_COPY *fhandler_console::dev_state; tty_min * fhandler_console::get_tty_stuff (int flags = 0) { - if (shared_console_info) + if (dev_state) return &shared_console_info->tty_min_state; shared_console_info = (console_state *) open_shared (NULL, 0, cygheap->console_h, sizeof (*shared_console_info), NULL); + dev_state = &shared_console_info->dev_state; + ProtectHandleINH (cygheap->console_h); if (!shared_console_info->tty_min_state.ntty) { @@ -113,7 +115,6 @@ fhandler_console::get_tty_stuff (int flags = 0) shared_console_info->tty_min_state.setsid (myself->sid); shared_console_info->tty_min_state.set_ctty (TTY_CONSOLE, flags); - fhandler_console::dev_state = &shared_console_info->dev_state; dev_state->scroll_region.Bottom = -1; dev_state->dwLastCursorPosition.X = -1; dev_state->dwLastCursorPosition.Y = -1; diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index e2683df1f..92e3803f4 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -457,7 +457,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, myself->progname, myself->progname, c_flags, &si, &pi); __malloc_lock (); void *newheap; - newheap = cygheap_setup_for_child (&ch,cygheap->fdtab.need_fixup_before ()); + newheap = cygheap_setup_for_child (&ch, cygheap->fdtab.need_fixup_before ()); rc = CreateProcess (myself->progname, /* image to run */ myself->progname, /* what we send in arg0 */ sec_attribs, diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 193f593bc..34927c1f0 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -254,17 +254,22 @@ class av char **argv; int calloced; public: + int error; int argc; - av (int ac, const char * const *av) : calloced (0), argc (ac) + av (int ac, const char * const *av) : calloced (0), error (false), argc (ac) { argv = (char **) cmalloc (HEAP_1_ARGV, (argc + 5) * sizeof (char *)); memcpy (argv, av, (argc + 1) * sizeof (char *)); } ~av () { - for (int i = 0; i < calloced; i++) - cfree (argv[i]); - cfree (argv); + if (argv) + { + for (int i = 0; i < calloced; i++) + if (argv[i]) + cfree (argv[i]); + cfree (argv); + } } int unshift (const char *what, int conv = 0); operator char **() {return argv;} @@ -272,21 +277,23 @@ class av void replace0_maybe (const char *arg0) { /* Note: Assumes that argv array has not yet been "unshifted" */ - if (!calloced) - { - argv[0] = cstrdup1 (arg0); - calloced = 1; - } + if (!calloced + && (argv[0] = cstrdup1 (arg0))) + calloced = true; + else + error = errno; } void dup_maybe (int i) { - if (i >= calloced) - argv[i] = cstrdup1 (argv[i]); + if (i >= calloced + && !(argv[i] = cstrdup1 (argv[i]))) + error = errno; } void dup_all () { for (int i = calloced; i < argc; i++) - argv[i] = cstrdup1 (argv[i]); + if (!(argv[i] = cstrdup1 (argv[i]))) + error = errno; } }; @@ -309,7 +316,8 @@ av::unshift (const char *what, int conv) *p = '\0'; what = buf; } - *argv = cstrdup1 (what); + if (!(*argv = cstrdup1 (what))) + error = errno; argc++; calloced++; return 1; @@ -338,7 +346,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, { syscall_printf ("argv is NULL"); set_errno (EINVAL); - return (-1); + return -1; } path_conv real_path; @@ -561,6 +569,12 @@ spawn_guts (const char * prog_arg, const char *const *argv, char *envblock; newargv.all_calloced (); + if (newargv.error) + { + set_errno (newargv.error); + return -1; + } + ciresrv.moreinfo->argc = newargv.argc; ciresrv.moreinfo->argv = newargv; ciresrv.hexec_proc = hexec_proc;