aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2002-10-09 04:08:05 +0000
committerChristopher Faylor <me@cgf.cx>2002-10-09 04:08:05 +0000
commit7da53596cf1385616721180b48b2159802045d1c (patch)
tree7c7c049a2429b3d778f4d8f33ede670f44fb7d58
parentce6ac4003f2155c0f76d086673aa12193661e1c3 (diff)
downloadnewlib-7da53596cf1385616721180b48b2159802045d1c.zip
newlib-7da53596cf1385616721180b48b2159802045d1c.tar.gz
newlib-7da53596cf1385616721180b48b2159802045d1c.tar.bz2
* 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).
-rw-r--r--winsup/cygwin/ChangeLog26
-rw-r--r--winsup/cygwin/cygheap.cc25
-rw-r--r--winsup/cygwin/cygheap.h2
-rw-r--r--winsup/cygwin/cygthread.cc4
-rw-r--r--winsup/cygwin/fhandler.h51
-rw-r--r--winsup/cygwin/fhandler_console.cc5
-rw-r--r--winsup/cygwin/fork.cc2
-rw-r--r--winsup/cygwin/spawn.cc42
8 files changed, 108 insertions, 49 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 7a47070..b81f856 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,31 @@
2002-10-08 Christopher Faylor <cgf@redhat.com>
+ * 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 <cgf@redhat.com>
+
* fhandler.h (dev_console): New class.
(fhandler_console::dev_state): New class element.
(fhandler_console::mouse_aware): Use dev_state element.
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index 60eafcd..d3d1bd6 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 6f81eaa..fd784ae 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 c3b74df..c6e5d17 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 b0dbb7d..6611b48 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 953e9c5..4b7c2da 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 e2683df..92e3803 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 193f593..34927c1 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;