diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c2a2e07c0..e860b36b3 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,16 @@ +2003-07-08 Christopher Faylor + + * cygheap.cc (creturn): Set appropriate errno when out of memory. + (ccalloc): Only issue system_printf when debugging. + * dtable.cc (dtable::extend): Only allocate 100 * the incremental growth + size max. Set errno appropriately. + (dtable::build_fhandler): Check for error from set_name. + * fhandler.cc (fhandler_base::set_name): Set errno and return error on OOM. + * fhandler.h (fhandler_base::set_name): Change to bool. + * fhandler_process.cc (format_process_stat): Fix formatting. + * resource.cc (getrlimit): Return greater of OPEN_MAX or fd table size. + * sysconf.cc (sysconf): Ditto. + 2003-07-07 Christopher Faylor * rmsym: Don't use ranlib. diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index aa213cc45..c79b0017c 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -285,7 +285,7 @@ creturn (cygheap_types x, cygheap_entry * c, unsigned len) { if (!c) { - __seterrno (); + set_errno (ENOMEM); return NULL; } c->type = x; @@ -348,8 +348,10 @@ ccalloc (cygheap_types x, DWORD n, DWORD size) c = (cygheap_entry *) _cmalloc (sizeof_cygheap (n)); if (c) memset (c->data, 0, n); +#ifdef DEBUGGING if (!c) system_printf ("ccalloc returned NULL"); +#endif return creturn (x, c, n); } diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 973b3c429..fd7d579bb 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -65,18 +65,25 @@ dtable::extend (int howmuch) if (howmuch <= 0) return 0; + if (new_size > (100 * NOFILE_INCR)) + { + set_errno (EMFILE); + return 0; + } + /* Try to allocate more space for fd table. We can't call realloc () here to preserve old table if memory allocation fails */ if (!(newfds = (fhandler_base **) ccalloc (HEAP_ARGV, new_size, sizeof newfds[0]))) { debug_printf ("calloc failed"); + set_errno (ENOMEM); return 0; } if (fds) { - memcpy (newfds, fds, size * sizeof (fds[0])); cfree (fds); + memcpy (newfds, fds, size * sizeof (fds[0])); } size = new_size; @@ -404,7 +411,8 @@ dtable::build_fhandler (int fd, DWORD dev, char *unix_name, for (p = (char *) win32_name; (p = strchr (p, '/')); p++) *p = '\\'; } - fh->set_name (unix_name, win32_name, fh->get_unit ()); + if (!fh->set_name (unix_name, win32_name, fh->get_unit ())) + return NULL; } debug_printf ("fd %d, fh %p", fd, fh); return fd >= 0 ? (fds[fd] = fh) : fh; diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 69fd48a7b..2ab56f5da 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -149,11 +149,11 @@ fhandler_base::get_readahead_into_buffer (char *buf, size_t buflen) in cases where the name is really required, the filename wouldn't ever be too long (e.g. devices or some such). The unix_path_name is also used by virtual fhandlers. */ -void +bool fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit) { if (unix_path == NULL || !*unix_path) - return; + return false; if (win32_path) win32_path_name = cstrdup (win32_path); @@ -161,14 +161,16 @@ fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit { const char *fmt = get_native_name (); char *w = (char *) cmalloc (HEAP_STR, strlen (fmt) + 16); - __small_sprintf (w, fmt, unit); + if (w) + __small_sprintf (w, fmt, unit); win32_path_name = w; } if (win32_path_name == NULL) { system_printf ("fatal error. strdup failed"); - exit (ENOMEM); + set_errno (ENOMEM); + return false; } assert (unix_path_name == NULL); @@ -183,8 +185,9 @@ fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit { char *p = cstrdup (win32_path_name); unix_path_name = p; - while ((p = strchr (p, '\\')) != NULL) - *p++ = '/'; + if (p) + while ((p = strchr (p, '\\')) != NULL) + *p++ = '/'; if (unix_path) cfree ((void *) unix_path); } @@ -192,9 +195,12 @@ fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit if (unix_path_name == NULL) { system_printf ("fatal error. strdup failed"); - exit (ENOMEM); + free ((void *) win32_path_name); + set_errno (ENOMEM); + return false; } namehash = hash_path_name (0, win32_path_name); + return true; } /* Detect if we are sitting at EOF for conditions where Windows diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 44cb155b4..5ab0ed51d 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -171,7 +171,7 @@ class fhandler_base HANDLE read_state; public: - void set_name (const char * unix_path, const char *win32_path = NULL, int unit = 0); + bool set_name (const char * unix_path, const char *win32_path = NULL, int unit = 0); virtual fhandler_base& operator =(fhandler_base &x); fhandler_base (DWORD dev, int unit = 0); diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 0d26d2cb6..193fd959c 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -400,7 +400,9 @@ format_process_stat (_pinfo *p, char *destbuf, size_t maxsize) state = 'T'; else if (wincap.is_winnt ()) state = get_process_state (p->dwProcessId); - if (wincap.is_winnt ()) + if (!wincap.is_winnt ()) + start_time = (GetTickCount () / 1000 - time (NULL) + p->start_time) * HZ; + else { NTSTATUS ret; HANDLE hProcess; @@ -459,9 +461,11 @@ format_process_stat (_pinfo *p, char *destbuf, size_t maxsize) ret, RtlNtStatusToDosError (ret)); return 0; } - fault_count = vmc.PageFaultCount; - utime = put.UserTime.QuadPart * HZ / 10000000ULL; - stime = put.KernelTime.QuadPart * HZ / 10000000ULL; + fault_count = vmc.PageFaultCount; + utime = put.UserTime.QuadPart * HZ / 10000000ULL; + stime = put.KernelTime.QuadPart * HZ / 10000000ULL; + start_time = (put.CreateTime.QuadPart - stodi.BootTime.QuadPart) * HZ / 10000000ULL; +#if 0 if (stodi.CurrentTime.QuadPart > put.CreateTime.QuadPart) start_time = (spt.KernelTime.QuadPart + spt.UserTime.QuadPart - stodi.CurrentTime.QuadPart + put.CreateTime.QuadPart) * HZ / 10000000ULL; @@ -471,17 +475,15 @@ format_process_stat (_pinfo *p, char *destbuf, size_t maxsize) * Note: some older versions of procps are broken and can't cope * with process start times > time(NULL). */ - start_time = (spt.KernelTime.QuadPart + spt.UserTime.QuadPart) * HZ / 10000000ULL; - priority = pbi.BasePriority; - unsigned page_size = getpagesize (); - vmsize = vmc.PagefileUsage; - vmrss = vmc.WorkingSetSize / page_size; - vmmaxrss = ql.MaximumWorkingSetSize / page_size; - } - else - { - start_time = (GetTickCount () / 1000 - time (NULL) + p->start_time) * HZ; + start_time = (spt.KernelTme.QuadPart + spt.UserTime.QuadPart) * HZ / 10000000ULL; +#endif + priority = pbi.BasePriority; + unsigned page_size = getpagesize (); + vmsize = vmc.PagefileUsage; + vmrss = vmc.WorkingSetSize / page_size; + vmmaxrss = ql.MaximumWorkingSetSize / page_size; } + return __small_sprintf (destbuf, "%d (%s) %c " "%d %d %d %d %d " "%lu %lu %lu %lu %lu %lu %lu " diff --git a/winsup/cygwin/resource.cc b/winsup/cygwin/resource.cc index e87702bab..536dfe8a5 100644 --- a/winsup/cygwin/resource.cc +++ b/winsup/cygwin/resource.cc @@ -137,6 +137,8 @@ getrlimit (int resource, struct rlimit *rlp) break; case RLIMIT_NOFILE: rlp->rlim_cur = getdtablesize (); + if (rlp->rlim_cur < OPEN_MAX) + rlp->rlim_cur = OPEN_MAX; break; case RLIMIT_CORE: rlp->rlim_cur = rlim_core; diff --git a/winsup/cygwin/sysconf.cc b/winsup/cygwin/sysconf.cc index 678d978a9..944afdd41 100644 --- a/winsup/cygwin/sysconf.cc +++ b/winsup/cygwin/sysconf.cc @@ -35,7 +35,12 @@ sysconf (int in) case _SC_OPEN_MAX: return getdtablesize (); case _SC_PAGESIZE: - return getpagesize (); + { + long max = getdtablesize (); + if (max < OPEN_MAX) + max = OPEN_MAX; + return max; + } case _SC_CLK_TCK: return CLOCKS_PER_SEC; case _SC_JOB_CONTROL: