diff options
author | Christopher Faylor <cgf@redhat.com> | 2003-09-19 01:55:53 +0000 |
---|---|---|
committer | Christopher Faylor <cgf@redhat.com> | 2003-09-19 01:55:53 +0000 |
commit | 6fd775d900181e93204b6c58065fcb9be07cd437 (patch) | |
tree | 8bff14b8ebfe03f9ffc96c50e7b3f54b9fc157a5 | |
parent | 69a7b5f79888513741e65a54216d7756474b76c2 (diff) | |
download | gdb-6fd775d900181e93204b6c58065fcb9be07cd437.tar.gz |
* fhandler_disk_file.cc (path_conv::ndisk_links): Fix potential off-by-one
problem when first file in a directory is a directory.
* Makefile.in: Make malloc_wrapper -fomit-frame-pointer.
* cygwin.din: Remove extraneous mallinfo definition.
* dcrt0.cc (quoted): Use strechr for efficiency.
* exceptions.cc (sig_handle_tty_stop): Fix boneheaded mistake by using correct
check for parent state rather than inverted check.
* getopt.c (opterr): Reinstate initialization.
(optind): Ditto.
(optopt): Ditto.
-rw-r--r-- | winsup/cygwin/ChangeLog | 3693 | ||||
-rw-r--r-- | winsup/cygwin/Makefile.in | 419 | ||||
-rw-r--r-- | winsup/cygwin/cygwin.din | 1525 | ||||
-rw-r--r-- | winsup/cygwin/dcrt0.cc | 1166 | ||||
-rw-r--r-- | winsup/cygwin/exceptions.cc | 1275 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_disk_file.cc | 851 | ||||
-rw-r--r-- | winsup/cygwin/libc/getopt.c | 504 |
7 files changed, 9433 insertions, 0 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog new file mode 100644 index 00000000000..490a1883378 --- /dev/null +++ b/winsup/cygwin/ChangeLog @@ -0,0 +1,3693 @@ +2003-09-18 Christopher Faylor <cgf@redhat.com> + + * fhandler_disk_file.cc (path_conv::ndisk_links): Fix potential + off-by-one problem when first file in a directory is a directory. + +2003-09-18 Christopher Faylor <cgf@redhat.com> + + * Makefile.in: Make malloc_wrapper -fomit-frame-pointer. + + * cygwin.din: Remove extraneous mallinfo definition. + + * dcrt0.cc (quoted): Use strechr for efficiency. + +2003-09-18 Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (sig_handle_tty_stop): Fix boneheaded mistake by using + correct check for parent state rather than inverted check. + +2003-09-18 Christopher Faylor <cgf@redhat.com> + + * getopt.c (opterr): Reinstate initialization. + (optind): Ditto. + (optopt): Ditto. + +2003-09-12 Christopher Faylor <cgf@redhat.com> + + * thread.cc (MTinterface::fixup_after_fork): Remove code which + potentially overwrote _impure pointer with contents of thread which + invoked fork since this eliminates important information like the + pointer to the atexit queue. + +2003-09-12 Christopher Faylor <cgf@redhat.com> + + * fhandler_disk_file.cc (path_conv::ndisk_links): Fix problem where + search characters overwrote the path instead of being tacked on the + end. + +2003-09-12 Christopher Faylor <cgf@redhat.com> + + * dcrt0.cc (_dll_crt0): Accommodate breaking apart of early_stuff_init. + * exceptions.cc (early_stuff_init): Delete. + (init_console_handler): New function - top half of early_stuff_init. + (init_global_security): New function - bottom half of early_stuff_init. + (sig_handle): Avoid special hExeced test for SIGINT. Just terminate + the captive process. + (signal_exit): Add debugging output. + * fhandler_tty.cc (fhandler_tty_slave::open): Don't allocate a console + if one already seems to exist. Properly initialize ctrl-c handling if + we do allocate a console. + * winsup.h (early_stuff_init): Delete declaration. + (init_console_handler): New declaration. + (init_global_security): New declaration. + +2003-09-11 Christopher Faylor <cgf@redhat.com> + + * fhandler_disk_file.cc (path_conv::ndisk_links): Rename from + num_entries. Accept an argument and calculate any extra links needed + based on missing . and .. entries. + (fhandler_disk_file::fstat_helper): Always call pc->ndisks_links() to + calculate the number of links. + * path.h (path_conv::ndisk_links): Declare. + +2003-09-11 Christopher Faylor <cgf@redhat.com> + + * path.cc (normalize_posix_path): Put check for '//' prefix back to + denote a UNC path. + (slash_unc_prefix_p): Remove vestige of old //c method for accessing + drives. + +2003-09-11 Christopher Faylor <cgf@redhat.com> + + * dir.cc (rmdir): Add more samba workarounds. + +2003-09-11 Corinna Vinschen <corinna@vinschen.de> + + * shared.cc (user_shared_initialize): Revert length attribute for name + variable to be just UNLEN + 1. + +2003-09-10 Pierre Humblet <pierre.humblet@ieee.org> + + * shared_info.h (shared_info::initialize): Remove argument. + * cygheap.h (cygheap_user::init): New declaration. + * uinfo.cc (cygheap_user::init): New. + (internal_getlogin): Move functionality to cygheap_user::init. Open + the process token to update the group sid. + * shared.cc (user_shared_initialize): Get the user information from + cygheap->user. + (shared_info::initialize): Remove argument. Call cygheap->user.init + instead of cygheap->user.set_name. + (memory_init): Do not get the user name and do not pass it to + shared_info::initialize. + * registry.cc (get_registry_hive_path): Make csid a cygpsid. + (load_registry_hive): Ditto. + +2003-09-10 Christopher Faylor <cgf@redhat.com> + + * fhandler_disk_file.cc (num_entries): Take . and .. into account if + they do not exist since cygwin simulates them. + (fhandler_cygdrive::fstat): Ditto. + (fhandler_cygdrive::readdir): Don't do any specific tests on + __d_position when seeing if a drive exists. + +2003-09-10 Corinna Vinschen <corinna@vinschen.de> + + * Makefile.in (DLL_OFILES): Add getopt.o and iruserok.o. + * cygwin.din: Export __check_rhosts_file, __rcmd_errstr, optarg, + opterr, optind, optopt, optreset, getopt, getopt_long, iruserok + and ruserok. + * getopt.c: Moved from lib to here. Define opt* variables as + dllexport. + * iruserok.c: Moved from lib to here. Rearrange function order. + Prefer using 64/32 bit functions. + * syscalls.cc (shell_fp): Define as struct __sFILE64. + (getusershell): Use fopen64 instead of fopen. + * winsup.h: Add declarations for seteuid32, fopen64, + cygwin_gethostbyname and cygwin_inet_addr. + * include/getopt.h: Declare opt* variables dllimport. + * include/cygwin/version.h: Bump API minor number. + +2003-09-10 Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (sig_handle_tty_stop): Check parent PID_NOCLDSTOP + rather than erroneously checking *my own* sigtodo. + +2003-09-10 Christopher Faylor <cgf@redhat.com> + + * Makefile.in: Add some more -fomit-frame-pointer files. + + * path.cc (conv_path_list_buf_size): Free normalized_path or suffer + memory leak. + * syscalls.cc (chroot): Ditto. + +2003-09-10 Corinna Vinschen <corinna@vinschen.de> + + * Makefile.in (DLL_OFILES): Add bsdlib.o. + * autoload.cc (RegisterServiceProcess): Add. + * bsdlib.cc: New file. + (daemon): New function. + (login_tty): Ditto. + (openpty): Ditto. + (forkpty): Ditto. + * cygwin.din: Export daemon, forkpty, login_tty, logwtmp, updwtmp, + openpty and revoke. + * syscalls.cc (updwtmp): New function, writing to wtmp exclusively. + (logwtmp): Ditto. + (login): Call updwtmp instead of writing to wtmp by itself. + (logout): Ditto. + * tty.cc (revoke): New funtion. + * include/paths.h: Define _PATH_DEVNULL. + * include/pty.h: New header. + * include/cygwin/version.h: Bump API minor number. + * include/sys/utmp.h: Declare logwtmp with const arguments. + Declare updwtmp. + * lib/iruserok.c: New file. + (ruserok): New function. + (iruserok): Ditto. + (__ivaliduser): Ditto. + (__icheckhost): Ditto. + +2003-09-10 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::fstat): Don't use PC_POSIX. + +2003-09-09 Pierre Humblet <pierre.humblet@ieee.org> + + * shared_info.h: Include security.h. + (open_shared): Add psa argument. + (user_shared_initialize): New declaration. + * security.h: Add _SECURITY_H guard. + (sec_user): Use sec_none in the no ntsec case. + * spawn.cc (spawn_guts): Remove call to load_registry_hive. + * syscalls (seteuid32): If warranted, call load_registry_hive, + user_shared_initialize and RegCloseKey(HKEY_CURRENT_USER). + * shared.cc (user_shared_initialize): New. + (open_shared): Add and use psa argument. + (memory_init): Move mount table initialization to + user_shared_initialize. Call it. + +2003-09-09 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc (mmap64): Change address types from caddr_t to void * + according to SUSv3. + (mmap): Ditto. + (munmap): Ditto. + (msync): Ditto. + (mprotect): Ditto. Move to before the fhandler methods. + * include/sys/mman.h: Change prototypes accordingly. + +2003-09-08 Christopher Faylor <cgf@redhat.com> + + * dcrt0.cc (dlL_crt0_1): Set __argc_safe after __argc is absolutely + know to be set. + * exceptions.cc (sig_handle_tty_stop): Don't reset sigCONT event since + it is reset automatically. + * fork.cc (fork): Remove obsolete usage of PID_SPLIT_HEAP. + * include/sys/cygwin.h: Ditto. + * sigproc.cc (sig_send): Use sigframe init method to set frame since it + checks for previous ownership of the frame. + * sigproc.h (sigframe::init): Accept an "is_exception" argument. + +2003-09-08 Christopher Faylor <cgf@redhat.com> + + * dir.cc (readdir): Reinstate setting of old ino field for legacy + applications. + * dirent.h (dirent): Rename unused field to __ino32. + +2003-09-08 Christopher Faylor <cgf@redhat.com> + + * passwd.cc (getpwnam_r): Initialize pw_comment field. + +2003-09-08 Christopher Faylor <cgf@redhat.com> + + * passwd.cc (getpwuid_r32): Initialize pw_comment field. + +2003-09-08 Christopher Faylor <cgf@redhat.com> + + * sigproc.cc (wait_sig_inited): Remove assertion since it is racy. + +2003-09-08 Corinna Vinschen <corinna@vinschen.de> + + * cygwin.din: Export endusershell, getusershell and setusershell. + * syscalls.cc (getusershell): New function. + (setusershell): Ditto. + (endusershell): Ditto. + * include/cygwin/version.h: Bump API minor number. + +2003-09-08 Nicholas Wourms <nwourms@netscape.net> + + * cygwin.din: Export argz_add argz_add_sep argz_append argz_count + argz_create argz_create_sep argz_delete argz_extract argz_insert + argz_next argz_replace argz_stringify envz_add envz_entry envz_get + envz_merge envz_remove envz_strip + * include/cygwin/version.h: Bump api minor number. + +2003-09-07 Christopher Faylor <cgf@redhat.com> + + Throughout, remove __d_u.__d_data fields from DIR structure. + * include/sys/dirent.h (dirent): Remvoe old_d_ino. + (DIR): Make __d_dirhash a 64 bit value. Remove __d_data and __d_u. + Add __flags. + * dir.cc (opendir_states): New enum. + (opendir): Clear new DIR __flags field. + (readdir): Fill in '.' and '..' entries if we hit EOF and we haven't + seen them already. Nuke setting of old_d_ino. + (rewinddir): Reset DIR __flags field. + (seekdir64): Ditto. + * fhandler_disk_file.cc (fhandler_cygdrive::fhandler_cygdrive): Remove + special handling of "." and ".." since they are now handled + automatically. + +2003-09-07 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/in.h: Don't define ipv6 stuff unless we call for it + specifically since it isn't really implemented yet. + +2003-09-07 Christopher Faylor <cgf@redhat.com> + + * cygheap.cc (_csbrk): More left coercion cleanup. + * fhandler_tty.cc (fhandler_tty_slave::read): Ditto. + (fhandler_tty_slave::write): Ditto. + * fhandler_windows.cc (fhandler_windows::read): Ditto. + * heap.cc (sbrk): Ditto. + +2003-09-07 Pierre Humblet <pierre.humblet@ieee.org> + + * signal.cc (nanosleep): Improve test for valid values. Round delay up + to resolution. Fix test for negative remainder. Use timeGetTime + through gtod. + (sleep): Round up return value. + +2003-09-07 Pierre Humblet <pierre.humblet@ieee.org> + Christopher Faylor <cgf@redhat.com> + + * hires.h (HIRES_DELAY_MAX): Define. + (hires_ms::minperiod): Declare static. + (hires_ms::resolution): New. + (hires_ms::dmsecs): New. + (hires_ms::prime): Return UINT. + (gtod): Declare. + * times.cc (hires_ms::prime): Always calculate minperiod and set it to + 1 in case of failure. Return minperiod. + (hires_ms::resolution): Define. + (hires_ms::~hires_ms): Delete. + (hires_ms::usecs): Check minperiod to prime. + (gtod) Define as global. + +2003-09-06 Christopher Faylor <cgf@redhat.com> + + Remove left coercion throughout. + +2003-09-04 Pierre Humblet <pierre.humblet@ieee.org> + + * hires.h (hires_ms::~hires_ms): Delete declaration. + * times.cc (hires_ms::~hires_ms): Delete definition.. + +2003-09-04 Christopher Faylor <cgf@redhat.com> + + * dcrt0.cc (__argc_safe): New variable. + (dll_crt0_1): Store argc in __argc_safe, which will theoretically + remain untouched by the user. + * fhandler_console.cc (fhandler_console::read): Silence some compiler + warnings. + * fhandler_raw.cc (fhandler_dev_raw::raw_read): Ditto. + * pinfo.cc (_pinfo::commune_recv): Carefully bound argv scan and check + for potentially bad pointers since user could have set argv cell to + anythinw. + * cygheap.h (CYGHEAPSIZE): Bump up size. + +2003-09-04 Corinna Vinschen <corinna@vinschen.de> + + * sysconf.cc (sysconf): Return more accurate value for _SC_AVPHYS_PAGES. + +2003-09-04 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc: Restructure. Add, remove and rewrite comments throughout + for better readability. Change function names for better + understanding. + (MAP_SET): Accomodate name change from map_map_ to page_map_. + (MAP_CLR): Ditto. + (MAP_ISSET): Ditto. + (mmap_record::page_map_): Rename from page_map_. + (mmap_record::get_map): Remove. + (mmap_record::alloc_page_map): Rename from alloc_map. Return bool + indicating success of cygheap memory allocation. + (mmap_record::free_page_map): Rename from free_map. + (mmap_record::fixup_page_map): Rename from fixup_map. + (mmap_record::find_unused_pages): Rename from find_empty. + (mmap_record::map_pages): Rename from map_map. + (mmap_record::unmap_pages): Rename from unmap_map. + (class list): Make all class members private. + (list::list): Remove. + (list::~list): Remove. + (list::get_fd): New attribute reader. + (list::get_hash): Ditto. + (list::get_record): Ditto. + (list::add_record): Manage all allocation for mmap_records. Check + for failed memory allocation and return NULL if so. + (list::set): New function. + (list::del_record): Rename from erase. Return true if last mmap_record + has been deleted, false otherwise. Check for legal incoming index + value. + (list::erase): Remove erase/0. + (list::search_record): Rename from match. + (map::map): Remove. + (map::~map): Remove. + (map::add_list): Manage all allocation for lists. Check for failed + memory allocation and return NULL if so. + (map::get_list): New method. + (map::del_list): Rename from erase. Check for legal incoming index + value. + (mmap64): Check for failed mmap_record memory allocation. Return + with MAP_FAILED and errno set to ENOMEM if so. + (munmap): Rearrange loop using new list and mmap_record accessor + functions. Rename loop index variables for better understanding. + Check if list can be deleted after last mmap_record in it has been + deleted. + (msync): Rearrange loop using new list and mmap_record accessor + functions. Rename loop index variables for better understanding. + (fixup_mmaps_after_fork): Ditto. + +2003-09-03 Christopher Faylor <cgf@redhat.com> + + * cxx.cc (new): Fix formatting. Just return result of ccalloc rather + than calling memset explicitly. + +2003-09-03 Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (set_process_mask): Set pending signals only when + signals become unmasked. + * sigproc.cc (pending_signals): Flip back to a global. + (wait_sig): Don't set pending signals when there is an armed semaphore + or signal is blocked. + + * shared.cc (shared_info::initialize): Add a username parameter for + user-mode mounts. Reorganize to try to avoid startup race. + (memory_init): Move some stuff into shared_info::initialize. + * shared_info.h (shared_info::initialize): Change declaration. + (CURR_SHARED_MAGIC): Update. + +2003-09-01 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/version.h: Bump DLL minor number to 4. + +2003-09-01 Christopher Faylor <cgf@redhat.com> + + * net.cc (dup_ent): Restore check for NULL input. + +2003-08-31 Christopher Faylor <cgf@redhat.com> + + * include/sys/cygwin.h: Don't define cygwin-specific things if + !__CYGWIN__. + +2003-08-31 Christopher Faylor <cgf@redhat.com> + + * cygheap.cc (cygheap_init): Allocate space for sigaction array in + cygheap. + * cygheap.h (cygheap_types): Add HEAP_SIGS. + * exceptions.cc (signal_fixup_after_exec): Remove from this file. + * pinfo.h (pinfo::getsig): Just return global_sigs array. + (pinfo::sigs): Delete. + * sigproc.cc (signal_fixup_after_exec): Move it here. + (global_sigs): New global array, moved from pinfo structure. + (sigalloc): New function. Allocate global sigaction array here. + (proc_subproc): Remove copysigs call. It's automatic now. + * include/sys/cygwin.h (PID_NOCLDSTOP): New value. + * signal.cc (sigaction): Set myself->PID_NODCLDSTOP when appropriate. + * sigproc.h (sigalloc): Declare. + + * fnmatch.c (fnmatch): Use C90 parameters. + (rangematch): Ditto. + + * fhandler.cc (fhandler_base::raw_read): Use right coercion to avoid a + compiler warning. + +2003-08-31 Christopher Faylor <cgf@redhat.com> + + * net.cc (dup_ent): Make debugging output consistent. + +2003-08-31 Christopher Faylor <cgf@redhat.com> + + Use dup_ent rather than specific dup_*_ptr functions throughout. + * (gen_ent): Delete. + (dup_ent): Subsume gen_ent functionality. + (dup_host_ptr): Delete. + (dup_proto_ptr): Ditto. + (dup_servent_ptr): Ditto. + +2003-08-31 Christopher Faylor <cgf@redhat.com> + + * net.cc (gen_ent): Invert sense of null check so that debug output + makes sense. + +2003-08-31 Christopher Faylor <cgf@redhat.com> + + * net.cc (free_char_list): Delete. + (dup_addr_list): Delete. + (dup_char_list): Delete. + (free_hostent_ptr): Delete. + (free_protoent_ptr): Delete. + (free_servent_ptr): Delete. + (DWORD_round): New function. + (strlen_round): New function. Returns strlen rounded up to word size. + (dup_ent): New, generic function to duplicate a {host,proto,serv}ent + structure. + (gen_ent): New macro. Generates a generic dup_{host,proto,serv}ent_ptr + function. + (cygwin_getservbyname): Remove call to free_servent_ptr, pass + servent_buf to dup_servent_ptr. + (cygwin_getservbyport): Ditto. + (cygwin_gethostbyname): Ditto for hostent. + (cygwin_gethostbyaddr): Ditto. + (cygwin_getprotobyname): Ditto for protoent. + (cygwin_getprotobynumber): Ditto. + +2003-08-31 Christopher Faylor <cgf@redhat.com> + + * Makefile.in (MALLOC_OFILES): Always fill in with correct malloc + object. + * configure.in: Fill in MALLOC_OFILES with either debugging or regular + malloc. + * configure: Regenerate. + * dlmalloc.c: Make various fruitless changes to attempt to get to work. + * dlmalloc.h: Ditto. + * malloc.cc (free): Check malloc pool when debugging. + + * path.cc (win32_device_name): Eliminate compiler warning. + + * sigproc.cc (sig_dispatch_pending): Remove use of was_pending. Let + thisframe.call_signal_handler decide if handler should be called rather + than using bogus was_pending check. + + * exceptions.cc (interrupt_setup): Remove accidentally checked in + debugging code. + +2003-08-30 Christopher Faylor <cgf@redhat.com> + + * heap.cc (sbrk): Save rounded addess in user_heap_max. + +2003-08-30 Christopher Faylor <cgf@redhat.com> + + * sigproc.cc (sig_dispatch_pending): Remove explicit call to + thisframe.call_signal_handler. + +2003-08-30 Christopher Faylor <cgf@redhat.com> + + Remove some cygserver files. + +2003-08-28 Christopher Faylor <cgf@redhat.com> + + * sigproc.h: Make some functions regparm. + * sigproc.cc (checkstate): Make regparm. + (getevent): Change parameters in declaration, rename from getsem, make regparm. + (sig_send): Recognize that nosync is now an event. Remove some old + cruft from previous interrupt anywhere signal handler. + (getevent): Change parameters in definition, rename from getsem. + Allocate event rather than semaphore. + (wait_sig): Treat sigcatch_nosync as an event. + +2003-08-28 Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (sigreturn): Fix problem where old return address was + not properly restored for a nested signal. + +2003-08-27 Christopher Faylor <cgf@redhat.com> + + * autoload.cc (SwitchToThread): Declare as autoload function. + * cygthread.h (cygthread::main_thread_id): Make public. + * exceptions.cc (setup_handler): Remove unneeded priority stuff. + Rename label to reflect what it does. Add debugging for idiotic + Windows NT problem. Change debugging output to include signal number. + * miscfuncs.cc (low_priority_sleep): If available, use SwitchToThread + function to give time slice to other threads. + * wincap.cc: Properly define have_switch_to_thread throughout. + * wincap.h (wincap::switch_to_thread): New element. + +2003-08-27 Christopher Faylor <cgf@redhat.com> + + * syscalls.cc (mount): Don't check win32_path when doing cygdrive + mount. + +2003-08-27 Christopher Faylor <cgf@redhat.com> + + * specdir: Correctly remove temporary directory prior to use. + +2003-08-27 Christopher Faylor <cgf@redhat.com> + + * sigproc.cc (wait_sig): Count number of iterations through + 'more_signals' loop and issue a warning if DEBUGGING and excessive. + (WFSO): When debugging and infinite timeout, loop. + +2003-08-26 Corinna Vinschen <corinna@vinschen.de> + + * include/cygwin/stat.h: Allow definition of internal stat structures + also when compiling newlib. + +2003-08-25 Christopher Faylor <cgf@redhat.com> + + Throughout, change USE_CYGSERVER to USE_SERVER. + * Makefile.in (LIBSERVER): Define and use. + * configure.in: Set LIBSERVER as appropriate. + * configure: Regenerate. + * acconfig.h: Regenerate. + * environ.cc: Rename allow_daemon to allow_server. Only recognize when + USE_SERVER is defined. + +2003-08-23 Christopher Faylor <cgf@redhat.com> + + * syscalls.cc (_remove_r): Define. + +2003-08-22 Corinna Vinschen <corinna@vinschen.de> + + * cygheap.h (enum cygheap_types): Add HEAP_MMAP. + (CYGHEAPSIZE): Add another 64K. + * mmap.cc: Use cmalloc, ccalloc and crealloc with HEAP_MMAP type + throughout. + +2003-08-22 Christopher Faylor <cgf@redhat.com> + + * cygheap.cc (user_heap_info::max): New field. + * heap.cc (heap_init): Save pointer to end of heap reserved memory. + (sbrk): Don't attempt to commit memory beyond end of heap reserved + memory. Attempt to honor comment and reserve commitbytes if heapchunk + fails. + +2003-08-20 Pierre Humblet <pierre.humblet@ieee.org> + + * exceptions.cc (sigreturn): Don't clobber ebp in recursive signal + calls. + +2003-08-22 Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (sig_handle): Change so that default signals indicate + success. + +2003-08-21 Christopher Faylor <cgf@redhat.com> + + * sigproc.cc (wait_sig): Remove redundant test in do/while. + +2003-08-21 Christopher Faylor <cgf@redhat.com> + + * sigproc.cc (wait_sig): Avoid infinite loop. + +2003-08-20 Christopher Faylor <cgf@redhat.com> + + * speclib: Reenable removal of temp files. + +2003-08-20 Christopher Faylor <cgf@redhat.com> + + * miscfuncs.cc (low_priority_sleep): Sleep at same priority as main + thread. + * sigproc.cc (wait_sig): Keep looping if there are more signals to + consider and we are flushing signals. + (sig_send): Put nonsync signals in the correct bucket. + +2003-08-20 Christopher Faylor <cgf@redhat.com> + + * speclib: Fix created lib to avoid "File truncated" problems. + +2003-08-20 Pierre Humblet <pierre.humblet@ieee.org> + + * exceptions.cc (interrupt_setup): Set sigsave.sig last to avoid a + race. + +2003-08-20 Christopher Faylor <cgf@redhat.com> + + * sigproc.cc (wait_sig): Ensure that myself->getsigtodo array is + flushed on a __SIGFLUSH. + +2003-08-20 Pierre Humblet <pierre.humblet@ieee.org> + Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (_sigreturn): Handle nested signals without growing the + stack. + +2003-08-19 Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (pending_signals): Remove unneeded declaration. + * sigproc.cc (pending_signals): Make static. + (wait_sig): Use defined values rather than integers for rc. Never scan + both todo arrays as this could cause hangs if signals arrive from two + different sources. Rename saw_pending_signals to saw_failed_interrupt. + Exit loop when signal found. Enter low-priority sleep, if necessary, + after finished signalling completion. Set pending_signals when blocked + (from Pierre Humblet). + +2003-08-19 Christopher Faylor <cgf@redhat.com> + + * signal.cc (sigpending): Move. + * sigproc.cc (sigpending): To here. + (getlocal_sigtodo): Return process-local signal array. + (sigpending): Accommodate new process-local signal array. + (sig_send): Ditto. + (sig_set_pending): Ditto. + (wait_sig): Ditto. + +2003-08-19 Christopher Faylor <cgf@redhat.com> + + Throughout, eliminate argument to sig_dispatch_pending. + * exceptions.cc (setup_handler): Move non-interruptible condition + handling (back) to wait_sig. + (set_process_mask): Don't worry about calling sig_dispatch_pending from + sigthread since it is detected in the function anyway. + (sig_handle): Eliminate thisproc arg. Don't call sig_dispatch_pending + on SIGCONT since that should happen automatically. + * sigproc.cc (sig_dispatch_pending): Eliminate justwake argument. Just + return when called from sigthread. + (wait_sig): Change some variables to bool. Change inner while to an + if. Move uninterruptible signal handling here. + (sigproc_terminate): Don't call sig_dispatch_pending. Just increment + semaphore on exit. + + * speclib: Use slightly different (but still flawed) method for + determining symbols to extract from libraries. + +2003-08-18 Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (sigdelayed): Fix race where signal handler could get + the wrong mask (as suggested by Pierre Humblet). + +2003-08-18 Christopher Faylor <cgf@redhat.com> + + * path.cc (mount): Add null/empty check for input parameters. + (umount): Add null/empty check for input parameters. + +2003-08-17 Pierre Humblet <pierre.humblet@ieee.org> + + * grp.cc (read_group): Revert previous change. + * uinfo.cc (pwdgrp::load): Always reset curr_lines. + +2003-08-17 Corinna Vinschen <corinna@vinschen.de> + + * errno.cc (errmap): Map ERROR_INVALID_BLOCK_LENGTH to EIO. + * fhandler_raw.cc (fhandler_dev_raw::raw_read): Set more accurate + errnos instead of EACCES. + (fhandler_dev_raw::raw_write): Ditto. + +2003-08-17 Christopher Faylor <cgf@redhat.com> + + * path.cc (special_name): Accommodate all special names with + extensions. + +2003-08-15 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc (mmap64): Avoid crash if file size is less than requested + map length. + +2003-08-13 Igor Pechtchanski <pechtcha@cs.nyu.edu> + + * path.cc (special_name): Add checks for some specials followed by + a "." and a FIXME comment. + +2003-08-13 Corinna Vinschen <corinna@vinschen.de> + + * cygwin.din: Accommodate change from cygwin_lstat to lstat. + * syscalls.cc: Add defines to avoid declaration issues when + renaming cygwin_lstat back to lstat. + (lstat): Reverted name change from cygwin_lstat. + +2003-08-12 Corinna Vinschen <corinna@vinschen.de> + + * include/sys/param.h (NBBY): Define if not defined. + +2003-08-12 Nicholas Wourms <nwourms@netscape.net> + + * include/sys/param.h (setbit): Add new bitmap related macro. + (clrbit): Likewise. + (isset): Likewise. + (isclr): Likewise. + (howmany): Add new counting/rounding macro. + (rounddown): Likewise. + (roundup): Likewise. + (roundup2): Likewise. + (powerof2): Likewise + (MIN): Add macro for calculating min. + (MAX): Add macro for calculating max. + +2003-08-09 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/version.h: Bump DLL minor number to 3. + +2003-08-08 Gerrit P. Haase <gp@familiehaase.de> + + * include/stdint.h: Correctly define INT32_MIN. + +2003-08-08 David Rothenberger <daveroth@acm.org> + + * grp.cc (read_group): Set __group32.gr_mem pointer back to &null_ptr + after free() is called. + +2003-08-05 Christopher Faylor <cgf@redhat.com> + + * Makefile.in: Rework to accommodate new speclib arguments. + * speclib: Rework to extract everything from libcygwin.a rather than + building things from existing object files. + +2003-08-05 Pavel Tsekov <ptsekov@gmx.net> + + * path.cc (cygdrive_getmntent): Do not skip over drives of type + DRIVE_REMOVABLE. + +2003-08-05 Christopher Faylor <cgf@redhat.com> + + * fhandler.cc (fhandler_base::lseek): Be more paranoid when + constructing offsets from 64 bit value. + * syscalls.cc (logout): Avoid temp buffer memcpy since new scheme does + not require it. + (utmp_data): Rework as a macro which returns a pointer into a buffer. + (getutent): Use new buffer allocation mechanism to grab a utmp buffer. + (getutid): Ditto. + (pututline): Ditto. + +2003-08-05 Pavel Tsekov <ptsekov@gmx.net> + + * fhandler_disk_file.cc (fhandler_cygdrive::readdir): Do not change + 'errno' if end of directory condition is encountered as per SUSv2. + * fhandler_proc.cc (fhandler_proc::readdir): Ditto. + * fhandler_process (fhandler_process::readdir): Ditto. + * fhandler_registry (fhandler_registry::readdir): Ditto. + +2003-07-30 Christopher Faylor <cgf@redhat.com> + + * dcrt0.cc (_dll_crt0): Move strace.microseconds initialization to + after pthread initialization. + (dll_crt0_1): i.e., here. + +2003-07-28 Christopher Faylor <cgf@redhat.com> + + * fhandler_base.cc (fhandler_base::readv): Rework to properly return + number of bytes from read. + +2003-07-28 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/version.h: Bump DLL minor number to 2. + +2003-07-26 Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (ctrl_c_handler): Send SIGHUP when events occur only if + there is a tty associated with the process. Send SIGHUP on + CTRL_LOGOFF_EVENT. + + * fhandler_tty.cc (fhandler_tty_slave::open): Adjust console open + handle counter regardless of whether this is a pty or tty. + (fhandler_tty_slave::open): Ditto. + (fhandler_tty_slave::dup): Ditto. + (fhandler_tty_common::set_close_on_exec): Ditto. + (fhandler_tty_master::init_console): Decrement console open handle + counter after init since it will now be handled by all tty open. + * syscalls.cc (setsid): Rework debugging output slightly. + +2003-07-25 Christopher Faylor <cgf@redhat.com> + + * configure.in: Use 'install-sh -c'. + * configure: Regenerate. + +2003-07-25 Christopher Faylor <cgf@redhat.com> + + * configure.in: Always use install-sh. + * configure: Regenerate. + +2003-07-25 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/socket.h: Conditionalize [AP]F_INET6 define. + +2003-07-25 Christopher Faylor <cgf@redhat.com> + + * Makefile.in (OBSOLETE_FUNCTION): Add fdopen. + +2003-07-25 Christopher Faylor <cgf@redhat.com> + + * cygwin.din: Export _fdopen64 + * Makefile.in (NEW_FUNCTIONS): Add _fdopen64 -> fdopen translation. + * include/cygwin/version.h: Bump api minor number. + + * ntdll.h: Remove (now) duplicate FILE_SYNCHRONOUS_IO_NONALERT + definition. + +2003-07-24 Christopher Faylor <cgf@redhat.com> + + * environ.cc (check_case_init): Use strncasematch. + + * cygwin.din: Export __mempcpy. + * cygwin/version.h: Bump api minor number. + +2003-07-21 Pavel Tsekov <ptsekov@gmx.net> + + * mmap.cc: Use proper format specifiers for _off64_t and size_t in + format strings passed to syscall_printf () and debug_printf () + throughout. + +2003-07-18 Pierre Humblet <pierre.humblet@ieee.org> + + * security.cc (verify_token): Fix white space and style. + Use type bool instead of BOOL and char. Use alloca + instead of malloc and free for my_grps. + +2003-07-17 Corinna Vinschen <corinna@vinschen.de> + + * sysconf.cc (sysconf): Fix OPEN_MAX patch. Return page size on + _SC_PAGESIZE again. + +2003-07-14 Corinna Vinschen <corinna@vinschen.de> + + * cygheap.h (class cygheap_user): Use INVALID_HANDLE_VALUE as invalid + value for tokens. + * syscalls.cc (seteuid32): Ditto. Set new_token to process token if + process token is suitable. + * uinfo.cc (uinfo_init): Initialize tokens in cygheap user info + to INVALID_HANDLE_VALUE. + +2003-07-14 Pierre Humblet <pierre.humblet@ieee.org> + + * cygheap.h (enum impersonation): Delete. + (cygheap_user::impersonation_state): Delete. + (cygheap_user::current_token): New. + (cygheap_user::issetuid): Modify to use current_token. + (cygheap_user::token): Ditto. + (cygheap_user::deimpersonate): Ditto. + (cygheap_user::reimpersonate): Ditto. + (cygheap_user::has_impersonation_tokens): Ditto. + (cygheap_user::close_impersonation_tokens): Ditto. + * security.cc (cygwin_set_impersonation_token): Always set the token. + (verify_token): Change type of gsid to cygpsid. + (get_file_attribute): Use the effective ids. + * syscalls.cc (seteuid32): Modify to use cygheap_user::current_token. + * uinfo.cc (uinfo_init) Do not set cygheap->user.impersonation_state. + +2003-07-12 Christopher Faylor <cgf@redhat.com> + + * pinfo.cc (_pinfo::commune_send): Fix bounds test so that poll of + communicating pid actually stops eventually. + +2003-07-10 Christopher Faylor <cgf@redhat.com> + + * path.cc (get_device_number): Remove special com? consideration. + (special_chars): Make static. + (special_introducers): New. + (special_char): Allow specified valid_chars args. + (fnunmunge): Handle aux-like filenames correctly. + (special_name): Add con, conin$, conout$. + (mount_item::fnmunge): Use __small_sprintf return value to calculate + increments. + +2003-07-09 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/version.h: Bump DLL minor number to 1. + +2003-07-09 Christopher Faylor <cgf@redhat.com> + + * fhandler_proc.cc (format_proc_stat): Use correctly sized constants + for filling in zeros on 98. + +2003-07-09 Christopher Faylor <cgf@redhat.com> + + * fhandler_proc.cc (fhandler_proc::fill_filebuf): Allocate more space + for stat buffer. + (format_proc_stat): Reorganize to accumulate and report on all cpus. + +2003-07-09 Christopher Faylor <cgf@redhat.com> + + * sysconf.cc (sysconf): Return processors online rather than bitmask + for _SC_NPROCESSORS_ONLN. + +2003-07-08 Christopher Faylor <cgf@redhat.com> + + * 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 <cgf@redhat.com> + + * rmsym: Don't use ranlib. + +2003-07-07 Christopher Faylor <cgf@redhat.com> + + * newsym: Reenable removal of tmp directory. Just use ar to generate + archive index. + * Makefile.in: Don't send ranlib to newsym or rmsym. + +2003-07-07 Christopher Faylor <cgf@redhat.com> + + * newsym: Create objects that are closer to those created by dlltool so + as not to confuse --export-all-symbols. + * rmsym: Be a little more accepting of object filenames now that + dlltool can create different format files. + +2003-07-06 Christopher Faylor <cgf@redhat.com> + + * newsym: Oops. Revert below change. + +2003-07-06 Christopher Faylor <cgf@redhat.com> + + * newsym: Use correct prefix for generating imports. + * pinfo.cc (_pinfo::commune_send): Don't wait forever for a response + from another process. + +2003-07-06 Christopher Faylor <cgf@redhat.com> + + * syscalls.cc (gethostid): Set thread affinity so that results are + predictable. + +2003-07-05 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc (list::match): Add parameters to return valid address and + length back to munmap(). Evaluate intersection between given + area and mapped area and return it, if any. + (mmap64): On regular files, don't allow mappings beginning beyond + EOF. Return with errno set to ENXIO instead. + (munmap): Rewrite SUSv3 conformant. Check if given memory area is + valid. Unmap all maps inside given memory area. Don't return error + if no mapping has been unmapped. + +2003-07-05 N Stephens <nigel@mips.com> + + * fhandler.h (fhandler_socket::get_connect_state): New method to + return socket connection state. + * fhandler_socket.cc (dup): Copy socket connect state to new file + handle. + * net.cc (cygwin_rcmd): Mark file handles of sockets returned by + rcmd() as CONNECTED state. + (cygwin_rexec): Similarly for rexec(). + (socketpair): Mark both ends of a new socket pair as CONNECTED. + +2003-07-04 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc (fhandler_disk_file::mmap): Fix address test. + +2003-07-03 Christopher Faylor <cgf@redhat.com> + + * path.cc (fillout_mntent): Change "posix" to "managed". + +2003-07-02 Christopher Faylor <cgf@redhat.com> + + * fhandler.h (FH_ENC): New enum. + (fhandler_base::get_encoded): New function. + (fhandler_base::set_encoded): Ditto. + * fhandler_disk_file.cc (fhandler_disk_file::opendir): Set encoded flag + in fhandler, as appropriate. + (fhandler_disk_file::readdir): Unmunge filename as appropriate based on + new encoding flag. + * path.cc (normalize_posix_path): Don't punt on files with colons. + (special_char): New function. + (mount_item::fnmunge): Ditto. + (fnunmunge): Ditto. + (special_name): Ditto. + (mount_item::build_win32): Avoid drive considerations when file is + encoded. + (mount_info::conv_to_win32_path): Handle encoded filenames. + (mount_info::conv_to_posix_path): Ditto. + (fillout_mntent): Add posix string when directory is encoded. + * path.h (fnunmunge): Declare. + (path_conv::is_encoded): Declare. + +2003-07-03 Christopher Faylor <cgf@redhat.com> + + * fhandler_tty.cc (fhandler_tty_slave::open): Conditionalize a little + more of the cygserver stuff so that ttys actually work. + +2003-07-03 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc (mmap64): Allow MAP_FIXED with pagesize granularity (4K). + If a non-zero addr is given, align it to the next lower 64K boundary. + (fhandler_disk_file::mmap): If a non-zero address is given, try + mapping using the given address first. If it fails and flags is not + MAP_FIXED, try again with NULL address. + +2003-07-01 Christopher Faylor <cgf@redhat.com> + + * thread.cc: Remove _MT_SAFE conditional. + +2003-07-01 Christopher Faylor <cgf@redhat.com> + + * configure.in: Fix --enable-server option. + * configure: Regenerate. + +2003-07-01 Christopher Faylor <cgf@redhat.com> + + * Makefile.in: Remove cygserver stuff. + * acconfig.h: Add USE_CYGSERVER define. + * config.h.in: Regenerate. + * configure.in: Add --enable-server setting. + * configure: Regenerate. + * fhandler_tty.cc (fhandler_tty_slave::open): Conditionalize + compilation of cygserver stuff. + * fork.cc (fork_child): Ditto. + * shm.cc: Ditto. + * tty.cc (tty::common_init): Ditto. + + * dcrt0.cc: Use bool rather than BOOL for CYGWIN environment variable + definitions. + * environ.cc: Ditto. + * ntea.cc: Ditto. + * security.cc: Ditto. + * security.h: Ditto. + * syscalls.cc (check_posix_perm): Remove externs that were already + declared in a header. + * winsup.h: Ditto. Declare _MT_SAFE here. Delete it someday since + cygwin should always be _MT_SAFE. + +2003-07-01 Christopher Faylor <cgf@redhat.com> + + * thread.cc: Remove _MT_SAFE conditional. + +2003-07-01 Christopher Faylor <cgf@redhat.com> + + * configure.in: Fix --enable-server option. + * configure: Regenerate. + +2003-07-01 Christopher Faylor <cgf@redhat.com> + + * Makefile.in: Remove cygserver stuff. + * acconfig.h: Add USE_CYGSERVER define. + * config.h.in: Regenerate. + * configure.in: Add --enable-server setting. + * configure: Regenerate. + * fhandler_tty.cc (fhandler_tty_slave::open): Conditionalize + compilation of cygserver stuff. + * fork.cc (fork_child): Ditto. + * shm.cc: Ditto. + * tty.cc (tty::common_init): Ditto. + + * dcrt0.cc: Use bool rather than BOOL for CYGWIN environment variable + definitions. + * environ.cc: Ditto. + * ntea.cc: Ditto. + * security.cc: Ditto. + * security.h: Ditto. + * syscalls.cc (check_posix_perm): Remove externs that were already + declared in a header. + * winsup.h: Ditto. Declare _MT_SAFE here. Delete it someday since + cygwin should always be _MT_SAFE. + +2003-06-30 Pierre Humblet <pierre.humblet@ieee.org> + + * cygheap.h (enum impersonation): New enum. + (cygheap_user::token): Delete. + (cygheap_user::impersonated): Delete. + (cygheap_user::external_token): New member. + (cygheap_user::internal_token): New member. + (cygheap_user::impersonation_state): New member. + (cygheap_user::issetuid): Modify. + (cygheap_user::token): New method. + (cygheap_user::deimpersonate): New method. + (cygheap_user::reimpersonate): New method. + (cygheap_user::has_impersonation_tokens): New method. + (cygheap_user::close_impersonation_tokens): New method. + * dtable.cc (dtable::vfork_child_dup): Use new cygheap_user methods. + * fhandler_socket.cc (fhandler_socket::dup): Ditto. + * fork.cc (fork_child): Ditto. + (fork_parent): Ditto. + * grp.cc (internal_getgroups): Ditto. + * security.cc (verify_token): Ditto. + (check_file_access): Ditto. + (cygwin_set_impersonation_token): Detect conflicts. Set + user.external_token. + * spawn.cc (spawn_guts): Use new cygheap_user methods. + * syscalls.cc (seteuid32): Rearrange to use the two tokens + in cygheap_user. + (setegid32): Use new cygheap_user methods. + * uinfo.cc: (internal_getlogin): Ditto. + +2003-06-25 Doru Carastan <doru.carastan@mvista.com> + + * Makefile.in: Use INSTALL_PROGRAM to install the cygwin DLL. + +2003-06-24 Thomas Pfaff <tpfaff@gmx.net> + + * thread.cc (MTinterface::fixup_after_fork): Fix thread list after + fork. + (pthread::threads): Instantiate. + (pthread::pthread): Initialize running and suspendend. + Initialize next with NULL. + Add thread to thread list if it is not the null_pthread. + (pthread::~pthread): Remove thread from thread list if it is + not the null_pthread. + (pthread::postcreate): Set running flag. + (pthread::exit): Reset running flag. + (pthread::cancel): Try to cancel thread only if still running. + (pthread::_fixup_after_fork): Implement. + (pthread::detach): Check if thread is still running before detach. + * thread.h (pthread::running): New member. + (pthread::next): Ditto. + (pthread::fixup_after_fork): New static method. + (pthread::threads): New static method. + (pthread::_fixup_after_fork): New method. + +2003-06-20 Christopher Faylor <cgf@redhat.com> + + * pinfo.cc (_pinfo::commune_send): Don't attempt to communicate with a + pure windows process. + +2003-06-18 Pierre Humblet <pierre.humblet@ieee.org> + + * autoload.cc (GetNetworkParams): Add. + * net.cc (getdomainname): Call GetNetworkParams and read the + DhcpDomain registry value if warranted. + +2003-06-17 Christopher Faylor <cgf@redhat.com> + + * path.cc (mount): Do more strict checking on posix path arguments. + +2003-06-15 Christopher Faylor <cgf@redhat.com> + + Throughout, remove "include <errno.h>" from files which already include + cygerrno.h. + +2003-06-15 Thomas Pfaff <tpfaff@gmx.net> + + * include/cygwin/config.h (__DYNAMIC_REENT__): Define. + * include/cygwin/version.h: Bump API minor version. + * cygwin.din: Export __getreent + * cygerrno.h: Include errno.h. Fix places where _impure_ptr is used + directly to store the errno value. + * debug.cc (__set_errno): Ditto. + * errno.cc: Remove _RRENT_ONLY define to get errno.cc compiled. + * signal.cc: Rename _reent_clib to _REENT throughout. + * thread.h (reent_clib): Remove prototype. + * thread.cc (reent_clib): Rename reent_clib to __getreent. Return + _impure_ptr until MTinterface is initialized. + (reent_winsup): Fix a possible SEGV when _r == NULL. Return NULL + instead. + * MTinterface::fixup_after_fork: Switch reent back to _impure_ptr to + keep signal handling running when fork is called from a thread other + than the mainthread. + +2003-06-12 Thomas Pfaff <tpfaff@gmx.net> + + * thread.cc (pthread_attr_init): Revert change from 2003-06-11 + to return 0 if attribute is already initialized back to EBUSY. + (pthread_condattr_init): Ditto. + (pthread_rwlockattr_init): Ditto. + (pthread_mutexattr_init): Ditto. + +2003-06-12 Corinna Vinschen <corinna@vinschen.de> + + * exceptions.cc (ctrl_c_handler): Don't send a signal on + CTRL_SHUTDOWN_EVENT. Add a comment to rationalize the patch. + +2003-06-11 Thomas Pfaff <tpfaff@gmx.net> + + * thread.cc (pthread_attr_init): Return 0 if attribute is already + initialized. + Fix return code if out of memory. + (pthread_condattr_init): Ditto. + (pthread_rwlockattr_init): Ditto. + (pthread_mutexattr_init): Return 0 if attribute is already + initialized. + +2003-06-09 Pierre Humblet <pierre.humblet@ieee.org> + + * spawn.cc (spawn_guts): Call CreateProcess while impersonated, + when the real {u,g}ids and the groups are original. + Move RevertToSelf and ImpersonateLoggedOnUser to the main line. + * uinfo.cc (uinfo_init): Reorganize. If CreateProcess was called + while impersonated, preserve the uids and gids and call + ImpersonateLoggedOnUser. Preserve the uids and gids on Win9X. + + * exceptions.cc (error_start_init): Quote the pgm in the command. + +2003-06-07 Christopher Faylor <cgf@redhat.com> + + * poll.cc: Define FD_SETSIZE to ridiculously large number so that there + will be no artificially small limits. + +2003-06-07 Christopher Faylor <cgf@redhat.com> + + * fhandler_tty.cc (fhandler_tty_slave::close): Free the console when + last tty closes. + +2003-06-07 Thomas Pfaff <tpfaff@gmx.net> + + * fhandler_socket.cc (fhandler_socket::connect): Change error + handling for nonblocking connects to return EALREADY when + connect is called more than once for the same socket. + +2003-06-06 Corinna Vinschen <corinna@vinschen.de> + + * cygwin.din: Add vsyslog. + * fhandler.cc (fhandler_base::write): Only make file sparse if the + seeked area is >= 128K. + * syslog.cc (vsyslog): New function, overtaking functionality from + syslog. + (syslog): Just call vsyslog. + * include/cygwin/version.h: Bump API minor. + * include/sys/syslog.h: Add vsyslog declaration. + +2003-06-05 Christopher Faylor <cgf@redhat.com> + + * cygthread.cc (cygthread::terminate_thread): Change system_printf to + debug_printf. + +2003-06-04 Christopher Faylor <cgf@redhat.com> + + * shared.cc (shared_info::heap_chunk_size): Be really defensive about + making sure that heap_chunk is set. + +2003-06-04 Christopher Faylor <cgf@redhat.com> + + * path.cc (conv_path_list): Use correct value when calculating length + to avoid a potential SEGV. + +2003-06-03 Pierre Humblet <pierre.humblet@ieee.org> + + * fhandler_disk_file.cc (fhandler_disk_file::fstat): Mark the pc + as non-executable if the file cannot be opened for read. Retry query + open only if errno is EACCES. Never change the mode, even if it is 000 + when query open() fails. + +2003-06-03 Christopher Faylor <cgf@redhat.com> + + * configure.in: Allow any i?86 variant. + * configure: Regenerate. + +2003-06-03 Corinna Vinschen <corinna@vinschen.de> + Thomas Pfaff <tpfaff@gmx.net> + + * fhandler_socket.cc (connect_thread): Remove. + (accept_thread): Remove. + (fhandler_socket::connect): Remove all special blocking handling. + (fhandler_socket::accept): Ditto. + * net.cc (cygwin_connect): Make blocking sockets temporarily + non-blocking and call cygwin_select on them to be interruptible. + (cygwin_accept): Ditto. + +2003-06-02 Christopher Faylor <cgf@redhat.com> + + * spawn.cc (spawn_guts): Don't hang around if the parent doesn't exist. + +2003-06-02 Christopher Faylor <cgf@redhat.com> + + * cygthread.h (cygthread::terminate_thread): Mark private. + * cygthread.cc (cygthread::terminate_thread): Deallocate free_range + thread stuff. + +2003-06-02 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::accept): Rename `signalled' + to `interrupted' as used in fhandler_socket::connect. + +2003-06-02 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::connect): Simplify previous + patch. + (fhandler_socket::accept): Ditto. + +2003-06-02 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc: Include cygthread.h. + (class sock_event): Remove. + (thread_connect): New function. + (thread_accept): Ditto. + (fhandler_socket::connect): Use cygthread instead of socket event + handling for blocking sockets. + (fhandler_socket::accept): Ditto. + +2003-06-02 Christopher Faylor <cgf@redhat.com> + + * fhandler.cc (fhandler_base::write): Correct minor printf formatting + style glitch. + +2003-06-01 Pierre Humblet <pierre.humblet@ieee.org> + + * fhandler_disk_file.cc (fhandler_disk_file::fstat_by_name): Assume + an existing directory is a root if FindFirstFile fails. + +2003-05-30 Christopher Faylor <cgf@redhat.com> + + * path.cc (mount_info::conv_to_win32_path): gcc warning about chroot_ok + was actually valid. Fix it. + +2003-05-30 Christopher Faylor <cgf@redhat.com> + + * cygheap.cc (init_cheap): Temporarily remove inline that newer gcc's + have problems with. + + * path.cc (path_conv::check): Rework has_acls logic slightly. Uncouple + exec tests away from filesystem tests. + +2003-05-30 Corinna Vinschen <corinna@vinschen.de> + + * include/sys/param.h: Add DEV_BSIZE. + +2003-05-29 Pierre Humblet <pierre.humblet@ieee.org> + Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::dup): Rearrange. Fix + conditional. + +2003-05-28 Christopher Faylor <cgf@redhat.com> + + * mkvers.sh: Avoid "-dontuse" tags. + + * path.cc (path_conv::check): Set exec state based on known situations. + + * path.cc (mount_item::fnmunge): New function. + (mount_item::build_win32): New function. + (mount_info::conv_to_win32_path): Use build_win32 to build windows + path. + * path.h (mount_item::fnmunge): Declare new function. + (mount_item::build_win32): Ditto. + * sys/mount.h (MOUNT_ENC): Define. + +2003-05-28 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::dup): If running impersonated, + revert to original account before calling fixup_before_fork_exec + and impersonate again afterwards. Change comment accordingly. + Clean up error handling and debug output. + +2003-05-27 Thomas Pfaff <tpfaff@gmx.net> + + * fhandler_socket.cc (sock_event::~sock_event): New method. + (sock_event::load): Change to void. Check if winsock2 is available. + (socke_event::wait): Return 0 if interruptible mode is not available. + (fhandler_socket::connect): Remove checks for winsock2 availability. + (fhandler_socket::accept): Ditto. + +2003-05-27 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::dup): First try duplicating + using WSADuplicateSocket/WSASocket, if that fails, try DuplicateHandle. + +2003-05-27 Bill C. Riemers <cygwin@docbill.net> + + * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Filter + permissions through umask on FAT or if ntsec is off. + +2003-05-26 Pierre Humblet <pierre.humblet@ieee.org> + + * syscalls.cc (statfs): Call GetDiskFreeSpaceEx before GetDiskFreeSpace. + +2003-05-26 Corinna Vinschen <corinna@vinschen.de> + + * fhandler.cc (is_at_eof): Fix conditional. Use INVALID_FILE_SIZE + instead of numeric constant. + +2003-05-26 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::connect): Guard calls to + sock_event methods by a check for WinSock2 availability. + (fhandler_socket::accept): Ditto. + +2003-05-26 Corinna Vinschen <corinna@vinschen.de> + + * fhandler.h: Rename FH_W95LSBUG flag to FH_LSEEKED. + (fhandler_base::set_did_lseek): Rename from set_check_win95_lseek_bug. + (fhandler_base::get_did_lseek): Rename from get_check_win95_lseek_bug. + (fhandler_base::set_fs_flags): New method. + (fhandler_base::get_fs_flags): Ditto. + * fhandler.cc (fhandler_base::write): Make 64 bit clean. Convert file + to a "sparse" file when writing after a long lseek (>64K) beyond EOF. + (fhandler_base::lseek): Call set_did_lseek() instead of + set_check_win95_lseek_bug(). + (fhandler_base::fhandler_base): Initialize fs_flags to 0. + * fhandler_disk_file.cc (fhandler_disk_file::open): Don't create files + as "sparse" unconditionally. Set fs_flags member. + +2003-05-25 Pierre Humblet <pierre.humblet@ieee.org> + + * autoload.cc (GetDiskFreeSpaceEx): Add. + * syscalls.cc (statfs): Call full_path.root_dir() instead of + rootdir(full_path). Use GetDiskFreeSpaceEx when available and + report space available in addition to free space. + * fhandler_disk_file.cc (fhandler_disk_file::fstat_by_name): + Do not call FindFirstFile for disk root directories. + +2003-05-24 Joe Buehler <jhpb@draco.hekimian.com> + + * fhandler_process.cc (format_process_stat): Use PagefileUsage + instead of VirtualSize. + (get_mem_values): Ditto. + +2003-05-21 Corinna Vinschen <corinna@vinschen.de> + + * shared_info.h: Match shared_name declaration with below change. + * shared.cc (shared_name): Use incoming char * parameter instead of + local static buffer. + (open_shared): Accommodate new calling convention for shared_name. + * exceptions.cc (events_init): Ditto. + * sigproc.cc (getsem): Ditto. + * syscalls.cc (login): Ditto. + (logout): Ditto. + (pututline): Ditto. + +2003-05-20 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (secret_event_name): Return void. Use incoming + char * parameter instead of local static buffer. + (fhandler_socket::create_secret_event): Accommodate new calling + convention for secret_event_name. + (fhandler_socket::close_secret_event): Ditto. + +2003-05-20 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (SECRET_EVENT_NAME): Remove. + (ENTROPY_SOURCE_NAME): Ditto. + (secret_event_name): New static function. Create shared event name + with "Global\" prefix on systems supporting terminal services. + (fhandler_socket::set_connect_secret): Fix conditional. + (fhandler_socket::create_secret_event): Create secret event using + secret_event_name(). + (fhandler_socket::close_secret_event): Ditto. + * shared.cc (shared_name): Create shared object name with "Global\" + prefix on systems supporting terminal services. + * wincap.cc: Set has_terminal_services capability throughout. + (wincap_2003): New global object representing Windows 2003 Server + capabilities. + (wincapc::init): Accommodate Windows 2003 Server. + * wincap.h (struct wincaps): Add has_terminal_services capability. + +2003-05-20 Charles Wilson <cygwin@cwilson.fastmail.fm> + + * winsup/cygwin/include/cygwin/version.h: Bump API minor version. + * winsup/cygwin/include/cygwin/types.h: Define key_t as long long. + * winsup/cygwin/cygwin.din: Add ftok, _ftok. + * winsup/cygwin/ipc.cc (ftok): Rework implementation. + +2003-05-18 Joe Buehler <jhpb@hekimian.com> + + * spawn.cc (spawn_guts): Show more of command line in strace output. + +2003-05-15 Thomas Pfaff <tpfaff@gmx.net> + + * thread.h (pthread::init_mainthread): Remove function parameter. + (MTinterface::Init): Ditto. + * thread.cc (MTinterface::Init): Remove function parameter. + Always initialize reent_key. + (pthread::init_mainthread): Remove function parameter. + (MTinterface::fixup_after_fork): Fix pthread::init_mainthread call. + * dcrt0.cc (dll_crt_0_1) Fix calls to MTinterface::Init and + pthread::init_mainthread. + Call pthread::init_mainthread only when not forked. + +2003-05-15 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_proc.cc (format_proc_meminfo): Make swap memory output + Linux style values. + +2003-05-13 Corinna Vinschen <corinna@vinschen.de> + + * include/cygwin/config.h: Define __USE_INTERNAL_STAT64 appropriately. + +2003-05-12 Corinna Vinschen <corinna@vinschen.de> + + * Makefile.in (CYGWIN_START): Define as crt0.o. Add to TARGET_LIBS. + * fhandler.h (fhandler_virtual::fstat): Remove useless declaration. + * fhandler_virtual.cc: Remove _COMPILING_NEWLIB define. + * ipc.cc (ftok): Use stat64. + * syscalls.cc (_fstat64): Remove alias. + (_fstat): Ditto. + (_stat): Ditto. + (_fstat64_r): New function. + (_fstat_r): Ditto. + (_stat64_r): Ditto. + (stat_r): Ditto. + * crt0.o: New file, moved from newlib. + * include/sys/param.h: Ditto. + * include/sys/utime.h: Ditto. + * include/sys/utmp.h: Ditto. + * include/sys/dirent.h: Ditto. Expose different struct dirent, + dependening of the environment. + +2003-05-11 Corinna Vinschen <corinna@vinschen.de> + + Replace ino_t by __ino64_t throughout. + +2003-05-11 Corinna Vinschen <corinna@vinschen.de> + + * include/cygwin/types.h: Add key_t typedef. + +2003-05-10 Christopher Faylor <cgf@redhat.com> + + * dir.cc (readdir): Fill out new old_d_ino field. + * fhandler.h (fhandler_base::namehash): Define as ino_t. + (fhandler_base::get_namehash): Ditto. + * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Accommodate + new 64 bit st_ino. + * fhandler_socket.cc (fhandler_socket::fstat): Ditto. + * path.cc (hash_path_name): Return ino_t. + * syscalls.cc (stat64_to_stat32): Convert 64 bit inode to 32 bit. + * winsup.h (hash_path_name): Declare as returning ino_t. + * include/cygwin/stat.h (__stat32): Use 32 bit st_ino. + (__stat64): Use 64 bit st_ino. + * include/cygwin/types.h (__ino64_t): Define. + (__ino32_t): Ditto. + (ino_t): Define appropriately. + +2003-05-10 Corinna Vinschen <corinna@vinschen.de> + + * Makefile.in (NEW_FUNCTIONS): All 32/64 from 0.79 API get + leading underscore. + * cygwin.din: Ditto. + * include/cygwin/version.h: Bump API minor number. + +2003-05-09 Corinna Vinschen <corinna@vinschen.de> + + * include/cygwin/config.h: New file. + +2003-05-09 Christopher Faylor <cgf@redhat.com> + + * cygthread.cc (cygthread::detach): Prioritize waiting for I/O + completion over waiting for signal delivery. + +2003-05-06 Thomas Pfaff <tpfaff@gmx.net> + + * signal.cc (nanosleep): Do not wait twice for signal arrival. + +2003-05-03 Corinna Vinschen <corinna@vinschen.de> + + * include/cygwin/types.h: Fix erroneous definition of ino_t from + 2003-04-28. + +2003-05-03 Corinna Vinschen <corinna@vinschen.de> + + * syscalls.cc (chown_worker): Allow chown'ing of socket files. + +2003-04-30 Thomas Pfaff <tpfaff@gmx.net> + + * Makefile.in: Revert patch from 2003-04-17. + +2003-04-28 Brian Ford <ford@vss.fsi.com> + + * profil.h (PROFADDR): Prevent overflow when text segments are larger + than 256k. + * profil.c (profthr_func): Raise thread priority for more accurate + sampling. + +2003-04-26 Christopher Faylor <cgf@redhat.com> + + * path.cc (hash_path_name): Use ino_t as type. + +2003-04-26 Christopher Faylor <cgf@redhat.com> + + * errno.cc (_sys_nerr): Fix compile error erroneously checked in on + 2003-04-23. + +2003-04-25 Corinna Vinschen <corinna@vinschen.de> + + * include/netinet/ip.h: Include netinet/in_systm.h and netinet/in.h + to allow standalone usage (autoconf). + +2003-04-23 Christopher Faylor <cgf@redhat.com> + + * fork.cc: Change SLOW_PID_REUSE to NO_SLOW_PID_REUSE and invert ifdef + sense throughout. + +2003-04-22 Christopher Faylor <cgf@redhat.com> + + * select.cc (fhandler_pipe::ready_for_read): Assure that get_guard is + called for successful non-blocking pipe reads. + +2003-04-22 Corinna Vinschen <corinna@vinschen.de> + + * include/inttypes.h: New file. + * include/stdint.h: New file. + * include/cygwin/in.h: Include stdint.h instead of sys/types.h. + * include/cygwin/types.h: Include stdint.h. Remove typedefs for + intN_t and uintN_t since these are defined in stdint.h now. + +2003-04-21 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/version.h: Bump DLL major number to 1005. Change DLL + minor number to 0. Bump API minor number. + +2003-04-20 Corinna Vinschen <corinna@vinschen.de> + + * autoload.cc (CreateWindowStationA): Add. + (SetProcessWindowStation): Add. + +2003-04-19 Christopher Faylor <cgf@redhat.com> + + * wincap.h (wincaps:pty_needs_alloc_console): New element. + (wincapc:pty_needs_alloc_console): New function. + * wincap.cc: Add pty_needs_alloc_console throughout. + * fhandler_tty.cc (fhandler_tty_slave::open): Open an "invisible" + console on first pty allocation. + +2003-04-18 Christopher Faylor <cgf@redhat.com> + + * fhandler_tty.cc (fhandler_tty_slave::open): Allocate a console + whenever a pty is allocated. + +2003-04-18 Christopher Faylor <cgf@redhat.com> + + * Makefile.in: Use ${nostdlib} variable. + +2003-04-18 Diego Biurrun <diego@biurrun.de> + + * fhandler_proc.cc (format_proc_cpuinfo): Change /proc/cpuinfo "vendor + id" string to "vendor_id" to conform with Linux systems. + +2003-04-17 Christopher Faylor <cgf@redhat.com> + + * syscalls.cc (setsid): Don't call FreeConsole if ctty is already < 0. + +2003-04-17 Thomas Pfaff <tpfaff@gmx.net> + + * Makefile.in: Add finline-functions optimization to CXXFLAGS. + * autoload.cc (LoadDLLprime): Rename std_dll_init to + _std_dll_init. + (std_dll_init): Remove name mangling prototype. Add attributes + used and noinline. + (wsock_init): Ditto. + Change wsock_init to _wsock_init in wsock32 and ws2_32 + LoadDLLprime. + * exceptions.cc (unused_sig_wrapper): Remove prototype. Add + attributes used and noinline. + * pwdgrp.h ((pwdgrp (passwd *&)): Remove inline code. + (pwdgrp (__group32 *&)): Ditto. + * grp.cc (pwdgrp (passwd *&)): Outline constructor. + (pwdgrp (__group32 *&)): Ditto. + +2003-04-17 Thomas Pfaff <tpfaff@gmx.net> + + * thread.h (pthread::equal): New static method. + * thread.cc: Rename pthread_equal to pthread::equal throughout. + (pthread_equal): Use pthread::equal to compare threads ids. + +2003-04-15 Christopher Faylor <cgf@redhat.com> + + * termios.cc (setspeed): New function. + (cfsetospeed): Use setspeed to set speed. + (cfsetispeed): Use setspeed to set speed. + +2003-04-15 Chris January <chris@atomice.net> + + * autoload.cc: Add load statement for UuidCreate, and + UuidCreateSequential. + * cpuid.h: New file. + * cygwin.din: Export gethostid. + * fhandler_proc.cc (cpuid): Move to cpuid.h. + (can_set_flag): Move to cpuid.h. + * syscalls.cc (gethostid): New function. + * version.h: Bump api minor version number to 83. + +2003-04-15 Thomas Pfaff <tpfaff@gmx.net> + + * thread.h (pthread_rwlock::release): New method. + * thread.cc (pthread_rwlock::unlock): Use release to signal waiting + threads. + (pthread_rwlock::rdlock_cleanup): Signal waiting threads after a + cancelation. + (pthread_rwlock::wrlock_cleanup): Ditto. + +2003-04-13 Pierre Humblet <pierre.humblet@ieee.org> + + * mkvers.sh: Prefix day with 0 in date only when day < 10. + +2003-04-11 Pierre Humblet <pierre.humblet@ieee.org> + + * security.cc (get_info_from_sd): New function. + (get_nt_attribute): Only call read_sd and get_info_from_sd. + Return void. + (get_file_attribute): Move sd error handling to get_info_from_sd. + and symlink handling to fhandler_disk_file::fstat_helper. + (get_nt_object_attribute): Only call read_sd and get_info_from_sd. + Return void. + (get_object_attribute): Remove symlink handling and simply return -1 + when ntsec is off. + * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): For + symlinks set the attribute, call get_file_attribute to get the ids + and return. In the normal case call get_file_attribute with the + addresses of the buffer ids and do not recheck if the file is a socket. + +2003-04-10 Christopher Faylor <cgf@redhat.com> + + * cygthread.cc (cygthread::stub): Initialize stack pointer earlier. + (cygthread::simplestub): Initialize stack pointer. + (cygthread::terminate_thread): Account for possibility that stack + pointer has not been set. Issue warnings for unusual conditions. + +2003-04-10 Corinna Vinschen <corinna@vinschen.de> + + * regex/regex.h: Define regoff_t as _off_t. + * regex/regex2.h: Ditto. + +2003-04-10 Corinna Vinschen <corinna@vinschen.de> + + * cygwin.din: Export wcscoll, wcswidth and wcwidth. + * include/cygwin/version.h: Bump API minor number. + +2003-04-10 Christopher Faylor <cgf@redhat.com> + + * cygthread.h: Change 'avail' cygthread element to 'inuse' throughout. + * cygthread.cc: Ditto. + (cygthread::stub): Don't initialize already initialized events. + (cygthread::freerange): Don't create thread here. + (cygthread::cygthread): Create thread here. Die if thread not created. + (cygthread::operator new): Simplify. Just grab a thread structure from + the pool. Don't try to start the thread. + (cygthread::terminate_thread): Don't close event handles. Just reuse + them. Call MEM_RELEASE rather than MEM_DECOMMIT (from Joe uehler). + +2003-04-08 Bob Cassels <bcassels@abinitio.com> + + * fhandler_console.cc (fhandler_console::read) Handle certain key up + events, to allow pasting accented characters and typing them using the + "alt + numerics" sequences. + +2003-04-07 Christopher Faylor <cgf@redhat.com> + + * include/limits.h (IOV_MAX): Set to a number which is small enough to + use in an array. + +2003-04-04 Christopher Faylor <cgf@redhat.com> + + * cygthread.h (cygthread::avail): Make LONG for easier use with + Interlocked* functions. + * cygthread.cc (cygthread::init): Eliminate unneeded muto. + (cygthread::operator new): Don't lock. Instead change use of avail + variable into tri-state: available (1), not available (-1), + uninitialized (0). + (cygthread::terminate_thread): Set avail to uninitialized. + (cygthread::detach): Eliminate local 'avail'. Always set avail to 1 + unless signalled. + +2003-04-04 Christopher Faylor <cgf@redhat.com> + + * cygthread.cc (cygthread::operator new): Be more defensive when messing with + threads that are marked "unavailable". + +2003-04-03 Christopher Faylor <cgf@redhat.com> + + * fhandler_console.cc (CONVERT_LIMIT): Use a size for the 21st century. + +2003-04-03 Corinna Vinschen <corinna@vinschen.de> + + * external.cc (check_ntsec): Return general ntsec state on NULL + filename. Check wincap.is_security() additionally. + +2003-04-02 Christopher Faylor <cgf@redhat.com> + + * Makefile.in (EXTRA_OFILES): Remove debugging object. + +2003-04-02 Jason Tishler <jason@tishler.net> + Christopher Faylor <cgf@redhat.com> + + * external.cc (check_ntsec): New function. + (cygwin_internal): Add CW_CHECK_NTSEC handling to call check_ntsec() + from applications. + * include/cygwin/version.h: Bump API minor number. + * include/sys/cygwin.h (cygwin_getinfo_types): Add CW_CHECK_NTSEC. + +2003-04-02 Christopher Faylor <cgf@redhat.com> + + * cygthread.cc (cygthread::new): Add more defensive debugging. + +2003-04-01 Pierre Humblet <pierre.humblet@ieee.org> + + * fhandler.cc (fhandler_base::fstat): Set the uid and gid fields + from the current effective ids. + * fhandler_socket.cc (fhandler_socket::fstat): Keep the uid and gid set + by fhandler_base::fstat. + * security.cc (get_nt_attribute): Do not test wincap.has_security (). + (get_nt_object_attribute): Ditto. + (get_file_attribute): Add test for wincap.has_security (). + (get_object_attribute): Ditto. + +2003-04-01 Corinna Vinschen <corinna@vinschen.de> + + * dir.cc: Change __off32_t to _off_t and __off64_t to _off64_t + throughout. + * fhandler.cc: Ditto. + * fhandler.h: Ditto. + * fhandler_clipboard.cc: Ditto. + * fhandler_disk_file.cc: Ditto. + * fhandler_dsp.cc: Ditto. + * fhandler_floppy.cc: Ditto. + * fhandler_mem.cc: Ditto. + * fhandler_proc.cc: Ditto. + * fhandler_process.cc: Ditto. + * fhandler_random.cc: Ditto. + * fhandler_registry.cc: Ditto. + * fhandler_tape.cc: Ditto. + * fhandler_termios.cc: Ditto. + * fhandler_virtual.cc: Ditto. + * fhandler_zero.cc: Ditto. + * mmap.cc: Ditto. + * pipe.cc: Ditto. + * syscalls.cc: Ditto. + * winsup.h: Ditto. + * include/cygwin/stat.h: Ditto. + * include/cygwin/types.h: Ditto. Remove definition of __off32_t + and __off64_t. + +2003-03-31 Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (setup_handler): Make sure winapi lock is released when + exiting loop. + +2003-03-30 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/fs.h: Remove unneeded include. + * include/cygwin/in.h: Include sys/types.h rather than cygwin/types.h. + +2003-03-29 Corinna Vinschen <corinna@vinschen.de> + + * syscalls.cc (login): Fix comment. + (logout): Ditto. + +2003-03-29 Corinna Vinschen <corinna@vinschen.de> + + * syscalls.cc: Slightly cleanup all utmp functions. + (login): Use mutex to secure against concurrent access to wtmp file. + (logout): Rewrite using POSIX calls. + (utmp_fd): Initialized to -1 now. Any value < 0 is treated as closed + in subsequent functions. + (utmp_readonly): New variable, indicating utmp file open for reading + only. + (internal_setutent): New function implementing setutent(). + (setutent): Call internal_setutent now. + (endutent): Reset utmp_readonly. + (getutent): Return immediately if utmp file can't be opened. + (getutid): Ditto. + (getutline): Ditto. + (pututline): Ditto. Use mutex to secure against concurrent access to + utmp file. + +2003-03-28 Christopher Faylor <cgf@redhat.com> + + * Makefile.in: Remove EXE_LDFLAGS. Fix fhandler_CFLAGS typo. Recognize .s suffix. + * configure.in: Remove EXE_LDFLAGS. + * configure: Regenerate. + +2003-03-28 Christopher Faylor <cgf@redhat.com> + + * include/sys/cygwin.h: Declare cygwin_internal as unsigned long. + * external.cc (cygwin_internal): Define as unsigned long. + +2003-03-27 Christopher Faylor <cgf@redhat.com> + + * include/sys/cygwin.h: Move cygwin_internal outside of WINVER + conditional. + +2003-03-27 Thomas Pfaff <tpfaff@gmx.net> + + * thread.cc: Change 1==foo equations to foo==1 throughout. + +2003-03-27 Thomas Pfaff <tpfaff@gmx.net> + + * thread.h: Change class names, methods, members and local vars + according to the GNU coding style. + * thread.cc: Ditto. + * dcrt0.cc (dll_crt0_1): Rename pthread::initMainThread call to + pthread::init_mainthread. + * pthread.cc (pthead_getsequence_np): Rename pthread::isGoodObject + call to pthread::is_good_object. + +2003-03-27 Joe Buehler <jhpb@draco.hekimian.com> + + * autoload.cc: Add RegGetKeySecurity(). + * security.cc (get_nt_object_attribute): Use RegGetKeySecurity() for + performance. + +2003-03-25 Christopher Faylor <cgf@redhat.com> + Joe Buehler <jhpb@draco.hekimian.com> + + * fork.cc (fork_parent): Don't copy signals from parent to child here. + * sigproc.cc (proc_subproc): Copy signals from parent to child pinfo + here. + +2003-03-23 Thomas Pfaff <tpfaff@gmx.net> + + * thread.h (class List): Move inline code inside class declaration. + (List::forEach): Change callback parameter to template class member + function pointer. + (pthread_keys::fixup_before_fork): Change to inline. Use List::forEach + to fixup keys. + (pthread_keys::fixup_after_fork): Ditto. + (pthread_keys::runAllDestructors): Ditto. + (pthread_key::saveAKey): Remove. + (pthread_key::restoreAKey): Ditto. + (pthread_key::destroyAKey): Ditto. + (pthread_key::run_destructor): Rename to runDestructor. + (pthread_mutex::fixup_after_fork): Change to inline. Use List::forEach + to fixup mutexes after a fork. + (pthread_mutex::FixupAfterFork): New method. + (pthread_mutex::mutexes): New member. + (pthread_cond::fixup_after_fork): Change to inline. Use List::forEach + to fixup conds after a fork. + (pthread_cond::FixupAfterFork): New method. + (pthread_cond::conds): New member. + (pthread_rwlock::fixup_after_fork): Change to inline. Use + List::forEach to fixup rwlocks after a fork. + (pthread_rwlock::FixupAfterFork): New method. + (pthread_rwlock::rwlocks): New member. + (semaphore::fixup_after_fork): Change to inline. Use List::forEach to + fixup mutexes after a fork. + (semaphore::FixupAfterFork): New method. + (semaphore::semaphores): New member. + (MTinterface::mutexs): Remove. + (MTinterface::conds): Ditto. + (MTinterface::rwlocks): Ditto. + (MTinterface::semaphores): Ditto. + (pthread_equal): Add extern "C". + (pthread_mutex_lock): Ditto. + + * thread.cc (MTinterface::fixup_after_fork): Change fixup_after_fork + calls for pthread objects. + (semaphore::conds): Instantiate. + (pthread_cond::pthread_cond): Use List::Insert rather than custom list + code. + (pthread_cond::~pthread_cond): Use List::Remove rather than custom list + code. + (pthread_cond::fixup_after_fork): Rename to FixupAfterFork. + (pthread_rwlock::rwlocks): Instantiate. + (pthread_rwlock::pthread_crwlock): Use List::Insert rather than custom + list code. + (pthread_rwlock::~pthread_rwlock): Use List::Remove rather than custom + list code. + (pthread_rwlock::fixup_after_fork): Rename to FixupAfterFork. + (pthread_key::saveAKey): Remove. + (pthread_key::fixup_before_fork): Ditto. + (pthread_key::restoreAKey): Ditto. + (pthread_key::fixup_after_fork): Ditto. + (pthread_key::destroyAKey): Ditto. + (pthread_key::runAllDestructors): Ditto. + (pthread_key::run_destructor): Rename to runDestructor. + (pthread_mutex::mutexes): Instantiate. + (pthread_mutex::pthread_mutex): Use List::Insert rather than custom + list code. + (pthread_mutex::~pthread_mutex): Use List::Remove rather than custom + list code. + (pthread_mutex::fixup_after_fork): Rename to FixupAfterFork. + (semaphore::conds): Instantiate. + (semaphore::semaphore): Use List::Insert rather than custom list code. + (semaphores::~semaphore): Use List::Remove rather than custom list + code. + (semaphore::fixup_after_fork): Rename to FixupAfterFork. + +2003-03-22 Christopher Faylor <cgf@redhat.com> + + * pipe.cc (fhandler_pipe::dup): Don't dup input_handle if it doesn't + exist. + +2003-03-22 Christopher Faylor <cgf@redhat.com> + + * syscalls.cc (unlink): Be more defensive when SetFileAttributes is + called. Fix typo in debugging output. + +2003-03-21 Christopher Faylor <cgf@redhat.com> + + * fork.cc: Conditionalize use of slow_pid_reuse throughout. It's not + necessary for newer versions of bash. + +2003-03-20 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::sendto): Restrict EPIPE and + SIGPIPE handling to connection oriented sockets. Add comment. + +2003-03-19 Christopher Faylor <cgf@redhat.com> + + * sigproc.h (signal_fixup_after_exec): Eliminate argument in declaration. + * exceptions.cc (signal_fixup_after_exec): Eliminate argument in + definition. Don't reset signal handlers after spawm. Just treat like + fork/exec. + * dcrt0.cc (dll_crt0_1): Don't pass PROC_SPAWN argument to + signal_fixup_after_exec. + * syscalls.cc (unlink): Don't change attributes of file if not readonly/system. + Ditto for resetting of arguments. + +2003-03-19 Corinna Vinschen <corinna@vinschen.de> + + * glob.c: Eliminate __INSIDE_CYGWIN__ preprocessor conditionals + throughout. + +2003-03-19 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Fix + wrong usage of S_IFDIR. + * security.cc (get_attribute_from_acl): Ditto. + (get_file_attribute): Fix wrong usage of S_IFLNK. + (get_object_attribute): Ditto. + (alloc_sd): Fix wrong usage of S_IFDIR. + * syscalls.cc (chmod): Allow chmod'ing of socket files. + +2003-03-19 Corinna Vinschen <corinna@vinschen.de> + + * include/cygwin/version.h (CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES): + Define. + * glob.c (g_lstat): Use CYGWIN_VERSION_CHECK_FOR_USING_BIG_TYPES + instead of numerical constants. + (g_stat): Ditto. + +2003-03-18 Thomas Pfaff <tpfaff@gmx.net> + + * pthread.cc (pthread_attr_init): Remove + (pthread_attr_destroy): Ditto. + (pthread_attr_setdetachstate): Ditto. + (pthread_attr_getdetachstate): Ditto. + (pthread_attr_setstacksize): Ditto. + (pthread_attr_getstacksize): Ditto. + (pthread_attr_setinheritsched): Ditto. + (pthread_attr_getinheritsched): Ditto. + (pthread_attr_setschedparam): Ditto. + (pthread_attr_getschedparam): Ditto. + (pthread_attr_setschedpolicy): Ditto. + (pthread_attr_getschedpolicy): Ditto. + (pthread_attr_setscope): Ditto. + (pthread_attr_getscope): Ditto. + (pthread_attr_setstackaddr): Ditto. + (pthread_attr_getstackaddr): Ditto. + (pthread_key_create): Ditto. + (pthread_key_delete): Ditto. + (pthread_setspecific): Ditto. + (pthread_getspecific): Ditto. + (pthread_kill): Ditto. + (pthread_sigmask): Ditto. + (pthread_equal): Ditto. + (pthread_mutex_lock): Ditto. + (pthread_mutex_trylock): Ditto. + (pthread_mutex_unlock): Ditto. + (pthread_mutex_destroy): Ditto. + (pthread_mutex_setprioceiling): Ditto. + (pthread_mutex_getprioceiling): Ditto. + (pthread_mutexattr_destroy): Ditto. + (pthread_mutexattr_getprioceiling): Ditto. + (pthread_mutexattr_getprotocol): Ditto. + (pthread_mutexattr_getpshared): Ditto. + (pthread_mutexattr_gettype): Ditto. + (pthread_mutexattr_init): Ditto. + (pthread_mutexattr_setprioceiling): Ditto. + (pthread_mutexattr_setprotocol): Ditto. + (pthread_mutexattr_setpshared): Ditto. + (pthread_mutexattr_settype): Ditto. + (pthread_cond_destroy): Ditto. + (pthread_cond_signal): Ditto. + (pthread_cond_broadcast): Ditto. + (pthread_condattr_init): Ditto. + (pthread_condattr_destroy): Ditto. + (pthread_condattr_getpshared): Ditto. + (pthread_condattr_setpshared): Ditto. + (pthread_rwlock_destroy): Ditto. + (pthread_rwlock_rdlock): Ditto. + (pthread_rwlock_tryrdlock): Ditto. + (pthread_rwlock_wrlock): Ditto. + (pthread_rwlock_trywrlock): Ditto. + (pthread_rwlock_unlock): Ditto. + (pthread_rwlockattr_init): Ditto. + (pthread_rwlockattr_getpshared): Ditto. + (pthread_rwlockattr_setpshared): Ditto. + (pthread_rwlockattr_destroy): Ditto. + (pthread_getconcurrency): Ditto. + (pthread_setconcurrency): Ditto. + (pthread_getschedparam): Ditto. + (pthread_setschedparam): Ditto. + + * thread.h (__pthread_attr_init): Remove prototype. + (__pthread_attr_destroy): Ditto. + (__pthread_attr_setdetachstate): Ditto. + (__pthread_attr_getdetachstate): Ditto. + (__pthread_attr_setstacksize): Ditto. + (__pthread_attr_getstacksize): Ditto. + (__pthread_attr_setinheritsched): Ditto. + (__pthread_attr_getinheritsched): Ditto. + (__pthread_attr_setschedparam): Ditto. + (__pthread_attr_getschedparam): Ditto. + (__pthread_attr_setschedpolicy): Ditto. + (__pthread_attr_getschedpolicy): Ditto. + (__pthread_attr_setscope): Ditto. + (__pthread_attr_getscope): Ditto. + (__pthread_attr_setstackaddr): Ditto. + (__pthread_attr_getstackaddr): Ditto. + (__pthread_key_create): Ditto. + (__pthread_key_delete): Ditto. + (__pthread_setspecific): Ditto. + (__pthread_getspecific): Ditto. + (__pthread_kill): Ditto. + (__pthread_sigmask): Ditto. + (__pthread_equal): Ditto. + (__pthread_mutex_lock): Ditto. + (__pthread_mutex_trylock): Ditto. + (__pthread_mutex_unlock): Ditto. + (__pthread_mutex_destroy): Ditto. + (__pthread_mutex_setprioceiling): Ditto. + (__pthread_mutex_getprioceiling): Ditto. + (__pthread_mutexattr_destroy): Ditto. + (__pthread_mutexattr_getprioceiling): Ditto. + (__pthread_mutexattr_getprotocol): Ditto. + (__pthread_mutexattr_getpshared): Ditto. + (__pthread_mutexattr_gettype): Ditto. + (__pthread_mutexattr_init): Ditto. + (__pthread_mutexattr_setprioceiling): Ditto. + (__pthread_mutexattr_setprotocol): Ditto. + (__pthread_mutexattr_setpshared): Ditto. + (__pthread_mutexattr_settype): Ditto. + (__pthread_cond_destroy): Ditto. + (__pthread_cond_signal): Ditto. + (__pthread_cond_broadcast): Ditto. + (__pthread_condattr_init): Ditto. + (__pthread_condattr_destroy): Ditto. + (__pthread_condattr_getpshared): Ditto. + (__pthread_condattr_setpshared): Ditto. + (__pthread_rwlock_destroy): Ditto. + (__pthread_rwlock_rdlock): Ditto. + (__pthread_rwlock_tryrdlock): Ditto. + (__pthread_rwlock_wrlock): Ditto. + (__pthread_rwlock_trywrlock): Ditto. + (__pthread_rwlock_unlock): Ditto. + (__pthread_rwlockattr_init): Ditto. + (__pthread_rwlockattr_getpshared): Ditto. + (__pthread_rwlockattr_setpshared): Ditto. + (__pthread_rwlockattr_destroy): Ditto. + (__pthread_getconcurrency): Ditto. + (__pthread_setconcurrency): Ditto. + (__pthread_getschedparam): Ditto. + (__pthread_setschedparam): Ditto. + + * thread.cc: Rename __pthread_equal to pthread_equal throughout. + Change pthread_self parameter appropriate. + (__pthread_attr_init): Remove __ prefix. Change to extern "C". + (__pthread_attr_destroy): Ditto. + (__pthread_attr_setdetachstate): Ditto. + (__pthread_attr_getdetachstate): Ditto. + (__pthread_attr_setstacksize): Ditto. + (__pthread_attr_getstacksize): Ditto. + (__pthread_attr_setinheritsched): Ditto. + (__pthread_attr_getinheritsched): Ditto. + (__pthread_attr_setschedparam): Ditto. + (__pthread_attr_getschedparam): Ditto. + (__pthread_attr_setschedpolicy): Ditto. + (__pthread_attr_getschedpolicy): Ditto. + (__pthread_attr_setscope): Ditto. + (__pthread_attr_getscope): Ditto. + (__pthread_attr_setstackaddr): Ditto. + (__pthread_attr_getstackaddr): Ditto. + (__pthread_key_create): Ditto. + (__pthread_key_delete): Ditto. + (__pthread_setspecific): Ditto. + (__pthread_getspecific): Ditto. + (__pthread_kill): Ditto. + (__pthread_sigmask): Ditto. + (__pthread_equal): Ditto. + (__pthread_mutex_lock): Ditto. + (__pthread_mutex_trylock): Ditto. + (__pthread_mutex_unlock): Ditto. + (__pthread_mutex_destroy): Ditto. + (__pthread_mutex_setprioceiling): Ditto. + (__pthread_mutex_getprioceiling): Ditto. + (__pthread_mutexattr_destroy): Ditto. + (__pthread_mutexattr_getprioceiling): Ditto. + (__pthread_mutexattr_getprotocol): Ditto. + (__pthread_mutexattr_getpshared): Ditto. + (__pthread_mutexattr_gettype): Ditto. + (__pthread_mutexattr_init): Ditto. + (__pthread_mutexattr_setprioceiling): Ditto. + (__pthread_mutexattr_setprotocol): Ditto. + (__pthread_mutexattr_setpshared): Ditto. + (__pthread_mutexattr_settype): Ditto. + (__pthread_cond_destroy): Ditto. + (__pthread_cond_signal): Ditto. + (__pthread_cond_broadcast): Ditto. + (__pthread_condattr_init): Ditto. + (__pthread_condattr_destroy): Ditto. + (__pthread_condattr_getpshared): Ditto. + (__pthread_condattr_setpshared): Ditto. + (__pthread_rwlock_destroy): Ditto. + (__pthread_rwlock_rdlock): Ditto. + (__pthread_rwlock_tryrdlock): Ditto. + (__pthread_rwlock_wrlock): Ditto. + (__pthread_rwlock_trywrlock): Ditto. + (__pthread_rwlock_unlock): Ditto. + (__pthread_rwlockattr_init): Ditto. + (__pthread_rwlockattr_getpshared): Ditto. + (__pthread_rwlockattr_setpshared): Ditto. + (__pthread_rwlockattr_destroy): Ditto. + (__pthread_getconcurrency): Ditto. + (__pthread_setconcurrency): Ditto. + (__pthread_getschedparam): Ditto. + (__pthread_setschedparam): Ditto. + +2003-03-18 Thomas Pfaff <tpfaff@gmx.net> + + * cygwin.din: Add pthread_rwlock_destroy, pthread_rwlock_init, + pthread_rwlock_rdlock, pthread_rwlock_tryrdlock, + pthread_rwlock_wrlock, pthread_rwlock_trywrlock, + pthread_rwlock_unlock, pthread_rwlockattr_init, + pthread_rwlockattr_getpshared, pthread_rwlockattr_setpshared, + and pthread_rwlockattr_destroy. + * include/cygwin/version.h: Bump API minor number. + * include/pthread.h (PTHREAD_RWLOCK_INITIALIZER): Define a + reasonable value. + Add prototypes for pthread_rwlock_destroy, pthread_rwlock_init, + pthread_rwlock_rdlock, pthread_rwlock_tryrdlock, + pthread_rwlock_wrlock, pthread_rwlock_trywrlock, + pthread_rwlock_unlock, pthread_rwlockattr_init, + pthread_rwlockattr_getpshared, pthread_rwlockattr_setpshared, + and pthread_rwlockattr_destroy. + * thread.h (PTHREAD_ONCE_MAGIC): Remove superflous semicolon. + (PTHREAD_RWLOCK_MAGIC): New define. + (PTHREAD_RWLOCKATTR_MAGIC): Ditto. + (pthread_rwlockattr): New class. + (pthread_rwlock): Ditto. + (MTinterface::rwlocks): New member. + (MTinterface::MTinterface): Initialize rwlocks. + Add prototypes for __pthread_rwlock_destroy, + __pthread_rwlock_wrlock, __pthread_rwlock_trywrlock, + __pthread_rwlock_unlock, __pthread_rwlockattr_init, + __pthread_rwlockattr_getpshared, __pthread_rwlockattr_setpshared, + and __pthread_rwlockattr_destroy. + * thread.cc (MTinterface::Init): Initialize rwlock internal mutex. + (MTinterface::fixup_after_fork): Fixup rwlocks after fork. + (pthread_rwlockattr::isGoodObject): Implement. + (pthread_rwlockattr::pthread_rwlockattr): Ditto. + (pthread_rwlockattr::~pthread_rwlockattr): Ditto. + (pthread_rwlock::initMutex): Ditto. + (pthread_rwlock::pthread_rwlock): Ditto. + (pthread_rwlock::~pthread_rwlock): Ditto. + (pthread_rwlock::RdLock): Ditto. + (pthread_rwlock::TryRdLock): Ditto. + (pthread_rwlock::WrLock): Ditto. + (pthread_rwlock::TryWrLock): Ditto. + (pthread_rwlock::UnLock): Ditto. + (pthread_rwlock::addReader): Ditto. + (pthread_rwlock::removeReader): Ditto. + (pthread_rwlock::lookupReader): Ditto. + (pthread_rwlock::RdLockCleanup): Ditto. + (pthread_rwlock::WrLockCleanup): Ditto. + (pthread_rwlock::fixup_after_fork): Ditto. + (pthread_rwlock::isGoodObject): Ditto. + (pthread_rwlock::isGoodInitializer): Ditto. + (pthread_rwlock::isGoodInitializerOrObject): Ditto. + (pthread_rwlock::isGoodInitializerOrBadObject): Ditto. + (__pthread_rwlock_destroy): Ditto. + (pthread_rwlock::init): Ditto. + (__pthread_rwlock_rdlock): Ditto. + (__pthread_rwlock_tryrdlock): Ditto. + (__pthread_rwlock_wrlock): Ditto. + (__pthread_rwlock_trywrlock): Ditto. + +2003-03-18 Thomas Pfaff <tpfaff@gmx.net> + + * thread.h (pthread_cond::ExitingWait): Remove. + (pthread_cond::mutex): Ditto. + (pthread_cond::cond_access): Ditto. + (pthread_cond::win32_obj_id): Ditto. + (pthread_cond::TimedWait): Ditto. + (pthread_cond::BroadCast): Ditto. + (pthread_cond::Signal): Ditto. + (pthread_cond::waiting): Change type to unsigned long. + (pthread_cond::pending): New member. + (pthread_cond::semWait): Ditto. + (pthread_cond::mtxIn): Ditto. + (pthread_cond::mtxOut): Ditto. + (pthread_cond::mtxCond): Ditto. + (pthread_cond::UnBlock): New method. + (pthread_cond::Wait): Ditto. + * thread.cc: Update list of cancellation points. + (pthread_cond::pthread_cond): Rewrite. + (pthread_cond::~pthread_cond): Ditto. + (pthread_cond::TimedWait): Remove. + (pthread_cond::BroadCast): Ditto. + (pthread_cond::Signal): Ditto. + (pthread_cond::UnBlock): Implement. + (pthread_cond::Wait): Ditto. + (pthread_cond::fixup_after_fork): Rewrite. + (pthread_mutex::fixup_after_fork): Remove DETECT_BAD_APP + conditional. + (__pthread_cond_broadcast): Just return 0 if the condition is + not initialized. Call pthread_cond::UnBlock to release blocked + threads. + (__pthread_cond_signal): Ditto. + (__pthread_cond__dowait): Rewrite. + (pthread_cond_timedwait): Add pthread_testcancel call. Fix + waitlength calculation. + (pthread_cond_wait): Add pthread_testcancel call. + +2003-03-18 Thomas Pfaff <tpfaff@gmx.net> + + * include/pthread.h (PTHREAD_MUTEX_NORMAL): New define. + * thread.cc: Remove errno.h include. + (pthread::precreate): Change internal mutex type to normal. + (pthread_mutex::canBeUnlocked): Implement. + (pthread_mutex::pthread_mutex): Initialize lock_counter with 0. + (pthread_mutex::Lock): Rename to _Lock. Add self parameter. + Change lock_counter logic. Update SetOwner call. + (pthread_mutex::TryLock): Rename to _TryLock. Add self parameter. + Change lock_counter logic. Update SetOwner call. + (pthread_mutex::UnLock): Rename to _UnLock. Add self parameter. + Change lock_counter logic. + (pthread_mutex::Destroy): Rename to _Destroy. Update TryLock call. + (pthread_mutex::SetOwner): Move to thread.h as inline. + (pthread_mutex::LockRecursive): Ditto. + (pthread_mutex::fixup_after_fork): Change lock_counter logic. + (__pthread_mutexattr_settype): Add PTHREAD_MUTEX_NORMAL to valid + types check. + * thread.h: Include errno.h and limits.h. + (MUTEX_LOCK_COUNTER_INITIAL): Remove. + (MUTEX_OWNER_ANONYMOUS): New define. + (pthread_mutex::canBeUnlocked): New static method. + (pthread_mutex::lock_counter): Change type to unsigned long. + (pthread_mutex::GetPthreadSelf): New method. + (pthread_mutex::Lock): Call _Lock with pthread_self pointer. + (pthread_mutex::TryLock): Call _TryLock with pthread_self pointer. + (pthread_mutex::UnLock): Call _UnLock with pthread_self pointer. + (pthread_mutex::Destroy): Call _Destroy with pthread_self pointer. + (pthread_mutex::SetOwner): Moved from thread.cc as inline. + (pthread_mutex::LockRecursive): Ditto. + (pthread_mutex::_Lock): New method. + (pthread_mutex::_TryLock): New method. + (pthread_mutex::_UnLock): New method. + (pthread_mutex::_Destroy): New method. + +2003-03-18 Christopher January <chris@atomice.net> + + * fhandler_proc.cc (format_proc_cpuinfo): Use IsProcessorFeaturePresent + only on Windows NT. Read CPU Mhz value only on NT. Revert previous + change so cpuid instruction is called even on non-NT systems. + +2003-03-17 Corinna Vinschen <corinna@vinschen.de> + + * glob.c (g_lstat): Change API minor test to match API minor number + change in previous patch. + (g_stat): Ditto. + +2003-03-17 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/version.h: Reorganize last two api versions so that + btowc and trunc exports show up before previous bump since there has + been no exported version of the DLL with the 64 bit changes yet but + 1.3.22 will have the btowc and trunc. + +2003-03-17 Christopher Faylor <cgf@redhat.com> + + * cygwin.din: Export btowc, trunc. + * include/cygwin/version.h: Reflect new exports. + * syscalls.cc (_stat): Rename to stat to avoid newlib wrapper. + * syscalls.cc (_fstat): Ditto. + +2003-03-16 Christopher Faylor <cgf@redhat.com> + + * fhandler_console.cc (fhandler_console::close): Correct check for + current tty. Add debugging output when console is freed. + (set_console_state_for_spawn): Add debugging output. + * fhandler_tty.cc (fhandler_tty_slave::open): Don't decrement console + open flag when vforking. + * sigproc.cc (sigproc_terminate): Fix debugging output. + * spawn.cc (handle): Eliminate second argument. + (spawn_guts): Reflect elimination of argument change to handle. + * syscalls.cc (setsid): Add debugging output when console is freed. + +2003-03-14 Christopher Faylor <cgf@redhat.com> + + * syscalls.cc (rename): Revert assumption that DELETE_ON_CLOSE works on + Win9x. + +2003-03-13 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/version.h: Bump DLL minor number to 23. + +2003-03-13 Corinna Vinschen <corinna@vinschen.de> + + * autoload.cc (IsProcessorFeaturePresent): Add. + * fhandler_proc.cc (format_proc_cpuinfo): Add case for 9x systems. + +2003-03-13 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_proc.cc (format_proc_cpuinfo): Fix vendor id in cpuid case. + +2003-03-13 Corinna Vinschen <corinna@vinschen.de> + + * net.cc (cygwin_rcmd): Use correct file descriptor in call to fdsock. + (cygwin_rexec): Ditto. + +2003-03-13 Christopher Faylor <cgf@redhat.com> + + * fhandler_tty.cc (fhandler_tty_slave::close): Fix typo in debug + output. + + * syscalls.cc (rename): Assume that DELETE_ON_CLOSE works on Win9x. + +2003-03-11 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::dup): Don't call + fhandler_base::dup() but call DuplicateHandle directly instead to have + control over socket inheritence. + +2003-03-11 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::dup): On NT systems avoid + using WinSock2 socket duplication methods. Add comment. + +2003-03-11 Pierre Humblet <pierre.humblet@ieee.org> + + * fhandler_socket.cc (fhandler_socket::fixup_after_fork): + Set io_handle to INVALID_SOCKET in case of failure. + (fhandler_socket::dup): Return 0 if the io_handle is valid. + +2003-03-10 Corinna Vinschen <corinna@vinschen.de> + + * sec_acl.cc (setacl): Don't handle DELETE flag specially. + * security.cc (alloc_sd): Ditto. + +2003-03-09 Corinna Vinschen <corinna@vinschen.de> + + * winver.rc: Change Copyright hint to include 2003. + +2003-03-09 Corinna Vinschen <corinna@vinschen.de> + + Switch to 32/64 datatypes: + * Makefile.in (OBSOLETE_FUNCTIONS): Add open acl aclcheck aclfrommode + aclfrompbits aclfromtext aclsort acltomode acltopbits acltotext chown + facl fchown fgetpos fopen freopen fseeko fsetpos fstat ftello + ftruncate getegid geteuid getgid getgrent getgrgid getgrnam getgroups + getpwuid getpwuid_r getuid initgroups lchown lseek lstat mknod mmap + seekdir setegid seteuid setgid setgroups setregid setreuid setuid stat + telldir truncate. + (NEW_FUNCTIONS): Add _open64 acl32 aclcheck32 aclfrommode32 + aclfrompbits32 aclfromtext32 aclsort32 acltomode32 acltopbits32 + acltotext32 chown32 facl32 fchown32 fgetpos64 fopen64 freopen64 + fseeko64 fsetpos64 fstat64 ftello64 ftruncate64 getegid32 geteuid32 + getgid32 getgrent32 getgrgid32 getgrnam32 getgroups32 getpwuid32 + getpwuid_r32 getuid32 initgroups32 lchown32 lseek64 lstat64 mknod32 + mmap64 seekdir64 setegid32 seteuid32 setgid32 setgroups32 setregid32 + setreuid32 setuid32 stat64 telldir64 truncate64 to substitute the + above. + * cygserver_shm.h (class client_request_shm): Change uid_t and gid_t + members to __uid32_t and __gid32_t. + * cygwin.din: Add symbols acl32 aclcheck32 aclfrommode32 + aclfrompbits32 aclfromtext32 aclsort32 acltomode32 acltopbits32 + acltotext32 facl32 fgetpos64 fopen64 freopen64 fseeko64 fsetpos64 + _fstat64 ftello64 _lseek64 mknod32 _open64. + * glob.c: Include perprocess.h. + (globtilde): Call getpwuid32 and getuid32 instead of getpwuid and + getuid. + (g_lstat): Check for applications API version to call the appropriate + typed gl_lstat function. + (g_stat): Ditto for gl_stat. + * shm.cc (client_request_shm::client_request_shm): Call geteuid32 + and getegid32 instead of geteuid and getegid throughout. + * syscalls.cc (_open64): New alias for open. + (_lseek64): New alias for lseek64. + (_fstat64): New alias for fseek64. + (mknod32): New function. + (mknod): Calls mknod32 now. + * winsup.h: Make function declarations for getuid32, geteuid32, + and getpwuid32 accessible for plain C sources. Add declarations + for getegid32 and getpwnam. + * include/cygwin/version.h: Bum API minor number to 78. + * include/sys/cygwin.h: Guard C++ specific members of struct + per_process against inclusion in plain C sources. + * include/sys/mman.h (mman): Add guard to avoid type clash when + compiling Cygwin. + +2003-03-09 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/version.h: Bump DLL minor number to 22. + +2003-03-09 Christopher Faylor <cgf@redhat.com> + + Do some minor reformatting of 'extern "C"' use throughout. + +2003-03-06 Christopher January <chris@atomice.net> + + * autoload.cc (GetSystemTimes): Define new autoload function. + * fhandler_proc.cc (proc_listing): Add cpuinfo and partitions entries. + (fhandler_proc::fill_filebuf): Add PROC_CPUINFO and PROC_PARTITIONS + cases. + (format_proc_uptime): Use GetSystemTimes if available. + (read_value): New macro. + (print): New macro. + (cpuid): New function. + (can_set_flag): New function. + (format_proc_cpuinfo): New function. + (format_proc_partitions): New function. + +2003-03-09 Christopher Faylor <cgf@redhat.com> + + * syscalls.cc (unlink): Attempt to be more clever about setting + attributes of file. Only open file in query mode to avoid having to + mess with security stuff for reading. + +2003-03-09 Corinna Vinschen <corinna@vinschen.de> + + * rmsym: Fix regular expression. + +2003-03-09 Christopher Faylor <cgf@redhat.com> + + * Makefile.in: Change from using new-* to cygwin0 for temporary + targets. + +2003-03-09 Corinna Vinschen <corinna@vinschen.de> + + * include/cygwin/socket.h: Set SOMAXCONN to Winsock2 value. + +2003-03-08 Christopher Faylor <cgf@redhat.com> + + * syscalls.cc (unlink): Always attempt to use FILE_FLAG_CLOSE_ON_DELETE + to delete files since this allows us to preserve the protection of hard + linked files. + (link): Generate full path for potentially recalculated .lnk target. + +2003-03-08 Christopher Faylor <cgf@redhat.com> + + Revert below changes regarding _pinfo::cmdline. + +2003-03-08 Corinna Vinschen <corinna@vinschen.de> + + * external.cc (cygwin_internal): Change n to __off64_t to match change + of _pinfo::cmdline. + * fhandler.h (class fhandler_virtual): Change filesize member to + __off64_t. + * fhandler_proc.cc (format_proc_meminfo): Change to return __off64_t. + (format_proc_stat): Ditto. + (format_proc_uptime): Ditto. + * fhandler_process.cc (format_process_stat): Ditto. + (format_process_status): Ditto. + (format_process_statm): Ditto. + * pinfo.cc (_pinfo::cmdline): Expect __off64_t parameter. + * pinfo.h (class _pinfo): Change declaration of cmdline accordingly. + +2003-03-07 Christopher Faylor <cgf@redhat.com> + + * path.h (PATH_LNK): New enum val. + (path_conv::is_lnk_symlink): New function. True if path represents + .lnk style symlink. + * path.cc (check_shortcut): Set PATH_LNK in pflags when appropriate. + (symlink_info::check): Ditto. Remove PATH_LNK from pflags initially. + * syscalls.cc (unlink): Always remove readonly attribute from a symlink + regardless of type. + (link): (from Corinna Vinschen) Allow links to symlinks. Reset + attributes on a symlink after successful link creation. + (chmod): Use is_lnk_symlink where appropriate. + (rename): Ditto. + +2003-03-07 Pierre Humblet <pierre.humblet@ieee.org> + + * tty.cc (create_tty_master): Call GetComputerName instead of + cygwin_gethostname. Set ut_id. + * syscalls.cc (login): Call endutent. + (setutent): Do not seek after a fresh open. + +2003-03-07 Corinna Vinschen <corinna@vinschen.de> + + * syscalls.cc (seteuid32): Fix formatting. + +2003-03-04 Thomas Pfaff <tpfaff@gmx.net> + + * thread.cc (MTinterface::fixup_after_fork): Initialize mainthread + prior to pthread objects. + +2003-03-04 Jason Tishler <jason@tishler.net> + + * fhandler_socket.cc (fhandler_socket::dup): Initialize type. + +2003-03-03 Christopher Faylor <cgf@redhat.com> + + * fhandler.h (fhandler_tty_slave::close): Declare new function. + (fhandler_tty_slave::dup): Declare new function. + (fhandler_tty_slave::fixup_after_function): Declare new function. + * fhandler_tty.cc (fhandler_tty_slave_open): Only increment + fhandler_console::open_fhs when associated with a pty. + (fhandler_tty_slave::close): Define new function. Decrement + fhandler_console::open_fhs when associated with a pty. + (fhandler_tty_slave::dup): Define new function. Increment + fhandler_console::open_fhs when associated with a pty. + (fhandler_tty_slave::fixup_after_fork): Define new function. Increment + fhandler_console::open_fhs when associated with a pty. + +2003-03-03 Christopher Faylor <cgf@redhat.com> + + * fhandler_tty.cc (fhandler_pty_slave::open): Grudgingly increment + fhandler_console::open_fhs here. + (fhandler_pty_slave::close): Ditto for close. + +2003-03-02 Christopher Faylor <cgf@redhat.com> + + * lib/getopt.c: Refresh from NetBSD sources. + +2003-03-02 Christopher Faylor <cgf@redhat.com> + + * fhandler_console.cc (fhandler_console::close): Don't decrement + in use counter if in vfork fixup stage. + +2003-03-02 Christopher Faylor <cgf@redhat.com> + + * lib/getopt.c: Nuke use of unneeded BSDisms. + +2003-03-02 Christopher Faylor <cgf@redhat.com> + + * dll_init.cc (dll_list::load_after_fork): Don't revert to LoadLibrary + if LoadLibraryEx fails. + * dtable.cc (dtable::dec_console_fds): Eliminate. + (dtable::release): Don't treat console specially. + (dtable::build_fhandler): Ditto. + * dtable.h (console_fds): Eliminate. + (dtable::dec_console_fds): Eliminate. + (dtable::inc_console_fds): Eliminate. + * fhandler.h (fhandler_console::open_fhs): New static element. + * fhandler_console.cc (fhandler_console::open): Increment open_fs. + (fhandler_console::close): Call FreeConsole if no more open consoles + and ctty is not associated with the console. + * syscalls.cc (setsid): Simplify check for when to call FreeConsole. + (check_pty_fds): Eliminate definition. + * winsup.h (check_pty_fds): Eliminate declaration. + +2003-03-02 Christopher Faylor <cgf@redhat.com> + + * dll_init.cc (dll_list::load_after_fork): Fix typo where result of + LoadLibrary was ignored. + +2003-03-01 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::bind): Open and write socket + file using Win32 calls. + +2003-03-01 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (get_inet_addr): Open and read socket file using + Win32 calls. + +2003-02-28 Christopher Faylor <cgf@redhat.com> + + * cygwin.din: Wrap atexit and exit with cygwin, thread-safe functions. + * dcrt0.cc (cygwin_atexit): New function. + (cygwin_exit): Ditto. + +2003-02-28 Pierre Humblet <pierre.humblet@ieee.org> + + * syscalls.cc (fstat64): Pass get_name () to pc. + (access): Pass fn to stat_worker. + +2003-03-27 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (class sock_event): New class managing Winsock + events for interruptible socket calls. + (fhandler_socket::connect): Move support for interruptible call to + class sock_event. Use class object instead. + (fhandler_socket::accept): Ditto. Remove useless casts. + +2003-03-27 Thomas Pfaff <tpfaff@gmx.net> + + * fhandler_socket.cc (fhandler_socket::connect): Add support for + an interruptable connect. + +2003-02-27 Pierre Humblet <pierre.humblet@ieee.org> + + * uinfo.cc (internal_getlogin): Only update user.groups.pgsid + if the call to set the primary group succeeds. + +2003-02-27 Christopher Faylor <cgf@redhat.com> + + * cygthread::detach: Improve error message. + +2003-02-26 Pierre Humblet <pierre.humblet@ieee.org> + + * sec_helper.cc (get_sids_info): debug_print owner_sid and group_sid. + +2003-02-25 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc (mmap64): Fix returned address by taking the granularity + into account. + +2003-02-23 Pierre Humblet <pierre.humblet@ieee.org> + + * syslog.cc (syslog): Do not unlock the file before closing it + and remove debug_printf about stream errors. + +2003-02-22 Christopher Faylor <cgf@redhat.com> + + * cygmalloc.h: Remove MORECORE_CANNOT_TRIM. It's not true. + # cygwin.din: Export mallinfo. + # malloc_wrapper.cc (mallinfo): New function. + +2003-02-22 Pierre Humblet <pierre.humblet@ieee.org> + + * syslog.cc (syslog): Do not print the Windows pid. Print the Cygwin + pid as an unsigned decimal. On Win95 print a timestamp and attempt to + lock the file up to four times in 3 ms. + +2003-02-21 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::fhandler_socket): Fix compiler + warning. + (fhandler_socket::fstat): Simplify. Set st_uid/st_gid to effective + uid/gid of current process in case of open sockets. + +2003-02-21 Corinna Vinschen <corinna@vinschen.de> + + * dtable.cc (dtable::build_fhandler_from_name): Set some fhandler + data on sockets to evaluate AF_LOCAL sockets correctly. + (dtable::build_fhandler): Set unit number on sockets. + * fhandler.h (fhandler_socket): Add unit number. + (fhandler_socket::get_unit): New method. + * fhandler_socket.cc (fhandler_socket::fhandler_socket): Set unit + number. + (fhandler_socket::fstat): Reorganize to return more Linux-like + values. + * net.cc: include ctype.h. + (fdsock): Set unit number when building fhandler. + * path.cc (path_conv::check): Set device type to FH_SOCKET if file + is a AF_UNIX socket. + (get_devn): Evaluate unit for virtual socket devices. + (win32_device_name): Set windows path for sockets to unix_path with + just backslashes to keep the different names. + * syscalls.cc (fstat64): Don't override st_ino, st_dev and st_rdev + for sockets. + (stat_worker): Ditto. + +2003-02-21 Pierre Humblet <pierre.humblet@ieee.org> + + * autoload.cc (AccessCheck): Add. + (DuplicateToken): Add. + * security.h (check_file_access): Declare. + * syscalls.cc (access): Convert path to Windows, check existence + and readonly attribute. Call check_file_access instead of acl_access. + * security.cc (check_file_access): Create. + * sec_acl (acl_access): Delete. + +2003-02-19 Christopher Faylor <cgf@redhat.com> + + * fhandler.cc (fhandler_base::open): Move some filesystem specific + stuff. + (fhandler_disk_file::open): Accept some filesystem specific stuff. + * sigproc.cc (wait_for_sigthread): Become slightly more thread safe. + (sig_send): Don't assume that signal thread is ready. + +2003-02-20 Corinna Vinschen <corinna@vinschen.de> + + * wincap.h (wincap): Remove unnecessary definition of + supports_sparse_files. + * wincap.cc: Ditto. + +2003-02-20 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_disk_file.cc (fhandler_disk_file::opendir): Check descriptor + created by cygheap_fdnew constructor. + * fhandler_virtual.cc (fhandler_virtual::opendir): Ditto. + * fhandler_socket.cc (fhandler_socket::accept): Ditto and move + creation of file descriptor behind blocking OS call. + * net.cc (cygwin_socket): Ditto. + (cygwin_rcmd): Ditto. + (cygwin_rresvport): Ditto. + (cygwin_rexec): Ditto. + (socketpair): Ditto. + +2003-02-20 Corinna Vinschen <corinna@vinschen.de> + + * autoload.cc (GetCompressedFileSize): Add. + * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Compute + st_blocks value from GetCompressedFileSize() if available. + +2003-02-18 Vaclav Haisman <V.Haisman@sh.cvut.cz> + + * wincap.h (wincaps::supports_sparse_files): New flag. + (wincapc::supports_sparse_files): New method. + * wincap.cc (wincap_unknown): Define value for the new flag. + (wincap_95): Ditto. + (wincap_95osr2): Ditto. + (wincap_98): Ditto. + (wincap_98se): Ditto. + (wincap_me): Ditto. + (wincap_nt3): Ditto. + (wincap_nt4): Ditto. + (wincap_nt4sp4): Ditto. + (wincap_2000): Ditto. + (wincap_xp): Ditto. + * path.h (path_conv::fs_flags): New method. + * fhandler_disk_file.cc: Include winioctl.h for DeviceIoControl. + (fhandler_disk_file::open): Set newly created and truncated files as + sparse on platforms that support it. + +2003-02-17 Pierre Humblet <pierre.humblet@ieee.org> + + * grp.cc (internal_getgroups): Handle properly tokens with + no groups. Fix bug introduced on 2003-02-04. + +2003-02-16 Christopher Faylor <cgf@redhat.com> + + * cygwin.din: Export all appropriate newlib libm functions. Sort. + * include/cygwin/version.h: Bump API minor number. + +2003-02-15 Christopher Faylor <cgf@redhat.com> + + * cygwin.din: Export all appropriate newlib libc functions. + * include/cygwin/version.h: Bump API minor number. + +2003-02-14 Jason Tishler <jason@tishler.net> + + * mmap.cc (mprotect): Add missing break. + +2003-02-13 Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (try_to_debug): Don't reset priority when returning + from non-waitloop call. + +2003-02-13 Vaclav Haisman <V.Haisman@sh.cvut.cz> + Christopher Faylor <cgf@redhat.com> + + * fhandler_console.cc (fhandler_console::write_normal): Use MessageBeep + for bell sound. + * autoload.cc (MessageBeep): Add. + +2003-02-13 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/types.h: Use correct ifdef guard for u_ definitions. + +2003-02-13 Christopher Faylor <cgf@redhat.com> + + * environ.cc (environ_init): Use strechr. + +2003-02-13 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/in.h (sockaddr_in): Fix typo. + +2003-02-12 Christopher Faylor <cgf@redhat.com> + + * path.h (path_conv): Reorganize slightly. + +2003-02-12 Christopher Faylor <cgf@redhat.com> + + * fhandler_tty.cc (process_input): Add sanity check to ensure that + console typeahead is cleared on signal. + +2003-02-12 Christopher Faylor <cgf@redhat.com> + + * spawn.cc (linebuf::~linebuf): Resurrect commented out (for + debugging?) code. + +2003-02-10 Ralf Habacker <ralf.habacker@freenet.de> + + * include/cygwin/in.h (in_attr_t): Define new type. + * include/arpa/inet.h (inet_addr): Change return type to in_addr_t. + (inet_lnaof): Ditto. + (inet_netof): Ditto. + (inet_network): Ditto. + +2003-02-10 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/types.h: Move many *_t typedefs here. Protect them + with ifdefs. + * fhandler_disk_file.cc (fhandler_disk_file::fstat): Change ntsec_atts to mode_t. + * security.cc (get_attribute_from_acl): Accept mode_t attribute. + (get_nt_attribute): Ditto. + (get_file_attribute): Ditto. + (get_nt_object_attribute): Ditto. + (get_object_attribute): Ditto. + * security.h: Reflect above changes. + * syscalls.cc (chown_worker): Change attrib to mode_t. + +2003-02-08 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/version.h: Bump DLL minor number to 21. + +2003-02-07 Christopher Faylor <cgf@redhat.com> + + * malloc.cc (DEFAULT_MMAP_THRESHOLD): Bump down to 16MB thanks to below + changes. + +2003-02-07 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc (mmap_record::alloc_map): De-inline. Add offset and length + parameter. Only protect pages actually unused currently. Do job + of map_map() when initializing a map. + (mmap_record::map_map): Reduce functionality for the reuse case + of private anonymous mapping. + (mmap_record::fixup_map): Format change. + (list::add_record): Add offset and length parameter to call + mmap_record::alloc_map() correctly. + (mmap64): Rename `l' variable to `map_list'. Accommodate above changes. + (munmap): Rename `l' variable to `map_list'. + (msync): Ditto. + (fhandler_disk_file::mmap): Streamline code. + (mprotect): Ditto. + (fixup_mmaps_after_fork): Rename `l' variable to `map_list'. + +2003-02-07 Vaclav Haisman <V.Haisman@sh.cvut.cz> + Christopher Faylor <cgf@redhat.com> + + * exceptions.cc (try_to_debug): Set priority of current thread rather + than the main thread. Make busy waiting loop less busy. Restore + priority when function returns. + +2003-02-07 Christopher Faylor <cgf@redhat.com> + + * malloc.cc (DEFAULT_MMAP_THRESHOLD): Set high to avoid mmaps. + +2003-02-07 Christopher Faylor <cgf@redhat.com> + + * pipe.cc (fhandler_pipe::close): Avoid extraneous this->. + +2003-02-06 Christopher Faylor <cgf@redhat.com> + + * heap.cc (heap_init): Remove debugging code. + +2003-02-06 Pierre Humblet <pierre.humblet@ieee.org> + + * security.h: Introduce names UNKNOWN_UID and UNKNOWN_GID and delete + declaration of is_grp_member. + * uinfo.cc (internal_getlogin): Use UNKNOWN_GID. + * passwd.cc (pwdgrp::read_passwd): Use UNKNOWN_UID. + * grp.cc (pwdgrp::read_group): Change group name to provide better + feedback. + (getgrgid): Use gid16togid32. + * sec_helper.cc (is_grp_member): Delete. + +2003-02-05 Christopher Faylor <cgf@redhat.com> + + * path.cc: Change 'to_posix_p' to 'to_posix' throughout. + (conv_path_list_buf_size): Accommodate relative paths. + +2003-02-05 Christopher Faylor <cgf@redhat.com> + + * path.cc (etc::dir_changed): Fix debug printf. + +2003-02-05 Corinna Vinschen <corinna@vinschen.de> + + * sec_acl.cc (setacl): Move all permission settings to beginning of + loop. Set default rights to same values as in alloc_sd(). Set DELETE + for owner and default owner only if S_IWOTH is given. + +2003-02-05 Pierre Humblet <pierre.humblet@ieee.org> + + * sec_acl.cc: Change all __aclent16_t to __aclent32_t except in + wrapper function definitions. Replace call to the aclXYZ functions by + calls aclXYZ32. + (searchace): Change type of third argument to __uid32_t and use + ILLEGAL_UID instead of -1; + (setacl): Remove some initializations. Only give STANDARD_RIGHTS_WRITE + for S_IWOTH. Replace -1 by ILLEGAL_UID. + (getacl): Change type of owner_sid, group_sid and ace_sid to cygpsid. + In last else clause, suppress second call to ace_sid.get_id and use + TRUE in first call. Replace EqualSid by ==. + (acl_access): Call internal_getgroups in USER and GROUP cases. + (acecmp: Define static. + (acl32): Create from 16 bit type. + (facl32): Ditto. + (lacl32): Ditto. + (aclcheck32): Ditto. + (aclsort32): Ditto. + (acltomode32): Ditto. + (aclfrommode32): Ditto. + (acltopbits32): Ditto. + (aclfrompbits32): Ditto. + (acltotext32): Ditto. + (aclfromtext32): Ditto, and use strechr. + (acl16to32): Create. + (acl): Make it a wrapper function. + (facl): Ditto. + (lacl): Ditto. + (aclcheck): Ditto. + (aclsort): Ditto. + (acltomode): Ditto. + (aclfrommode): Ditto. + (acltopbits): Ditto. + (aclfrompbits): Ditto. + (acltotext): Ditto. + (aclfromtext): Ditto. + * security.cc (write_sd): Call set_process_privilege and check + ownership. + (alloc_sd): Remove call to set_process_privilege and the owner check. + +2003-02-05 Christopher Faylor <cgf@redhat.com> + + * include/sys/cygwin.h: Use C-style comments. + +2003-02-05 Pierre Humblet <pierre.humblet@ieee.org> + + * sec_helper.cc (get_sids_info): New function. + * security.cc (extract_nt_dom_user): Simplify with strechr. + (get_user_groups): Initialize glen to MAX_SID_LEN. + (get_user_local_groups): Ditto. + (get_attribute_from_acl): Define ace_sid as cygpsid. + (get_nt_attribute): Define owner_sid and group_sid as cygpsid. + Call get_sids_info instead of cygsid.get_{u,g}id and is_grp_member. + (get_nt_object_attribute): Ditto. + (alloc_sd): Define ace_sid as cygpsid. + +2003-02-04 Thomas Pfaff <tpfaff@gmx.net> + + * syscalls.cc (struct system_cleanup_args): New struct. + (system_cleanup): New function. + (system): Use pthread_cleanup_push and _pop to save and restore + signal handlers and sigprocmask. + +2003-02-04 Corinna Vinschen <corinna@vinschen.de> + + * path.cc (symlink): Create security attributes so that only the + user can modify the symlink. + * security.cc (set_security_attribute): Remove symlink special + handling. + +2003-02-04 Pierre Humblet <pierre.humblet@ieee.org> + + * grp.cc (internal_getgroups): Do not return without closing + the process handle. + +2003-02-04 Pierre Humblet <pierre.humblet@ieee.org> + + * security.h (class cygpsid): New class. + (class cygsid): Use cygpsid as base. Remove members psid, get_id, + get_uid, get_gid, string, debug_printf and the == and != operators. + (cygsidlist::clear_supp): Only do work if setgroups has been called. + * sec_helper.cc: Define sid_auth NO_COPY. + (cygpsid::operator==): New operator. + (cygpsid::get_id): New function. + (cygpsid::string): New function. + (cygsid::string): Delete. + (cygsid::get_id): Delete. + * pwdgrp.h: Change arguments of internal_getpwsid, + internal_getgrsid and internal_getgroups to cygpsid. + * passwd.cc (internal_getpwsid): Change argument from cygsid to cygpsid. + * grp.cc (internal_getgrsid): Ditto. + (internal_getgroups): Ditto. + +2003-02-03 Christopher Faylor <cgf@redhat.com> + + Eliminate most unneeded this-> pointers throughout. + +2003-02-03 Pierre Humblet <pierre.humblet@ieee.org> + + * security.h: Add third argument to set_process_privilege. + * autoload.cc: Add OpenThreadToken. + * sec_helper.cc (set_process_privilege): Add and use use_thread + argument. + * security.cc (alloc_sd): Modify call to set_process_privilege. + Remember the result in each process. If failed and file owner is not + the user, fail. + +2003-02-03 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::recvfrom): Return buffer + length and don't set errno in case of WSAEMSGSIZE error. + (fhandler_socket::recvmsg): Ditto. + +2003-02-01 Christopher Faylor <cgf@redhat.com> + + * grp.cc (getgrent32): Only refresh group entries when at beginning. + (internal_getgrsid): Only refresh if uninitialized. + (internal_getgrent): Ditto. + * passwd.cc (getpwent): Only refresh passwd entries when at beginning. + (pwdgrp::read_passwd): linebuf *cannot* be NO_COPY. + (internal_getpwsid): Only refresh if uninitialized. + (getpass): No need to refresh passwd data here. + * pwdgrp.h (refresh): Eliminate default. + +2003-01-31 Christopher Faylor <cgf@redhat.com> + + * dlfcn.cc (dlerror): Only report load errors once per error. + +2003-01-31 Christopher Faylor <cgf@redhat.com> + + * fhandler_serial.cc (fhandler_serial::open): Avoid extraneous setting + of res. + + * termios.cc (tcsetattr): Correctly record errno after tcsetattr call. + +2003-01-31 Troy Curtiss <troyc@usa.net> + + * fhandler_serial.cc (fhandler_serial::tcsetattr): Add error-checking + so that if any Win32 SetComm*() calls fail, errno gets set to EINVAL + and tcsetattr() returns -1. Catch invalid bitrates, mostly. If baud + rate setting is B0, just drop DTR and leave Win32 DCB bitrate as-is + since 0 is not a valid Win32 setting. + (fhandler_serial::tcgetattr): If DTR is low, populate the bitrate as + B0, otherwise get it from the DCB. + +2003-01-31 Christopher Faylor <cgf@redhat.com> + + * passwd.cc (pwdgrp::read_passwd): linebuf *must* be static (from + Pierre Humblet). + * pwdgrp.h (pwdgrp::refresh): Avoid calling read function if we already + have lock since that means we are in the process of reading the file. + +2003-01-31 Jason Tishler <jason@tishler.net> + + * shared.cc (shared_info::heap_chunk_size): Use correct variable when + reading HKLM. + +2003-01-30 Christopher Faylor <cgf@redhat.com> + + * fhandler_registry.cc (fhandler_registry::exists): Fix off-by-one + error when inspecting path. + +2003-01-29 Christopher Faylor <cgf@redhat.com> + + * lib/getopt.c: Allow environment variable control of POSIXLY_INCORRECT + behavior. + +2003-01-28 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_socket.cc (fhandler_socket::accept): On successful execution + set connection state of returned socket to CONNECTED. + +2003-01-27 Christopher Faylor <cgf@redhat.com> + + * passwd.cc (pwdgrp::parse_passwd): Be more unforgiving about + non-numeric fields. + +2003-01-26 Christopher Faylor <cgf@redhat.com> + + * uinfo.cc (pwdgrp::next_num): Remove check for NULL since it is no + longer a valid return from next_str. + (pwdgrp::add_line): Duh. Revert to use strchr. + +2003-01-26 Christopher Faylor <cgf@redhat.com> + + * string.h (strechr): New function. + * uinfo.cc (pwdgrp::next_str): Search only for input char in string. + Return EOS on failure. Don't check for NULL since it shouldn't be + possible. + (pwdgrp::add_line): Revert to replacing '\n' in input line with '\0'. + (pwdgrp::next_num): Pass explicit separator character to next_str. + * grp.cc (pwdgrp::parse_group): Ditto. + * passwd.cc (pwdgrp::parse_passwd): Ditto. Revamp test for garbage + input. + * pwdgrp.h (pwdgrp::next_str): Don't use default parameter. + +2003-01-26 Christopher Faylor <cgf@redhat.com> + + * uinfo.cc (pwdgrp::load): Regularize strace output. Add warning for + CreateFile failure. + +2003-01-26 Christopher Faylor <cgf@redhat.com> + + * passwd.cc (pwdgrp::parse_passwd): Eliminate use of memset. The + structure should always be completely filled out. + * grp.cc (pwdgrp::parse_group): Ditto. + +2003-01-26 Christopher Faylor <cgf@redhat.com> + + * grp.cc (pwdgrp::parse_group): Fix off-by-one problem in allocating + gr_mem. + +2003-01-26 Christopher Faylor <cgf@redhat.com> + + * include/sys/strace.h (paranoid_printf): Define as not being part of + "all" output. + +2003-01-25 Christopher Faylor <cgf@redhat.com> + + * pwdgrp.h (pwdgrp::next_num): Rename from next_int. Returns + true/false if parse operation succeeded. + (pwdgrp::reparse): Remove. + (pwdgrp::raw_ptr): New function. Returns pointer in line. + (pwdgrp::next_num): New functions for parsing other than unsigned long. + * grp.cc (pwdgrp::parse_group): Reinstate previous parsing behavior. + Don't fill in fields with NULL and assign empty gr_mem to known pointer + rather than doing a pointless calloc. Streamline gr_mem parsing. + Don't increment curr_lines here. + * passwd.cc (pwdgrp::parse_passwd): Use new behavior of next_num. + Don't increment curr_lines here. + * uinfo.cc (pwdgrp::next_str): Keep returning EOL if out of data. + (pwdgrp::reparse): Remove. + (pwdgrp::next_num): Rename from next_int. Return bool indicating + success of parse, argument returns value parsed. + (pwdgrp::add_line): Increment curr_lines here on successful parse. + (pwdgrp::load): (from Pierre Humblet) Don't return status. Just report + it here. + +2003-01-25 Christopher Faylor <cgf@redhat.com> + + * pwdgrp.cc (pwdgrp::reparse): Declare. + * uinfo.cc (pwdgrp::reparse): Define. + * grp.cc (pwdgrp::parse_group): Use reparse. + +2003-01-25 Pierre Humblet <pierre.humblet@ieee.org> + + * syscalls.cc (seteuid32): On Win95 get the pw entry. If it exists + update the euid and call cygheap->user.set_name. Remove special + handling of ILLEGAL_UID. + (setgid32): Add a debug_printf. On Win95, always set the egid. + Remove special handling of ILLEGAL_GID. Do not compare gid and gr_gid. + * child_info.h (class cygheap_exec_info): Remove uid. + * spawn.cc (spawn_guts): Do not set ciresrv.moreinfo->uid. + * dcrto.cc (dll_crt0_1): Always call uinfo_init. + * uinfo.cc (uinfo_init): Reorganize and close handle if needed. + (cygheap_user::ontherange): Do not call internal_getpwnam if pw is NULL. + +2003-01-24 Christopher Faylor <cgf@redhat.com> + + * fhandler_console.cc (fhandler_console::send_winch_maybe): Reset + scroll region if size changes. + +2003-01-24 Pierre Humblet <pierre.humblet@ieee.org> + Jason Tishler <jason@tishler.net> + + * cygwin.din: Export setreuid32, setreuid, setregid32, setregid. + * syscalls.cc (setreuid32): New function. + (setreuid): Ditto. + (setregid32): Ditto. + (setregid): Ditto. + * include/cygwin/version.h: Bump API minor number. + +2003-01-23 Christopher Faylor <cgf@redhat.com> + + * pwdrp.h (pwdgrp::refresh): Lock entire test prior to reading. + +2003-01-23 Christopher Faylor <cgf@redhat.com> + + * grp.cc (pwdgrp::parse_group): Eliminate arg and use class member + instead. Use next_str and next_int to parse arguments. + * passwd.cc (pwdgrp::parse_passwd): Ditto. + (grab_string): Eliminate. + (grab_int): Ditto. + * pwdgrp.h (pwdgrp::parse): Eliminate input arg. + (pwdgrp::parse_passwd): Reflect above change. + (pwdgrp::parse_group): Reflect above change. + (pwdgrp::next_str): New function. + (pwdgrp::next_int): Ditto. + (pwdgrp::gets): Eliminate. + * uinfo.cc (pwdgrp::next_str): New function. + (pwdgrp::next_int): Ditto. + (pwdgrp::add_line): Subsume gets. + (pwdgrp::gets): Eliminate. + (pwdgrp::load): Just call add_line to parse input buffer. + +2003-01-22 Thomas Pfaff <tpfaff@gmx.net> + + * include/pthread.h (PTHREAD_MUTEX_RECURSIVE): Revert changes from + 2003-01-09 mutex patch. + (PTHREAD_MUTEX_ERRORCHECK): Ditto. + +2003-01-22 Corinna Vinschen <corinna@vinschen.de> + + * cygrun.c: Move from here to ../testsuite. + * Makefile.in: Remove cygrun.exe dependencies. + +2003-01-21 Jason Tishler <jason@tishler.net> + + * cygwin.din: Export nanosleep(). + * signal.cc (nanosleep): New function. + (sleep): Move old functionality to nanosleep(). Call nanosleep(). + (usleep): Remove old functionality. Call nanosleep(). + * include/cygwin/version.h: Bump API minor number. + +2003-01-21 Christopher Faylor <cgf@redhat.com> + + * grp.cc: Call gr.refresh() rather than doing isunitialized tests + throughout. + (gr): Use constructor (sigh). + (pwdgrp::parse_group): Rename from parse_grp. + (pwdgrp::read_group): Rename from read_etc_group. Just call gr.load + with a single argument. + * passwd.cc: Call pr.refresh() rather than doing isunitialized tests + throughout. + (pr): Use constructor (sigh). + (pwdgrp::parse_passwd): Rename from "parse_pwd". + (pwdgrp::read_passwd): Rename from read_etc_passwd. Just call pr.load + with a single argument. + * pwdgrp.h (pwdgrp_state): Eliminate. + (pwdgrp): Reflect above renamings. + (pwdgrp::etc_ix): Rename from pwd_ix. + (pwdgrp::read): New element. + (pwdgrp::lock): New element. + (pwdgrp::refresh): New function. + (pwdgrp::load): Eliminate variations which take buffer arguments. + (pwdgrp::pwdgrp): New constructors. Initialize mutex here. + * uinfo.cc (pwdgrp::load): Accommodate pwd_ix -> etc_ix renaming. + (pwdgrp::load): Set initialized state to true rather than setting state + to loaded. + +2003-01-21 Christopher Faylor <cgf@redhat.com> + + * include/cygwin/version.h: Bump DLL minor number. + +2003-01-21 Pierre Humblet <pierre.humblet@ieee.org> + + * path.h (etc::change_possible): Revert the type to bool. + (etc::set_last_modified): Remove obsolete function. + * path.cc (etc::change_possible): Revert type to bool. + (etc::test_file_change): Do not test for negative values of + change_possible and do not set it to -res. + (etc::dir_changed): When the handle is NULL, call memset instead of + test_file_changed. When the handle is invalid, return true. Detect + filename change in /etc. + (etc::file_changed): Remove unneeded check for !fn[n]. + * uinfo.cc (pwdgrp::load): Eliminate spurious setting of fh to NULL. + * pwdgrp.h (pwdgrp::operator =): Eliminate. + +2003-01-19 Christopher Faylor <cgf@redhat.com> + + * pwdgrp.h (etc): Move to path.h. + (pwdgrp::max_lines): New field. + (pwdgrp::curr_lines): New field. + (pwdgrp::pwdgrp_buf): Ditto. + (pwdgrp_buf_elem_size): Ditto. + (pwdgrp_parse): Ditto. + (pwdgrp::gets): Just declare here. + (pwdgrp::load): Ditto. Just take one argument. + (pwdgrp::load): Define overloaded function accepting passwd buf. + (pwdgrp::load): Define overloaded function accepting group buf. + * grp.cc: Use pwdgrp elements rather than standalone static variables + throughout. + (curr_lines): Eliminate. + (max_lines): Ditto. + (add_grp_line): Ditto. + (parse_grp): Define as returning boolean. Accept void * arg and line + count. Coerce first argument into __group32 buf reference. Increment + curr_line as appropriate. + (read_etc_group): Pass pwdgrp buffer to gr.load. + * passwd.cc: Use pwdgrp elements rather than standalone static variables + throughout. + (curr_lines): Eliminate. + (max_lines): Ditto. + (add_grp_line): Ditto. + (parse_passwd): Define as returning boolean. Accept void * arg and line + count. Coerce first argument into passwd buf reference. Increment + curr_line as appropriate. + (read_etc_group): Pass pwdgrp buffer to pr.load. + * path.cc (etc::fn): Extend buffer size to allow index by 1 rather than + zero. + (etc::last_modified): Ditto. + (etc::change_possible): Ditto. Renamed from sawchange. Change to + signed char since elements are now tri-state. + (etc::init): Assume "handle" is 1 based rather than 0. + (etc::test_file_change): New function. Sets change_possible based on + file date comparison. + (etc::dir_changed): Check file states immediately after changed_h is + initialized to avoid a race. + (etc::file_changed): Use test_file_change to detect if file needs to be + updated. + * path.h (etc): Move class here from pwdgrp.h. + * uinfo.cc: Move etc:: functions to path.cc. Move pwdgrp functions + here. + (pwdgrp::gets): Eliminate buf checks. Just check eptr and set lptr. + (pwdgrp::add_line): New function. + (pwdgrp::load): Call generic add_line function which will call correct + parser. + +2003-01-17 Christopher Faylor <cgf@redhat.com> + + * cygheap.cc: Change most 'int's to 'unsigned's. + (_cmalloc): Only check for size of malloced region when calculating + bucket. Add overhead when performing the sbrk. Previous change broke + _crealloc. + +2003-01-17 Christopher Faylor <cgf@redhat.com> + + * dcrt0.cc (initialize_env): Use colon for CYGWIN_DEBUG separator. + * grp.cc: Change most statics to NO_COPY throughout. + * passwd.cc: Ditto. + +2003-01-17 Christopher Faylor <cgf@redhat.com> + + * pwdgrp.h: Change some BOOLs to bools. + (pwdgrp::pwdgrp): Remove unneeded constructor. + * passwd.cc: Change BOOL to bool throughout. + +2003-01-17 Corinna Vinschen <corinna@vinschen.de> + + * cygwin.din: Add strerror_r. + * include/cygwin/version.h: Bump API minor number. + +2003-01-17 Christopher Faylor <cgf@redhat.com> + + * uinfo.cc (etc::dir_changed): Don't print a warning if can't open + /etc, unless debugging. + +2003-01-17 Pierre Humblet <pierre.humblet@ieee.org> + + * grp.cc (read_etc_group): On NT, add a line for gid = -1. Change name + "unknown" to "mkgroup". + (internal_getgrgid): Do not return default in nontsec case. + (internal_getgroups): Add argument srchsid and look for it in groups if + not NULL. + * passwd.cc (read_etc_passwd): On NT, add a line for uid = -1. Use + same default uid for Win95 and NT. Call cygheap_user::ontherange to + initialize HOME. + +2003-01-16 Christopher Faylor <cgf@redhat.com> + + * cygheap.cc (init_cygheap::etc_changed): Move to uinfo.cc. + * cygheap.h (init_cygheap::etc_changed_h): Remove. + (init_cygheap::etc_changed): Ditto. + * grp.cc (group_state): Remove. Use gr instead throughout. + (gr): Define as class pwdgrp. + (read_etc_group): Remove gr definition. Remove calls to + set_last_modified and close. Pass add_grp to gr.load to load file. + * passwd.cc (passwd_state): Remove. Use pr instead, throughout. + (pr): Define as class pwdgrp. + (read_etc_passwd): Remove pr definition. Remove calls to + set_last_modified and close. Pass add_pwd_line to pr.load to load + file. + * pwdgrp.h (etc): New helper class for pwdgrp. + (pwdgrp): Combine pwdgrp_check and pwdgrp_read into one class. Remove + file_w32 and last_modified fields. + (pwdgrp::set_last_modified): Remove. + (pwdgrp::isinitializing): Remove FindFirstFile stuff. Move to + etc::file_changed. + (pwdgrp::load): Rename from 'open'. Call etc::init to initialize etc + scanning. Close file handle after reading buffer into memory. Parse + buffer by calling second argument. + (pwdgrp::gets): Reorganize slightly to rely on eptr starting at + beginning of buffer. + (pwdgrp::close): Remove. + * uinfo.cc (etc::dir_changed): New function. + (etc::init): Ditto. + (etc::file_changed): Ditto. + (etc::set_last_modified): Ditto. + +2003-01-16 Jason Tishler <jason@tishler.net> + + * mmap.cc (fixup_mmaps_after_fork): Add ERROR_NOACCESS to the list of + ReadProcessMemory() error codes that trigger a retry with temporary + PAGE_READONLY access. Note that this can occur on NT 4.0. + +2003-01-15 Christopher Faylor <cgf@redhat.com> + + * path.cc (normalize_posix_path): Convert win32 path separators to + slashes when full path is specified. + +2003-01-15 Pierre Humblet <pierre.humblet@ieee.org> + + * cmalloc.cc (_cmalloc): Fix memory leak. + +2003-01-15 Corinna Vinschen <corinna@vinschen.de> + + * autoload.cc: Fix copyright date. + * fhandler_dsp.cc: Ditto. + * mmap.cc: Ditto. + * net.cc: Ditto. + * ntdll.h: Ditto. + * signal.cc: Ditto. + * syscalls.cc: Ditto. + * uname.cc: Ditto. + * wait.cc: Ditto. + +2003-01-14 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc (fixup_mmaps_after_fork): Copy protection to child process. + Change ambiguous debug output. + +2003-01-14 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc (mmap_record::access): Change argument type to caddr_t + for strictness. + (mprotect): Protect against calling VirtualProtect() for shared + pages on 9x/Me. + (fixup_mmaps_after_fork): If ReadProcessMemory() fails, try to + change protection of parent page to PAGE_READONLY, then try again. + Revert protection afterwards. + +2003-01-14 Thomas Pfaff <tpfaff@gmx.net> + + * syscalls.cc (system): Add pthread_testcancel call. + * thread.cc: Update list of cancellation points. + +2003-01-14 Thomas Pfaff <tpfaff@gmx.net> + + * wait.cc: Include thread.h + (wait4): Add pthread_testcancel call. + Wait for child process and cancellation event. + * thread.cc: Update list of cancellation points. + +2003-01-14 Thomas Pfaff <tpfaff@gmx.net> + + * signal.cc (sleep): Add pthread_testcancel call. + Wait for signal and cancellation event. + (usleep): Ditto. + +2003-01-14 Thomas Pfaff <tpfaff@gmx.net> + + * exceptions.cc (handle_sigsuspend): Add pthread_testcancel call. + Wait for signal and cancellation event. + * thread.cc: Update list of cancellation points. + +2003-01-14 David Huang <davehzhr@hotmail.com> + + * fhandler_dsp.cc (fhandler_dsp::ioctl): Add limited support for + SNDCTL_DSP_GETFMTS. + +2003-01-12 Christopher Faylor <cgf@redhat.com> + + * ntdll.h: Fix typo. + +2003-01-12 Corinna Vinschen <corinna@vinschen.de> + + * uname.cc (uname): Use cygwin_gethostname() to retrieve hostname. + +2003-01-12 Pierre Humblet <pierre.humblet@ieee.org> + + * sec_acl.cc (search_ace): Use id == -1, instead of < 0, as wildcard. + (setacl): Start the search for a matching default at the next entry. + Invalidate the type of merged entries instead of clearing it. + Use well_known_creator for default owner and owning group and do + not try to merge non-default and default entries in these cases. + (getacl): Recognize well_known_creator for default owner and group. + (acl_worker): Improve errno settings and streamline the nontsec case. + * security.cc (write_sd): Remove the call to set_process_privilege. + (alloc_sd): If the owner changes, call set_process_privilege and return + immediately on failure. Change inheritance rules: on new directories add + inherit only allow ACEs for creator_owner, creator_group and everyone. + Preserve all inheritances through chmod and chown calls. Introduce + isownergroup to implement the uid == gid case, to keep the inheritance + code simple. Do not initialize owner_sid and group_sid and stop using + the variable psd. + +2003-01-10 Christopher Faylor <cgf@redhat.com> + + * net.cc: Use gethostname define from winsock2.h. + +2003-01-10 Christopher Faylor <cgf@redhat.com> + + * path.cc: Unrevert below reversion except for + mount_info::conv_to_posix_path part. + +2003-01-10 Corinna Vinschen <corinna@vinschen.de> + + * path.cc: Revert patch from 2003-01-09 to normalize a windows path + rather than converting to posix. + +2003-01-10 Corinna Vinschen <corinna@vinschen.de> + + * autoload.cc (gethostname): Make call optional, return 1 if function + can't get loaded. + * net.cc (cygwin_gethostname): Call GetComputerName if return value + of gethostname is non-zero. + +2003-01-10 Charles Wilson <cwilson@ece.gatech.edu> + + * cygwin.din: Add asprintf and vasprintf, as well as the reentrant + versions and underscore variants. + * include/cygwin/version.h: Bump CYGWIN_VERSION_API_MINOR. + +2003-01-10 Corinna Vinschen <corinna@vinschen.de> + + * net.cc (cygwin_gethostname): Fix call to wsock function gethostname. + +2003-01-09 Christopher Faylor <cgf@redhat.com> + + * cygthread.cc (cygthread::cygthread): Be more noisy about odd + condition. + * miscfuncs.cc (low_priority_sleep): Sleep in regular priority if + that's what we're currently running at. + +2003-01-09 Thomas Pfaff <tpfaff@gmx.net> + + * include/semaphore.h: Modify typedef for sem_t. + * include/cygwin/types.h: Modify typedefs for pthread_t, + pthread_mutex_t, pthread_key_t, pthread_attr_t, + pthread_mutexattr_t, pthread_condattr_t, pthread_cond_t, + pthread_rwlock_t and pthread_rwlockattr_t. + +2003-01-09 Thomas Pfaff <tpfaff@gmx.net> + + * thread.h (WAIT_CANCELED): New define. + (pthread::cancelable_wait): New static method. + * thread.cc (pthread::cancelable_wait): Implement. + (semaphore::Wait): Wait on semaphore and thread cancellation. + (pthread::join): Wait on joined thread and thread cancellation. + (semaphore::wait): Add testcancel to check for thread + cancellation even if the semaphore is available. + +2003-01-09 Thomas Pfaff <tpfaff@gmx.net> + + * include/pthread.h: Add define for errorchecking mutexes. + Change default mutex type. + * thread.cc (pthread_cond::TimedWait): Update mutex unlock + calls. + (pthread_mutex::pthread_mutex): New implement. + (pthread_mutex::~pthread_mutex): Ditto. + (pthread_mutex::Lock): Ditto. + (pthread_mutex::TryLock): Ditto. + (pthread_mutex::UnLock): Ditto. + (pthread_mutex::Destroy): Implement new method. + (pthread_mutex::SetOwner): Ditto. + (pthread_mutex::LockRecursive): Ditto. + (pthread_mutex::fixup_after_fork): Restore locking state after + fork. + (__pthread_mutex_lock): Return pthread_mutex::Lock errorcode. + (__pthread_mutex_trylock): Return pthread_mutex::TryLock + errorcode. + (__pthread_mutex_unlock): Return pthread_mutex::UnLock + errorcode. + (__pthread_mutex_destroy): Call pthread_mutex::Destroy to + destroy mutex. + (__pthread_mutexattr_settype): Allow errorchecking and recursive + types. + * thread.h (MUTEX_LOCK_COUNTER_INITIAL): New define. + (pthread_mutex::criticalsection): Remove. + (pthread_mutex::lock_counter): New member. + (pthread_mutex::recursion_counter): Ditto. + (pthread_mutex::owner): Ditto. + (pthread_mutex::type): Ditto. + (pthread_mutex::Destroy): New method. + (pthread_mutex::SetOwner): Ditto. + (pthread_mutex::LockRecursive): Ditto. + +2003-01-09 Thomas Pfaff <tpfaff@gmx.net> + + * pthread.cc (pthread_cond_init): Use new pthread_cond::init. + * thread.cc: Some white spaces cleanups. + Change __pthread_cond_init to pthread_cond::init throughout. + (nativeMutex): Move class methods outside pthread_mutex. + (MTinterface::Init): Initialize pthread_cond init lock. + (pthread_cond::condInitializationLock): Instantiate. + (pthread_cond::initMutex): New Method. + (pthread_cond::isGoodInitializerOrBadObject): Ditto. + * thread.h: Some white spaces cleanups. + (nativeMutex): Move class declaration outside pthread_mutex. + (pthread_cond::condInitializationLock): New static member. + (pthread_cond::initMutex): New Method. + (pthread_cond::isGoodInitializerOrBadObject): Ditto. + (__pthread_cond_init): Remove prototype. + +2003-01-09 Corinna Vinschen <corinna@vinschen.de> + + * fhandler_disk_file.cc (num_entries): Return 2 as link count if + directory unreadable. + +2003-01-09 Corinna Vinschen <corinna@vinschen.de> + + * security.cc (get_nt_attribute): Always return -1 when read_sd() + fails. + (get_file_attribute): Set permissions to 0 and owner/group to -1 + if security descriptor is unreadable. + +2003-01-09 Christopher Faylor <cgf@redhat.com> + + Use isdirsep rather than SLASH_P throughout. + * path.cc (iscygdrive): Disallow /cygdrive\x. + (normalize_posix_path): "Normalize" a windows path, if detected, rather + than converting to posix. + +2003-01-06 Troy Curtiss <troyc@usa.net> + + * fhandler_serial.cc (fhandler_serial::tcsetattr): Add support and + capability checking for B230400 bitrate. + (fhandler_serial::tcgetattr): Add support for B230400 bitrate. + * include/sys/termios.h: Add B230400 definition for Posix support of + 230.4Kbps. + +2003-01-05 Christopher Faylor <cgf@redhat.com> + + * pinfo.cc (_pinfo::commune_send): Use myself->lock rather than just + lock when leaving. + +2003-01-03 Christopher Faylor <cgf@redhat.com> + + * dtable.h (dtable::in_vfork_cleanup): New function. True if vfork + cleanup needed. + * dtable.cc (dtable::vfork_parent_restore): Remove assertion. + * pipe.cc (fhandler_pipe::close): Don't close read_state during + fork_fixup since it wasn't inherited. + +2003-01-01 Christopher Faylor <cgf@redhat.com> + + * passwd.cc (getpwuid_r32): Revert previous change. + +2003-01-01 Christopher Faylor <cgf@redhat.com> + + * sysconf.cc (sysconf): Return arbitrary values for + _SC_GETGR_R_SIZE_MAX, _SC_LOGIN_NAME_MAX, _SC_GETPW_R_SIZE_MAX. + + * passwd.cc (getpwuid_r32): Add uid/gid fields to size check + calculation. diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in new file mode 100644 index 00000000000..a5d35151a60 --- /dev/null +++ b/winsup/cygwin/Makefile.in @@ -0,0 +1,419 @@ +# Makefile.in for Cygwin. +# Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 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. + +# This makefile requires GNU make. + +SHELL:=@SHELL@ +srcdir:=@srcdir@ +objdir:=. + +CONFIG_DIR:=$(srcdir)/config/@CONFIG_DIR@ +VPATH:=$(srcdir):$(CONFIG_DIR):$(srcdir)/regex:$(srcdir)/regexp:$(srcdir)/lib + +target_alias:=@target_alias@ +build_alias:=@build_alias@ +host_alias:=@host_alias@ +prefix:=@prefix@ + +program_transform_name:=@program_transform_name@ +exec_prefix:=@exec_prefix@ +bindir:=@bindir@ +libdir:=@libdir@ +ifeq ($(target_alias),$(host_alias)) +ifeq ($(build_alias),$(host_alias)) +tooldir:=$(exec_prefix) +else +tooldir:=$(exec_prefix)/$(target_alias) +endif +else +tooldir:=$(exec_prefix)/$(target_alias) +endif +datadir:=@datadir@ +infodir:=@infodir@ +includedir:=@includedir@ + +override INSTALL:=@INSTALL@ +override INSTALL_PROGRAM:=@INSTALL_PROGRAM@ +override INSTALL_DATA:=@INSTALL_DATA@ + +# +# --enable options from configure +# +MT_SAFE:=@MT_SAFE@ +DEFS:=@DEFS@ + +cygheap_CFLAGS:=-fomit-frame-pointer +malloc_CFLAGS:=-fomit-frame-pointer +malloc_wrapper_CFLAGS:=-fomit-frame-pointer +shared_CFLAGS:=-fomit-frame-pointer +cygthread_CFLAGS:=-fomit-frame-pointer +miscfuncs_CFLAGS:=-fomit-frame-pointer +fhandler_CFLAGS:=-fomit-frame-pointer +fhandler_clipboard_CFLAGS:=-fomit-frame-pointer +fhandler_clipboard_CFLAGS:=-fomit-frame-pointer +fhandler_console_CFLAGS:=-fomit-frame-pointer +fhandler_disk_file_CFLAGS:=-fomit-frame-pointer +fhandler_dsp_CFLAGS:=-fomit-frame-pointer +fhandler_floppy_CFLAGS:=-fomit-frame-pointer +fhandler_mem_CFLAGS:=-fomit-frame-pointer +fhandler_proc_CFLAGS:=-fomit-frame-pointer +fhandler_process_CFLAGS:=-fomit-frame-pointer +fhandler_random_CFLAGS:=-fomit-frame-pointer +fhandler_raw_CFLAGS:=-fomit-frame-pointer +fhandler_registry_CFLAGS:=-fomit-frame-pointer +fhandler_serial_CFLAGS:=-fomit-frame-pointer +fhandler_socket_CFLAGS:=-fomit-frame-pointer +fhandler_tape_CFLAGS:=-fomit-frame-pointer +fhandler_termios_CFLAGS:=-fomit-frame-pointer +fhandler_tty_CFLAGS:=-fomit-frame-pointer +fhandler_virtual_CFLAGS:=-fomit-frame-pointer +fhandler_windows_CFLAGS:=-fomit-frame-pointer +fhandler_zero_CFLAGS:=-fomit-frame-pointer +regcomp_CFLAGS=-fomit-frame-pointer +regerror_CFLAGS=-fomit-frame-pointer +regexec_CFLAGS=-fomit-frame-pointer +regfree_CFLAGS=-fomit-frame-pointer + +CC:=@CC@ +# FIXME: Which is it, CC or CC_FOR_TARGET? +CC_FOR_TARGET:=$(CC) +CFLAGS=@CFLAGS@ +override CFLAGS+=-MMD ${$(*F)_CFLAGS} +CXX=@CXX@ +CXXFLAGS=@CXXFLAGS@ + +AR:=@AR@ +AR_FLAGS:=qv +RANLIB:=@RANLIB@ +LD:=@LD@ +DLLTOOL:=@DLLTOOL@ +WINDRES:=@WINDRES@ +AS:=@AS@ +NM:=@NM@ +LDSCRIPT:=cygwin.sc + +# +# Include common definitions for winsup directory +# +include $(srcdir)/../Makefile.common + +@SET_MAKE@ + +# Setup the testing framework, if you have one +EXPECT = `if [ -f $${rootme}/../../expect/expect$(EXEEXT) ] ; then \ + echo $${rootme}/../../expect/expect$(EXEEXT) ; \ + else echo expect ; fi` + +RUNTEST = `if [ -f $${srcdir}/../dejagnu/runtest ] ; then \ + echo $${srcdir}/../dejagnu/runtest ; \ + else echo runtest; fi` +RUNTESTFLAGS = + +# Parameters used in building the cygwin.dll. +# We build as cygwin0.dll and rename at install time to overcome +# native rebuilding issues (we don't want the build tools to see a partially +# built cygwin.dll and attempt to use it instead of the old one). + +DLL_NAME:=cygwin1.dll +TEST_DLL_NAME:=cygwin0.dll +TEST_LIB_NAME:=libcygwin0.a +DEF_FILE:=cygwin.def +DLL_ENTRY:=@DLL_ENTRY@ + +LIBGMON_A:=libgmon.a +CYGWIN_START:=crt0.o +GMON_START:=gcrt0.o + +# Some things want these from libc, but they have their own static +# data which apps can get to, which is a pain in the dll, so we +# include them directly into the library. + +LIBCOS:=${sort ${addsuffix .o,${basename ${notdir ${wildcard $(srcdir)/lib/*.c}}}} \ + ${addsuffix .o,${basename ${notdir ${wildcard $(srcdir)/lib/*.cc}}}}} + +# Build all source files in the config directory + +EXTRA_DLL_OFILES:=${addsuffix .o,${basename ${notdir ${wildcard $(CONFIG_DIR)/*.c}}}} + +EXTRA_OFILES=$(bupdir1)/libiberty/random.o $(bupdir1)/libiberty/strsignal.o + +MALLOC_OFILES=@MALLOC_OFILES@ + +DLL_IMPORTS:=$(w32api_lib)/libkernel32.a + +# Please maintain this list in sorted order, with maximum files per 80 col line +DLL_OFILES:=assert.o autoload.o bsdlib.o cxx.o cygheap.o cygthread.o dcrt0.o \ + debug.o delqueue.o dir.o dlfcn.o dll_init.o dtable.o environ.o \ + errno.o exceptions.o exec.o external.o fcntl.o fhandler.o \ + fhandler_clipboard.o fhandler_console.o fhandler_disk_file.o \ + fhandler_dsp.o fhandler_floppy.o fhandler_mem.o \ + fhandler_proc.o fhandler_process.o fhandler_random.o \ + fhandler_raw.o fhandler_registry.o fhandler_serial.o \ + fhandler_socket.o fhandler_tape.o fhandler_termios.o \ + fhandler_tty.o fhandler_virtual.o fhandler_windows.o \ + fhandler_zero.o fnmatch.o fork.o getopt.o glob.o grp.o heap.o init.o \ + ioctl.o ipc.o iruserok.o localtime.o malloc_wrapper.o miscfuncs.o \ + mmap.o msg.o net.o netdb.o ntea.o passwd.o path.o pinfo.o pipe.o \ + poll.o pthread.o regcomp.o regerror.o regexec.o regfree.o registry.o \ + resource.o scandir.o sched.o sec_acl.o sec_helper.o security.o \ + select.o sem.o shared.o shm.o signal.o sigproc.o smallprint.o spawn.o \ + strace.o strsep.o sync.o syscalls.o sysconf.o syslog.o termios.o \ + thread.o times.o tty.o uinfo.o uname.o v8_regexp.o v8_regerror.o \ + v8_regsub.o wait.o wincap.o window.o \ + $(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS) + +GMON_OFILES:=gmon.o mcount.o profil.o + +OBSOLETE_FUNCTIONS:=regcomp regerror regexec regfree regsub \ + open acl aclcheck aclfrommode aclfrompbits \ + aclfromtext aclsort acltomode acltopbits \ + acltotext chown facl fchown fdopen fgetpos fopen \ + freopen fseeko fsetpos fstat ftello ftruncate \ + getegid geteuid getgid getgrent getgrgid getgrnam \ + getgroups getpwuid getpwuid_r getuid initgroups \ + lchown lseek lstat mknod mmap seekdir setegid seteuid \ + setgid setgroups setregid setreuid setuid stat \ + telldir truncate + +NEW_FUNCTIONS:=regcomp posix_regcomp \ + regerror posix_regerror \ + regexec posix_regexec \ + regfree posix_regfree \ + open _open64 \ + acl _acl32 \ + aclcheck _aclcheck32 \ + aclfrommode _aclfrommode32 \ + aclfrompbits _aclfrompbits32 \ + aclfromtext _aclfromtext32 \ + aclsort _aclsort32 \ + acltomode _acltomode32 \ + acltopbits _acltopbits32 \ + acltotext _acltotext32 \ + chown _chown32 \ + facl _facl32 \ + fchown _fchown32 \ + fdopen _fdopen64 \ + fgetpos _fgetpos64 \ + fopen _fopen64 \ + freopen _freopen64 \ + fseeko _fseeko64 \ + fsetpos _fsetpos64 \ + fstat _fstat64 \ + ftello _ftello64 \ + ftruncate _ftruncate64 \ + getegid _getegid32 \ + geteuid _geteuid32 \ + getgid _getgid32 \ + getgrent _getgrent32 \ + getgrgid _getgrgid32 \ + getgrnam _getgrnam32 \ + getgroups _getgroups32 \ + getpwuid _getpwuid32 \ + getpwuid_r _getpwuid_r32 \ + getuid _getuid32 \ + initgroups _initgroups32 \ + lchown _lchown32 \ + lseek _lseek64 \ + lstat _lstat64 \ + mknod _mknod32 \ + mmap _mmap64 \ + seekdir _seekdir64 \ + setegid _setegid32 \ + seteuid _seteuid32 \ + setgid _setgid32 \ + setgroups _setgroups32 \ + setregid _setregid32 \ + setreuid _setreuid32 \ + setuid _setuid32 \ + stat _stat64 \ + telldir _telldir64 \ + truncate _truncate64 + +API_VER:=$(srcdir)/include/cygwin/version.h + +PWD:=${shell pwd} +LIB_NAME:=$(PWD)/libcygwin.a +LIBSERVER:=@LIBSERVER@ +SUBLIBS:=$(PWD)/libpthread.a $(PWD)/libm.a $(PWD)/libc.a +EXTRALIBS:=libautomode.a libbinmode.a libtextmode.a +INSTOBJS:=automode.o binmode.o textmode.o +TARGET_LIBS:=$(LIB_NAME) $(CYGWIN_START) $(GMON_START) $(LIBGMON_A) $(SUBLIBS) $(INSTOBJS) $(EXTRALIBS) +.PHONY: all force dll_ofiles install all_target install_target all_host install_host \ + install install-libs install-headers -lgcc + +.SUFFIXES: +.SUFFIXES: .c .cc .def .a .o .d .s + +all_host=@all_host@ +install_host=@install_host@ + +all: all_target $(all_host) + +all_target: $(TARGET_LIBS) + +all_host: $(TEST_LIB_NAME) + +force: + +install: install-libs install-headers install-man install_target \ + $(install_host) $(install_target) + +uninstall: uninstall-libs uninstall-headers uninstall-man + +install-libs: $(TARGET_LIBS) + $(INSTALL_PROGRAM) $(TEST_DLL_NAME) $(bindir)/$(DLL_NAME); \ + for i in $^; do \ + $(INSTALL_DATA) $$i $(tooldir)/lib/`basename $$i` ; \ + done + +install-headers: + cd $(srcdir); \ + for sub in `find include -name '[a-z]*' -type d -print | sort`; do \ + for i in $$sub/*.h ; do \ + $(INSTALL_DATA) $$i $(tooldir)/$$sub/`basename $$i` ; \ + done ; \ + done ; \ + $(INSTALL_DATA) regex/regex.h $(tooldir)/include/regex.h + +install-man: + cd $(srcdir); \ + for i in `find . -type f -name '*.2'`; do \ + $(INSTALL_DATA) $$i $(tooldir)/man/man2/`basename $$i` ; \ + done; \ + for i in `find . -type f -name '*.3'`; do \ + $(INSTALL_DATA) $$i $(tooldir)/man/man3/`basename $$i` ; \ + done; \ + for i in `find . -type f -name '*.5'`; do \ + $(INSTALL_DATA) $$i $(tooldir)/man/man5/`basename $$i` ; \ + done; \ + for i in `find . -type f -name '*.7'`; do \ + $(INSTALL_DATA) $$i $(tooldir)/man/man7/`basename $$i` ; \ + done + +install_target: + +install_host: + + +uninstall-libs: $(TARGET_LIBS) + rm -f $(bindir)/$(DLL_NAME); \ + for i in $^; do \ + rm -f $(tooldir)/lib/$$i ; \ + done + +uninstall-headers: + cd $(srcdir); \ + for sub in `find include -name '[a-z]*' -type d -print | sort`; do \ + for i in $$sub/*.h ; do \ + rm -f $(tooldir)/$$sub/`basename $$i` ; \ + done ; \ + done ; \ + rm -f $(tooldir)/include/regex.h + +uninstall-man: + cd $(srcdir); \ + for i in `find . -type f -name '*.2'`; do \ + rm -f $(tooldir)/man/man2/`basename $$i` ; \ + done; \ + for i in `find . -type f -name '*.3'`; do \ + rm -f $(tooldir)/man/man3/`basename $$i` ; \ + done; \ + for i in `find . -type f -name '*.5'`; do \ + rm -f $(tooldir)/man/man5/`basename $$i` ; \ + done; \ + for i in `find . -type f -name '*.7'`; do \ + rm -f $(tooldir)/man/man7/`basename $$i` ; \ + done + +clean: + -rm -f *.o *.dll *.a *.exp junk *.base version.cc regexp/*.o winver_stamp *.exe *.d *stamp* *_magic.h + +maintainer-clean realclean: clean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + -rm -fr configure + + +# Rule to build cygwin.dll +$(TEST_DLL_NAME): $(LDSCRIPT) $(DLL_OFILES) $(DEF_FILE) $(DLL_IMPORTS) $(LIBSERVER) $(LIBC) $(LIBM) $(API_VER) Makefile winver_stamp + $(CXX) $(CXXFLAGS) $(nostdlib) -Wl,-T$(firstword $^) -Wl,--out-implib,cygdll.a -shared -o $@ \ + -e $(DLL_ENTRY) $(DEF_FILE) $(DLL_OFILES) version.o winver.o \ + $(MALLOC_OBJ) $(LIBSERVER) $(LIBM) $(LIBC) \ + -lgcc $(DLL_IMPORTS) + @ln -f $@ new-$(DLL_NAME) + +# Rule to build libcygwin.a +$(LIB_NAME): rmsym newsym $(TEST_DLL_NAME) $(LIBCOS) + /bin/sh ${word 1,$^} ./cygdll.a "$(NM)" "$(AR)" $(OBSOLETE_FUNCTIONS) || exit 0 + /bin/sh ${word 2,$^} ./cygdll.a "$(AS)" "$(AR)" $(NEW_FUNCTIONS) || exit 0 + (echo create $(LIB_NAME); echo addmod $(LIBCOS); echo addlib cygdll.a; echo save) | $(AR) -M + $(RANLIB) $@ + +# Rule to make stub library used by testsuite +# dependency set to $(LIB_NAME) to accommodate make -j2. +# Otherwise dlltool gets confused. cgf (11-16-2000) +$(TEST_LIB_NAME): $(LIB_NAME) + perl -p -e 'BEGIN{binmode(STDIN); binmode(STDOUT);}; s/cygwin1/cygwin0/g' < $? > $@ + +dll_ofiles: $(DLL_OFILES) + +$(LIBGMON_A): $(GMON_OFILES) $(GMON_START) + $(AR) rcv $(LIBGMON_A) $(GMON_OFILES) + +$(API_VER): $(srcdir)/cygwin.din + @echo Error: Version info is older than DLL API! + @false + +version.cc winver.o: winver_stamp + @ : + +shared_info_magic.h: cygmagic shared_info.h + /bin/sh ${word 1,$^} $@ "$(CC) -x c" ${word 2,$^} MOUNT_MAGIC 'class mount_info' SHARED_MAGIC 'class shared_info' + +child_info_magic.h: cygmagic child_info.h + /bin/sh ${word 1,$^} $@ "$(CC) -x c" ${word 2,$^} CHILD_INFO_MAGIC 'class child_info' + +dcrt0.o sigproc.o: child_info_magic.h + +shared.o: shared_info_magic.h + +$(PWD)/libpthread.a: speclib $(LIB_NAME) pthread.o thread.o + /bin/sh ${word 1, $^} $@ "${NM}" "$(AR)" ${wordlist 2, 99, $^} + +$(PWD)/libm.a: speclib $(LIB_NAME) $(LIBM) + /bin/sh ${word 1, $^} $@ "${NM}" "$(AR)" ${wordlist 2, 99, $^} + +$(PWD)/libc.a: speclib $(LIB_NAME) $(PWD)/libm.a libpthread.a + /bin/sh ${word 1, $^} -v $@ "${NM}" "$(AR)" ${wordlist 2, 99, $^} + +lib%.a: %.o + $(AR) cru $@ $? + +winver_stamp: mkvers.sh include/cygwin/version.h winver.rc $(DLL_OFILES) + @echo "Making version.o and winver.o";\ + $(SHELL) ${word 1,$^} ${word 2,$^} ${word 3,$^} $(WINDRES) && \ + $(COMPILE_CXX) -o version.o version.cc && \ + touch $@ + +-lgcc: + : + +# + +Makefile: cygwin.din + +$(DEF_FILE): cygwin.din config.status + $(SHELL) config.status + +winsup.h: config.h + +deps:=${wildcard *.d} +ifneq (,$(deps)) +include $(deps) +endif diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din new file mode 100644 index 00000000000..a61edbdb678 --- /dev/null +++ b/winsup/cygwin/cygwin.din @@ -0,0 +1,1525 @@ +LIBRARY "cygwin1.dll" BASE=0x61000000 + +EXPORTS +__argc DATA +__argv DATA +__check_rhosts_file DATA +__cygwin_environ DATA +__cygwin_user_data DATA +__mb_cur_max DATA +__progname DATA +__rcmd_errstr DATA +_check_for_executable DATA +_ctype_ DATA +_daylight DATA +_sys_errlist DATA +sys_errlist = _sys_errlist DATA +_sys_nerr DATA +sys_nerr = _sys_nerr DATA +_timezone DATA +_tzname DATA +h_errno DATA +optarg DATA +opterr DATA +optind DATA +optopt DATA +optreset DATA +reent_data DATA +@ALLOCA@ +@DEF_DLL_ENTRY@ +__assert +__assertfail +__eprintf +__errno +__fpclassifyd +__fpclassifyf +__getreent +__infinity +__main +__signbitd +__signbitf +__signgam +__srget +__swbuf +_asprintf_r +asprintf_r = _asprintf_r +_dll_crt0@0 +_exit +_f_atan2 +__f_atan2 = _f_atan2 +_f_atan2f +__f_atan2f = _f_atan2f +_f_exp +__f_exp = _f_exp +_f_expf +__f_expf = _f_expf +_f_frexp +__f_frexp = _f_frexp +_f_frexpf +__f_frexpf = _f_frexpf +_f_ldexp +__f_ldexp = _f_ldexp +_f_ldexpf +__f_ldexpf = _f_ldexpf +_f_log +__f_log = _f_log +_f_log10 +__f_log10 = _f_log10 +_f_log10f +__f_log10f = _f_log10f +_f_logf +__f_logf = _f_logf +_f_pow +__f_pow = _f_pow +_f_powf +__f_powf = _f_powf +_f_tan +__f_tan = _f_tan +_f_tanf +__f_tanf = _f_tanf +_fcloseall_r +fcloseall_r = _fcloseall_r +_fscanf_r +fscanf_r = _fscanf_r +fstat +_fstat = fstat +_pipe +_pthread_cleanup_pop +_pthread_cleanup_push +_scanf_r +scanf_r = _scanf_r +_sscanf_r +sscanf_r = _sscanf_r +stat +_stat = stat +_strtold +trunc +_vasprintf_r +vasprintf_r = _vasprintf_r +_vfscanf_r +vfscanf_r = _vfscanf_r +_vscanf_r +vscanf_r = _vscanf_r +_vsscanf_r +vsscanf_r = _vsscanf_r +a64l +abort +_abort = abort +abs +_abs = abs +access +_access = access +acl +_acl = acl +_acl32 = acl32 +aclcheck +_aclcheck = aclcheck +_aclcheck32 = aclcheck32 +aclfrommode +_aclfrommode = aclfrommode +_aclfrommode32 = aclfrommode32 +aclfrompbits +_aclfrompbits = aclfrompbits +_aclfrompbits32 = aclfrompbits32 +aclfromtext +_aclfromtext = aclfromtext +_aclfromtext32 = aclfromtext32 +aclsort +_aclsort = aclsort +_aclsort32 = aclsort32 +acltomode +_acltomode = acltomode +_acltomode32 = acltomode32 +acltopbits +_acltopbits = acltopbits +_acltopbits32 = acltopbits32 +acltotext +_acltotext = acltotext +_acltotext32 = acltotext32 +acos +_acos = acos +acosf +_acosf = acosf +acosh +_acosh = acosh +acoshf +_acoshf = acoshf +alarm +_alarm = alarm +alphasort +_alphasort = alphasort +argz_add +__argz_add = argz_add +argz_add_sep +__argz_add_sep = argz_add_sep +argz_append +__argz_append = argz_append +argz_count +__argz_count = argz_count +argz_create +__argz_create = argz_create +argz_create_sep +__argz_create_sep = argz_create_sep +argz_delete +__argz_delete = argz_delete +argz_extract +__argz_extract = argz_extract +argz_insert +__argz_insert = argz_insert +argz_next +__argz_next = argz_next +argz_replace +__argz_replace = argz_replace +argz_stringify +__argz_stringify = argz_stringify +asctime +_asctime = asctime +asctime_r +_asctime_r = asctime_r +asin +_asin = asin +asinf +_asinf = asinf +asinh +_asinh = asinh +asinhf +_asinhf = asinhf +asprintf +_asprintf = asprintf +atan +_atan = atan +atan2 +_atan2 = atan2 +atan2f +_atan2f = atan2f +atanf +_atanf = atanf +atanh +_atanh = atanh +atanhf +_atanhf = atanhf +atexit = cygwin_atexit +_atexit = cygwin_atexit +atof +_atof = atof +atoff +_atoff = atoff +atoi +_atoi = atoi +atol +_atol = atol +bcmp +_bcmp = bcmp +bcopy +_bcopy = bcopy +bsearch +_bsearch = bsearch +btowc +bzero +_bzero = bzero +cabs +_cabs = cabs +cabsf +_cabsf = cabsf +calloc +_calloc = calloc +cbrt +_cbrt = cbrt +cbrtf +_cbrtf = cbrtf +ceil +_ceil = ceil +ceilf +_ceilf = ceilf +cfgetispeed +cfgetospeed +cfsetispeed +cfsetospeed +chdir +_chdir = chdir +chmod +_chmod = chmod +chown +_chown = chown +_chown32 = chown32 +chroot +_chroot = chroot +cleanup_glue +clearerr +_clearerr = clearerr +clock +_clock = clock +close +_close = close +closedir +_closedir = closedir +closelog +_closelog = closelog +copysign +_copysign = copysign +copysignf +_copysignf = copysignf +cos +_cos = cos +cosf +_cosf = cosf +cosh +_cosh = cosh +coshf +_coshf = coshf +creat +_creat = creat +ctermid +ctime +_ctime = ctime +ctime_r +_ctime_r = ctime_r +cuserid +_cuserid = cuserid +cwait +_cwait = cwait +accept = cygwin_accept +cygwin_attach_handle_to_fd +cygwin32_attach_handle_to_fd = cygwin_attach_handle_to_fd +bind = cygwin_bind +connect = cygwin_connect +cygwin_conv_to_full_posix_path +cygwin32_conv_to_full_posix_path = cygwin_conv_to_full_posix_path +cygwin_conv_to_full_win32_path +cygwin32_conv_to_full_win32_path = cygwin_conv_to_full_win32_path +cygwin_conv_to_posix_path +cygwin32_conv_to_posix_path = cygwin_conv_to_posix_path +cygwin_conv_to_win32_path +cygwin32_conv_to_win32_path = cygwin_conv_to_win32_path +cygwin_detach_dll +cygwin32_detach_dll = cygwin_detach_dll +cygwin_dll_init +endprotoent = cygwin_endprotoent +endservent = cygwin_endservent +endusershell +gethostbyaddr = cygwin_gethostbyaddr +gethostbyname = cygwin_gethostbyname +_gethostname = cygwin_gethostname +gethostname = cygwin_gethostname +getpeername = cygwin_getpeername +getprotobyname = cygwin_getprotobyname +getprotobynumber = cygwin_getprotobynumber +getprotoent = cygwin_getprotoent +getservbyname = cygwin_getservbyname +getservbyport = cygwin_getservbyport +getservent = cygwin_getservent +getsockname = cygwin_getsockname +getsockopt = cygwin_getsockopt +getusershell +herror = cygwin_herror +hstrerror = cygwin_hstrerror +inet_addr = cygwin_inet_addr +inet_aton = cygwin_inet_aton +inet_network = cygwin_inet_network +inet_ntoa = cygwin_inet_ntoa +cygwin_internal +cygwin32_internal = cygwin_internal +listen = cygwin_listen +cygwin_logon_user +lstat +_lstat = lstat +cygwin_posix_path_list_p +cygwin32_posix_path_list_p = cygwin_posix_path_list_p +cygwin_posix_to_win32_path_list +cygwin32_posix_to_win32_path_list = cygwin_posix_to_win32_path_list +cygwin_posix_to_win32_path_list_buf_size +cygwin32_posix_to_win32_path_list_buf_size = cygwin_posix_to_win32_path_list_buf_size +rcmd = cygwin_rcmd +recv = cygwin_recv +recvfrom = cygwin_recvfrom +recvmsg = cygwin_recvmsg +rexec = cygwin_rexec +rresvport = cygwin_rresvport +_select = cygwin_select +select = cygwin_select +send = cygwin_send +sendmsg = cygwin_sendmsg +sendto = cygwin_sendto +cygwin_set_impersonation_token +setprotoent = cygwin_setprotoent +setservent = cygwin_setservent +setsockopt = cygwin_setsockopt +setusershell +shutdown = cygwin_shutdown +socket = cygwin_socket +cygwin_split_path +cygwin32_split_path = cygwin_split_path +cygwin_stackdump +cygwin_umount +cygwin_win32_to_posix_path_list +cygwin32_win32_to_posix_path_list = cygwin_win32_to_posix_path_list +cygwin_win32_to_posix_path_list_buf_size +cygwin32_win32_to_posix_path_list_buf_size = cygwin_win32_to_posix_path_list_buf_size +cygwin_winpid_to_pid +cygwin32_winpid_to_pid = cygwin_winpid_to_pid +daemon +difftime +_difftime = difftime +dirfd +_dirfd = dirfd +div +_div = div +dlclose +dlerror +dlfork +dll_crt0__FP11per_process +dll_dllcrt0 +dll_noncygwin_dllcrt0 +dlopen +dlsym +drand48 +_drand48 = drand48 +drem +_drem = drem +dremf +_dremf = dremf +dup +_dup = dup +dup2 +_dup2 = dup2 +ecvt +_ecvt = ecvt +ecvtbuf +_ecvtbuf = ecvtbuf +ecvtf +_ecvtf = ecvtf +endgrent +_endgrent = endgrent +endhostent +endmntent +_endmntent = endmntent +endpwent +_endpwent = endpwent +endutent +_endutent = endutent +envz_add +__envz_add = envz_add +envz_entry +__envz_entry = envz_entry +envz_get +__envz_get = envz_get +envz_merge +__envz_merge = envz_merge +envz_remove +__envz_remove = envz_remove +envz_strip +__envz_strip = envz_strip +erand48 +_erand48 = erand48 +erf +_erf = erf +erfc +_erfc = erfc +erfcf +_erfcf = erfcf +erff +_erff = erff +execl +_execl = execl +execle +_execle = execle +execlp +_execlp = execlp +execv +_execv = execv +execve +_execve = execve +execvp +_execvp = execvp +exit = cygwin_exit +exp +_exp = exp +exp2 +exp2f +expf +_expf = expf +expm1 +_expm1 = expm1 +expm1f +_expm1f = expm1f +fabs +_fabs = fabs +fabsf +_fabsf = fabsf +facl +_facl = facl +_facl32 = facl32 +fchdir +_fchdir = fchdir +fchmod +_fchmod = fchmod +fchown +_fchown = fchown +_fchown32 = fchown32 +fclose +_fclose = fclose +fcloseall +_fcloseall = fcloseall +fcntl +_fcntl = fcntl +fcvt +_fcvt = fcvt +fcvtbuf +_fcvtbuf = fcvtbuf +fcvtf +_fcvtf = fcvtf +fdim +fdimf +fdopen +_fdopen = fdopen +_fdopen64 = fdopen64 +feof +_feof = feof +ferror +_ferror = ferror +fflush +_fflush = fflush +ffs +_ffs = ffs +fgetc +_fgetc = fgetc +fgetpos +_fgetpos = fgetpos +_fgetpos64 = fgetpos64 +fgets +_fgets = fgets +fileno +_fileno = fileno +finite +_finite = finite +finitef +_finitef = finitef +fiprintf +_fiprintf = fiprintf +floor +_floor = floor +floorf +_floorf = floorf +fma +fmaf +fmax +fmaxf +fmin +fminf +fmod +_fmod = fmod +fmodf +_fmodf = fmodf +fnmatch +_fnmatch = fnmatch +fopen +_fopen = fopen +_fopen64 = fopen64 +fork +_fork = fork +forkpty +fpathconf +fprintf +_fprintf = fprintf +fputc +_fputc = fputc +fputs +_fputs = fputs +fread +_fread = fread +free +_free = free +freopen +_freopen = freopen +_freopen64 = freopen64 +frexp +_frexp = frexp +frexpf +_frexpf = frexpf +fscanf +_fscanf = fscanf +fseek +_fseek = fseek +fseeko +_fseeko = fseeko +_fseeko64 = fseeko64 +fsetpos +_fsetpos = fsetpos +_fsetpos64 = fsetpos64 +_fstat64 = fstat64 +fstatfs +_fstatfs = fstatfs +fsync +_fsync = fsync +ftell +_ftell = ftell +ftello +_ftello = ftello +_ftello64 = ftello64 +ftime +_ftime = ftime +ftok +_ftok = ftok +ftruncate +_ftruncate = ftruncate +_ftruncate64 = ftruncate64 +fwrite +_fwrite = fwrite +gamma +_gamma = gamma +gamma_r +_gamma_r = gamma_r +gammaf +_gammaf = gammaf +gammaf_r +_gammaf_r = gammaf_r +gcvt +_gcvt = gcvt +gcvtf +_gcvtf = gcvtf +get_osfhandle +_get_osfhandle = get_osfhandle +getc +_getc = getc +getc_unlocked +_getc_unlocked = getc_unlocked +getchar +_getchar = getchar +getchar_unlocked +_getchar_unlocked = getchar_unlocked +getcwd +_getcwd = getcwd +getdomainname +_getdomainname = getdomainname +getdtablesize +_getdtablesize = getdtablesize +getegid +_getegid = getegid +_getegid32 = getegid32 +getenv +_getenv = getenv +geteuid +_geteuid = geteuid +_geteuid32 = geteuid32 +getgid +_getgid = getgid +_getgid32 = getgid32 +getgrent +_getgrent = getgrent +_getgrent32 = getgrent32 +getgrgid +_getgrgid = getgrgid +_getgrgid32 = getgrgid32 +getgrnam +_getgrnam = getgrnam +_getgrnam32 = getgrnam32 +getgroups +_getgroups = getgroups +_getgroups32 = getgroups32 +gethostid +getitimer +getlogin +_getlogin = getlogin +getmntent +_getmntent = getmntent +getmode +_getmode = getmode +getopt +getopt_long +getpagesize +_getpagesize = getpagesize +getpass +_getpass = getpass +getpgid +getpgrp +_getpgrp = getpgrp +getpid +_getpid = getpid +getppid +_getppid = getppid +getpwduid +_getpwduid = getpwduid +getpwent +_getpwent = getpwent +getpwnam +_getpwnam = getpwnam +getpwnam_r +getpwuid +_getpwuid = getpwuid +_getpwuid32 = getpwuid32 +getpwuid_r +_getpwuid_r32 = getpwuid_r32 +getrlimit +_getrlimit = getrlimit +getrusage +_getrusage = getrusage +gets +_gets = gets +getsid +gettimeofday +_gettimeofday = gettimeofday +getuid +_getuid = getuid +_getuid32 = getuid32 +getutent +_getutent = getutent +getutid +_getutid = getutid +getutline +_getutline = getutline +getw +_getw = getw +getwd +_getwd = getwd +glob +_glob = glob +globfree +_globfree = globfree +gmtime +_gmtime = gmtime +gmtime_r +_gmtime_r = gmtime_r +grantpt +hcreate +hcreate_r +hdestroy +hdestroy_r +hsearch +hsearch_r +htonl +_htonl = htonl +htons +_htons = htons +hypot +_hypot = hypot +hypotf +_hypotf = hypotf +ilogb +_ilogb = ilogb +ilogbf +_ilogbf = ilogbf +index +_index = index +inet_makeaddr +inet_netof +infinity +_infinity = infinity +infinityf +_infinityf = infinityf +initgroups +_initgroups32 = initgroups32 +initstate +ioctl +_ioctl = ioctl +iprintf +_iprintf = iprintf +iruserok +ruserok +isalnum +_isalnum = isalnum +isalpha +_isalpha = isalpha +isascii +_isascii = isascii +isatty +_isatty = isatty +isblank +iscntrl +_iscntrl = iscntrl +isdigit +_isdigit = isdigit +isgraph +_isgraph = isgraph +isinf +_isinf = isinf +isinff +_isinff = isinff +islower +_islower = islower +isnan +_isnan = isnan +isnanf +_isnanf = isnanf +isprint +_isprint = isprint +ispunct +_ispunct = ispunct +isspace +_isspace = isspace +isupper +_isupper = isupper +iswalnum +iswalpha +iswblank +iswcntrl +iswctype +iswdigit +iswgraph +iswlower +iswprint +iswpunct +iswspace +iswupper +iswxdigit +isxdigit +_isxdigit = isxdigit +j0 +_j0 = j0 +j0f +_j0f = j0f +j1 +_j1 = j1 +j1f +_j1f = j1f +jn +_jn = jn +jnf +_jnf = jnf +jrand48 +_jrand48 = jrand48 +kill +_kill = kill +killpg +l64a +labs +_labs = labs +lacl +_lacl = lacl +lchown +_lchown = lchown +_lchown32 = lchown32 +lcong48 +_lcong48 = lcong48 +ldexp +_ldexp = ldexp +ldexpf +_ldexpf = ldexpf +ldiv +_ldiv = ldiv +lgamma +_lgamma = lgamma +lgamma_r +_lgamma_r = lgamma_r +lgammaf +_lgammaf = lgammaf +lgammaf_r +_lgammaf_r = lgammaf_r +link +_link = link +localeconv +_localeconv = localeconv +localtime +_localtime = localtime +localtime_r +_localtime_r = localtime_r +log +_log = log +log10 +_log10 = log10 +log10f +_log10f = log10f +log1p +_log1p = log1p +log1pf +_log1pf = log1pf +logb +_logb = logb +logbf +_logbf = logbf +logf +_logf = logf +login +login_tty +logout +logwtmp +updwtmp +longjmp +_longjmp = longjmp +lrand48 +_lrand48 = lrand48 +lrint +lrintf +lround +lroundf +lseek +_lseek = lseek +_lseek64 = lseek64 +_lstat64 = lstat64 +mallinfo +malloc +_malloc = malloc +malloc_stats +malloc_trim +malloc_usable_size +mallopt +matherr +_matherr = matherr +mblen +_mblen = mblen +mbrlen +mbrtowc +mbsinit +mbsrtowcs +mbstowcs +_mbstowcs = mbstowcs +mbtowc +_mbtowc = mbtowc +memalign +memccpy +_memccpy = memccpy +memchr +_memchr = memchr +memcmp +_memcmp = memcmp +memcpy +_memcpy = memcpy +memmove +_memmove = memmove +mempcpy +__mempcpy = mempcpy +memset +_memset = memset +mkdir +_mkdir = mkdir +mkfifo +mknod +_mknod = mknod +_mknod32 = mknod32 +mkstemp +_mkstemp = mkstemp +mktemp +_mktemp = mktemp +mktime +_mktime = mktime +mmap +_mmap64 = mmap64 +modf +_modf = modf +modff +_modff = modff +mount +_mount = mount +mprotect +mrand48 +msync +munmap +nan +_nan = nan +nanf +_nanf = nanf +nanosleep +_nanosleep = nanosleep +nearbyint +nearbyintf +nextafter +_nextafter = nextafter +nextafterf +_nextafterf = nextafterf +nice +_nice = nice +nl_langinfo +_nl_langinfo = nl_langinfo +nrand48 +_nrand48 = nrand48 +ntohl +_ntohl = ntohl +ntohs +_ntohs = ntohs +on_exit +open +_open = open +_open64 +opendir +_opendir = opendir +openlog +_openlog = openlog +openpty +pathconf +_pathconf = pathconf +pause +pclose +_pclose = pclose +perror +_perror = perror +pipe +poll +_poll = poll +popen +_popen = popen +posix_regcomp +posix_regerror +posix_regexec +posix_regfree +pow +_pow = pow +powf +_powf = powf +printf +_printf = printf +pthread_atfork +pthread_attr_destroy +pthread_attr_getdetachstate +pthread_attr_getinheritsched +pthread_attr_getschedparam +pthread_attr_getschedpolicy +pthread_attr_getscope +pthread_attr_getstacksize +pthread_attr_init +pthread_attr_setdetachstate +pthread_attr_setinheritsched +pthread_attr_setschedparam +pthread_attr_setschedpolicy +pthread_attr_setscope +pthread_attr_setstacksize +pthread_cancel +pthread_cond_broadcast +pthread_cond_destroy +pthread_cond_init +pthread_cond_signal +pthread_cond_timedwait +pthread_cond_wait +pthread_condattr_destroy +pthread_condattr_getpshared +pthread_condattr_init +pthread_condattr_setpshared +pthread_continue +pthread_create +pthread_detach +pthread_equal +pthread_exit +pthread_getconcurrency +pthread_getschedparam +pthread_getsequence_np +pthread_getspecific +pthread_join +pthread_key_create +pthread_key_delete +pthread_kill +pthread_mutex_destroy +pthread_mutex_getprioceiling +pthread_mutex_init +pthread_mutex_lock +pthread_mutex_setprioceiling +pthread_mutex_trylock +pthread_mutex_unlock +pthread_mutexattr_destroy +pthread_mutexattr_getprioceiling +pthread_mutexattr_getprotocol +pthread_mutexattr_getpshared +pthread_mutexattr_gettype +pthread_mutexattr_init +pthread_mutexattr_setprioceiling +pthread_mutexattr_setprotocol +pthread_mutexattr_setpshared +pthread_mutexattr_settype +pthread_once +pthread_rwlock_destroy +pthread_rwlock_init +pthread_rwlock_rdlock +pthread_rwlock_tryrdlock +pthread_rwlock_wrlock +pthread_rwlock_trywrlock +pthread_rwlock_unlock +pthread_rwlockattr_init +pthread_rwlockattr_getpshared +pthread_rwlockattr_setpshared +pthread_rwlockattr_destroy +pthread_self +pthread_setcancelstate +pthread_setcanceltype +pthread_setconcurrency +pthread_setschedparam +pthread_setspecific +pthread_sigmask +pthread_suspend +pthread_testcancel +ptsname +putc +_putc = putc +putc_unlocked +_putc_unlocked = putc_unlocked +putchar +_putchar = putchar +putchar_unlocked +_putchar_unlocked = putchar_unlocked +putenv +_putenv = putenv +puts +_puts = puts +pututline +_pututline = pututline +putw +_putw = putw +qsort +_qsort = qsort +raise +_raise = raise +rand +_rand = rand +random +read +_read = read +readdir +_readdir = readdir +readlink +_readlink = readlink +readv +_readv = readv +realloc +_realloc = realloc +realpath +remainder +_remainder = remainder +remainderf +_remainderf = remainderf +remove +_remove = remove +remquo +remquof +rename +_rename = rename +revoke +rewind +_rewind = rewind +rewinddir +_rewinddir = rewinddir +rindex +_rindex = rindex +rint +_rint = rint +rintf +_rintf = rintf +rmdir +_rmdir = rmdir +round +roundf +sbrk +_sbrk = sbrk +scalb +_scalb = scalb +scalbf +_scalbf = scalbf +scalbln +scalblnf +scalbn +_scalbn = scalbn +scalbnf +_scalbnf = scalbnf +scandir +_scandir = scandir +scanf +_scanf = scanf +sched_get_priority_max +sched_get_priority_min +sched_getparam +sched_getscheduler +sched_rr_get_interval +sched_setparam +sched_setscheduler +sched_yield +seed48 +_seed48 = seed48 +seekdir +_seekdir = seekdir +_seekdir64 = seekdir64 +sem_destroy +sem_init +sem_post +sem_trywait +sem_wait +setbuf +_setbuf = setbuf +setbuffer +setdtablesize +_setdtablesize = setdtablesize +setegid +_setegid = setegid +_setegid32 = setegid32 +setenv +_setenv = setenv +seteuid +_seteuid = seteuid +_seteuid32 = seteuid32 +setgid +_setgid = setgid +_setgid32 = setgid32 +setgrent +_setgrent = setgrent +setgroups +_setgroups = setgroups +_setgroups32 = setgroups32 +sethostent +setitimer +setjmp +_setjmp = setjmp +setlinebuf +setlocale +_setlocale = setlocale +setlogmask +setmntent +_setmntent = setmntent +setmode +_setmode = setmode +setpassent +_setpassent = setpassent +setpgid +_setpgid = setpgid +setpgrp +_setpgrp = setpgrp +setpwent +_setpwent = setpwent +setregid +_setregid = setregid +setregid32 +_setregid32 = setregid32 +setreuid +_setreuid = setreuid +setreuid32 +_setreuid32 = setreuid32 +setrlimit +_setrlimit = setrlimit +setsid +_setsid = setsid +setstate +settimeofday +_settimeofday = settimeofday +setuid +_setuid = setuid +_setuid32 = setuid32 +setutent +_setutent = setutent +setvbuf +_setvbuf = setvbuf +sexecl = sexecve_is_bad +sexecle = sexecve_is_bad +sexeclp = sexecve_is_bad +sexeclpe = sexecve_is_bad +sexecp = sexecve_is_bad +sexecv = sexecve_is_bad +sexecve = sexecve_is_bad +sexecvpe = sexecve_is_bad +sigaction +_sigaction = sigaction +sigaddset +_sigaddset = sigaddset +sigdelset +_sigdelset = sigdelset +sigemptyset +_sigemptyset = sigemptyset +sigfillset +_sigfillset = sigfillset +siginterrupt +_siginterrupt = siginterrupt +sigismember +_sigismember = sigismember +signal +_signal = signal +significand +_significand = significand +significandf +_significandf = significandf +sigpause +sigpending +_sigpending = sigpending +sigprocmask +_sigprocmask = sigprocmask +sigsuspend +_sigsuspend = sigsuspend +sin +_sin = sin +sincos +sincosf +sinf +_sinf = sinf +sinh +_sinh = sinh +sinhf +_sinhf = sinhf +siprintf +_siprintf = siprintf +sleep +_sleep = sleep +snprintf +_snprintf = snprintf +socketpair +spawnl +_spawnl = spawnl +spawnle +_spawnle = spawnle +spawnlp +_spawnlp = spawnlp +spawnlpe +_spawnlpe = spawnlpe +spawnv +_spawnv = spawnv +spawnve +_spawnve = spawnve +spawnvp +_spawnvp = spawnvp +spawnvpe +_spawnvpe = spawnvpe +sprintf +_sprintf = sprintf +sqrt +_sqrt = sqrt +sqrtf +_sqrtf = sqrtf +srand +_srand = srand +srand48 +_srand48 = srand48 +srandom +sscanf +_sscanf = sscanf +_stat64 = stat64 +statfs +_statfs = statfs +strcasecmp +_strcasecmp = strcasecmp +strcat +_strcat = strcat +strchr +_strchr = strchr +strcmp +_strcmp = strcmp +strcoll +_strcoll = strcoll +strcpy +_strcpy = strcpy +strcspn +_strcspn = strcspn +strdup +_strdup = strdup +strerror +_strerror = strerror +strerror_r +_strerror_r = strerror_r +strftime +_strftime = strftime +strlcat +_strlcat = strlcat +strlcpy +_strlcpy = strlcpy +strlen +_strlen = strlen +strlwr +_strlwr = strlwr +strncasecmp +_strncasecmp = strncasecmp +strncat +_strncat = strncat +strncmp +_strncmp = strncmp +strncpy +_strncpy = strncpy +strndup +strnlen +strpbrk +_strpbrk = strpbrk +strptime +_strptime = strptime +strrchr +_strrchr = strrchr +strsep +_strsep = strsep +strsignal +strspn +_strspn = strspn +strstr +_strstr = strstr +strtod +_strtod = strtod +strtof +_strtodf = strtof +strtodf = strtof +strtok +_strtok = strtok +strtok_r +_strtok_r = strtok_r +strtol +_strtol = strtol +strtoll +_strtoll = strtoll +strtosigno +strtoul +_strtoul = strtoul +strtoull +_strtoull = strtoull +strupr +_strupr = strupr +strxfrm +_strxfrm = strxfrm +swab +_swab = swab +symlink +_symlink = symlink +sync +_sync = sync +sysconf +_sysconf = sysconf +syslog +_syslog = syslog +vsyslog +system +_system = system +tan +_tan = tan +tanf +_tanf = tanf +tanh +_tanh = tanh +tanhf +_tanhf = tanhf +tcdrain +_tcdrain = tcdrain +tcflow +_tcflow = tcflow +tcflush +_tcflush = tcflush +tcgetattr +_tcgetattr = tcgetattr +tcgetpgrp +_tcgetpgrp = tcgetpgrp +tcsendbreak +_tcsendbreak = tcsendbreak +tcsetattr +_tcsetattr = tcsetattr +tcsetpgrp +_tcsetpgrp = tcsetpgrp +tdelete +tdestroy +telldir +_telldir = telldir +_telldir64 = telldir64 +tempnam +_tempnam = tempnam +tfind +tgamma +tgammaf +time +_time = time +times +_times = times +timezone +tmpfile +_tmpfile = tmpfile +tmpnam +_tmpnam = tmpnam +toascii +_toascii = toascii +tolower +_tolower = tolower +toupper +_toupper = toupper +towctrans +towlower +towupper +truncate +_truncate = truncate +_truncate64 = truncate64 +truncf +tsearch +ttyname +_ttyname = ttyname +ttyslot +twalk +tzset +_tzset = tzset +ualarm +_ualarm = ualarm +umask +_umask = umask +umount +_umount = umount +uname +_uname = uname +ungetc +_ungetc = ungetc +unlink +_unlink = unlink +unlockpt +unsetenv +_unsetenv = unsetenv +usleep +_usleep = usleep +utime +_utime = utime +utimes +_utimes = utimes +utmpname +_utmpname = utmpname +valloc +vasprintf +_vasprintf = vasprintf +vfiprintf +_vfiprintf = vfiprintf +vfork +_vfork = vfork +vfprintf +_vfprintf = vfprintf +vfscanf +_vfscanf = vfscanf +vhangup +_vhangup = vhangup +vprintf +_vprintf = vprintf +vscanf +_vscanf = vscanf +vsnprintf +_vsnprintf = vsnprintf +vsprintf +_vsprintf = vsprintf +vsscanf +_vsscanf = vsscanf +wait +_wait = wait +wait3 +wait4 +waitpid +_waitpid = waitpid +wcrtomb +wcscat +wcschr +wcscmp +_wcscmp = wcscmp +wcscoll +wcscpy +wcscspn +wcslcat +wcslcpy +wcslen +_wcslen = wcslen +wcsncat +wcsncmp +wcsncpy +wcspbrk +wcsrchr +wcsrtombs +wcsspn +wcsstr +wcstombs +_wcstombs = wcstombs +wcswidth +wctob +wctomb +_wctomb = wctomb +wctrans +wctype +wcwidth +wmemchr +wmemcmp +wmemcpy +wmemmove +wmemset +wprintf +_wprintf = wprintf +write +_write = write +writev +_writev = writev +y0 +y0f +y1 +y1f +yn +ynf diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc new file mode 100644 index 00000000000..51cc55f2529 --- /dev/null +++ b/winsup/cygwin/dcrt0.cc @@ -0,0 +1,1166 @@ +/* dcrt0.cc -- essentially the main() for the Cygwin dll + + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 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 <unistd.h> +#include <stdlib.h> +#include "glob.h" +#include "exceptions.h" +#include <ctype.h> +#include <limits.h> +#include <wingdi.h> +#include <winuser.h> +#include "sigproc.h" +#include "pinfo.h" +#include "cygerrno.h" +#define NEED_VFORK +#include "perprocess.h" +#include "security.h" +#include "fhandler.h" +#include "path.h" +#include "dtable.h" +#include "cygheap.h" +#include "child_info_magic.h" +#include "perthread.h" +#include "shared_info.h" +#include "cygwin_version.h" +#include "dll_init.h" +#include "cygthread.h" +#include "sync.h" + +#define MAX_AT_FILE_LEVEL 10 + +#define PREMAIN_LEN (sizeof (user_data->premain) / sizeof (user_data->premain[0])) + +HANDLE NO_COPY hMainProc; +HANDLE NO_COPY hMainThread; + +sigthread NO_COPY mainthread; // ID of the main thread + +per_thread_waitq NO_COPY waitq_storage; +per_thread_vfork NO_COPY vfork_storage; +per_thread_signal_dispatch NO_COPY signal_dispatch_storage; + +per_thread NO_COPY *threadstuff[] = {&waitq_storage, + &vfork_storage, + &signal_dispatch_storage, + NULL}; + +bool display_title; +bool strip_title_path; +bool allow_glob = TRUE; +codepage_type current_codepage = ansi_cp; + +int cygwin_finished_initializing; + +/* Used in SIGTOMASK for generating a bit for insertion into a sigset_t. + This is subtracted from the signal number prior to shifting the bit. + In older versions of cygwin, the signal was used as-is to shift the + bit for masking. So, we'll temporarily detect this and set it to zero + for programs that are linked using older cygwins. This is just a stopgap + measure to allow an orderly transfer to the new, correct sigmask method. */ +unsigned NO_COPY int signal_shift_subtract = 1; + +ResourceLocks _reslock NO_COPY; +MTinterface _mtinterf; + +bool NO_COPY _cygwin_testing; +unsigned NO_COPY _cygwin_testing_magic; + +char NO_COPY almost_null[1]; + +extern "C" +{ + /* This is an exported copy of environ which can be used by DLLs + which use cygwin.dll. */ + char **__cygwin_environ; + char ***main_environ; + /* __progname used in getopt error message */ + char *__progname; + struct _reent reent_data = _REENT_INIT(reent_data); + struct per_process __cygwin_user_data = + {/* initial_sp */ 0, /* magic_biscuit */ 0, + /* dll_major */ CYGWIN_VERSION_DLL_MAJOR, + /* dll_major */ CYGWIN_VERSION_DLL_MINOR, + /* impure_ptr_ptr */ NULL, /* envptr */ NULL, + /* malloc */ malloc, /* free */ free, + /* realloc */ realloc, + /* fmode_ptr */ NULL, /* main */ NULL, /* ctors */ NULL, + /* dtors */ NULL, /* data_start */ NULL, /* data_end */ NULL, + /* bss_start */ NULL, /* bss_end */ NULL, + /* calloc */ calloc, + /* premain */ {NULL, NULL, NULL, NULL}, + /* run_ctors_p */ 0, + /* unused */ {0, 0, 0, 0, 0, 0, 0}, + /* forkee */ 0, + /* hmodule */ NULL, + /* api_major */ CYGWIN_VERSION_API_MAJOR, + /* api_minor */ CYGWIN_VERSION_API_MINOR, + /* unused2 */ {0, 0, 0, 0, 0}, + /* resourcelocks */ &_reslock, /* threadinterface */ &_mtinterf, + /* impure_ptr */ &reent_data, + }; + bool ignore_case_with_glob; + int __declspec (dllexport) _check_for_executable = TRUE; +#ifdef DEBUGGING + int pinger; +#endif +}; + +char *old_title; +char title_buf[TITLESIZE + 1]; + +static void +do_global_dtors (void) +{ + if (user_data->dtors) + { + void (**pfunc)() = user_data->dtors; + while (*++pfunc) + (*pfunc) (); + } +} + +static void __stdcall +do_global_ctors (void (**in_pfunc)(), int force) +{ + if (!force) + { + if (user_data->forkee || user_data->run_ctors_p) + return; // inherit constructed stuff from parent pid + user_data->run_ctors_p = 1; + } + + /* Run ctors backwards, so skip the first entry and find how many + there are, then run them. */ + + void (**pfunc)() = in_pfunc; + + while (*++pfunc) + ; + while (--pfunc > in_pfunc) + (*pfunc) (); + + if (user_data->magic_biscuit == SIZEOF_PER_PROCESS) + atexit (do_global_dtors); +} + +/* + * Replaces @file in the command line with the contents of the file. + * There may be multiple @file's in a single command line + * A \@file is replaced with @file so that echo \@foo would print + * @foo and not the contents of foo. + */ +static int __stdcall +insert_file (char *name, char *&cmd) +{ + HANDLE f; + DWORD size; + + f = CreateFile (name + 1, + GENERIC_READ, /* open for reading */ + FILE_SHARE_READ, /* share for reading */ + &sec_none_nih, /* no security */ + OPEN_EXISTING, /* existing file only */ + FILE_ATTRIBUTE_NORMAL, /* normal file */ + NULL); /* no attr. template */ + + if (f == INVALID_HANDLE_VALUE) + { + debug_printf ("couldn't open file '%s', %E", name); + return FALSE; + } + + /* This only supports files up to about 4 billion bytes in + size. I am making the bold assumption that this is big + enough for this feature */ + size = GetFileSize (f, NULL); + if (size == 0xFFFFFFFF) + { + debug_printf ("couldn't get file size for '%s', %E", name); + return FALSE; + } + + int new_size = strlen (cmd) + size + 2; + char *tmp = (char *) malloc (new_size); + if (!tmp) + { + debug_printf ("malloc failed, %E"); + return FALSE; + } + + /* realloc passed as it should */ + DWORD rf_read; + BOOL rf_result; + rf_result = ReadFile (f, tmp, size, &rf_read, NULL); + CloseHandle (f); + if (!rf_result || (rf_read != size)) + { + debug_printf ("ReadFile failed, %E"); + return FALSE; + } + + tmp[size++] = ' '; + strcpy (tmp + size, cmd); + cmd = tmp; + return TRUE; +} + +static inline int +isquote (char c) +{ + char ch = c; + return ch == '"' || ch == '\''; +} + +/* Step over a run of characters delimited by quotes */ +static /*__inline*/ char * +quoted (char *cmd, int winshell) +{ + char *p; + char quote = *cmd; + + if (!winshell) + { + char *p; + strcpy (cmd, cmd + 1); + if (*(p = strechr (cmd, quote))) + strcpy (p, p + 1); + return p; + } + + const char *s = quote == '\'' ? "'" : "\\\""; + /* This must have been run from a Windows shell, so preserve + quotes for globify to play with later. */ + while (*cmd && *++cmd) + if ((p = strpbrk (cmd, s)) == NULL) + { + cmd = strchr (cmd, '\0'); // no closing quote + break; + } + else if (*p == '\\') + cmd = ++p; + else if (quote == '"' && p[1] == '"') + { + *p = '\\'; + cmd = ++p; // a quoted quote + } + else + { + cmd = p + 1; // point to after end + break; + } + return cmd; +} + +/* Perform a glob on word if it contains wildcard characters. + Also quote every character between quotes to force glob to + treat the characters literally. */ +static int __stdcall +globify (char *word, char **&argv, int &argc, int &argvlen) +{ + if (*word != '~' && strpbrk (word, "?*[\"\'(){}") == NULL) + return 0; + + int n = 0; + char *p, *s; + int dos_spec = isdrive (word); + if (!dos_spec && isquote (*word) && word[1] && word[2]) + dos_spec = isdrive (word + 1); + + /* We'll need more space if there are quoting characters in + word. If that is the case, doubling the size of the + string should provide more than enough space. */ + if (strpbrk (word, "'\"")) + n = strlen (word); + char pattern[strlen (word) + ((dos_spec + 1) * n) + 1]; + + /* Fill pattern with characters from word, quoting any + characters found within quotes. */ + for (p = pattern, s = word; *s != '\000'; s++, p++) + if (!isquote (*s)) + { + if (dos_spec && *s == '\\') + *p++ = '\\'; + *p = *s; + } + else + { + char quote = *s; + while (*++s && *s != quote) + { + if (dos_spec || *s != '\\') + /* nothing */; + else if (s[1] == quote || s[1] == '\\') + s++; + *p++ = '\\'; + *p++ = *s; + } + if (*s == quote) + p--; + if (*s == '\0') + break; + } + + *p = '\0'; + + glob_t gl; + gl.gl_offs = 0; + + /* Attempt to match the argument. Return just word (minus quoting) if no match. */ + if (glob (pattern, GLOB_TILDE | GLOB_NOCHECK | GLOB_BRACE | GLOB_QUOTE, NULL, &gl) || !gl.gl_pathc) + return 0; + + /* Allocate enough space in argv for the matched filenames. */ + n = argc; + if ((argc += gl.gl_pathc) > argvlen) + { + argvlen = argc + 10; + argv = (char **) realloc (argv, (1 + argvlen) * sizeof (argv[0])); + } + + /* Copy the matched filenames to argv. */ + char **gv = gl.gl_pathv; + char **av = argv + n; + while (*gv) + { + debug_printf ("argv[%d] = '%s'", n++, *gv); + *av++ = *gv++; + } + + /* Clean up after glob. */ + free (gl.gl_pathv); + return 1; +} + +/* Build argv, argc from string passed from Windows. */ + +static void __stdcall +build_argv (char *cmd, char **&argv, int &argc, int winshell) +{ + int argvlen = 0; + int nesting = 0; // monitor "nesting" from insert_file + + argc = 0; + argvlen = 0; + argv = NULL; + + /* Scan command line until there is nothing left. */ + while (*cmd) + { + /* Ignore spaces */ + if (issep (*cmd)) + { + cmd++; + continue; + } + + /* Found the beginning of an argument. */ + char *word = cmd; + char *sawquote = NULL; + while (*cmd) + { + if (*cmd != '"' && (!winshell || *cmd != '\'')) + cmd++; // Skip over this character + else + /* Skip over characters until the closing quote */ + { + sawquote = cmd; + cmd = quoted (cmd, winshell && argc > 0); + } + if (issep (*cmd)) // End of argument if space + break; + } + if (*cmd) + *cmd++ = '\0'; // Terminate `word' + + /* Possibly look for @file construction assuming that this isn't + the very first argument and the @ wasn't quoted */ + if (argc && sawquote != word && *word == '@') + { + if (++nesting > MAX_AT_FILE_LEVEL) + api_fatal ("Too many levels of nesting for %s", word); + if (insert_file (word, cmd)) + continue; // There's new stuff in cmd now + } + + /* See if we need to allocate more space for argv */ + if (argc >= argvlen) + { + argvlen = argc + 10; + argv = (char **) realloc (argv, (1 + argvlen) * sizeof (argv[0])); + } + + /* Add word to argv file after (optional) wildcard expansion. */ + if (!winshell || !argc || !globify (word, argv, argc, argvlen)) + { + debug_printf ("argv[%d] = '%s'", argc, word); + argv[argc++] = word; + } + } + + argv[argc] = NULL; + + debug_printf ("argc %d", argc); +} + +/* sanity and sync check */ +void __stdcall +check_sanity_and_sync (per_process *p) +{ + /* Sanity check to make sure developers didn't change the per_process */ + /* struct without updating SIZEOF_PER_PROCESS [it makes them think twice */ + /* about changing it]. */ + if (sizeof (per_process) != SIZEOF_PER_PROCESS) + { + api_fatal ("per_process sanity check failed"); + } + + /* Make sure that the app and the dll are in sync. */ + + /* Complain if older than last incompatible change */ + if (p->dll_major < CYGWIN_VERSION_DLL_EPOCH) + api_fatal ("cygwin DLL and APP are out of sync -- DLL version mismatch %d < %d", + p->dll_major, CYGWIN_VERSION_DLL_EPOCH); + + /* magic_biscuit != 0 if using the old style version numbering scheme. */ + if (p->magic_biscuit != SIZEOF_PER_PROCESS) + api_fatal ("Incompatible cygwin .dll -- incompatible per_process info %d != %d", + p->magic_biscuit, SIZEOF_PER_PROCESS); + + /* Complain if incompatible API changes made */ + if (p->api_major != cygwin_version.api_major) + api_fatal ("cygwin DLL and APP are out of sync -- API version mismatch %d < %d", + p->api_major, cygwin_version.api_major); + + if (CYGWIN_VERSION_DLL_MAKE_COMBINED (p->dll_major, p->dll_minor) <= + CYGWIN_VERSION_DLL_BAD_SIGNAL_MASK) + signal_shift_subtract = 0; +} + +child_info NO_COPY *child_proc_info = NULL; +static MEMORY_BASIC_INFORMATION NO_COPY sm; + +#define CYGWIN_GUARD ((wincap.has_page_guard ()) ? \ + PAGE_EXECUTE_READWRITE|PAGE_GUARD : PAGE_NOACCESS) + +// __inline__ void +extern void +alloc_stack_hard_way (child_info_fork *ci, volatile char *b) +{ + void *new_stack_pointer; + MEMORY_BASIC_INFORMATION m; + void *newbase; + int newlen; + LPBYTE curbot = (LPBYTE) sm.BaseAddress + sm.RegionSize; + bool noguard; + + if (ci->stacktop > (LPBYTE) sm.AllocationBase && ci->stacktop < curbot) + { + newbase = curbot; + newlen = (LPBYTE) ci->stackbottom - (LPBYTE) curbot; + noguard = 1; + } + else + { + newbase = ci->stacktop; + newlen = (DWORD) ci->stackbottom - (DWORD) ci->stacktop; + noguard = 0; + } + if (!VirtualAlloc (newbase, newlen, MEM_RESERVE, PAGE_NOACCESS)) + api_fatal ("fork: can't reserve memory for stack %p - %p, %E", + ci->stacktop, ci->stackbottom); + + new_stack_pointer = (void *) ((LPBYTE) ci->stackbottom - ci->stacksize); + + if (!VirtualAlloc (new_stack_pointer, ci->stacksize, MEM_COMMIT, + PAGE_EXECUTE_READWRITE)) + api_fatal ("fork: can't commit memory for stack %p(%d), %E", + new_stack_pointer, ci->stacksize); + if (!VirtualQuery ((LPCVOID) new_stack_pointer, &m, sizeof m)) + api_fatal ("fork: couldn't get new stack info, %E"); + if (!noguard) + { + m.BaseAddress = (LPVOID)((DWORD)m.BaseAddress - 1); + if (!VirtualAlloc ((LPVOID) m.BaseAddress, 1, MEM_COMMIT, + CYGWIN_GUARD)) + api_fatal ("fork: couldn't allocate new stack guard page %p, %E", + m.BaseAddress); + } + if (!VirtualQuery ((LPCVOID) m.BaseAddress, &m, sizeof m)) + api_fatal ("fork: couldn't get new stack info, %E"); + ci->stacktop = m.BaseAddress; + *b = 0; +} + +/* extend the stack prior to fork longjmp */ + +static void +alloc_stack (child_info_fork *ci) +{ + /* FIXME: adding 16384 seems to avoid a stack copy problem during + fork on Win95, but I don't know exactly why yet. DJ */ + volatile char b[ci->stacksize + 16384]; + + if (!VirtualQuery ((LPCVOID) &b, &sm, sizeof sm)) + api_fatal ("fork: couldn't get stack info, %E"); + + if (sm.AllocationBase != ci->stacktop) + alloc_stack_hard_way (ci, b + sizeof (b) - 1); + else + ci->stacksize = 0; + + return; +} + +static NO_COPY int mypid = 0; +int __argc_safe; +int _declspec(dllexport) __argc; +char _declspec(dllexport) **__argv; +vfork_save NO_COPY *main_vfork = NULL; + +void +sigthread::init (const char *s) +{ + InitializeCriticalSection (&lock); + id = GetCurrentThreadId (); +} + +/* Take over from libc's crt0.o and start the application. Note the + various special cases when Cygwin DLL is being runtime loaded (as + opposed to being link-time loaded by Cygwin apps) from a non + cygwin app via LoadLibrary. */ +static void +dll_crt0_1 () +{ + /* According to onno@stack.urc.tue.nl, the exception handler record must + be on the stack. */ + /* FIXME: Verify forked children get their exception handler set up ok. */ + exception_list cygwin_except_entry; + + /* Initialize SIGSEGV handling, etc. */ + init_exceptions (&cygwin_except_entry); + + /* Set the os_being_run global. */ + wincap.init (); + check_sanity_and_sync (user_data); + + do_global_ctors (&__CTOR_LIST__, 1); + + /* Nasty static stuff needed by newlib -- point to a local copy of + the reent stuff. + Note: this MUST be done here (before the forkee code) as the + fork copy code doesn't copy the data in libccrt0.cc (that's why we + pass in the per_process struct into the .dll from libccrt0). */ + + _impure_ptr = &reent_data; + + user_data->resourcelocks->Init (); + user_data->threadinterface->Init (); + + mainthread.init ("mainthread"); // For use in determining if signals + // should be blocked. + + winpids::init (); + + int envc = 0; + char **envp = NULL; + + if (!child_proc_info) + memory_init (); + else + { + bool close_ppid_handle = false; + bool close_hexec_proc = false; + switch (child_proc_info->type) + { + case _PROC_FORK: + alloc_stack (fork_info); + cygheap_fixup_in_child (0); + memory_init (); + set_myself (mypid); + close_ppid_handle = !!child_proc_info->pppid_handle; + break; + case _PROC_SPAWN: + /* Have to delay closes until after cygheap is setup */ + close_hexec_proc = !!spawn_info->hexec_proc; + close_ppid_handle = !!child_proc_info->pppid_handle; + goto around; + case _PROC_EXEC: + hexec_proc = spawn_info->hexec_proc; + around: + HANDLE h; + cygheap_fixup_in_child (1); + memory_init (); + if (!spawn_info->moreinfo->myself_pinfo || + !DuplicateHandle (hMainProc, spawn_info->moreinfo->myself_pinfo, + hMainProc, &h, 0, 0, + DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) + h = NULL; + set_myself (mypid, h); + __argc = spawn_info->moreinfo->argc; + __argv = spawn_info->moreinfo->argv; + envp = spawn_info->moreinfo->envp; + envc = spawn_info->moreinfo->envc; + cygheap->fdtab.fixup_after_exec (spawn_info->parent); + signal_fixup_after_exec (); + CloseHandle (spawn_info->parent); + if (spawn_info->moreinfo->old_title) + { + old_title = strcpy (title_buf, spawn_info->moreinfo->old_title); + cfree (spawn_info->moreinfo->old_title); + } + break; + } + if (close_hexec_proc) + CloseHandle (spawn_info->hexec_proc); + if (close_ppid_handle) + CloseHandle (child_proc_info->pppid_handle); + } + + ProtectHandle (hMainProc); + ProtectHandle (hMainThread); + cygthread::init (); + + /* Initialize pthread mainthread when not forked and it is save to call new, + otherwise it is reinitalized in fixup_after_fork */ + if (!user_data->forkee) + pthread::init_mainthread (); + +#ifdef DEBUGGING + strace.microseconds (); +#endif + + /* Initialize debug muto, if DLL is built with --enable-debugging. + Need to do this before any helper threads start. */ + debug_init (); + + cygheap->fdtab.vfork_child_fixup (); + + (void) SetErrorMode (SEM_FAILCRITICALERRORS); + + /* Initialize events. */ + events_init (); + + cygheap->cwd.init (); + main_vfork = vfork_storage.create (); + + cygbench ("pre-forkee"); + if (user_data->forkee) + { + /* If we've played with the stack, stacksize != 0. That means that + fork() was invoked from other than the main thread. Make sure that + frame pointer is referencing the new stack so that the OS knows what + to do when it needs to increase the size of the stack. + + NOTE: Don't do anything that involves the stack until you've completed + this step. */ + if (fork_info->stacksize) + { + asm ("movl %0,%%fs:4" : : "r" (fork_info->stackbottom)); + asm ("movl %0,%%fs:8" : : "r" (fork_info->stacktop)); + } + + longjmp (fork_info->jmp, fork_info->cygpid); + } + +#ifdef DEBUGGING + { + extern void fork_init (); + fork_init (); + } +#endif + + /* Initialize our process table entry. */ + pinfo_init (envp, envc); + + if (!old_title && GetConsoleTitle (title_buf, TITLESIZE)) + old_title = title_buf; + + /* Allocate cygheap->fdtab */ + dtable_init (); + + /* Init global well known SID objects */ + cygsid::init (); + + /* Initialize user info. */ + uinfo_init (); + + /* Initialize signal/subprocess handling. */ + sigproc_init (); + + /* Connect to tty. */ + tty_init (); + + if (!__argc) + { + char *line = GetCommandLineA (); + line = strcpy ((char *) alloca (strlen (line) + 1), line); + + if (current_codepage == oem_cp) + CharToOemA (line, line); + + /* Scan the command line and build argv. Expand wildcards if not + called from another cygwin process. */ + build_argv (line, __argv, __argc, + NOTSTATE (myself, PID_CYGPARENT) && allow_glob); + + /* Convert argv[0] to posix rules if it's currently blatantly + win32 style. */ + if ((strchr (__argv[0], ':')) || (strchr (__argv[0], '\\'))) + { + char *new_argv0 = (char *) alloca (MAX_PATH); + cygwin_conv_to_posix_path (__argv[0], new_argv0); + __argv[0] = new_argv0; + } + } + + __argc_safe = __argc; + if (user_data->premain[0]) + for (unsigned int i = 0; i < PREMAIN_LEN / 2; i++) + user_data->premain[i] (__argc, __argv, user_data); + + /* Set up standard fds in file descriptor table. */ + cygheap->fdtab.stdio_init (); + + /* Set up __progname for getopt error call. */ + if (__argv[0] && (__progname = strrchr (__argv[0], '/'))) + ++__progname; + else + __progname = __argv[0]; + if (__progname) + { + char *cp = strchr (__progname, '\0') - 4; + if (cp > __progname && strcasematch (cp, ".exe")) + *cp = '\0'; + } + + /* Set new console title if appropriate. */ + + if (display_title && !dynamically_loaded) + { + char *cp = __progname; + if (strip_title_path) + for (char *ptr = cp; *ptr && *ptr != ' '; ptr++) + if (isdirsep (*ptr)) + cp = ptr + 1; + set_console_title (cp); + } + + cygwin_finished_initializing = 1; + /* Call init of loaded dlls. */ + dlls.init (); + + /* Execute any specified "premain" functions */ + if (user_data->premain[PREMAIN_LEN / 2]) + for (unsigned int i = PREMAIN_LEN / 2; i < PREMAIN_LEN; i++) + user_data->premain[i] (__argc, __argv, user_data); + + debug_printf ("user_data->main %p", user_data->main); + + if (dynamically_loaded) + { + set_errno (0); + return; + } + + /* Disable case-insensitive globbing */ + ignore_case_with_glob = FALSE; + + /* Flush signals and ensure that signal thread is up and running. Can't + do this for noncygwin case since the signal thread is blocked due to + LoadLibrary serialization. */ + wait_for_sigthread (); + + set_errno (0); + + MALLOC_CHECK; + cygbench (__progname); + if (user_data->main) + exit (user_data->main (__argc, __argv, *user_data->envptr)); +} + +#ifdef DEBUGGING +void +break_here () +{ + debug_printf ("break here"); +} +#endif + +void +initial_env () +{ + DWORD len; + char buf[MAX_PATH + 1]; +#ifdef DEBUGGING + if (GetEnvironmentVariable ("CYGWIN_SLEEP", buf, sizeof (buf) - 1)) + { + DWORD ms = atoi (buf); + buf[0] = '\0'; + len = GetModuleFileName (NULL, buf, MAX_PATH); + console_printf ("Sleeping %d, pid %u %s\n", ms, GetCurrentProcessId (), buf); + Sleep (ms); + } + if (GetEnvironmentVariable ("CYGWIN_DEBUG", buf, sizeof (buf) - 1)) + { + char buf1[MAX_PATH + 1]; + len = GetModuleFileName (NULL, buf1, MAX_PATH); + strlwr (buf1); + strlwr (buf); + char *p = strchr (buf, ':'); + if (!p) + p = (char *) "gdb.exe -nw"; + else + *p++ = '\0'; + if (strstr (buf1, buf)) + { + error_start_init (p); + try_to_debug (); + break_here (); + } + } +#endif + + if (GetEnvironmentVariable ("CYGWIN_TESTING", buf, sizeof (buf) - 1)) + { + _cygwin_testing = 1; + if ((len = GetModuleFileName (cygwin_hmodule, buf, MAX_PATH)) + && len > sizeof ("new-cygwin1.dll") + && strcasematch (buf + len - sizeof ("new-cygwin1.dll"), + "\\new-cygwin1.dll")) + _cygwin_testing_magic = 0x10; + } +} + +/* Wrap the real one, otherwise gdb gets confused about + two symbols with the same name, but different addresses. + + UPTR is a pointer to global data that lives on the libc side of the + line [if one distinguishes the application from the dll]. */ + +extern "C" void __stdcall +_dll_crt0 () +{ + DECLARE_TLS_STORAGE; + initial_env (); + char zeros[sizeof (fork_info->zero)] = {0}; + static NO_COPY STARTUPINFO si; + + main_environ = user_data->envptr; + *main_environ = NULL; + + init_console_handler (); + init_global_security (); + if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (), + GetCurrentProcess (), &hMainProc, 0, FALSE, + DUPLICATE_SAME_ACCESS)) + hMainProc = GetCurrentProcess (); + + DuplicateHandle (hMainProc, GetCurrentThread (), hMainProc, + &hMainThread, 0, false, DUPLICATE_SAME_ACCESS); + + GetStartupInfo (&si); + child_proc_info = (child_info *) si.lpReserved2; + if (si.cbReserved2 < EXEC_MAGIC_SIZE || !child_proc_info + || memcmp (child_proc_info->zero, zeros, sizeof (zeros)) != 0) + child_proc_info = NULL; + else + { + if ((child_proc_info->intro & OPROC_MAGIC_MASK) == OPROC_MAGIC_GENERIC) + multiple_cygwin_problem ("proc", child_proc_info->intro, 0); + else if (child_proc_info->intro == PROC_MAGIC_GENERIC + && child_proc_info->magic != CHILD_INFO_MAGIC) + multiple_cygwin_problem ("proc", child_proc_info->magic, + CHILD_INFO_MAGIC); + else if (child_proc_info->cygheap != (void *) &_cygheap_start) + multiple_cygwin_problem ("cygheap", (DWORD) child_proc_info->cygheap, + (DWORD) &_cygheap_start); + unsigned should_be_cb = 0; + switch (child_proc_info->type) + { + case _PROC_FORK: + user_data->forkee = child_proc_info->cygpid; + should_be_cb = sizeof (child_info_fork); + /* fall through */; + case _PROC_SPAWN: + case _PROC_EXEC: + if (!should_be_cb) + should_be_cb = sizeof (child_info); + if (should_be_cb != child_proc_info->cb) + multiple_cygwin_problem ("proc size", child_proc_info->cb, should_be_cb); + else if (sizeof (fhandler_union) != child_proc_info->fhandler_union_cb) + multiple_cygwin_problem ("fhandler size", child_proc_info->fhandler_union_cb, sizeof (fhandler_union)); + else + { + cygwin_mount_h = child_proc_info->mount_h; + mypid = child_proc_info->cygpid; + break; + } + default: + system_printf ("unknown exec type %d", child_proc_info->type); + /* intentionally fall through */ + case _PROC_WHOOPS: + child_proc_info = NULL; + break; + } + } + dll_crt0_1 (); +} + +void +dll_crt0 (per_process *uptr) +{ + DECLARE_TLS_STORAGE; + /* Set the local copy of the pointer into the user space. */ + if (uptr && uptr != user_data) + { + memcpy (user_data, uptr, per_process_overwrite); + *(user_data->impure_ptr_ptr) = &reent_data; + } + _dll_crt0 (); +} + +/* This must be called by anyone who uses LoadLibrary to load cygwin1.dll */ +extern "C" void +cygwin_dll_init () +{ + static char **envp; + static int _fmode; + + if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (), + GetCurrentProcess (), &hMainProc, 0, FALSE, + DUPLICATE_SAME_ACCESS)) + hMainProc = GetCurrentProcess (); + + DuplicateHandle (hMainProc, GetCurrentThread (), hMainProc, + &hMainThread, 0, FALSE, DUPLICATE_SAME_ACCESS); + user_data->magic_biscuit = sizeof (per_process); + + user_data->envptr = &envp; + user_data->fmode_ptr = &_fmode; + + dll_crt0_1 (); +} + +extern "C" void +__main (void) +{ + do_global_ctors (user_data->ctors, FALSE); +} + +enum exit_states + { + ES_NOT_EXITING = 0, + ES_THREADTERM, + ES_SIGNAL, + ES_CLOSEALL, + ES_SIGPROCTERMINATE, + ES_TITLE, + ES_HUP_PGRP, + ES_HUP_SID, + ES_TTY_TERMINATE, + ES_EVENTS_TERMINATE + }; + +exit_states NO_COPY exit_state; +extern CRITICAL_SECTION exit_lock; + +extern "C" void __stdcall +do_exit (int status) +{ + EnterCriticalSection (&exit_lock); + UINT n = (UINT) status; + + syscall_printf ("do_exit (%d)", n); + + vfork_save *vf = vfork_storage.val (); + if (vf != NULL && vf->pid < 0) + vf->restore_exit (status); + + if (exit_state < ES_THREADTERM) + { + exit_state = ES_THREADTERM; + cygthread::terminate (); + } + + if (exit_state < ES_SIGNAL) + { + exit_state = ES_SIGNAL; + if (!(n & EXIT_REPARENTING)) + { + signal (SIGCHLD, SIG_IGN); + signal (SIGHUP, SIG_IGN); + signal (SIGINT, SIG_IGN); + signal (SIGQUIT, SIG_IGN); + } + } + + if (exit_state < ES_CLOSEALL) + { + exit_state = ES_CLOSEALL; + close_all_files (); + } + + if (exit_state < ES_SIGPROCTERMINATE) + { + exit_state = ES_SIGPROCTERMINATE; + sigproc_terminate (); + } + + myself->stopsig = 0; + if (exit_state < ES_TITLE) + { + exit_state = ES_TITLE; + /* restore console title */ + if (old_title && display_title) + set_console_title (old_title); + } + + if (exit_state < ES_HUP_PGRP) + { + exit_state = ES_HUP_PGRP; + /* Kill orphaned children on group leader exit */ + if (myself->has_pgid_children && myself->pid == myself->pgid) + { + sigproc_printf ("%d == pgrp %d, send SIG{HUP,CONT} to stopped children", + myself->pid, myself->pgid); + kill_pgrp (myself->pgid, -SIGHUP); + } + } + + if (exit_state < ES_HUP_SID) + { + exit_state = ES_HUP_SID; + /* Kill the foreground process group on session leader exit */ + if (getpgrp () > 0 && myself->pid == myself->sid && real_tty_attached (myself)) + { + tty *tp = cygwin_shared->tty[myself->ctty]; + sigproc_printf ("%d == sid %d, send SIGHUP to children", + myself->pid, myself->sid); + + /* CGF FIXME: This can't be right. */ + if (tp->getsid () == myself->sid) + tp->kill_pgrp (SIGHUP); + } + + } + + if (exit_state < ES_TTY_TERMINATE) + { + exit_state = ES_TTY_TERMINATE; + tty_terminate (); + } + + if (exit_state < ES_EVENTS_TERMINATE) + { + exit_state = ES_EVENTS_TERMINATE; + events_terminate (); + } + + minimal_printf ("winpid %d, exit %d", GetCurrentProcessId (), n); + myself->exit (n); +} + +static muto *atexit_lock; + +extern "C" int +cygwin_atexit (void (*function)(void)) +{ + int res; + if (!atexit_lock) + new_muto (atexit_lock); + atexit_lock->acquire (); + res = atexit (function); + atexit_lock->release (); + return res; +} + +extern "C" void +cygwin_exit (int n) +{ + if (atexit_lock) + atexit_lock->acquire (); + exit (n); +} + +extern "C" void +_exit (int n) +{ + do_exit ((DWORD) n & 0xffff); +} + +extern "C" void +__api_fatal (const char *fmt, ...) +{ + char buf[4096]; + va_list ap; + + va_start (ap, fmt); + __small_vsprintf (buf, fmt, ap); + va_end (ap); + strcat (buf, "\n"); + int len = strlen (buf); + DWORD done; + (void) WriteFile (GetStdHandle (STD_ERROR_HANDLE), buf, len, &done, 0); + + /* Make sure that the message shows up on the screen, too, since this is + a serious error. */ + if (GetFileType (GetStdHandle (STD_ERROR_HANDLE)) != FILE_TYPE_CHAR) + { + HANDLE h = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_WRITE | FILE_SHARE_WRITE, + &sec_none, OPEN_EXISTING, 0, 0); + if (h != INVALID_HANDLE_VALUE) + (void) WriteFile (h, buf, len, &done, 0); + } + + /* We are going down without mercy. Make sure we reset + our process_state. */ + sigproc_terminate (); +#ifdef DEBUGGING + (void) try_to_debug (); +#endif + myself->exit (1); +} + +void +multiple_cygwin_problem (const char *what, unsigned magic_version, unsigned version) +{ + if (_cygwin_testing && (strstr (what, "proc") || strstr (what, "cygheap"))) + { + child_proc_info->type = _PROC_WHOOPS; + return; + } + + char buf[1024]; + if (GetEnvironmentVariable ("CYGWIN_MISMATCH_OK", buf, sizeof (buf))) + return; + + if (CYGWIN_VERSION_MAGIC_VERSION (magic_version) == version) + system_printf ("%s magic number mismatch detected - %p/%p", what, magic_version, version); + else + api_fatal ("%s version mismatch detected - %p/%p.\n\ +You have multiple copies of cygwin1.dll on your system.\n\ +Search for cygwin1.dll using the Windows Start->Find/Search facility\n\ +and delete all but the most recent version. The most recent version *should*\n\ +reside in x:\\cygwin\\bin, where 'x' is the drive on which you have\n\ +installed the cygwin distribution.", what, magic_version, version); +} + +#ifdef DEBUGGING +void __stdcall +cygbench (const char *s) +{ + char buf[1024]; + if (GetEnvironmentVariable ("CYGWIN_BENCH", buf, sizeof (buf))) + small_printf ("%05d ***** %s : %10d\n", GetCurrentProcessId (), s, strace.microseconds ()); +} +#endif diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc new file mode 100644 index 00000000000..a83fb0917d1 --- /dev/null +++ b/winsup/cygwin/exceptions.cc @@ -0,0 +1,1275 @@ +/* exceptions.cc + + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 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 <imagehlp.h> +#include <stdlib.h> + +#include "exceptions.h" +#include "sync.h" +#include "sigproc.h" +#include "pinfo.h" +#include "cygerrno.h" +#include "perthread.h" +#include "shared_info.h" +#include "perprocess.h" +#include "security.h" + +#define CALL_HANDLER_RETRY 20 + +char debugger_command[2 * MAX_PATH + 20]; + +extern "C" { +static int handle_exceptions (EXCEPTION_RECORD *, void *, CONTEXT *, void *); +extern void sigreturn (); +extern void sigdelayed (); +extern void sigdelayed0 (); +extern void siglast (); +extern DWORD __no_sig_start, __no_sig_end; +}; + +extern DWORD sigtid; + +extern HANDLE hExeced; +extern DWORD dwExeced; + +static BOOL WINAPI ctrl_c_handler (DWORD); +static void signal_exit (int) __attribute__ ((noreturn)); +static char windows_system_directory[1024]; +static size_t windows_system_directory_length; + +/* This is set to indicate that we have already exited. */ + +static NO_COPY int exit_already = 0; +static NO_COPY muto *mask_sync = NULL; + +HMODULE NO_COPY cygwin_hmodule; + +NO_COPY static struct +{ + unsigned int code; + const char *name; +} status_info[] = +{ +#define X(s) s, #s + { X (STATUS_ABANDONED_WAIT_0) }, + { X (STATUS_ACCESS_VIOLATION) }, + { X (STATUS_ARRAY_BOUNDS_EXCEEDED) }, + { X (STATUS_BREAKPOINT) }, + { X (STATUS_CONTROL_C_EXIT) }, + { X (STATUS_DATATYPE_MISALIGNMENT) }, + { X (STATUS_FLOAT_DENORMAL_OPERAND) }, + { X (STATUS_FLOAT_DIVIDE_BY_ZERO) }, + { X (STATUS_FLOAT_INEXACT_RESULT) }, + { X (STATUS_FLOAT_INVALID_OPERATION) }, + { X (STATUS_FLOAT_OVERFLOW) }, + { X (STATUS_FLOAT_STACK_CHECK) }, + { X (STATUS_FLOAT_UNDERFLOW) }, + { X (STATUS_GUARD_PAGE_VIOLATION) }, + { X (STATUS_ILLEGAL_INSTRUCTION) }, + { X (STATUS_INTEGER_DIVIDE_BY_ZERO) }, + { X (STATUS_INTEGER_OVERFLOW) }, + { X (STATUS_INVALID_DISPOSITION) }, + { X (STATUS_IN_PAGE_ERROR) }, + { X (STATUS_NONCONTINUABLE_EXCEPTION) }, + { X (STATUS_NO_MEMORY) }, + { X (STATUS_PENDING) }, + { X (STATUS_PRIVILEGED_INSTRUCTION) }, + { X (STATUS_SINGLE_STEP) }, + { X (STATUS_STACK_OVERFLOW) }, + { X (STATUS_TIMEOUT) }, + { X (STATUS_USER_APC) }, + { X (STATUS_WAIT_0) }, + { 0, 0 } +#undef X +}; + +/* Initialization code. */ + +#ifdef __i386__ + +// Set up the exception handler for the current thread. The PowerPC & Mips +// use compiler generated tables to set up the exception handlers for each +// region of code, and the kernel walks the call list until it finds a region +// of code that handles exceptions. The x86 on the other hand uses segment +// register fs, offset 0 to point to the current exception handler. + +asm (".equ __except_list,0"); + +extern exception_list *_except_list asm ("%fs:__except_list"); + +static void +init_exception_handler (exception_list *el) +{ + el->handler = handle_exceptions; + el->prev = _except_list; + _except_list = el; +} +#endif + +void +init_console_handler () +{ + (void) SetConsoleCtrlHandler (ctrl_c_handler, FALSE); + if (!SetConsoleCtrlHandler (ctrl_c_handler, TRUE)) + system_printf ("SetConsoleCtrlHandler failed, %E"); +} + +void +init_global_security () +{ + /* Initialize global security attribute stuff */ + + sec_none.nLength = sec_none_nih.nLength = + sec_all.nLength = sec_all_nih.nLength = sizeof (SECURITY_ATTRIBUTES); + sec_none.bInheritHandle = sec_all.bInheritHandle = TRUE; + sec_none_nih.bInheritHandle = sec_all_nih.bInheritHandle = FALSE; + sec_none.lpSecurityDescriptor = sec_none_nih.lpSecurityDescriptor = NULL; + sec_all.lpSecurityDescriptor = sec_all_nih.lpSecurityDescriptor = + get_null_sd (); +} + +extern "C" void +init_exceptions (exception_list *el) +{ + init_exception_handler (el); +} + +extern "C" void +error_start_init (const char *buf) +{ + if (!buf || !*buf) + { + debugger_command[0] = '\0'; + return; + } + + char pgm[MAX_PATH + 1]; + if (!GetModuleFileName (NULL, pgm, MAX_PATH)) + strcpy (pgm, "cygwin1.dll"); + for (char *p = strchr (pgm, '\\'); p; p = strchr (p, '\\')) + *p = '/'; + + __small_sprintf (debugger_command, "%s \"%s\"", buf, pgm); +} + +static void +open_stackdumpfile () +{ + if (myself->progname[0]) + { + const char *p; + /* write to progname.stackdump if possible */ + if (!myself->progname[0]) + p = "unknown"; + else if ((p = strrchr (myself->progname, '\\'))) + p++; + else + p = myself->progname; + char corefile[strlen (p) + sizeof (".stackdump")]; + __small_sprintf (corefile, "%s.stackdump", p); + HANDLE h = CreateFile (corefile, GENERIC_WRITE, 0, &sec_none_nih, + CREATE_ALWAYS, 0, 0); + if (h != INVALID_HANDLE_VALUE) + { + if (!myself->ppid_handle) + system_printf ("Dumping stack trace to %s", corefile); + else + debug_printf ("Dumping stack trace to %s", corefile); + SetStdHandle (STD_ERROR_HANDLE, h); + } + } +} + +/* Utilities for dumping the stack, etc. */ + +static void +exception (EXCEPTION_RECORD *e, CONTEXT *in) +{ + const char *exception_name = NULL; + + if (e) + { + for (int i = 0; status_info[i].name; i++) + { + if (status_info[i].code == e->ExceptionCode) + { + exception_name = status_info[i].name; + break; + } + } + } + +#ifdef __i386__ +#define HAVE_STATUS + if (exception_name) + small_printf ("Exception: %s at eip=%08x\r\n", exception_name, in->Eip); + else + small_printf ("Exception %d at eip=%08x\r\n", e->ExceptionCode, in->Eip); + small_printf ("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\r\n", + in->Eax, in->Ebx, in->Ecx, in->Edx, in->Esi, in->Edi); + small_printf ("ebp=%08x esp=%08x program=%s\r\n", + in->Ebp, in->Esp, myself->progname); + small_printf ("cs=%04x ds=%04x es=%04x fs=%04x gs=%04x ss=%04x\r\n", + in->SegCs, in->SegDs, in->SegEs, in->SegFs, in->SegGs, in->SegSs); +#endif + +#ifndef HAVE_STATUS + system_printf ("Had an exception"); +#endif +} + +#ifdef __i386__ +/* Print a stack backtrace. */ + +#define HAVE_STACK_TRACE + +/* A class for manipulating the stack. */ +class stack_info +{ + int walk (); /* Uses the "old" method */ + char *next_offset () {return *((char **) sf.AddrFrame.Offset);} + bool needargs; + DWORD dummy_frame; +public: + STACKFRAME sf; /* For storing the stack information */ + void init (DWORD, bool, bool); /* Called the first time that stack info is needed */ + + /* Postfix ++ iterates over the stack, returning zero when nothing is left. */ + int operator ++(int) { return walk (); } +}; + +/* The number of parameters used in STACKFRAME */ +#define NPARAMS (sizeof (thestack.sf.Params) / sizeof (thestack.sf.Params[0])) + +/* This is the main stack frame info for this process. */ +static NO_COPY stack_info thestack; +static signal_dispatch sigsave; + +/* Initialize everything needed to start iterating. */ +void +stack_info::init (DWORD ebp, bool wantargs, bool goodframe) +{ +# define debp ((DWORD *) ebp) + memset (&sf, 0, sizeof (sf)); + if (!goodframe) + sf.AddrFrame.Offset = ebp; + else + { + dummy_frame = ebp; + sf.AddrFrame.Offset = (DWORD) &dummy_frame; + } + sf.AddrReturn.Offset = debp[1]; + sf.AddrFrame.Mode = AddrModeFlat; + needargs = wantargs; +# undef debp +} + +/* Walk the stack by looking at successive stored 'bp' frames. + This is not foolproof. */ +int +stack_info::walk () +{ + char **ebp; + if ((ebp = (char **) next_offset ()) == NULL) + return 0; + + sf.AddrFrame.Offset = (DWORD) ebp; + sf.AddrPC.Offset = sf.AddrReturn.Offset; + + if (!sf.AddrPC.Offset) + return 0; /* stack frames are exhausted */ + + /* The return address always follows the stack pointer */ + sf.AddrReturn.Offset = (DWORD) *++ebp; + + if (needargs) + /* The arguments follow the return address */ + for (unsigned i = 0; i < NPARAMS; i++) + sf.Params[i] = (DWORD) *++ebp; + + return 1; +} + +static void +stackdump (DWORD ebp, int open_file, bool isexception) +{ + extern unsigned long rlim_core; + + if (rlim_core == 0UL) + return; + + if (open_file) + open_stackdumpfile (); + + int i; + + thestack.init (ebp, 1, !isexception); /* Initialize from the input CONTEXT */ + small_printf ("Stack trace:\r\nFrame Function Args\r\n"); + for (i = 0; i < 16 && thestack++; i++) + { + small_printf ("%08x %08x ", thestack.sf.AddrFrame.Offset, + thestack.sf.AddrPC.Offset); + for (unsigned j = 0; j < NPARAMS; j++) + small_printf ("%s%08x", j == 0 ? " (" : ", ", thestack.sf.Params[j]); + small_printf (")\r\n"); + } + small_printf ("End of stack trace%s", + i == 16 ? " (more stack frames may be present)" : ""); +} + +/* Temporary (?) function for external callers to get a stack dump */ +extern "C" void +cygwin_stackdump () +{ + CONTEXT c; + c.ContextFlags = CONTEXT_FULL; + GetThreadContext (GetCurrentThread (), &c); + stackdump (c.Ebp, 0, 0); +} + +#define TIME_TO_WAIT_FOR_DEBUGGER 10000 + +extern "C" int +try_to_debug (bool waitloop) +{ + debug_printf ("debugger_command '%s'", debugger_command); + if (*debugger_command == '\0' || being_debugged ()) + return 0; + + __small_sprintf (strchr (debugger_command, '\0'), " %u", GetCurrentProcessId ()); + + LONG prio = GetThreadPriority (GetCurrentThread ()); + SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST); + PROCESS_INFORMATION pi = {NULL, 0, 0, 0}; + + STARTUPINFO si = {0, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL}; + si.lpReserved = NULL; + si.lpDesktop = NULL; + si.dwFlags = 0; + si.cb = sizeof (si); + + /* FIXME: need to know handles of all running threads to + suspend_all_threads_except (current_thread_id); + */ + + /* if any of these mutexes is owned, we will fail to start any cygwin app + until trapped app exits */ + + ReleaseMutex (title_mutex); + + /* prevent recursive exception handling */ + char* rawenv = GetEnvironmentStrings () ; + for (char* p = rawenv; *p != '\0'; p = strchr (p, '\0') + 1) + { + if (strncmp (p, "CYGWIN=", sizeof ("CYGWIN=") - 1) == 0) + { + char* q = strstr (p, "error_start") ; + /* replace 'error_start=...' with '_rror_start=...' */ + if (q) *q = '_' ; + SetEnvironmentVariable ("CYGWIN", p + sizeof ("CYGWIN=")) ; + break ; + } + } + + BOOL dbg; + dbg = CreateProcess (NULL, + debugger_command, + NULL, + NULL, + FALSE, + CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, + NULL, + NULL, + &si, + &pi); + + if (!dbg) + system_printf ("Failed to start debugger: %E"); + else + { + if (!waitloop) + return 1; + SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_IDLE); + while (!being_debugged ()) + Sleep (0); + Sleep (2000); + small_printf ("*** continuing from debugger call\n"); + SetThreadPriority (GetCurrentThread (), prio); + } + + /* FIXME: need to know handles of all running threads to + resume_all_threads_except (current_thread_id); + */ + return 0; +} + +/* Main exception handler. */ + +static int +handle_exceptions (EXCEPTION_RECORD *e, void *, CONTEXT *in, void *) +{ + int sig; + static int NO_COPY debugging = 0; + static int NO_COPY recursed = 0; + + if (debugging && ++debugging < 500000) + { + SetThreadPriority (hMainThread, THREAD_PRIORITY_NORMAL); + return 0; + } + + /* If we've already exited, don't do anything here. Returning 1 + tells Windows to keep looking for an exception handler. */ + if (exit_already) + return 1; + + /* Coerce win32 value to posix value. */ + switch (e->ExceptionCode) + { + case STATUS_FLOAT_DENORMAL_OPERAND: + case STATUS_FLOAT_DIVIDE_BY_ZERO: + case STATUS_FLOAT_INEXACT_RESULT: + case STATUS_FLOAT_INVALID_OPERATION: + case STATUS_FLOAT_OVERFLOW: + case STATUS_FLOAT_STACK_CHECK: + case STATUS_FLOAT_UNDERFLOW: + case STATUS_INTEGER_DIVIDE_BY_ZERO: + case STATUS_INTEGER_OVERFLOW: + sig = SIGFPE; + break; + + case STATUS_ILLEGAL_INSTRUCTION: + case STATUS_PRIVILEGED_INSTRUCTION: + case STATUS_NONCONTINUABLE_EXCEPTION: + sig = SIGILL; + break; + + case STATUS_TIMEOUT: + sig = SIGALRM; + break; + + case STATUS_ACCESS_VIOLATION: + case STATUS_DATATYPE_MISALIGNMENT: + case STATUS_ARRAY_BOUNDS_EXCEEDED: + case STATUS_GUARD_PAGE_VIOLATION: + case STATUS_IN_PAGE_ERROR: + case STATUS_NO_MEMORY: + case STATUS_INVALID_DISPOSITION: + case STATUS_STACK_OVERFLOW: + sig = SIGSEGV; + break; + + case STATUS_CONTROL_C_EXIT: + sig = SIGINT; + break; + + case STATUS_INVALID_HANDLE: + /* CloseHandle will throw this exception if it is given an + invalid handle. We don't care about the exception; we just + want CloseHandle to return an error. This can be revisited + if gcc ever supports Windows style structured exception + handling. */ + return 0; + + default: + /* If we don't recognize the exception, we have to assume that + we are doing structured exception handling, and we let + something else handle it. */ + return 1; + } + + debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp); + debug_printf ("In cygwin_except_handler sig = %d at %p", sig, in->Eip); + + if (myself->getsig (sig).sa_mask & SIGTOMASK (sig)) + syscall_printf ("signal %d, masked %p", sig, myself->getsig (sig).sa_mask); + + debug_printf ("In cygwin_except_handler calling %p", + myself->getsig (sig).sa_handler); + + DWORD *ebp = (DWORD *)in->Esp; + for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--) + if (*ebp == in->SegCs && ebp[-1] == in->Eip) + { + ebp -= 2; + break; + } + + if (!myself->progname[0] + || GetCurrentThreadId () == sigtid + || (void *) myself->getsig (sig).sa_handler == (void *) SIG_DFL + || (void *) myself->getsig (sig).sa_handler == (void *) SIG_IGN + || (void *) myself->getsig (sig).sa_handler == (void *) SIG_ERR) + { + /* Print the exception to the console */ + if (e) + { + for (int i = 0; status_info[i].name; i++) + { + if (status_info[i].code == e->ExceptionCode) + { + if (!myself->ppid_handle) + system_printf ("Exception: %s", status_info[i].name); + break; + } + } + } + + /* Another exception could happen while tracing or while exiting. + Only do this once. */ + if (recursed++) + system_printf ("Error while dumping state (probably corrupted stack)"); + else + { + if (try_to_debug (0)) + { + debugging = 1; + return 0; + } + + open_stackdumpfile (); + exception (e, in); + stackdump ((DWORD) ebp, 0, 1); + } + + signal_exit (0x80 | sig); // Flag signal + core dump + } + + sig_send (NULL, sig, (DWORD) ebp, 1); // Signal myself + return 0; +} +#endif /* __i386__ */ + +#ifndef HAVE_STACK_TRACE +void +stack (void) +{ + system_printf ("Stack trace not yet supported on this machine."); +} +#endif + +/* Utilities to call a user supplied exception handler. */ + +#define SIG_NONMASKABLE (SIGTOMASK (SIGKILL) | SIGTOMASK (SIGSTOP)) + +#ifdef __i386__ +#define HAVE_CALL_HANDLER + +/* Non-raceable sigsuspend + * Note: This implementation is based on the Single UNIX Specification + * man page. This indicates that sigsuspend always returns -1 and that + * attempts to block unblockable signals will be silently ignored. + * This is counter to what appears to be documented in some UNIX + * man pages, e.g. Linux. + */ +int __stdcall +handle_sigsuspend (sigset_t tempmask) +{ + sig_dispatch_pending (); + sigframe thisframe (mainthread); + sigset_t oldmask = myself->getsigmask (); // Remember for restoration + + set_process_mask (tempmask & ~SIG_NONMASKABLE);// Let signals we're + // interested in through. + sigproc_printf ("old mask %x, new mask %x", oldmask, tempmask); + + pthread_testcancel (); + pthread::cancelable_wait (signal_arrived, INFINITE); + + set_sig_errno (EINTR); // Per POSIX + + /* A signal dispatch function will have been added to our stack and will + be hit eventually. Set the old mask to be restored when the signal + handler returns. */ + + sigsave.oldmask = oldmask; // Will be restored by signal handler + return -1; +} + +extern DWORD exec_exit; // Possible exit value for exec + +extern "C" { +static void +sig_handle_tty_stop (int sig) +{ + /* Silently ignore attempts to suspend if there is no accomodating + cygwin parent to deal with this behavior. */ + if (!myself->ppid_handle) + { + myself->process_state &= ~PID_STOPPED; + return; + } + + myself->stopsig = sig; + /* See if we have a living parent. If so, send it a special signal. + It will figure out exactly which pid has stopped by scanning + its list of subprocesses. */ + if (my_parent_is_alive ()) + { + pinfo parent (myself->ppid); + if (ISSTATE (parent, PID_NOCLDSTOP)) + sig_send (parent, SIGCHLD); + } + sigproc_printf ("process %d stopped by signal %d, myself->ppid_handle %p", + myself->pid, sig, myself->ppid_handle); + if (WaitForSingleObject (sigCONT, INFINITE) != WAIT_OBJECT_0) + api_fatal ("WaitSingleObject failed, %E"); + return; +} +} + +int +interruptible (DWORD pc, int testvalid = 0) +{ + int res; + MEMORY_BASIC_INFORMATION m; + + memset (&m, 0, sizeof m); + if (!VirtualQuery ((LPCVOID) pc, &m, sizeof m)) + sigproc_printf ("couldn't get memory info, pc %p, %E", pc); + + char *checkdir = (char *) alloca (windows_system_directory_length + 4); + memset (checkdir, 0, sizeof (checkdir)); + +# define h ((HMODULE) m.AllocationBase) + /* Apparently Windows 95 can sometimes return bogus addresses from + GetThreadContext. These resolve to a strange allocation base. + These should *never* be treated as interruptible. */ + if (!h || m.State != MEM_COMMIT) + res = 0; + else if (testvalid) + res = 1; /* All we wanted to know was if this was a valid module. */ + else if (h == user_data->hmodule) + res = 1; + else if (h == cygwin_hmodule) + res = 0; + else if (!GetModuleFileName (h, checkdir, windows_system_directory_length + 2)) + res = 0; + else + res = !strncasematch (windows_system_directory, checkdir, + windows_system_directory_length); + sigproc_printf ("pc %p, h %p, interruptible %d, testvalid %d", pc, h, res, testvalid); +# undef h + return res; +} + +bool +sigthread::get_winapi_lock (int test) +{ + if (test) + return !InterlockedExchange (&winapi_lock, 1); + + /* Need to do a busy loop because we can't block or a potential SuspendThread + will hang. */ + while (InterlockedExchange (&winapi_lock, 1)) + low_priority_sleep (0); + return 1; +} + +void +sigthread::release_winapi_lock () +{ + /* Assumes that we have the lock. */ + InterlockedExchange (&winapi_lock, 0); +} + +static void __stdcall interrupt_setup (int sig, void *handler, DWORD retaddr, + DWORD *retaddr_on_stack, + struct sigaction& siga) + __attribute__((regparm(3))); +static void __stdcall +interrupt_setup (int sig, void *handler, DWORD retaddr, DWORD *retaddr_on_stack, + struct sigaction& siga) +{ + sigsave.retaddr = retaddr; + sigsave.retaddr_on_stack = retaddr_on_stack; + /* FIXME: Not multi-thread aware */ + sigsave.oldmask = myself->getsigmask (); + sigsave.newmask = sigsave.oldmask | siga.sa_mask | SIGTOMASK (sig); + sigsave.sa_flags = siga.sa_flags; + sigsave.func = (void (*)(int)) handler; + sigsave.saved_errno = -1; // Flag: no errno to save + if (handler == sig_handle_tty_stop) + { + myself->stopsig = 0; + myself->process_state |= PID_STOPPED; + } + /* Clear any waiting threads prior to dispatching to handler function */ + proc_subproc (PROC_CLEARWAIT, 1); + int res = SetEvent (signal_arrived); // For an EINTR case + sigsave.sig = sig; // Should ALWAYS be last thing set to avoid a race + sigproc_printf ("armed signal_arrived %p, res %d", signal_arrived, res); +} + +static bool interrupt_now (CONTEXT *, int, void *, struct sigaction&) __attribute__((regparm(3))); +static bool +interrupt_now (CONTEXT *ctx, int sig, void *handler, struct sigaction& siga) +{ + interrupt_setup (sig, handler, ctx->Eip, 0, siga); + ctx->Eip = (DWORD) sigdelayed; + SetThreadContext (myself->getthread2signal (), ctx); /* Restart the thread in a new location */ + return 1; +} + +void __stdcall +signal_fixup_after_fork () +{ + if (sigsave.sig) + { + sigsave.sig = 0; + if (sigsave.retaddr_on_stack) + { + *sigsave.retaddr_on_stack = sigsave.retaddr; + set_process_mask (sigsave.oldmask); + } + } + sigproc_init (); +} + +static int interrupt_on_return (sigthread *, int, void *, struct sigaction&) __attribute__((regparm(3))); +static int +interrupt_on_return (sigthread *th, int sig, void *handler, struct sigaction& siga) +{ + int i; + DWORD ebp = th->frame; + + if (!ebp) + return 0; + + thestack.init (ebp, 0, 1); /* Initialize from the input CONTEXT */ + for (i = 0; i < 32 && thestack++ ; i++) + if (th->exception || interruptible (thestack.sf.AddrReturn.Offset)) + { + DWORD *addr_retaddr = ((DWORD *)thestack.sf.AddrFrame.Offset) + 1; + if (*addr_retaddr == thestack.sf.AddrReturn.Offset) + { + interrupt_setup (sig, handler, *addr_retaddr, addr_retaddr, siga); + *addr_retaddr = (DWORD) sigdelayed; + } + return 1; + } + + sigproc_printf ("couldn't find a stack frame, i %d", i); + return 0; +} + +extern "C" void __stdcall +set_sig_errno (int e) +{ + set_errno (e); + sigsave.saved_errno = e; + // sigproc_printf ("errno %d", e); +} + +static int setup_handler (int, void *, struct sigaction&) __attribute__((regparm(3))); +static int +setup_handler (int sig, void *handler, struct sigaction& siga) +{ + CONTEXT cx; + bool interrupted = false; + sigthread *th = NULL; // Initialization needed to shut up gcc + + if (sigsave.sig) + goto out; + + for (int i = 0; i < CALL_HANDLER_RETRY; i++) + { + DWORD res; + HANDLE hth; + + EnterCriticalSection (&mainthread.lock); + if (mainthread.frame) + { + hth = NULL; + th = &mainthread; + } + else + { + LeaveCriticalSection (&mainthread.lock); + + if (!mainthread.get_winapi_lock (1)) + continue; + + hth = myself->getthread2signal (); + th = NULL; + + /* Suspend the thread which will receive the signal. But first ensure that + this thread doesn't have any mutos. (FIXME: Someday we should just grab + all of the mutos rather than checking for them) + For Windows 95, we also have to ensure that the addresses returned by GetThreadContext + are valid. + If one of these conditions is not true we loop for a fixed number of times + since we don't want to stall the signal handler. FIXME: Will this result in + noticeable delays? + If the thread is already suspended (which can occur when a program has called + SuspendThread on itself then just queue the signal. */ + + EnterCriticalSection (&mainthread.lock); +#ifndef DEBUGGING + sigproc_printf ("suspending mainthread"); +#else + cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; + if (!GetThreadContext (hth, &cx)) + memset (&cx, 0, sizeof cx); +#if 0 + if ((cx.Eip & 0xff000000) == 0x77000000) + try_to_debug (); +#endif + sigproc_printf ("suspending mainthread PC %p", cx.Eip); +#endif + res = SuspendThread (hth); + /* Just release the lock now since we hav suspended the main thread and it + definitely can't be grabbing it now. This will have to change, of course, + if/when we can send signals to other than the main thread. */ + LeaveCriticalSection (&mainthread.lock); + + /* Just set pending if thread is already suspended */ + if (res) + { + mainthread.release_winapi_lock (); + (void) ResumeThread (hth); + break; + } + + mainthread.release_winapi_lock (); + if (mainthread.frame) + goto resume_thread; /* We just got the frame. What are the odds? + Just loop and we'll hopefully pick it up on + the next pass through. */ + + muto *m; + /* FIXME: Make multi-thread aware */ + for (m = muto_start.next; m != NULL; m = m->next) + if (m->unstable () || m->owner () == mainthread.id) + { + sigproc_printf ("suspended thread owns a muto (%s)", m->name); + goto resume_thread; + } + + if (mainthread.frame) + th = &mainthread; + else + { + cx.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; + if (!GetThreadContext (hth, &cx)) + { + system_printf ("couldn't get context of main thread, %E"); + goto resume_thread; + } + } + } + + if (th) + { + interrupted = interrupt_on_return (th, sig, handler, siga); + LeaveCriticalSection (&th->lock); + } + else if (interruptible (cx.Eip)) + interrupted = interrupt_now (&cx, sig, handler, siga); + + resume_thread: + if (hth) + res = ResumeThread (hth); + + if (interrupted) + break; + + sigproc_printf ("couldn't interrupt. trying again."); + } + +out: + sigproc_printf ("signal %d %sdelivered", sig, interrupted ? "" : "not "); + return interrupted; +} +#endif /* i386 */ + +#ifndef HAVE_CALL_HANDLER +#error "Need to supply machine dependent setup_handler" +#endif + +/* Keyboard interrupt handler. */ +static BOOL WINAPI +ctrl_c_handler (DWORD type) +{ + static bool saw_close; + + /* Return FALSE to prevent an "End task" dialog box from appearing + for each Cygwin process window that's open when the computer + is shut down or console window is closed. */ + + if (type == CTRL_SHUTDOWN_EVENT) + { +#if 0 + /* Don't send a signal. Only NT service applications and their child + processes will receive this event and the services typically already + handle the shutdown action when getting the SERVICE_CONTROL_SHUTDOWN + control message. */ + sig_send (NULL, SIGTERM); +#endif + return FALSE; + } + + if (myself->ctty != -1 + && (type == CTRL_CLOSE_EVENT || (!saw_close && type == CTRL_LOGOFF_EVENT))) + { + if (type == CTRL_CLOSE_EVENT) + saw_close = true; + sig_send (NULL, SIGHUP); + return FALSE; + } + + /* If we are a stub and the new process has a pinfo structure, let it + handle this signal. */ + if (dwExeced && pinfo (dwExeced)) + return TRUE; + + /* We're only the process group leader when we have a valid pinfo structure. + If we don't have one, then the parent "stub" will handle the signal. */ + if (!pinfo (cygwin_pid (GetCurrentProcessId ()))) + return TRUE; + + tty_min *t = cygwin_shared->tty.get_tty (myself->ctty); + /* Ignore this if we're not the process group leader since it should be handled + *by* the process group leader. */ + if (myself->ctty != -1 && t->getpgid () == myself->pid && + (GetTickCount () - t->last_ctrl_c) >= MIN_CTRL_C_SLOP) + /* Otherwise we just send a SIGINT to the process group and return TRUE (to indicate + that we have handled the signal). At this point, type should be + a CTRL_C_EVENT or CTRL_BREAK_EVENT. */ + { + t->last_ctrl_c = GetTickCount (); + kill (-myself->pid, SIGINT); + t->last_ctrl_c = GetTickCount (); + return TRUE; + } + + return TRUE; +} + +/* Set the signal mask for this process. + Note that some signals are unmaskable, as in UNIX. */ +extern "C" void __stdcall +set_process_mask (sigset_t newmask) +{ + sigframe thisframe (mainthread); + mask_sync->acquire (INFINITE); + sigset_t oldmask = myself->getsigmask (); + newmask &= ~SIG_NONMASKABLE; + sigproc_printf ("old mask = %x, new mask = %x", myself->getsigmask (), newmask); + myself->setsigmask (newmask); // Set a new mask + mask_sync->release (); + if (!(oldmask & ~newmask)) + sigproc_printf ("not calling sig_dispatch_pending. sigtid %p current %p", + sigtid, GetCurrentThreadId ()); + else + { + extern bool pending_signals; + pending_signals = true; + sig_dispatch_pending (); + } + return; +} + +int __stdcall +sig_handle (int sig) +{ + int rc = 1; + + sigproc_printf ("signal %d", sig); + + struct sigaction thissig = myself->getsig (sig); + void *handler = (void *) thissig.sa_handler; + + myself->rusage_self.ru_nsignals++; + + /* Clear pending SIGCONT on stop signals */ + if (sig == SIGSTOP || sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU) + sig_clear (SIGCONT); + + if (sig == SIGKILL) + goto exit_sig; + + if (sig == SIGSTOP) + goto stop; + + /* FIXME: Should we still do this if SIGCONT has a handler? */ + if (sig == SIGCONT) + { + DWORD stopped = myself->process_state & PID_STOPPED; + myself->stopsig = 0; + myself->process_state &= ~PID_STOPPED; + /* Clear pending stop signals */ + sig_clear (SIGSTOP); + sig_clear (SIGTSTP); + sig_clear (SIGTTIN); + sig_clear (SIGTTOU); + if (stopped) + SetEvent (sigCONT); + /* process pending signals */ +#if 0 // FIXME? + sig_dispatch_pending (); +#endif + } + +#if 0 + char sigmsg[24]; + __small_sprintf (sigmsg, "cygwin: signal %d\n", sig); + OutputDebugString (sigmsg); +#endif + + if (handler == (void *) SIG_DFL) + { + if (sig == SIGCHLD || sig == SIGIO || sig == SIGCONT || sig == SIGWINCH + || sig == SIGURG) + { + sigproc_printf ("default signal %d ignored", sig); + goto done; + } + + if (sig == SIGTSTP || sig == SIGTTIN || sig == SIGTTOU) + goto stop; + + goto exit_sig; + } + + if (handler == (void *) SIG_IGN) + { + sigproc_printf ("signal %d ignored", sig); + goto done; + } + + if (handler == (void *) SIG_ERR) + goto exit_sig; + + goto dosig; + +stop: + /* Eat multiple attempts to STOP */ + if (ISSTATE (myself, PID_STOPPED)) + goto done; + handler = (void *) sig_handle_tty_stop; + thissig = myself->getsig (SIGSTOP); + +dosig: + /* Dispatch to the appropriate function. */ + sigproc_printf ("signal %d, about to call %p", sig, handler); + rc = setup_handler (sig, handler, thissig); + +done: + sigproc_printf ("returning %d", rc); + return rc; + +exit_sig: + if (sig == SIGQUIT || sig == SIGABRT) + { + CONTEXT c; + c.ContextFlags = CONTEXT_FULL; + GetThreadContext (hMainThread, &c); + if (!try_to_debug ()) + stackdump (c.Ebp, 1, 1); + sig |= 0x80; + } + sigproc_printf ("signal %d, about to call do_exit", sig); + signal_exit (sig); + /* Never returns */ +} + +CRITICAL_SECTION NO_COPY exit_lock; + +/* Cover function to `do_exit' to handle exiting even in presence of more + exceptions. We used to call exit, but a SIGSEGV shouldn't cause atexit + routines to run. */ +static void +signal_exit (int rc) +{ + EnterCriticalSection (&exit_lock); + rc = EXIT_SIGNAL | (rc << 8); + if (exit_already++) + myself->exit (rc); + + /* We'd like to stop the main thread from executing but when we do that it + causes random, inexplicable hangs. So, instead, we set up the priority + of this thread really high so that it should do its thing and then exit. */ + (void) SetThreadPriority (hMainThread, THREAD_PRIORITY_IDLE); + (void) SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); + + /* Unlock any main thread mutos since we're executing with prejudice. */ + muto *m; + for (m = muto_start.next; m != NULL; m = m->next) + if (m->unstable () || m->owner () == mainthread.id) + m->reset (); + + user_data->resourcelocks->Delete (); + user_data->resourcelocks->Init (); + + if (hExeced) + { + sigproc_printf ("terminating captive process"); + TerminateProcess (hExeced, rc); + } + + sigproc_printf ("about to call do_exit (%x)", rc); + (void) SetEvent (signal_arrived); + do_exit (rc); +} + +HANDLE NO_COPY title_mutex = NULL; + +void +events_init (void) +{ + char *name; + char mutex_name[MAX_PATH]; + /* title_mutex protects modification of console title. It's necessary + while finding console window handle */ + + if (!(title_mutex = CreateMutex (&sec_all_nih, FALSE, + name = shared_name (mutex_name, + "title_mutex", 0)))) + api_fatal ("can't create title mutex '%s', %E", name); + + ProtectHandle (title_mutex); + 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'); + if (end == windows_system_directory) + api_fatal ("can't find windows system directory"); + if (end[-1] != '\\') + { + *end++ = '\\'; + *end = '\0'; + } + windows_system_directory_length = end - windows_system_directory; + debug_printf ("windows_system_directory '%s', windows_system_directory_length %d", + windows_system_directory, windows_system_directory_length); + debug_printf ("cygwin_hmodule %p", cygwin_hmodule); + InitializeCriticalSection (&exit_lock); +} + +void +events_terminate (void) +{ + exit_already = 1; +} + +extern "C" { +static int __stdcall +call_signal_handler_now () +{ + if (!sigsave.sig) + { + sigproc_printf ("call_signal_handler_now called when no signal active"); + return 0; + } + + int sa_flags = sigsave.sa_flags; + sigproc_printf ("sa_flags %p", sa_flags); + *sigsave.retaddr_on_stack = sigsave.retaddr; + sigdelayed0 (); + return sa_flags & SA_RESTART; +} +/* This kludge seems to keep a copy of call_signal_handler_now around + even when compiling with -finline-functions. */ +static int __stdcall call_signal_handler_now_dummy () + __attribute__((alias ("call_signal_handler_now"))); +}; + +int +sigframe::call_signal_handler () +{ + return unregister () ? call_signal_handler_now () : 0; +} + +#define pid_offset (unsigned)(((_pinfo *)NULL)->pid) +extern "C" { +void __stdcall +reset_signal_arrived () +{ + (void) ResetEvent (signal_arrived); + sigproc_printf ("reset signal_arrived"); +} + +#undef errno +#define errno ((DWORD volatile) _impure_ptr) + (((char *) &_impure_ptr->_errno) - ((char *) _impure_ptr)) + +__attribute__((const, used, noinline)) static void +unused_sig_wrapper () +{ +/* Signal cleanup stuff. Cleans up stack (too bad that we didn't + prototype signal handlers as __stdcall), calls _set_process_mask + to restore any mask, restores any potentially clobbered registers + and returns to original caller. */ +__asm__ volatile ("\n\ + .text \n\ +_sigreturn: \n\ + addl $4,%%esp # Remove argument \n\ + call _set_process_mask@4 \n\ + \n\ + cmpl $0,%4 # Did a signal come in? \n\ + jz 1f # No, if zero \n\ + movl %2,%%eax \n\ + movl %8,%%ebx # Where return address lives \n\ + movl %%eax,(%%ebx) # Restore return address of \n\ + # most recent caller \n\ + jmp 3f \n\ + \n\ +1: popl %%eax # saved errno \n\ + testl %%eax,%%eax # Is it < 0 \n\ + jl 2f # yup. ignore it \n\ + movl %1,%%ebx \n\ + movl %%eax,(%%ebx) \n\ +2: popl %%eax \n\ + popl %%ebx \n\ + popl %%ecx \n\ + popl %%edx \n\ + popl %%edi \n\ + popl %%esi \n\ + popf \n\ + popl %%ebp \n\ + ret \n\ + \n\ +__no_sig_start: \n\ +_sigdelayed: \n\ + pushl %2 # original return address \n\ +_sigdelayed0: \n\ + pushl %%ebp \n\ + movl %%esp,%%ebp \n\ + pushf \n\ + pushl %%esi \n\ + pushl %%edi \n\ + pushl %%edx \n\ + pushl %%ecx \n\ + pushl %%ebx \n\ + pushl %%eax \n\ + pushl %6 # saved errno \n\ +3: pushl %3 # oldmask \n\ + pushl %4 # signal argument \n\ + pushl $_sigreturn \n\ + \n\ + call _reset_signal_arrived@0 \n\ + pushl %5 # signal number \n\ + pushl %7 # newmask \n\ + \n\ + call _set_process_mask@4 \n\ + movl $0,%0 # zero the signal number as a \n\ + # flag to the signal handler thread\n\ + # that it is ok to set up sigsave\n\ + popl %%eax \n\ + jmp *%%eax \n\ +__no_sig_end: \n\ +" : "=m" (sigsave.sig)/*0*/: "X" ((char *) &_impure_ptr->_errno)/*1*/, + "g" (sigsave.retaddr)/*2*/, "g" (sigsave.oldmask)/*3*/, "g" (sigsave.sig)/*4*/, + "g" (sigsave.func)/*5*/, "g" (sigsave.saved_errno)/*6*/, "g" (sigsave.newmask)/*7*/, + "g" (sigsave.retaddr_on_stack)/*8*/ +); +} +} diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc new file mode 100644 index 00000000000..4fe7d159350 --- /dev/null +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -0,0 +1,851 @@ +/* fhandler_disk_file.cc + + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 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 <unistd.h> +#include <stdlib.h> +#include <sys/cygwin.h> +#include <signal.h> +#include "cygerrno.h" +#include "perprocess.h" +#include "security.h" +#include "cygwin/version.h" +#include "fhandler.h" +#include "path.h" +#include "dtable.h" +#include "cygheap.h" +#include "shared_info.h" +#include "pinfo.h" +#include <assert.h> +#include <ctype.h> + +#define _COMPILING_NEWLIB +#include <dirent.h> + +unsigned __stdcall +path_conv::ndisk_links (DWORD nNumberOfLinks) +{ + if (!isdir () || isremote ()) + return nNumberOfLinks; + + int len = strlen (*this); + char fn[len + 3]; + strcpy (fn, *this); + + const char *s; + unsigned count; + if (nNumberOfLinks <= 1) + { + s = "/*"; + count = 0; + } + else + { + s = "/.."; + count = nNumberOfLinks; + } + + if (len == 0 || isdirsep (fn[len - 1])) + strcpy (fn + len, s + 1); + else + strcpy (fn + len, s); + + WIN32_FIND_DATA buf; + HANDLE h = FindFirstFile (fn, &buf); + + int saw_dot = 2; + if (h != INVALID_HANDLE_VALUE) + { + if (nNumberOfLinks > 1) + saw_dot--; + else + do + { + if (buf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + count++; + if (buf.cFileName[0] == '.' + && (buf.cFileName[1] == '\0' + || (buf.cFileName[1] == '.' && buf.cFileName[2] == '\0'))) + saw_dot--; + } + while (FindNextFileA (h, &buf)); + FindClose (h); + } + + if (nNumberOfLinks > 1) + { + fn[len + 2] = '\0'; + h = FindFirstFile (fn, &buf); + if (h) + saw_dot--; + FindClose (h); + } + + return count + saw_dot; +} + +int __stdcall +fhandler_disk_file::fstat_by_handle (struct __stat64 *buf, path_conv *pc) +{ + int res = 0; + BY_HANDLE_FILE_INFORMATION local; + + /* NT 3.51 seems to have a bug when attempting to get vol serial + numbers. This loop gets around this. */ + for (int i = 0; i < 2; i++) + { + if (!(res = GetFileInformationByHandle (get_handle (), &local))) + break; + if (local.dwVolumeSerialNumber && (long) local.dwVolumeSerialNumber != -1) + break; + } + debug_printf ("%d = GetFileInformationByHandle (%s, %d)", + res, get_win32_name (), get_handle ()); + if (res == 0) + /* GetFileInformationByHandle will fail if it's given stdin/out/err + or a pipe*/ + { + memset (&local, 0, sizeof (local)); + local.nFileSizeLow = GetFileSize (get_handle (), &local.nFileSizeHigh); + } + + return fstat_helper (buf, pc, + local.ftCreationTime, + local.ftLastAccessTime, + local.ftLastWriteTime, + local.nFileSizeHigh, + local.nFileSizeLow, + local.nFileIndexHigh, + local.nFileIndexLow, + local.nNumberOfLinks); +} + +int __stdcall +fhandler_disk_file::fstat_by_name (struct __stat64 *buf, path_conv *pc) +{ + int res; + HANDLE handle; + WIN32_FIND_DATA local; + + if (!pc->exists ()) + { + debug_printf ("already determined that pc does not exist"); + set_errno (ENOENT); + res = -1; + } + else if ((handle = FindFirstFile (*pc, &local)) != INVALID_HANDLE_VALUE) + { + FindClose (handle); + res = fstat_helper (buf, pc, + local.ftCreationTime, + local.ftLastAccessTime, + local.ftLastWriteTime, + local.nFileSizeHigh, + local.nFileSizeLow); + } + else if (pc->isdir ()) + { + FILETIME ft = {}; + res = fstat_helper (buf, pc, ft, ft, ft, 0, 0); + } + else + { + debug_printf ("FindFirstFile failed for '%s', %E", (char *) *pc); + __seterrno (); + res = -1; + } + return res; +} + +int __stdcall +fhandler_disk_file::fstat (struct __stat64 *buf, path_conv *pc) +{ + int res = -1; + int oret; + int open_flags = O_RDONLY | O_BINARY | O_DIROPEN; + bool query_open_already; + + if (get_io_handle ()) + { + if (get_nohandle ()) + return fstat_by_name (buf, pc); + else + return fstat_by_handle (buf, pc); + } + /* If we don't care if the file is executable or we already know if it is, + then just do a "query open" as it is apparently much faster. */ + if (pc->exec_state () != dont_know_if_executable) + set_query_open (query_open_already = true); + else + query_open_already = false; + + if (query_open_already && strncasematch (pc->volname (), "FAT", 3) + && !strpbrk (get_win32_name (), "?*|<>")) + oret = 0; + else if (!(oret = open (pc, open_flags, 0)) + && !query_open_already + && get_errno () == EACCES) + { + /* If we couldn't open the file, try a "query open" with no permissions. + This will allow us to determine *some* things about the file, at least. */ + pc->set_exec (0); + set_query_open (true); + oret = open (pc, open_flags, 0); + } + + if (!oret || get_nohandle ()) + res = fstat_by_name (buf, pc); + else + { + res = fstat_by_handle (buf, pc); + close (); + } + + return res; +} + +int __stdcall +fhandler_disk_file::fstat_helper (struct __stat64 *buf, path_conv *pc, + FILETIME ftCreationTime, + FILETIME ftLastAccessTime, + FILETIME ftLastWriteTime, + DWORD nFileSizeHigh, + DWORD nFileSizeLow, + DWORD nFileIndexHigh, + DWORD nFileIndexLow, + DWORD nNumberOfLinks) +{ + /* This is for FAT filesystems, which don't support atime/ctime */ + if (ftLastAccessTime.dwLowDateTime == 0 + && ftLastAccessTime.dwHighDateTime == 0) + ftLastAccessTime = ftLastWriteTime; + if (ftCreationTime.dwLowDateTime == 0 + && ftCreationTime.dwHighDateTime == 0) + ftCreationTime = ftLastWriteTime; + + to_timestruc_t (&ftLastAccessTime, &buf->st_atim); + to_timestruc_t (&ftLastWriteTime, &buf->st_mtim); + to_timestruc_t (&ftCreationTime, &buf->st_ctim); + buf->st_dev = pc->volser (); + buf->st_size = ((_off64_t)nFileSizeHigh << 32) + nFileSizeLow; + /* The number of links to a directory includes the + number of subdirectories in the directory, since all + those subdirectories point to it. + This is too slow on remote drives, so we do without it. + Setting the count to 2 confuses `find (1)' command. So + let's try it with `1' as link count. */ + buf->st_nlink = pc->ndisk_links (nNumberOfLinks); + + /* Assume that if a drive has ACL support it MAY have valid "inodes". + It definitely does not have valid inodes if it does not have ACL + support. */ + switch (pc->has_acls () && (nFileIndexHigh || nFileIndexLow) + ? pc->drive_type () : DRIVE_UNKNOWN) + { + case DRIVE_FIXED: + case DRIVE_REMOVABLE: + case DRIVE_CDROM: + case DRIVE_RAMDISK: + /* Although the documentation indicates otherwise, it seems like + "inodes" on these devices are persistent, at least across reboots. */ + buf->st_ino = (((__ino64_t) nFileIndexHigh) << 32) + | (__ino64_t) nFileIndexLow; + break; + default: + /* Either the nFileIndex* fields are unreliable or unavailable. Use the + next best alternative. */ + buf->st_ino = get_namehash (); + break; + } + + buf->st_blksize = S_BLKSIZE; + + /* GetCompressedFileSize() gets autoloaded. It returns INVALID_FILE_SIZE + if it doesn't exist. Since that's also a valid return value on 64bit + capable file systems, we must additionally check for the win32 error. */ + nFileSizeLow = GetCompressedFileSizeA (pc->get_win32 (), &nFileSizeHigh); + if (nFileSizeLow != INVALID_FILE_SIZE || GetLastError () == NO_ERROR) + /* On systems supporting compressed (and sparsed) files, + GetCompressedFileSize() returns the actual amount of + bytes allocated on disk. */ + buf->st_blocks = (((_off64_t)nFileSizeHigh << 32) + + nFileSizeLow + S_BLKSIZE - 1) / S_BLKSIZE; + else + /* Just compute no. of blocks from file size. */ + buf->st_blocks = (buf->st_size + S_BLKSIZE - 1) / S_BLKSIZE; + + buf->st_mode = 0; + /* Using a side effect: get_file_attibutes checks for + directory. This is used, to set S_ISVTX, if needed. */ + if (pc->isdir ()) + buf->st_mode = S_IFDIR; + else if (pc->issymlink ()) + { + /* symlinks are everything for everyone! */ + buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO; + get_file_attribute (pc->has_acls (), get_win32_name (), NULL, + &buf->st_uid, &buf->st_gid); + goto done; + } + else if (pc->issocket ()) + buf->st_mode = S_IFSOCK; + + if (get_file_attribute (pc->has_acls (), get_win32_name (), &buf->st_mode, + &buf->st_uid, &buf->st_gid) == 0) + { + /* If read-only attribute is set, modify ntsec return value */ + if (pc->has_attribute (FILE_ATTRIBUTE_READONLY) && !get_symlink_p ()) + buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); + + if (!(buf->st_mode & S_IFMT)) + buf->st_mode |= S_IFREG; + } + else + { + buf->st_mode |= STD_RBITS; + + if (!pc->has_attribute (FILE_ATTRIBUTE_READONLY)) + buf->st_mode |= STD_WBITS; + /* | S_IWGRP | S_IWOTH; we don't give write to group etc */ + + if (S_ISDIR (buf->st_mode)) + buf->st_mode |= S_IFDIR | STD_XBITS; + else if (buf->st_mode & S_IFMT) + /* nothing */; + else + { + buf->st_mode |= S_IFREG; + if (pc->exec_state () == dont_know_if_executable) + { + DWORD cur, done; + char magic[3]; + + /* First retrieve current position, set to beginning + of file if not already there. */ + cur = SetFilePointer (get_handle (), 0, NULL, FILE_CURRENT); + if (cur != INVALID_SET_FILE_POINTER + && (!cur || SetFilePointer (get_handle (), 0, NULL, FILE_BEGIN) + != INVALID_SET_FILE_POINTER)) + { + /* FIXME should we use /etc/magic ? */ + magic[0] = magic[1] = magic[2] = '\0'; + if (ReadFile (get_handle (), magic, 3, &done, NULL) + && has_exec_chars (magic, done)) + { + set_execable_p (); + pc->set_exec (); + buf->st_mode |= STD_XBITS; + } + (void) SetFilePointer (get_handle (), cur, NULL, FILE_BEGIN); + } + } + } + + if (pc->exec_state () == is_executable) + buf->st_mode |= STD_XBITS; + + /* This fakes the permissions of all files to match the current umask. */ + buf->st_mode &= ~(cygheap->umask); + } + + done: + syscall_printf ("0 = fstat (, %p) st_atime=%x st_size=%D, st_mode=%p, st_ino=%d, sizeof=%d", + buf, buf->st_atime, buf->st_size, buf->st_mode, + (int) buf->st_ino, sizeof (*buf)); + return 0; +} + +fhandler_disk_file::fhandler_disk_file (DWORD devtype) : + fhandler_base (devtype) +{ +} + +fhandler_disk_file::fhandler_disk_file () : + fhandler_base (FH_DISK) +{ +} + +int +fhandler_disk_file::open (path_conv *real_path, int flags, mode_t mode) +{ + if (real_path->case_clash && flags & O_CREAT) + { + debug_printf ("case clash detected"); + set_errno (ECASECLASH); + return 0; + } + + set_has_acls (real_path->has_acls ()); + set_isremote (real_path->isremote ()); + + int res = fhandler_base::open (real_path, flags | O_DIROPEN, mode); + if (!res) + goto out; + + /* This is for file systems known for having a buggy CreateFile call + which might return a valid HANDLE without having actually opened + the file. + The only known file system to date is the SUN NFS Solstice Client 3.1 + which returns a valid handle when trying to open a file in a nonexistent + directory. */ + if (real_path->has_buggy_open () && !real_path->exists ()) + { + debug_printf ("Buggy open detected."); + close (); + set_errno (ENOENT); + return 0; + } + + /* Attributes may be set only if a file is _really_ created. + This code is now only used for ntea here since the files + security attributes are set in CreateFile () now. */ + if (flags & O_CREAT + && GetLastError () != ERROR_ALREADY_EXISTS + && !allow_ntsec && allow_ntea) + set_file_attribute (has_acls (), get_win32_name (), mode); + + set_fs_flags (real_path->fs_flags ()); + set_symlink_p (real_path->issymlink ()); + set_execable_p (real_path->exec_state ()); + set_socket_p (real_path->issocket ()); + +out: + syscall_printf ("%d = fhandler_disk_file::open (%s, %p)", res, + get_win32_name (), flags); + return res; +} + +int +fhandler_disk_file::close () +{ + int res = fhandler_base::close (); + if (!res) + cygwin_shared->delqueue.process_queue (); + return res; +} + +/* + * FIXME !!! + * The correct way to do this to get POSIX locking + * semantics is to keep a linked list of posix lock + * requests and map them into Win32 locks. The problem + * is that Win32 does not deal correctly with overlapping + * lock requests. Also another pain is that Win95 doesn't do + * non-blocking or non exclusive locks at all. For '95 just + * convert all lock requests into blocking,exclusive locks. + * This shouldn't break many apps but denying all locking + * would. + * For now just convert to Win32 locks and hope for the best. + */ + +int +fhandler_disk_file::lock (int cmd, struct flock *fl) +{ + _off64_t win32_start; + int win32_len; + DWORD win32_upper; + _off64_t startpos; + + /* + * We don't do getlck calls yet. + */ + + if (cmd == F_GETLK) + { + set_errno (ENOSYS); + return -1; + } + + /* + * Calculate where in the file to start from, + * then adjust this by fl->l_start. + */ + + switch (fl->l_whence) + { + case SEEK_SET: + startpos = 0; + break; + case SEEK_CUR: + if ((startpos = lseek (0, SEEK_CUR)) == ILLEGAL_SEEK) + return -1; + break; + case SEEK_END: + { + BY_HANDLE_FILE_INFORMATION finfo; + if (GetFileInformationByHandle (get_handle (), &finfo) == 0) + { + __seterrno (); + return -1; + } + startpos = ((_off64_t)finfo.nFileSizeHigh << 32) + + finfo.nFileSizeLow; + break; + } + default: + set_errno (EINVAL); + return -1; + } + + /* + * Now the fun starts. Adjust the start and length + * fields until they make sense. + */ + + win32_start = startpos + fl->l_start; + if (fl->l_len < 0) + { + win32_start -= fl->l_len; + win32_len = -fl->l_len; + } + else + win32_len = fl->l_len; + + if (win32_start < 0) + { + /* watch the signs! */ + win32_len -= -win32_start; + if (win32_len <= 0) + { + /* Failure ! */ + set_errno (EINVAL); + return -1; + } + win32_start = 0; + } + + /* + * Special case if len == 0 for POSIX means lock + * to the end of the entire file (and all future extensions). + */ + if (win32_len == 0) + { + win32_len = 0xffffffff; + win32_upper = wincap.lock_file_highword (); + } + else + win32_upper = 0; + + BOOL res; + + if (wincap.has_lock_file_ex ()) + { + DWORD lock_flags = (cmd == F_SETLK) ? LOCKFILE_FAIL_IMMEDIATELY : 0; + lock_flags |= (fl->l_type == F_WRLCK) ? LOCKFILE_EXCLUSIVE_LOCK : 0; + + OVERLAPPED ov; + + ov.Internal = 0; + ov.InternalHigh = 0; + ov.Offset = (DWORD)win32_start; + ov.OffsetHigh = 0; + ov.hEvent = (HANDLE) 0; + + if (fl->l_type == F_UNLCK) + { + res = UnlockFileEx (get_handle (), 0, (DWORD)win32_len, win32_upper, &ov); + } + else + { + res = LockFileEx (get_handle (), lock_flags, 0, (DWORD)win32_len, + win32_upper, &ov); + /* Deal with the fail immediately case. */ + /* + * FIXME !! I think this is the right error to check for + * but I must admit I haven't checked.... + */ + if ((res == 0) && (lock_flags & LOCKFILE_FAIL_IMMEDIATELY) && + (GetLastError () == ERROR_LOCK_FAILED)) + { + set_errno (EAGAIN); + return -1; + } + } + } + else + { + /* Windows 95 -- use primitive lock call */ + if (fl->l_type == F_UNLCK) + res = UnlockFile (get_handle (), (DWORD)win32_start, 0, (DWORD)win32_len, + win32_upper); + else + res = LockFile (get_handle (), (DWORD)win32_start, 0, (DWORD)win32_len, win32_upper); + } + + if (res == 0) + { + __seterrno (); + return -1; + } + + return 0; +} + +DIR * +fhandler_disk_file::opendir (path_conv& real_name) +{ + DIR *dir; + DIR *res = NULL; + size_t len; + + if (!real_name.isdir ()) + set_errno (ENOTDIR); + else if ((len = strlen (real_name))> MAX_PATH - 3) + set_errno (ENAMETOOLONG); + else if ((dir = (DIR *) malloc (sizeof (DIR))) == NULL) + set_errno (ENOMEM); + else if ((dir->__d_dirname = (char *) malloc (len + 3)) == NULL) + { + free (dir); + set_errno (ENOMEM); + } + else if ((dir->__d_dirent = + (struct dirent *) malloc (sizeof (struct dirent))) == NULL) + { + free (dir->__d_dirname); + free (dir); + set_errno (ENOMEM); + } + else + { + strcpy (dir->__d_dirname, real_name.get_win32 ()); + dir->__d_dirent->d_version = __DIRENT_VERSION; + cygheap_fdnew fd; + if (fd >= 0) + { + fd = this; + fd->set_nohandle (true); + dir->__d_dirent->d_fd = fd; + dir->__fh = this; + /* FindFirstFile doesn't seem to like duplicate /'s. */ + len = strlen (dir->__d_dirname); + if (len == 0 || isdirsep (dir->__d_dirname[len - 1])) + strcat (dir->__d_dirname, "*"); + else + strcat (dir->__d_dirname, "\\*"); /**/ + dir->__d_cookie = __DIRENT_COOKIE; + dir->__handle = INVALID_HANDLE_VALUE; + dir->__d_position = 0; + dir->__d_dirhash = get_namehash (); + + res = dir; + } + if (real_name.isencoded ()) + set_encoded (); + } + + syscall_printf ("%p = opendir (%s)", res, get_name ()); + return res; +} + +struct dirent * +fhandler_disk_file::readdir (DIR *dir) +{ + WIN32_FIND_DATA buf; + HANDLE handle; + struct dirent *res = NULL; + + if (dir->__handle == INVALID_HANDLE_VALUE + && dir->__d_position == 0) + { + handle = FindFirstFileA (dir->__d_dirname, &buf); + DWORD lasterr = GetLastError (); + dir->__handle = handle; + if (handle == INVALID_HANDLE_VALUE && (lasterr != ERROR_NO_MORE_FILES)) + { + seterrno_from_win_error (__FILE__, __LINE__, lasterr); + return res; + } + } + else if (dir->__handle == INVALID_HANDLE_VALUE) + return res; + else if (!FindNextFileA (dir->__handle, &buf)) + { + DWORD lasterr = GetLastError (); + (void) FindClose (dir->__handle); + dir->__handle = INVALID_HANDLE_VALUE; + /* POSIX says you shouldn't set errno when readdir can't + find any more files; so, if another error we leave it set. */ + if (lasterr != ERROR_NO_MORE_FILES) + seterrno_from_win_error (__FILE__, __LINE__, lasterr); + syscall_printf ("%p = readdir (%p)", res, dir); + return res; + } + + /* We get here if `buf' contains valid data. */ + if (get_encoded ()) + (void) fnunmunge (dir->__d_dirent->d_name, buf.cFileName); + else + strcpy (dir->__d_dirent->d_name, buf.cFileName); + + /* Check for Windows shortcut. If it's a Cygwin or U/WIN + symlink, drop the .lnk suffix. */ + if (buf.dwFileAttributes & FILE_ATTRIBUTE_READONLY) + { + char *c = dir->__d_dirent->d_name; + int len = strlen (c); + if (strcasematch (c + len - 4, ".lnk")) + { + char fbuf[MAX_PATH + 1]; + strcpy (fbuf, dir->__d_dirname); + strcpy (fbuf + strlen (fbuf) - 1, dir->__d_dirent->d_name); + path_conv fpath (fbuf, PC_SYM_NOFOLLOW); + if (fpath.issymlink ()) + c[len - 4] = '\0'; + } + } + + dir->__d_position++; + res = dir->__d_dirent; + syscall_printf ("%p = readdir (%p) (%s)", + &dir->__d_dirent, dir, buf.cFileName); + return res; +} + +_off64_t +fhandler_disk_file::telldir (DIR *dir) +{ + return dir->__d_position; +} + +void +fhandler_disk_file::seekdir (DIR *dir, _off64_t loc) +{ + rewinddir (dir); + while (loc > dir->__d_position) + if (!readdir (dir)) + break; +} + +void +fhandler_disk_file::rewinddir (DIR *dir) +{ + if (dir->__handle != INVALID_HANDLE_VALUE) + { + (void) FindClose (dir->__handle); + dir->__handle = INVALID_HANDLE_VALUE; + } + dir->__d_position = 0; +} + +int +fhandler_disk_file::closedir (DIR *dir) +{ + int res = 0; + if (dir->__handle != INVALID_HANDLE_VALUE && + FindClose (dir->__handle) == 0) + { + __seterrno (); + res = -1; + } + syscall_printf ("%d = closedir (%p)", res, dir); + return 0; +} + +fhandler_cygdrive::fhandler_cygdrive (int unit) : + fhandler_disk_file (FH_CYGDRIVE), unit (unit), ndrives (0), pdrive (NULL) +{ +} + +#define DRVSZ sizeof ("x:\\") +void +fhandler_cygdrive::set_drives () +{ + const int len = 2 + 26 * DRVSZ; + char *p = (char *) crealloc ((void *) win32_path_name, len); + + win32_path_name = pdrive = p; + ndrives = GetLogicalDriveStrings (len, p) / DRVSZ; +} + +int +fhandler_cygdrive::fstat (struct __stat64 *buf, path_conv *pc) +{ + if (!iscygdrive_root ()) + return fhandler_disk_file::fstat (buf, pc); + buf->st_mode = S_IFDIR | 0555; + if (!ndrives) + set_drives (); + buf->st_nlink = ndrives + 2; + return 0; +} + +DIR * +fhandler_cygdrive::opendir (path_conv& real_name) +{ + DIR *dir; + + dir = fhandler_disk_file::opendir (real_name); + if (dir && iscygdrive_root () && !ndrives) + set_drives (); + + return dir; +} + +struct dirent * +fhandler_cygdrive::readdir (DIR *dir) +{ + if (!iscygdrive_root ()) + return fhandler_disk_file::readdir (dir); + if (!pdrive || !*pdrive) + return NULL; + if (GetFileAttributes (pdrive) == INVALID_FILE_ATTRIBUTES) + { + pdrive = strchr (pdrive, '\0') + 1; + return readdir (dir); + } + + *dir->__d_dirent->d_name = cyg_tolower (*pdrive); + dir->__d_dirent->d_name[1] = '\0'; + dir->__d_position++; + pdrive = strchr (pdrive, '\0') + 1; + syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir, + dir->__d_dirent->d_name); + return dir->__d_dirent; +} + +_off64_t +fhandler_cygdrive::telldir (DIR *dir) +{ + return fhandler_disk_file::telldir (dir); +} + +void +fhandler_cygdrive::seekdir (DIR *dir, _off64_t loc) +{ + if (!iscygdrive_root ()) + return fhandler_disk_file::seekdir (dir, loc); + + for (pdrive = win32_path_name, dir->__d_position = -1; *pdrive; + pdrive = strchr (pdrive, '\0') + 1) + if (++dir->__d_position >= loc) + break; + + return; +} + +void +fhandler_cygdrive::rewinddir (DIR *dir) +{ + if (!iscygdrive_root ()) + return fhandler_disk_file::rewinddir (dir); + pdrive = win32_path_name; + dir->__d_position = 0; + return; +} + +int +fhandler_cygdrive::closedir (DIR *dir) +{ + if (!iscygdrive_root ()) + return fhandler_disk_file::closedir (dir); + pdrive = win32_path_name; + return -1; +} diff --git a/winsup/cygwin/libc/getopt.c b/winsup/cygwin/libc/getopt.c new file mode 100644 index 00000000000..90a2026019e --- /dev/null +++ b/winsup/cygwin/libc/getopt.c @@ -0,0 +1,504 @@ +/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "winsup.h" +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <getopt.h> +#include <stdarg.h> +#include <stdio.h> + +#define REPLACE_GETOPT + +#define _DIAGASSERT(x) do {} while (0) + +#ifdef REPLACE_GETOPT +#ifdef __weak_alias +__weak_alias(getopt,_getopt) +#endif +int __declspec(dllexport) opterr = 1; /* if error message should be printed */ +int __declspec(dllexport) optind = 1; /* index into parent argv vector */ +int __declspec(dllexport) optopt = '?'; /* character checked for validity */ +int __declspec(dllexport) optreset; /* reset getopt */ +char __declspec(dllexport) *optarg; /* argument associated with option */ +#endif + +#ifdef __weak_alias +__weak_alias(getopt_long,_getopt_long) +#endif + +#ifndef __CYGWIN__ +#define __progname __argv[0] +#else +extern char *__progname; +#endif + +#define IGNORE_FIRST (*options == '-' || *options == '+') +#define PRINT_ERROR ((opterr) && ((*options != ':') \ + || (IGNORE_FIRST && options[1] != ':'))) + +#define IS_POSIXLY_CORRECT (getenv("POSIXLY_INCORRECT_GETOPT") == NULL) + +#define PERMUTE (!IS_POSIXLY_CORRECT && !IGNORE_FIRST) +/* XXX: GNU ignores PC if *options == '-' */ +#define IN_ORDER (!IS_POSIXLY_CORRECT && *options == '-') + +/* return values */ +#define BADCH (int)'?' +#define BADARG ((IGNORE_FIRST && options[1] == ':') \ + || (*options == ':') ? (int)':' : (int)'?') +#define INORDER (int)1 + +static char EMSG[1]; + +static int getopt_internal (int, char * const *, const char *); +static int gcd (int, int); +static void permute_args (int, int, int, char * const *); + +static char *place = EMSG; /* option letter processing */ + +/* XXX: set optreset to 1 rather than these two */ +static int nonopt_start = -1; /* first non option argument (for permute) */ +static int nonopt_end = -1; /* first option after non options (for permute) */ + +/* Error messages */ +static const char recargchar[] = "option requires an argument -- %c"; +static const char recargstring[] = "option requires an argument -- %s"; +static const char ambig[] = "ambiguous option -- %.*s"; +static const char noarg[] = "option doesn't take an argument -- %.*s"; +static const char illoptchar[] = "unknown option -- %c"; +static const char illoptstring[] = "unknown option -- %s"; + +static void +_vwarnx(const char *fmt, va_list ap) +{ + (void)fprintf(stderr, "%s: ", __progname); + if (fmt != NULL) + (void)vfprintf(stderr, fmt, ap); + (void)fprintf(stderr, "\n"); +} + +static void +warnx(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + _vwarnx(fmt, ap); + va_end(ap); +} + +/* + * Compute the greatest common divisor of a and b. + */ +static int +gcd(a, b) + int a; + int b; +{ + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return b; +} + +/* + * Exchange the block from nonopt_start to nonopt_end with the block + * from nonopt_end to opt_end (keeping the same order of arguments + * in each block). + */ +static void +permute_args(panonopt_start, panonopt_end, opt_end, nargv) + int panonopt_start; + int panonopt_end; + int opt_end; + char * const *nargv; +{ + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + _DIAGASSERT(nargv != NULL); + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = panonopt_end - panonopt_start; + nopts = opt_end - panonopt_end; + ncycle = gcd(nnonopts, nopts); + cyclelen = (opt_end - panonopt_start) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = panonopt_end+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= panonopt_end) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } +} + +/* + * getopt_internal -- + * Parse argc/argv argument vector. Called by user level routines. + * Returns -2 if -- is found (can be long option or end of options marker). + */ +static int +getopt_internal(nargc, nargv, options) + int nargc; + char * const *nargv; + const char *options; +{ + char *oli; /* option letter list index */ + int optchar; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + + optarg = NULL; + + /* + * XXX Some programs (like rsyncd) expect to be able to + * XXX re-initialize optind to 0 and have getopt_long(3) + * XXX properly function again. Work around this braindamage. + */ + if (optind == 0) + optind = 1; + + if (optreset) + nonopt_start = nonopt_end = -1; +start: + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc) { /* end of argument vector */ + place = EMSG; + if (nonopt_end != -1) { + /* do permutation, if we have to */ + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + else if (nonopt_start != -1) { + /* + * If we skipped non-options, set optind + * to the first of them. + */ + optind = nonopt_start; + } + nonopt_start = nonopt_end = -1; + return -1; + } + if ((*(place = nargv[optind]) != '-') + || (place[1] == '\0')) { /* found non-option */ + place = EMSG; + if (IN_ORDER) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + optarg = nargv[optind++]; + return INORDER; + } + if (!PERMUTE) { + /* + * if no permutation wanted, stop parsing + * at first non-option + */ + return -1; + } + /* do permutation */ + if (nonopt_start == -1) + nonopt_start = optind; + else if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + nonopt_start = optind - + (nonopt_end - nonopt_start); + nonopt_end = -1; + } + optind++; + /* process next argument */ + goto start; + } + if (nonopt_start != -1 && nonopt_end == -1) + nonopt_end = optind; + if (place[1] && *++place == '-') { /* found "--" */ + place++; + return -2; + } + } + if ((optchar = (int)*place++) == (int)':' || + (oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) { + /* option letter unknown or ':' */ + if (!*place) + ++optind; + if (PRINT_ERROR) + warnx(illoptchar, optchar); + optopt = optchar; + return BADCH; + } + if (optchar == 'W' && oli[1] == ';') { /* -W long-option */ + /* XXX: what if no long options provided (called by getopt)? */ + if (*place) + return -2; + + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return BADARG; + } else /* white space */ + place = nargv[optind]; + /* + * Handle -W arg the same as --arg (which causes getopt to + * stop parsing). + */ + return -2; + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*place) + ++optind; + } else { /* takes (optional) argument */ + optarg = NULL; + if (*place) /* no white space */ + optarg = place; + /* XXX: disable test for :: if PC? (GNU doesn't) */ + else if (oli[1] != ':') { /* arg not optional */ + if (++optind >= nargc) { /* no arg */ + place = EMSG; + if (PRINT_ERROR) + warnx(recargchar, optchar); + optopt = optchar; + return BADARG; + } else + optarg = nargv[optind]; + } + place = EMSG; + ++optind; + } + /* dump back option letter */ + return optchar; +} + +#ifdef REPLACE_GETOPT +/* + * getopt -- + * Parse argc/argv argument vector. + * + * [eventually this will replace the real getopt] + */ +int +getopt(nargc, nargv, options) + int nargc; + char * const *nargv; + const char *options; +{ + int retval; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + + if ((retval = getopt_internal(nargc, nargv, options)) == -2) { + ++optind; + /* + * We found an option (--), so if we skipped non-options, + * we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, optind, + nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + retval = -1; + } + return retval; +} +#endif + +/* + * getopt_long -- + * Parse argc/argv argument vector. + */ +int +getopt_long(nargc, nargv, options, long_options, idx) + int nargc; + char * const *nargv; + const char *options; + const struct option *long_options; + int *idx; +{ + int retval; + + _DIAGASSERT(nargv != NULL); + _DIAGASSERT(options != NULL); + _DIAGASSERT(long_options != NULL); + /* idx may be NULL */ + + if ((retval = getopt_internal(nargc, nargv, options)) == -2) { + char *current_argv, *has_equal; + size_t current_argv_len; + int i, match; + + current_argv = place; + match = -1; + + optind++; + place = EMSG; + + if (*current_argv == '\0') { /* found "--" */ + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (nonopt_end != -1) { + permute_args(nonopt_start, nonopt_end, + optind, nargv); + optind -= nonopt_end - nonopt_start; + } + nonopt_start = nonopt_end = -1; + return -1; + } + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else + current_argv_len = strlen(current_argv); + + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == + (unsigned)current_argv_len) { + /* exact match */ + match = i; + break; + } + if (match == -1) /* partial match */ + match = i; + else { + /* ambiguous abbreviation */ + if (PRINT_ERROR) + warnx(ambig, (int)current_argv_len, + current_argv); + optopt = 0; + return BADCH; + } + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (PRINT_ERROR) + warnx(noarg, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets optopt to val regardless of + * flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + return BADARG; + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + optarg = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use + * next nargv + */ + optarg = nargv[optind++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (optarg == NULL)) { + /* + * Missing argument; leading ':' + * indicates no error should be generated + */ + if (PRINT_ERROR) + warnx(recargstring, current_argv); + /* + * XXX: GNU sets optopt to val regardless + * of flag + */ + if (long_options[match].flag == NULL) + optopt = long_options[match].val; + else + optopt = 0; + --optind; + return BADARG; + } + } else { /* unknown option */ + if (PRINT_ERROR) + warnx(illoptstring, current_argv); + optopt = 0; + return BADCH; + } + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + retval = 0; + } else + retval = long_options[match].val; + if (idx) + *idx = match; + } + return retval; +} |