Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Collins <rbtcollins@hotmail.com>2002-06-13 18:34:20 +0400
committerRobert Collins <rbtcollins@hotmail.com>2002-06-13 18:34:20 +0400
commit5db981e43b6fd700ca5b16e64468662b247a4ed5 (patch)
treee9ca06bd344662375321197afcc8671bcc8cd633 /winsup/cygwin
parent5eea0254c7a10b31f9c9b3f6339ce454d1d0a27c (diff)
Merged changes from HEAD
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog1409
-rw-r--r--winsup/cygwin/Makefile.in35
-rw-r--r--winsup/cygwin/autoload.cc27
-rw-r--r--winsup/cygwin/child_info.h2
-rw-r--r--winsup/cygwin/cygheap.cc26
-rw-r--r--winsup/cygwin/cygheap.h28
-rwxr-xr-xwinsup/cygwin/cygserver.cc107
-rwxr-xr-xwinsup/cygwin/cygserver_client.cc12
-rwxr-xr-xwinsup/cygwin/cygserver_process.cc17
-rwxr-xr-xwinsup/cygwin/cygserver_shm.cc651
-rw-r--r--winsup/cygwin/cygserver_shm.h3
-rwxr-xr-xwinsup/cygwin/cygserver_transport.cc4
-rwxr-xr-xwinsup/cygwin/cygserver_transport_pipes.cc53
-rwxr-xr-xwinsup/cygwin/cygserver_transport_sockets.cc8
-rw-r--r--winsup/cygwin/cygwin.din94
-rw-r--r--winsup/cygwin/dcrt0.cc6
-rw-r--r--winsup/cygwin/debug.cc2
-rw-r--r--winsup/cygwin/debug.h3
-rw-r--r--winsup/cygwin/dir.cc86
-rw-r--r--winsup/cygwin/dll_init.cc8
-rw-r--r--winsup/cygwin/dtable.cc265
-rw-r--r--winsup/cygwin/dtable.h3
-rw-r--r--winsup/cygwin/environ.cc243
-rw-r--r--winsup/cygwin/environ.h15
-rw-r--r--winsup/cygwin/errno.cc9
-rw-r--r--winsup/cygwin/exceptions.cc4
-rw-r--r--winsup/cygwin/exec.cc127
-rw-r--r--winsup/cygwin/external.cc21
-rw-r--r--winsup/cygwin/fcntl.cc3
-rw-r--r--winsup/cygwin/fhandler.cc148
-rw-r--r--winsup/cygwin/fhandler.h139
-rw-r--r--winsup/cygwin/fhandler_clipboard.cc2
-rw-r--r--winsup/cygwin/fhandler_console.cc48
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc449
-rw-r--r--winsup/cygwin/fhandler_dsp.cc17
-rw-r--r--winsup/cygwin/fhandler_floppy.cc1
-rw-r--r--winsup/cygwin/fhandler_mem.cc1
-rw-r--r--winsup/cygwin/fhandler_random.cc2
-rw-r--r--winsup/cygwin/fhandler_raw.cc10
-rw-r--r--winsup/cygwin/fhandler_serial.cc7
-rw-r--r--winsup/cygwin/fhandler_socket.cc28
-rw-r--r--winsup/cygwin/fhandler_tape.cc7
-rw-r--r--winsup/cygwin/fhandler_termios.cc40
-rw-r--r--winsup/cygwin/fhandler_tty.cc58
-rw-r--r--winsup/cygwin/fhandler_windows.cc4
-rw-r--r--winsup/cygwin/fhandler_zero.cc2
-rw-r--r--winsup/cygwin/fork.cc15
-rw-r--r--winsup/cygwin/glob.c58
-rw-r--r--winsup/cygwin/gmon.c7
-rw-r--r--winsup/cygwin/grp.cc212
-rw-r--r--winsup/cygwin/heap.cc3
-rw-r--r--winsup/cygwin/hires.h29
-rw-r--r--winsup/cygwin/how-fhandlers-work.txt10
-rwxr-xr-xwinsup/cygwin/include/cygwin/cygserver.h2
-rwxr-xr-xwinsup/cygwin/include/cygwin/cygserver_process.h2
-rwxr-xr-xwinsup/cygwin/include/cygwin/cygserver_transport.h2
-rwxr-xr-xwinsup/cygwin/include/cygwin/cygserver_transport_pipes.h2
-rwxr-xr-xwinsup/cygwin/include/cygwin/cygserver_transport_sockets.h2
-rw-r--r--winsup/cygwin/include/cygwin/grp.h6
-rw-r--r--winsup/cygwin/include/cygwin/ip.h1
-rw-r--r--winsup/cygwin/include/cygwin/socket.h4
-rw-r--r--winsup/cygwin/include/cygwin/stat.h39
-rw-r--r--winsup/cygwin/include/cygwin/types.h12
-rw-r--r--winsup/cygwin/include/cygwin/version.h4
-rw-r--r--winsup/cygwin/include/glob.h5
-rw-r--r--winsup/cygwin/include/netinet/ip.h203
-rw-r--r--winsup/cygwin/include/netinet/tcp.h146
-rw-r--r--winsup/cygwin/include/pthread.h18
-rw-r--r--winsup/cygwin/include/sys/cygwin.h19
-rw-r--r--winsup/cygwin/include/sys/ipc.h7
-rw-r--r--winsup/cygwin/include/sys/mount.h8
-rw-r--r--winsup/cygwin/include/sys/strace.h1
-rw-r--r--winsup/cygwin/include/sys/sysmacros.h8
-rw-r--r--winsup/cygwin/include/sys/termios.h8
-rw-r--r--winsup/cygwin/include/sys/vfs.h2
-rw-r--r--winsup/cygwin/include/wchar.h1
-rw-r--r--winsup/cygwin/ipc.cc8
-rw-r--r--winsup/cygwin/localtime.cc14
-rw-r--r--winsup/cygwin/malloc_wrapper.cc2
-rw-r--r--winsup/cygwin/mmap.cc78
-rw-r--r--winsup/cygwin/net.cc73
-rw-r--r--winsup/cygwin/ntdll.h237
-rw-r--r--winsup/cygwin/passwd.cc159
-rw-r--r--winsup/cygwin/path.cc339
-rw-r--r--winsup/cygwin/path.h58
-rw-r--r--winsup/cygwin/pinfo.cc12
-rw-r--r--winsup/cygwin/pinfo.h20
-rw-r--r--winsup/cygwin/pipe.cc4
-rw-r--r--winsup/cygwin/poll.cc84
-rw-r--r--winsup/cygwin/pthread.cc16
-rw-r--r--winsup/cygwin/pwdgrp.h79
-rw-r--r--winsup/cygwin/registry.cc5
-rw-r--r--winsup/cygwin/resource.cc4
-rw-r--r--winsup/cygwin/sched.cc1
-rw-r--r--winsup/cygwin/sec_acl.cc19
-rw-r--r--winsup/cygwin/sec_helper.cc27
-rw-r--r--winsup/cygwin/security.cc413
-rw-r--r--winsup/cygwin/security.h25
-rw-r--r--winsup/cygwin/select.cc3
-rw-r--r--winsup/cygwin/shared.cc81
-rw-r--r--winsup/cygwin/shared_info.h5
-rw-r--r--winsup/cygwin/shm.cc109
-rw-r--r--winsup/cygwin/signal.cc1
-rw-r--r--winsup/cygwin/sigproc.h3
-rw-r--r--winsup/cygwin/smallprint.c3
-rw-r--r--winsup/cygwin/spawn.cc112
-rw-r--r--winsup/cygwin/strace.cc13
-rw-r--r--winsup/cygwin/sync.cc2
-rw-r--r--winsup/cygwin/syscalls.cc680
-rw-r--r--winsup/cygwin/sysconf.cc4
-rw-r--r--winsup/cygwin/termios.cc2
-rw-r--r--winsup/cygwin/thread.cc151
-rw-r--r--winsup/cygwin/thread.h98
-rwxr-xr-xwinsup/cygwin/threaded_queue.cc3
-rw-r--r--winsup/cygwin/times.cc121
-rw-r--r--winsup/cygwin/tty.cc4
-rw-r--r--winsup/cygwin/tty.h2
-rw-r--r--winsup/cygwin/uinfo.cc286
-rw-r--r--winsup/cygwin/uname.cc4
-rw-r--r--winsup/cygwin/wait.cc3
-rw-r--r--winsup/cygwin/wincap.cc26
-rw-r--r--winsup/cygwin/wincap.h5
-rw-r--r--winsup/cygwin/window.cc4
-rw-r--r--winsup/cygwin/winsup.h21
124 files changed, 5795 insertions, 2698 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 1b8bbb9ea..a395e9aa0 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,1368 @@
+2002-06-13 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygheap.cc (cygheap_user::set_name): Remove setting homedrive and
+ homepath to NULL.
+ (cygheap_user::set_logsrv): Fix free'ing of plogsrv.
+ * cygheap.h (cygheap_user::cygheap_user): Initialize homedrive and
+ homepath to NULL.
+
+2002-06-13 Christopher Faylor <cgf@redhat.com>
+
+ * security.cc (get_logon_server): Use strcasematch rather than
+ strcasecmp.
+
+2002-06-12 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (chdir): Minor cleanup.
+
+2002-06-12 Christopher Faylor <cgf@redhat.com>
+
+ * environ.cc (build_env): Correctly fill out windows environment block
+ with win32 paths rather than posix paths.
+
+2002-06-12 Christopher Faylor <cgf@redhat.com>
+
+ * cygheap.cc (cygheap_user::set_name): Set homedrive and homepath to
+ NULL on user name change.
+ (cygheap_user::set_logsrv): Allocate enough space for leading \\ so
+ that we can put this in the environment, if needed.
+ * cygheap.h (homebodies): New enum.
+ (cygheap_user::homedrive): New field.
+ (cygheap_user::homepath): Ditto.
+ (cygheap_user::env_logsrv): New method.
+ (cygheap_user::env_homepath): New method.
+ (cygheap_user::env_homedrive): New method.
+ (cygheap_user::env_userprofile): New method.
+ (cygheap_user::ontherange): New method.
+ * environ.cc (envsize): Eliminate debugging argument.
+ (environ_init): Assume that envc counts number of elments not total
+ size.
+ (spenv): New class.
+ (spenvs): New array, renamed from forced_winenv_vars, using spenv.
+ (spenv::retrieve): New method.
+ (build_env): Rename from 'winenv' -- one stop shopping for building new
+ environment blocks for both windows and "unix".
+ * environ.h (build_env: Declare.
+ (winenv): Delete declaration.
+ (envsize): Ditto.
+ * spawn.cc (spawn_guts): Use build_env to build windows and cygwin
+ environment blocks.
+ * uinfo.cc (internal_getlogin): Eliminate environment manipulation.
+ Default to info from GetUserName if it exists. Move HOMEPATH and
+ HOMEDRIVE stuff elsewhere. Move HOME setting elsewhere. Only set HOME
+ environment variable in processes that are not parented by a cygwin
+ process.
+ (cygheap_user::ontherange): Define new method.
+ (cygheap_user::env_logsrv): Ditto.
+ (cygheap_user::env_homepath): Ditto.
+ (cygheap_user::env_homedrive): Ditto.
+ (cygheap_user::env_userprofile): Ditto.
+
+2002-06-11 Christopher Faylor <cgf@redhat.com>
+
+ * spawn.cc (spawn_guts): More hToken removal cleanup.
+
+2002-06-09 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * spawn.cc (spawn_guts): Define sec_attribs and call sec_user_nih()
+ only once.
+
+2002-06-10 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in: Ensure that -MD gets added to CFLAGS regardless of
+ CFLAGS command-line setting.
+
+ * cygwin.din: Export sexec* functions as function which returns ENOSYS
+ (i.e., sexec* is deprecated).
+ * dtable.cc (dtable::vfork_child_dup): Ensure that impersonation is
+ restored even on failure.
+ * exec.cc: Throughout, remove references to sexec* and _spawnve.
+ * pinfo.h: Remove _spawnve declaration.
+ * spawn.cc: Rename _spawnve to spawnve and use throughout.
+ (spawn_guts): Eliminate hToken argument and processing of same. Just
+ perform special actions if impersonating.
+ (spawnve): Rename from _spawnve.
+
+2002-06-10 Christopher Faylor <cgf@redhat.com>
+
+ * include/sys/strace.h (strace): Avoid use of constructor.
+
+2002-06-10 Christopher Faylor <cgf@redhat.com>
+
+ * dcrt0.cc (dll_crt0_1): Initialize wincap and check for sanity before
+ running global ctors.
+ * wincap.h (wincap): Eliminate constructor. Default is to zero memory,
+ anyway.
+ * wincap.cc (wincap): Copy this on fork to avoid initialization in
+ forked processes.
+
+2002-06-10 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h (fhandler_socket::fixup_after_fork): Revert patch from
+ 2002-06-04.
+ * fhandler_socket.cc (fhandler_socket::fixup_after_fork): Ditto.
+ (fhandler_socket::dup): Ditto.
+ * net.cc (fdsock): Make sockets explicitely noninheritable on NT.
+
+2002-06-09 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Correctly
+ set number of links for directory, if appropriate.
+
+2002-06-10 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.cc: Variation of a patch from Thomas Pffaf.
+ (__pthread_detach): Cleanup thread object if the thread has terminated.
+ (__pthread_join): Change order of error checks, and lock against
+ join/detach/exit races.
+ (__pthread_exit): Lock object against join/detach/exit races.
+ (pthread::thread_init_wrapper): Ditto.
+ (thread_init_wrapper): Rename to pthread::thread_init_wrapper.
+ (pthread::create): Check that the mutex initialized correctly.
+ (pthread::push_cleanup_handler): Lock against potential cancellation
+ race. NB: this may not be required if pthread_cleanup_push is non-
+ cancelable.
+ * thread.h (pthread::mutex): New member.
+ (thread_init_wrapper): Rename to pthread::thread_init_wrapper.
+ (pthread::thread_init_wrapper_: New static member.
+
+2002-06-10 Robert Collins <rbtcollins@hotmail.com>
+
+ * cygwin.din: Add _pthread_cleanup_push and _pthread_cleanup_pop.
+ * pthread.cc: Change __pthread_self to pthread::self() thruoghout.
+ (_pthread_cleanup_push): New function.
+ (_pthread_cleanup_pop): Ditto.
+ * thread.cc: Thanks to Thomas Pfaff for the pthread cleanup_push,_pop
+ patch, this work is derived from that.
+ Change __pthread_self to pthread::self() thruoghout.
+ (__pthread_self): Rename to pthread::self.
+ (pthread::self): New method.
+ (pthread::pthread): Initialize new member.
+ (pthread::push_cleanup_handler): New method.
+ (pthread::pop_cleanup_handler): New method.
+ (pthread::pop_all_cleanup_handlers): New method.
+ (__pthread_exit): Pop all cleanup handlers.
+ * thread.h (pthread::push_cleanup_handler): Declare.
+ (pthread::pop_cleanup_handler): Ditto.
+ (pthread::pop_all_cleanup_handlers): Ditto.
+ (pthread::self): New static method.
+ (__pthread_exit): Give C++ linkage.
+ (__pthread_join): Ditto.
+ (__pthread_detach): Ditto.
+ (__pthread_self): Remove.
+
+2002-04-24 Thomas Pfaff <tpfaff@gmx.net>
+
+ * include/pthread.h (__pthread_cleanup_handler): New structure.
+ (pthread_cleanup_push): Rewritten.
+ (pthread_cleanup_pop): Ditto.
+ (_pthread_cleanup_push): New prototype.
+ (_pthread_cleanup_pop): Ditto.
+
+2002-04-24 Thomas Pfaff <tpfaff@gmx.net>
+
+ * thread.cc (thread_init_wrapper): Check if thread is already joined.
+ (__pthread_join): Set joiner first.
+ (__pthread_detach): Ditto.
+
+2002-06-10 Robert Collins <rbtcollins@hotmail.com>
+
+ * cygserver_transport.cc (create_server_transport): Finish the split
+ out of sockets code from transport_layer_base. Thanks to Nicholas
+ Wourms and Conrad Scott for catching this.
+
+2002-06-08 Christopher Faylor <cgf@redhat.com>
+
+ * pinfo.cc (pinfo_dummy): Initialize to correct size.
+
+2002-06-08 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc: Change MOUNT_AUTO to MOUNT_CYGDRIVE throughout.
+ * shared_info.h (CURR_MOUNT_MAGIC): Update.
+
+2002-06-08 Christopher Faylor <cgf@redhat.com>
+
+ * external.cc (cygwin_internal): Make v1 mount table access invalid.
+ * path.cc (mount_info::init): Remove had_to_create_mount_areas initialization.
+ (mount_info::from_registry): Remove v1 table import.
+ (mount_info::read_v1_mounts): Eliminate.
+ (mount_info::import_v1_mounts): Ditto.
+ * shared_info.h (mount_info): Ditto for both of above.
+ * sys/mount.h (MOUNT_DEVFS): New enum.
+ (MOUNT_PROC): Ditto.
+
+2002-06-08 Christopher Faylor <cgf@redhat.com>
+
+ * include/wchar.h: Define __need_size_t.
+
+2002-06-07 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_socket.cc (fhandler_socket::fstat): Don't assume that socket
+ is unix-domain socket.
+
+2002-06-07 Christopher Faylor <cgf@redhat.com>
+
+ * times.cc (hires_ms::prime): Set init flag.
+
+2002-06-07 Conrad Scott <conrad.scott@dsl.pipex.com>
+
+ * times.cc (hires_ms::prime): Adjust epoch of initime_us from 1601 to
+ 1970.
+
+2002-06-06 Christopher Faylor <cgf@redhat.com>
+
+ * autoload.cc (timeGetDevCaps): Define new autoload function.
+ (timeGetTime): Ditto.
+ (timeBeginPeriod): Ditto.
+ (timeEndPeriod): Ditto.
+ * hires.h (hires_base): New class. Renamed from hires.
+ (hires_us): New class.
+ (hires_ms): New class.
+ * strace.cc (strace::microseconds): Use hires_us class.
+ * times.cc (gettimeofday): Use hires-ms class.
+ (hires_us::prime): Renamed from hires::prime.
+ (hires_us::usecs): Renamed from hires:usecs.
+ (hires_ms::prime): New method.
+ (hires_ms::usecs): New method.
+ (hires_ms::~hires_ms): New destructor.
+
+2002-06-06 Christopher Faylor <cgf@redhat.com>
+
+ * autoload.cc (noload): Correctly save argument count register.
+
+2002-06-05 Conrad Scott <conrad.scott@dsl.pipex.com>
+
+ * fhandler.cc (fhandler_base::fstat): Initialise tv_nsec member of
+ st_atim, st_mtim, and st_ctim fields.
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Ditto.
+ * fhandler_process.cc (fhandler_process::fstat): Ditto.
+ * glob.c (stat32_to_STAT): Copy across the whole st_atim, st_mtime, and
+ st_ctim fields.
+ * syscalls.cc (stat64_to_stat32): Ditto.
+ * times.cc (to_timestruc_t): New function.
+ (time_as_timestruc_t): New function.
+ * winsup.h: Add to_timestruc_t and time_as_timestruc_t functions.
+ * include/cygwin/stat.h: Replace time_t with timestruc_t throughout for
+ all file times, removing the st_spare1, st_spare2, and st_spare3 fields
+ in the process. Add macros to access tv_sec fields by old names.
+ * include/cygwin/types.h: Typedef timespec_t and timestruc_t as struct
+ timespec.
+
+2002-06-03 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * sec_helper.cc (lookup_name): Suppress.
+ * security.cc (alloc_sd): Remove logsrv argument.
+ Remove two calls to lookup_name.
+ (set_security_attribute): Remove logsrv argument.
+ Remove logsrv argument in call to alloc_sd.
+ (set_nt_attribute): Remove logsrv argument.
+ Remove logsrv argument in call to set_security_attribute.
+ (set_file_attribute): Remove logsrv argument.
+ Remove logsrv argument in call to set_nt_attribute.
+ (set_file_attribute): Remove logsrv argument.
+ Remove logsrv argument in call to set_file_attribute.
+ * syscalls.cc (chown_worker): Remove logserver argument in
+ call to set_file_attribute.
+ (chmod): Ditto.
+ * shm.cc (shmget): Remove logsrv argument in call to alloc_sd.
+ * uinfo.cc (internal_getlogin): Replace calls to
+ lookup_name by call to LookupAccountName.
+ * security.h: Remove logsrv in declarations of set_file_attribute
+ and alloc_sd. Remove declaration of lookup_name.
+
+2002-06-05 Christopher Faylor <cgf@redhat.com>
+
+ * child_info.h (CHILD_INFO_MAGIC): Oops. Revert previous change. gcc
+ 3.1 bug?
+
+2002-06-05 Christopher Faylor <cgf@redhat.com>
+
+ * child_info.h (CHILD_INFO_MAGIC): Update.
+
+2002-06-05 Christopher Faylor <cgf@redhat.com>
+
+ * strace.cc (strace::hello): Set inited, when appropriate.
+
+2002-06-05 Christopher Faylor <cgf@redhat.com>
+
+ * cygwin.din: Eliminate some newlib wrappers.
+ * path.cc (get_devn): Only consider first 99 potential com devices.
+ (get_device_number): Ditto.
+ * times.cc (_times): Eliminate.
+ (_times): Renamed from times().
+
+2002-06-05 Christopher Faylor <cgf@redhat.com>
+
+ * dir.cc (rmdir): Streamline. Detect attempts to remove directories
+ from "read-only" virtual devices. (Suggested by Pavel Tsekov)
+ * syscalls.cc (unlink): Detect attempts to remove directories from
+ "read-only" virtual devices. (From Pavel Tsekov)
+
+2002-06-05 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (handle_to_fn): Check error return value from NtQueryObject
+ first before seeing if name buffer is NULL.
+
+ * grp.cc (read_etc_group): Fix gcc warning regarding snprintf format.
+ * passwd.cc (read_etc_passwd): Ditto.
+
+2002-04-18 Thomas Pfaff <tpfaff@gmx.net>
+
+ * thread.h (pthread::joiner): New member.
+ * thread.cc (pthread::pthread): Initialize joiner to NULL
+ (pthread::create): Increment of thread counter moved from
+ __pthread_create to this location.
+ (__pthread_create): Increment thread counter removed.
+ (thread_init_wrapper): Set joiner to self when thread was created
+ detached.
+ (__pthread_exit): delete thread when it is detached and not
+ joined.
+ (__pthread_join): Check for deadlock and delete thread when it has
+ terminated.
+ (__pthread_detach): Set joiner to self when thread state
+ changed to detached.
+
+2002-06-05 Corinna Vinschen <corinna@vinschen.de>
+
+ * grp.cc (read_etc_group): When emulating nonexisting group file on
+ NT systems, read primary group SID from process token. Use that info
+ to create correct group entry. On error or on 9x systems fallback
+ to emulating Administrators group as before.
+ * passwd.cc (read_etc_passwd): When emulating nonexisting passwd file
+ on NT systems, read user and primary group SID from process token.
+ Use that info to create correct passwd entry. On error or on 9x
+ systems fallback to emulating user with Administrator user id and
+ Administrators group as before.
+
+2002-06-05 Corinna Vinschen <corinna@vinschen.de>
+
+ * grp.cc (etc_group): Removed.
+ (parse_grp): Make line parameter nonconst. Don't copy data into new
+ allocated memory. Check for CR instead of LF to accomodate new
+ read method.
+ (add_grp_line): Make line parameter nonconst.
+ (read_etc_group): Rearrange using new pwdgrp_read class.
+ * passwd.cc (parse_pwd): Don't copy data into new allocated memory.
+ Check for CR instead of LF to accomodate new read method.
+ (read_etc_passwd): Rearrange using new pwdgrp_read class.
+ * pwdgrp.h (pwdgrp_check::set_last_modified): Use different
+ parameters.
+ (class pwdgrp_read): New class for opening and reading passwd and
+ group files.
+
+2002-06-04 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (handle_to_fn): Attempt to handle "raw" accesses to remote
+ shares.
+ * path.cc (mount_info::conv_to_win32_path): Set flags to binary when
+ mount entry is not found.
+ (mount_info::set_flags_from_win32_path): Ditto.
+
+2002-06-04 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (handle_to_fn): Correct placement and length of name
+ buffer. (Suggested by Pavel Tsekov)
+
+2002-06-04 Christopher Faylor <cgf@redhat.com>
+
+ Remove fcntl.h includes throughout.
+ * fhandler.h: Move fcntl.h include here.
+ (fhandler_base::set_flags): Accept supplied_bin argument. Make
+ non-inlined.
+ * dtable.cc (dtable::init_std_file_from_handle): Just use binmode from
+ pc.
+ (reset_to_open_binmode): Use set_flags.
+ * cygwin.din (open): Avoid newlib wrapper.
+ (read): Ditto.
+ (unlink): Ditto.
+ (write): Ditto.
+ * fhandler.cc (fhandler_base::set_flags): Accept supplied_bin argument.
+ Make binmode decisions here.
+ (fhandler_base::open): Avoid using pc if it is NULL. Eliminate binmode
+ logic. Just call set_flags with binmode argument.
+ (fhandler_base::init): Call set_flags with binmode argument.
+ * fhandler_clipboard.cc (fhandler_dev_clipboard::open): Ditto.
+ * fhandler_console.cc (fhandler_console::open): Ditto.
+ (fhandler_console::init): Force binary on open.
+ * fhandler_disk_file.cc (fhandler_disk_file::open): Don't set binmode
+ here. Let it happen in base class.
+ * fhandler_dsp.cc (fhandler_dev_dsp::open): Force binmode open. Set
+ return value appropriately if unable to open.
+ * fhandler_proc.cc (fhandler_proc::open): Make sure flags are set
+ before open_status.
+ * fhandler_process.cc (fhandler_process::open): Ditto.
+ * fhandler_registry.cc (fhandler_registry::open): Ditto.
+ * fhandler_random.cc (fhandler_dev_random::fhandler_dev_random): Ditto.
+ * fhandler_raw.cc (fhandler_dev_raw::open): Force O_BINARY by default.
+ * fhandler_serial.cc (fhandler_serial::init): Ditto.
+ * fhandler_tty.cc (fhandler_tty_slave::open): Ditto.
+ (fhandler_pty_master::open): Ditto.
+ * fhandler_virtual.cc (fhandler_virtual::open): Ditto.
+ * fhandler_windows.cc (fhandler_windows::open): Ditto.
+ * fhandler_zero.cc (fhandler_dev_zero::open): Ditto.
+ * net.cc (fdsock): Ditto.
+ * path.cc (path_conv::check): Avoid checking for executable extension
+ when directory. (Suggested by Pavel Tsekov)
+ (set_flags): Set PATH_TEXT explicitly, when appropriate.
+ (mount_info::conv_to_win32_path): Use set_flags() to set path flags.
+ * path.h (PATH_TEXT): New enum.
+ (path_conv::binmode): Return appropriate constant based on binmode.
+ * pipe.cc (make_pipe): Set binmode to O_TEXT xor O_BINARY.
+ * syscalls.cc (setmode_helper): Make debugging message a little
+ clearer.
+ (setmode): Set binmode via set_flags.
+
+2002-06-04 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h (class fhandler_socket): Add private method
+ fixup_after_fork (bool, HANDLE).
+ * fhandler_socket.cc (fhandler_socket::fixup_after_fork): Move
+ functionality to new private method. Add closing parent socket
+ if not called from dup(). Create method new calling private method
+ with appropriate parameter.
+ (fhandler_socket::fixup_after_exec): Call private method
+ fixup_after_fork with appropriate parameter.
+ (fhandler_socket::dup): Ditto.
+
+2002-06-04 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_dsp.cc (fhandler_dev_dsp::open): Set errno to EACCES if
+ requested mode isn't supported.
+
+2002-06-03 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.cc (fhandler_base::open): Don't set binmode if already set.
+ Don't check for file. Files should already be set. Report on binary
+ mode for debugging.
+ (fhandler_base::fhandler_base): Don't set default binmode here. That's
+ for later.
+ * fhandler_console.cc (fhandler_console::output_tcsetattr): Don't set
+ binmode, ever, for console.
+ * fhandler_disk_file.cc (fhandler_disk_file::open): Always set the
+ binary mode to the value derived from mount table.
+ * path.cc (mount_info::conv_to_win32_path): Default to binmode if path
+ does not translate into anything in the mount table.
+
+2002-06-03 Corinna Vinschen <corinna@vinschen.de>
+
+ * external.cc (cygwin_internal): Add CW_EXTRACT_DOMAIN_AND_USER
+ handling to call extract_nt_dom_user() from applications.
+ * include/sys/cygwin.h (cygwin_getinfo_types): Add
+ CW_EXTRACT_DOMAIN_AND_USER.
+
+2002-06-03 Corinna Vinschen <corinna@vinschen.de>
+
+ * syscalls.cc (stat64_to_stat32): Transform st_dev correctly.
+ (fstat64): Add evaluating st_ino and st_dev.
+ (stat_worker): Evaluate st_dev as 32 bit value.
+ * include/cygwin/stat.h: Use new dev_t definition throughout.
+ * include/cygwin/types.h: Define __dev16_t and __dev32_t. Define
+ dev_t according to __CYGWIN_USE_BIG_TYPES__ setting.
+ * include/sys/sysmacros.h: Define major, minor and makedev
+ according to __CYGWIN_USE_BIG_TYPES__ setting.
+
+2002-06-03 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * syscalls.cc (setegid32): Verify the correctness of the gid
+ of the group returned by getgrgid32.
+
+2002-06-03 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * security.cc (lsa2wchar): Suppressed.
+ (get_lsa_srv_inf): Suppressed.
+ (get_logon_server_and_user_domain): Suppressed.
+ (get_logon_server): Essentially new.
+ (get_user_groups): Add "domain" argument. Only lookup the
+ designated server and use "domain" in LookupAccountName.
+ (is_group_member): Simplify the arguments.
+ (get_user_local_groups): Simplify the arguments. Do only a
+ local lookup. Use "BUILTIN" and local domain in LookupAccountName.
+ (get_user_primary_group). Only lookup the designated server.
+ (get_group_sidlist): Remove logonserver argument. Do not lookup
+ any server for the SYSTEM account.
+ (create_token): Delete logonserver and call to get_logon_server.
+ Adjust arguments of get_group_sidlist, see above.
+ * security.h: Delete declaration of get_logon_server_and_user_domain
+ and add declaration of get_logon_server.
+ * uinfo.cc (internal_get_login): Call get_logon_server instead of
+ get_logon_server_and_user_domain.
+
+2002-06-02 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (handle_to_fn): Use largest match for device. Correctly
+ (?) deal with remote drive weirdness.
+
+2002-06-02 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat_by_name): Check
+ specifically for non-existent file, first.
+ (fhandler_disk_file::fstat): Perform fd open on files with funny
+ characters.
+
+2002-06-02 Christopher January <chris@atomice.net>
+
+ * fhandler_process.cc (fhandler_process::open): Set fileid.
+
+2002-06-02 Christopher Faylor <cgf@redhat.com>
+
+ Remove unneeded sigproc.h includes throughout.
+ * fhandler.h (fhandler_proc::fill_filebuf): Take a pinfo argument.
+ * fhandler_proc.cc (fhandler_proc::get_proc_fhandler): Simplify search
+ for given pid.
+ (fhandler_proc::readdir): Assume that pid exists if it shows up in the
+ winpid list.
+ * fhandler_process.cc (fhandler_process::open): Simplify search for
+ given pid. Call fill_filebuf with pinfo argument.
+ (fhandler_process::fill_filebuf): Pass pinfo here and assume that it
+ exists.
+ * pinfo.h (pinfo::remember): Define differently if sigproc.h is not
+ included.
+
+2002-06-02 Christopher Faylor <cgf@redhat.com>
+
+ * dll_init.cc (dll_list::detach): Don't run destructor on exit.
+
+2002-06-01 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.cc (fhandler_base::fstat): Move dev and ino calculation into
+ caller.
+ * syscalls.cc (stat_worker): Calculate dev and ino calculation here, if
+ zero.
+ * fhandler_proc.cc (fhandler_proc::fhandler_proc): Minor reorg for
+ debugging.
+ * fhandler_process.cc (fhandler_process::exists): Return 0 on
+ nonexistence.
+ (fhandler_process::fstat): Simplify pid logic.
+ * fhandler_tape.cc (fhandler_dev_tape::fstat): Minor reformatting.
+
+2002-06-01 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (chdir): Don't allow cd'ing to a non-directory virtual path.
+
+2002-05-31 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_disk_file.cc (readdir): Move inode calculation into caller.
+ (fhandler_cygdrive::readdir): Add "." and "..".
+ * dir.cc (readdir): Move inode calculation here so that fhandler
+ readdirs can benefit.
+
+2002-05-31 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_console.cc (fhandler_console::open): Reinstate setting of
+ flags.
+
+ * dtable.cc (dtable::init_std_file_from_handle): Default to using
+ binmode derived from path_conv, when required.
+ * fhandler.h (fhandler_base::get_w_binary): Default to binmode if
+ nothing else is specified.
+ * fhandler.h (fhandler_base::get_r_binary): Ditto.
+
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat_by_handle): Work
+ around g++ warning.
+
+ * path.cc (path_conv::check): Remove a debugging statement.
+
+2002-05-31 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_console.cc (fhandler_console::open): Always default to
+ binmode.
+ (fhandler_console::write_normal): Don't honor binmode setting. There
+ is already a termios setting for this.
+ (fhandler_console::init): Correct argument order in init call.
+
+2002-05-31 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.cc (fhandler_base::open): Make default open mode == binmode.
+ (fhandler_base::init): Set open flags based on derived binmode argument.
+
+2002-05-31 Christopher Faylor <cgf@redhat.com>
+
+ * dll_init.cc (dll_list::init): Eliminate unneeded debugging statement.
+
+2002-05-31 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_proc.cc (fhandler_proc::readdir): Set errno when no more
+ files.
+ * fhandler_process.cc (fhandler_process::readdir): Ditto.
+ * fhandler_registry.cc (fhandler_registry::readdir): Ditto.
+
+2002-05-30 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (path_conv::check): Set fileattr to INVALID_FILE_ATTRIBUTES
+ for nonexistent virtual device path.
+ (chdir): Set correct errno when attempt is made to cd to nonexistent
+ virtual device path.
+
+2002-05-30 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat): Always call
+ fstat_by_name if fd is not opened to allow fstat_by_name to properly
+ set errno.
+
+2002-05-30 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc: Replace autoload statments for ZwXXX by NtXXX.
+ Drop ZwQuerySystemInformation since NtQuerySystemInformation was
+ already available.
+ * fhandler_proc.cc (format_proc_uptime): Replace call to
+ ZwQuerySystemInformation by call to NtQuerySystemInformation.
+ (format_proc_stat): Ditto.
+ * fhandler_process.cc (format_process_stat): Replace call to
+ ZwQueryInformationProcess by call to NtQueryInformationProcess.
+ (get_process_state): Ditto.
+ (get_mem_values): Ditto. Replace call to ZwQueryVirtualMemory by
+ call to NtQueryVirtualMemory.
+ * ntdll.h: Cleanup. Drop ZwQuerySystemInformation since
+ NtQuerySystemInformation was already available. Replace declarations
+ of ZwXXX functions by declarations of NtXXX.
+ * pinfo.cc (winpids::enumNT): Replace call to ZwQuerySystemInformation
+ by call to NtQuerySystemInformation.
+
+2002-05-29 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.cc (binmode): Default to binmode when mode is not known.
+
+2002-05-29 Christopher Faylor <cgf@redhat.com>
+
+ * include/sys/cygwin.h (EXTERNAL_PINFO_VERSION): Reinstate.
+ * external.cc (fillout_pinfo): Use it.
+
+2002-05-29 Corinna Vinschen <corinna@vinschen.de>
+
+ * external.cc (fillout_pinfo): Use new version define.
+ * include/sys/cygwin.h (external_pinfo): Define
+ EXTERNAL_PINFO_VERSION_16_BIT and EXTERNAL_PINFO_VERSION_32_BIT
+ instead of just EXTERNAL_PINFO_VERSION.
+
+2002-05-29 Christopher Faylor <cgf@redhat.com>
+
+ * external.cc (fillout_pinfo): Set new version field in external_pinfo
+ structure.
+ * include/sys/cygwin.h (external_pinfo): Replace strace_file with
+ version field.
+
+2002-05-29 Corinna Vinschen <corinna@vinschen.de>
+
+ Change internal uid datatype from __uid16_t to __uid32_t
+ throughout.
+ * cygwin.din: Export new symbols getpwuid32, getpwuid_r32, getuid32,
+ geteuid32, setuid32, seteuid32.
+ * passwd.cc (getpwuid32): New function.
+ (getpwuid_r32): Ditto.
+ * syscalls.cc (seteuid32): Ditto.
+ (setuid32): Ditto.
+ * uinfo.cc (getuid32): Ditto.
+ (geteuid32): Ditto.
+ * winsup.h (uid16touid32): New macro, correct casting from __uid16_t
+ to __uid32_t.
+ (gid16togid32): Ditto fir gids.
+ (getuid32): Declare.
+ (geteuid32): Ditto.
+ (getpwuid32): Ditto.
+ * include/sys/cygwin.h (struct external_pinfo): Add members uid32 and
+ gid32.
+
+2002-05-29 Corinna Vinschen <corinna@vinschen.de>
+
+ * include/cygwin/socket.h: Protect some symbols against multiple
+ definition.
+ * include/netinet/ip.h: Ditto.
+ * include/netinet/tcp.h: Ditto.
+
+2002-05-29 Wu Yongwei <adah@netstd.com>
+
+ * include/netinet/ip.h: Replace by BSD derived version of the file.
+ * include/netinet/tcp.h: Ditto.
+ * include/netinet/udp.h: New file.
+ * include/cygwin/ip.h: Remove.
+
+2002-05-29 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (dtable::init_std_file_from_handle): Attempt stronger
+ detection of invalid handle.
+ (handle_to_fn): Detect pathological condition where NT resets the
+ buffer pointer to NULL on an invalid handle.
+
+2002-05-28 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Properly
+ check for whether we should be opening the file to search for #!
+ characters. Set path_conv structure execability, too, when
+ appropriate.
+
+2002-05-28 Corinna Vinschen <corinna@vinschen.de>
+
+ * security.cc (set_security_attribute): Call getegid32() instead of
+ getegid().
+ * include/cygwin/grp.h: Declare getegid32().
+
+2002-05-28 Corinna Vinschen <corinna@vinschen.de>
+
+ Change internal gid datatype from __gid16_t to __gid32_t
+ throughout.
+ * cygwin.din: Export new symbols chown32, fchown32, getegid32,
+ getgid32, getgrgid32, getgrnam32, getgroups32, initgroups32, lchown32,
+ setgid32, setegid32, getgrent32.
+ * grp.cc (grp32togrp16): New static function.
+ (getgrgid32): New function.
+ (getgrnam32): Ditto.
+ (getgrent32): Ditto.
+ (getgroups32): Change name of internal function from getgroups.
+ (getgroups32): New function.
+ (initgroups32): Ditto.
+ * syscalls.cc (chown32): Ditto.
+ (lchown32): Ditto.
+ (fchown32): Ditto.
+ (setegid32): Ditto.
+ (setgid32): Ditto.
+ * uinfo.cc (getgid32): Ditto.
+ (getegid32): Ditto.
+ * include/cygwin/grp.h: Remove declaration of getgrgid() and getgrnam().
+ Declare getgrgid32() and getgrnam32() instead. Declare getgid32().
+
+2002-05-27 Christopher Faylor <cgf@redhat.com>
+
+ * autoload.cc (noload): Properly mask low order word for determining
+ number of bytes to pop.
+
+2002-05-27 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat): Minor logic
+ cleanup.
+
+2002-05-27 Christopher Faylor <cgf@redhat.com>
+
+ * autoload.cc (LoadFuncEx): Define via new LoadFuncEx2 macro.
+ (LoadFuncEx2): Adapted from LoadFuncEx. Provides control of return
+ value for nonexistent function.
+ (NtQueryObject): Declare.
+ (IsDebuggerPresent): Declare via LoadFuncEx2 and always return true if
+ not available.
+ * debug.h (being_debugged): Just rely on IsDebuggerPresent return
+ value.
+ * dtable.cc (handle_to_fn): New function.
+ (dtable::init_std_file_from_handle): Attempt to derive std handle's
+ name via handle_to_fn.
+ (dtable::build_fhandler_from_name): Fill in what we can in path_conv
+ structure when given a handle and path doesn't exist.
+ * fhandler.cc (fhandler_base::open): Don't set the file pointer here.
+ Use pc->exists () to determine if file exists rather than calling
+ GetFileAttributes again.
+ * fhandler.h (fhandler_base::exec_state_isknown): New method.
+ (fhandler_base::fstat_helper): Add extra arguments to declaration.
+ (fhandler_base::fstat_by_handle): Declare new method.
+ (fhandler_base::fstat_by_name): Declare new method.
+ * fhandler_disk_file (num_entries): Make __stdcall.
+ (fhandler_base::fstat_by_handle): Define new method.
+ (fhandler_base::fstat_by_name): Define new method.
+ (fhandler_base:fstat): Call fstat_by_{handle,name} as appropriate.
+ (fhandler_disk_file::fstat_helper): Accept extra arguments for filling
+ out stat structure. Move handle or name specific stuff to new methods
+ above.
+ (fhandler_disk_file::open): Use real_path->exists rather than calling
+ GetFileAttributes again.
+ * ntdll.h (FILE_NAME_INFORMATION): Define new structure.
+ (OBJECT_INFORMATION_CLASS): Partially define new enum.
+ (OBJECT_NAME_INFORMATION): Define new structure.
+ (NtQueryInformationFile): New declaration.
+ (NtQueryObject): New declaration.
+ * path.cc (path_conv::fillin): Define new method.
+ * path.h (path_conv::fillin): Declare new method.
+ (path_conv::drive_thpe): Rename from 'get_drive_type'.
+ (path_conv::volser): Declare new method.
+ (path_conv::volname): Declare new method.
+ (path_conv::root_dir): Declare new method.
+ * syscalls.cc (fstat64): Send real path_conv to fstat as second
+ argument.
+
+2002-05-24 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * security.cc (lsa2str): New function.
+ (get_priv_list): Call lsa2str instead of sys_wcstombs.
+
+2002-05-22 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * syscalls.cc (seteuid): Do not take allow_ntsec into account.
+ Attempt to use an existing or new token even when the uid
+ matches orig_uid, but the gid is not in the process token.
+ Major reorganization after several incremental changes.
+ (setegid): Do not take allow_ntsec into account. Minor
+ reorganization after several incremental changes.
+
+2002-05-26 Christopher Faylor <cgf@redhat.com>
+
+ * debug.h (being_debugged): New macro.
+ * dtable.cc (dtable::extend): Use new macro.
+ * exceptions.cc (try_to_debug): Ditto.
+ * strace.cc (strace::hello): Only output debugging info when we think
+ we're being debugged.
+
+2002-05-25 Robert Collins <rbtcollins@hotmail.com>
+
+ * winsup.h: Remove duplicate declarations of malloc_lock and
+ malloc_unlock.
+
+2002-05-24 Christopher Faylor <cgf@redhat.com>
+
+ Remove unneeded sync.h, where appropriate, throughout.
+ Remove unneeded heap.h, where appropriate, throughout.
+ Remove unneeded exceptions.h, where appropriate, throughout.
+ Remove unneeded perprocess.h, where appropriate, throughout.
+
+2002-05-22 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * security.cc (create_token): Call __sec_user() instead of
+ sec_user() to remove dependence on allow_ntsec. Verify that
+ the returned sd is non-null.
+
+2002-05-25 Robert Collins <rbtcollins@hotmail.com>
+
+ * gmon.c (fake_sbrk): Correctly return -1 on failed malloc's.
+
+2002-05-24 Christopher Faylor <cgf@redhat.com>
+
+ * dtable.cc (dtable::build_fhandler_from_name): Just pass posix path
+ along to set_name via return_and_clear_normalized_path.
+ (dtable::build_fhandler): New method with const char * argument.
+ (dtable::reset_unix_path_name): Eliminate.
+ (dtable::dup_worker): Use correct build_fhandler method.
+ * mmap.cc (mmap_record::alloc_fh): Ditto.
+ * dtable.h (dtable::build_fhandler): New method.
+ (dtable::reset_unix_path_name): Eliminate.
+ * fhandler.cc (fhandler_base::set_name): Assume that unix_name has
+ already been cmalloced.
+ (fhandler_base::reset_unix_path_name): Eliminate.
+ (fhandler_base::~fhandler_base): Coercion for cfree.
+ * fhandler.h (fhandler_base::unix_path_name): Make const char *.
+ (fhandler_base::win32_path_name): Ditto.
+ (fhandler_base::reset_unix_path_name): Eliminate.
+ * fhandler_disk_file.cc (fhandler_cygdrive::set_drives): Accommodate
+ const char *ness of win32_path_name.
+ * fhandler_socket.cc (fhandler_socket::fstat): Accommodate new set_name
+ requirements.
+ * path.cc (path_conv::return_and_clear_normalized_path): New method.
+ (path_conv::clear_normalized_path): Eliminate.
+ (path_conv::~path_conv): Ditto.
+ (path_conv::check): Accommodate new build_fhandler method.
+ * path.h (path_conv::~path_conv): Eliminate.
+ (path_conv::clear_normalized_path): Ditto.
+ (path_conv::return_and_clear_normalized_path): Declare new method.
+
+2002-05-23 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (path_conv::check): Make sure any trailing path component is
+ part of potential normalized posix path.
+
+2002-05-23 Christopher Faylor <cgf@redhat.com>
+
+ * smallprint.c (__small_vsprintf): Implement '%o' after all these
+ years.
+
+2002-05-22 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.h (fhandler_virtual::exists): Eliminate path argument.
+ (fhandler_proc::exists): Ditto.
+ (fhandler_registry::exists): Ditto.
+ (fhandler_process::exists): Ditto.
+ * fhandler_proc.cc (fhandler_proc::exists): Ditto. Use built-in name.
+ * fhandler_process.cc (fhandler_process::exists): Ditto.
+ (fstat): Ditto.
+ * fhandler_registry.cc (fhandler_registry::exists): Ditto.
+ (fhandler_registry::fstat): Ditto.
+ * fhandler_virtual.cc (fhandler_virtual::opendir): Ditto.
+ * path.cc (path_conv::check): Ditto. Add debugging.
+
+2002-05-22 Christopher Faylor <cgf@redhat.com>
+
+ * syscalls.cc (dup): Always call dup2 for error handling.
+
+2002-05-22 Corinna Vinschen <corinna@vinschen.de>
+
+ * include/cygwin/types.h: Revert previous patch.
+
+2002-05-22 Corinna Vinschen <corinna@vinschen.de>
+
+ * include/cygwin/types.h: Define pthread stuff only if _POSIX_THREADS
+ is defined.
+
+2002-05-19 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * security.cc (open_local_policy): Initialize lsa to
+ INVALID_HANDLE_VALUE instead of NULL.
+ (get_logon_server_and_user_domain): Test for INVALID_HANDLE_VALUE
+ instead of NULL.
+ (create_token): Both of the above.
+
+2002-05-18 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat): Make handling of
+ nlink consistent for remote files.
+
+2002-05-18 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (path_conv::check): Always set executable bit for executable
+ extension.
+
+2002-05-17 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.cc (fhandler_base::lseek): Avoid calling SetFilePointer with
+ high order part of 64 bit address on OS's which do not support that
+ kind of operation. Otherwise Windows 95 will become confused.
+
+2002-05-16 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * fhandler_raw.cc (fhandler_dev_raw::open): Replace set_errno()
+ by __seterrno_from_win_error().
+ * security.cc (open_local_policy): Ditto.
+ (get_lsa_srv_inf): Ditto.
+ (get_user_groups): Ditto.
+ (get_user_primary_group): Ditto.
+ (create_token): Ditto.
+ (subauth): Ditto.
+
+2002-05-17 Corinna Vinschen <corinna@vinschen.de>
+
+ * times.cc (utimes): Use FILE_WRITE_ATTRIBUTES even on 9x/Me when
+ opening file for writing timestamp.
+ * wincap.cc: Remove flag has_specific_access_rights.
+ * wincap.h: Ditto.
+
+2002-05-13 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * syscalls.cc (seteuid): Set default dacl in process token.
+ Replace in-line code by call to verify_token().
+ (setegid): Reverse change from 2002-01-21. Add call to
+ RevertToSelf and set primary group in impersonation token.
+ * security.cc (create_token): Store pgrpsid in token security
+ descriptor, except if it already appears in my_grps.
+ Use sec_acl() in place of get_dacl().
+ (verify_token): Create from code in seteuid(), with tighter checks.
+ (get_dacl): Deleted.
+ (get_group_sidlist): Add argument to indicate if pgrpsid is already
+ in the groups.
+ * security.h: Define verify_token().
+ * autoload.cc: Load GetKernelObjectSecurity().
+
+2002-05-13 Mark Bradshaw <bradshaw@staff.crosswalk.com>
+
+ * cygwin.din: Add strlcat and strlcpy.
+ * include/cygwin/version.h: Increment API minor version number.
+
+2002-05-09 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * shared.cc (__sec_user): Split into sec_acl() and call orig_sid().
+ (sec_acl): Create from part of __sec_user(), except creator/owner.
+ * security.h: Define sec_acl() and MAX_DACL_LEN.
+
+2002-05-12 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_disk_file.cc (fhandler_disk_file::open): Avoid using
+ O_DIROPEN when OS doesn't support it. Return proper errno in that
+ case.
+
+2002-05-12 Christopher Faylor <cgf@redhat.com>
+
+ * syscalls.cc (_read): Change error to EBADF if attempt to read from a
+ non-readable fd.
+
+2002-05-11 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler.h (executable_states): For now, make dont_care_if_executable
+ equivalent to not_executable.
+ * sys/mount.h: Define MOUNT_NOTEXEC.
+ * path.h (fs_info): New class.
+ (path_conv): Move fs-specific fields to new 'fs' structure.
+ (path_conv::update_fs_info): Move to fs_info and rename to just 'update'.
+ * path.cc (fs_info::update): Ditto. Return 'true' if successful.
+ (fillout_mntent): Add ',noexec' to list of reported options.
+
+2002-05-11 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_virtual.cc (fhandler_virtual::close): Quiet a compiler
+ warning.
+
+2002-05-10 Christopher January <chris@atomice.net>
+
+ * autoload.cc: Add dynamic load statements for
+ 'ZwQueryInformationProcess' and 'ZwQueryVirtualMemory'.
+ * fhandler.h: Change type of bufalloc and filesize members of
+ fhandler_virtual from int to size_t. Change type of position member
+ from __off32_t to __off64_t. Add new fileid member to fhandler_virtual
+ class. Make seekdir take an __off64_t argument. Make lseek take an
+ __off64_t argument. Add fill_filebuf method to fhandler_virtual. Add
+ fill_filebuf method to fhandler_proc. Add fill_filebuf method to
+ fhandler_registry. Add fill_filebuf method to fhandler_process. Add
+ saved_pid and saved_p members to fhandler_process.
+ * fhandler_proc.cc (proc_listing_array): Add 'loadavg', 'meminfo', and 'stat'.
+ (proc_fhandlers array): Ditto.
+ (fhandler_proc::open): Use fill_filebuf to flesh out the file contents.
+ (fhandler_proc::fill_filebuf): New method.
+ (fhandler_proc::format_proc_meminfo): Ditto.
+ (fhandler_proc::format_proc_stat): Ditto.
+ (fhandler_proc::format_proc_uptime): Ditto.
+ * fhandler_process.cc (process_listing): Add 'stat' and 'statm'.
+ (fhandler_process::fstat): Find the _pinfo structure for the process
+ named in the filename. Return ENOENT if the process is no longer
+ around. Set the gid and uid fields of the stat structure.
+ (fhandler_process::open): Store pid and pointer to _pinfo structure in
+ saved_pid and saved_p respectively. Use fill_filebuf to flesh out file
+ contents.
+ (fhandler_proc::fill_filebuf): New method.
+ (format_process_stat): New function.
+ (format_process_status): Ditto.
+ (format_process_statm): Ditto.
+ (get_process_state): Ditto.
+ (get_mem_values): Ditto.
+ * fhandler_registry.cc (fhandler_registry::seekdir): Change argument
+ type from __off32_t to __off64_t.
+ (fhandler_registry::fill_filebuf): New method.
+ * fhandler_virtual.cc (fhandler_virtual::seekdir): Change argument type
+ from __off32_t to __off64_t.
+ (fhandler_virtual::lseek): Ditto.
+ (fhandler_virtual::fill_filebuf): New method.
+ (fhandler_virtual::fhandler_virtual): Initialise fileid to -1.
+ * wincap.cc: Set flag has_process_io_counters appropriately.
+ * wincap.h: Add flag has_process_io_counters.
+
+2002-05-09 Christopher Faylor <cgf@redhat.com>
+
+ * syscalls.cc (_write): Change error to EBADF if attempt to write to a
+ non-writeable fd.
+
+2002-05-08 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygheap.h (class cygheap_user): Add member `orig_psid'.
+ Add method `orig_sid()'.
+ * cygheap.cc (cygheap_user::set_sid): Maintain orig_psid.
+
+2002-04-28 Norbert Schulze <norbert.schulze@web.de>
+
+ * localtime.cc (tzsetwall): Use wildabbr if generated timezone name
+ length < 3.
+
+2002-05-05 Pierre Humblet <pierre.humblet@ieee.org>
+
+ * spawn.cc (spawn_guts): Move call to set_process_privilege()
+ to load_registry_hive().
+ * registry.cc (load_registry_hive): ditto.
+ * fork.cc (fork_parent): Call sec_user_nih() only once.
+
+2002-05-04 Christopher January <chris@atomice.net>
+
+ * path.h (path_conv::path_conv): Initialise normalized_path to NULL.
+
+2002-05-03 Christopher Faylor <cgf@redhat.com>
+
+ * net.cc (getdomainname): Change second argument of getdomainname to
+ size_t.
+
+2002-05-03 Christopher January <chris@atomice.net>
+
+ * fhandler_proc.cc (proc_listing): Add '.' and '..' to directory
+ listing.
+ (fhandler_proc::open): Change use of mode to flags. If the file does
+ not exist already, fail with EROFS if O_CREAT flag is set. Change
+ EROFS error to EACCES error when writing to a file. Use cmalloc to
+ allocate memory for filebuf.
+ (fhandler_proc::close): Use cfree to free filebuf.
+ (fhandler_proc::get_proc_fhandler): Properly detect attempts to access
+ unknown subdir.
+ * fhandler_process.cc (process_listing): Add '.' and '..' to directory
+ listing.
+ (fhandler_process::open): Use cmalloc to allocate memory for filebuf.
+ (fhandler_process::close): Use cfree to free filebuf.
+ * fhandler_registry.cc (registry_listing): Add . and '..' to directory
+ listing.
+ (fhandler_registry::open): Move check for open for writing before
+ open_key. Use cmalloc to allocate memory for filebuf.
+ (fhandler_registry::close): Use cfree to free filebuf.
+ (fhandler_registry::telldir): Use lower 16 bits of __d_position as
+ position in directory.
+ (fhandler_registry::seekdir): Ditto.
+ * fhandler_virtual.cc (fhandler_virtual::write): Change EROFS error to
+ EACCES error.
+ (fhandler_virtual::open): Set the NOHANDLE flag.
+ (fhandler_virtual::dup): Add call to fhandler_base::dup. Allocate
+ child's filebuf using cmalloc. Copy filebuf from parent to child.
+ (fhandler_virtual::close): Use cfree to free filebuf.
+ (fhandler_virtual::~fhandler_virtual): Ditto.
+ (from Chris Faylor <cgf@redhat.com>).
+ (fhandler_registry::readdir): Add support for '.' and '..' files in
+ subdirectories of /proc/registry.
+ * path.cc (path_conv::check): Do not return ENOENT if a file is not
+ found in /proc.
+
+2002-05-02 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_proc.cc (fhandler_proc::fstat): Use fhandler name rather
+ than path_conv name.
+ (fhandler_proc::open): Ditto.
+ * fhandler_process.cc (fhandler_process::fstat): Use fhandler name
+ rather than path_conv name.
+ (fhandler_process::open): Ditto.
+ * fhandler_registry.cc (fhandler_registry::fstat): Use fhandler name
+ rather than path_conv name.
+ (fhandler_registry::open): Ditto.
+ * path.cc (path_conv::check): Don't copy posix path when virtual.
+ (mount_info::conv_to_win32_path): Don't zero string when isproc. Just
+ derive normal windows path.
+
+ * path.h (path_conv::clear_normalized_path): Declare new method.
+ * path.cc (path_conv::clear_normalized_path): Define new method.
+ * dtable.cc (build_fhandler_from_name): Clear normalized path when
+ finished to conserve space.
+
+2002-05-02 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_proc.cc (fhandler_proc::fstat): Prime with information from
+ fhandler_base::fstat. Use defines rather than constants for permission
+ settings.
+
+2002-04-30 Eric Blake <ebb9@email.byu.edu>
+
+ * path.cc (hash_path_name): Improve hash function strength.
+
+2002-05-02 Robert Collins <rbtcollins@hotmail.com>
+
+ * thread.cc (__pthread_cond_dowait): Fix a race on signalling from a
+ thread woken by the same condition variable it's signalling on. Thanks
+ to Michael Beach for the report and test case.
+
+2002-05-02 Christopher Faylor <cgf@redhat.com>
+
+ * path.h (pathconv_arg): Add PC_POSIX.
+ (path_conv): Add normalized_path field.
+ * path.cc (path_conv::~path_conv): New destructor.
+ (path_conv::check): Set normalized_path, where appropriate.
+ * dtable.cc (build_fhandler_from_name): Use normalized path from
+ path_conv.
+ * syscalls.cc (chroot): Ditto.
+
+ * cygheap.h: Remove path_prefix_p declaration.
+
+2002-02-26 Christopher January <chris@atomice.net>
+ Christopher Faylor <cgf@redhat.com> (minor fixups)
+
+ * Makefile.in: Add fhandler_proc.o, fhandler_registry.o,
+ fhandler_process.o and fhandler_virtual.o.
+ * dtable.cc (dtable::build_fhandler): Add entries for FH_PROC,
+ FH_REGISTRY and FH_PROCESS. Set unix_name to the normalized posix
+ path.
+ * fhandler.h: Add constants for FH_PROC, FH_REGISTRY and FH_PROCESS.
+ Add class declarations for fhandler_virtual, fhandler_proc,
+ fhandler_registry and fhandler_virtual. Update fhandler_union
+ accordingly.
+ * fhandler_proc.cc: New file. Add implementation for fhandler_proc.
+ * fhandler_virtual.cc: New file. Add implementation for
+ fhandler_virtual.
+ * fhandler_process.cc: New file. Add implementation for
+ fhandler_process.
+ * fhandler_registry.cc: New file. Add implementation for
+ fhandler_registry.
+ * path.cc (isproc): New macro.
+ (isvirtual_dev): Ditto.
+ * path.cc (path_conv::check): Add check for virtual devices.
+ * path.cc (mount_info::conv_to_win32_path): Convert paths in /proc to
+ empty Win32 paths.
+ * path.cc (chdir): Replace check for FH_CYGDRIVE with more generic
+ isvirtual_dev macro. Force setting of posix path for virtual
+ fhandlers.
+ * path.h (path_prefix_p): Declare.
+
+
+Wed May 1 16:06:02 2002 Jason Tishler <jason@tishler.net>
+
+ * include/cygwin/types.h: Include <sys/sysmacros.h>.
+
+Wed Apr 17 11:27:04 2002 Jason Tishler <jason@tishler.net>
+
+ * security.cc (get_lsa_srv_inf): Prevent extraneous backslashes for
+ the NT Domain case.
+
+2002-04-12 Corinna Vinschen <corinna@vinschen.de>
+
+ * net.cc (cygwin_accept): Set socket type for accepted socket.
+ (socketpair): Set socket type for both sockets.
+
+2002-04-12 Egor Duda <deo@logos-m.ru>
+
+ * fhandler.h (class fhandler_socket): New member to store socket type.
+ (fhandler_socket::get_socket_type): Access it.
+ (fhandler_socket::set_socket_type): Ditto.
+ * net.cc (cygwin_socket): Store socket type.
+ (cygwin_connect): Disable security checks for connectionless sockets.
+ (cygwin_accept): Ditto.
+
+2002-04-09 Mark Bradshaw <bradshaw@staff.crosswalk.com>
+
+ * cygwin.din: Add strptime.
+ * include/cygwin/version.h: Increment API version number.
+
+2002-04-09 Corinna Vinschen <corinna@vinschen.de>
+
+ * fork.cc (fork_child): Call fixup_mmaps_after_fork() somewhat earlier.
+
+2002-04-09 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.cc (fhandler_base::open): Set read-only bit in
+ file_attributes when adequate.
+
+2002-03-28 Christopher Faylor <cgf@redhat.com>
+
+ * times.cc (gettimeofday): Fix typo in previous patch.
+
+2002-03-27 Wu Yongwei <adah@netstd.com>
+
+ * times.cc (gettimeofday): Revert to setting timezone info if tz !=
+ NULL.
+
+2002-03-21 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Always set
+ st_[ug]id to value derived from get_file_attributes.
+
+2002-03-21 Christopher Faylor <cgf@redhat.com>
+
+ * spawn.cc (find_exec): Return input if file not found.
+
+2002-03-19 Boris Schaeling <boriss@web.de>
+
+ * poll.cc (poll): Add support for invalid descriptors.
+
+2002-03-15 Robert Collins <rbtcollins@hotmail.com>
+
+ * fhandler.h (fhandler_termios::lseek): Override lseek.
+ * fhandler_termios.cc (fhandler_termios::lseek): Implement this.
+
+2002-03-15 Christopher Faylor <cgf@redhat.com>
+
+ * cygserver.cc: Include stdlib.h for exit declaration.
+ * threaded_queue.cc: Ditto.
+
+2002-03-15 Christopher Faylor <cgf@redhat.com>
+
+ * pinfo.cc (pinfo::init): Use PID_ALLPIDS flag to control when a
+ redirected block should be marked as nonexistent.
+ (winpids::add): Use PID_ALLPIDS when looking for all pids.
+ * cygwin.h (PID_ALLPIDS): New enum element.
+
+2002-03-15 Corinna Vinschen <corinna@vinschen.de>
+
+ * glob.c (stat32_to_STAT): New function.
+ (g_lstat): Call user space functions always with 32 bit struct stat
+ as a workaround.
+ (g_stat): Ditto.
+ * include/glob.h (struct glob): Don't prototype function pointers
+ when compiling Cygwin.
+
+2002-03-14 Christopher Faylor <cgf@redhat.com>
+
+ * pinfo.cc (pinfo::init): Properly handle execed process stub when
+ PID_NOREDIR is specified.
+
+2002-03-13 Boris Schaeling <boriss@web.de>
+
+ * poll.cc (poll): Remove variable open_fds. Rearrange and add code to
+ fix settings of revents.
+
+2002-03-13 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (mmap_record::map_map): Return -1 if VirtualProtect fails.
+ (list::erase): New method with no argument. Erase latest record
+ added.
+ (mmap64): Fail if map_map() fails.
+
+2002-03-12 Corinna Vinschen <corinna@vinschen.de>
+
+ * sysconf.cc (sysconf): Fix condition.
+
+2002-03-11 Corinna Vinschen <corinna@vinschen.de>
+
+ * mmap.cc (msync): Check area given by addr and len for being a
+ contigeous mmap'd region.
+
+2002-03-11 Corinna Vinschen <corinna@vinschen.de>
+
+ * fork.cc (fork_child): Call fixup_mmaps_after_fork() before
+ closing parent process handle. Call fixup_mmaps_after_fork()
+ with parent process handle as parameter.
+ * mmap.cc (mmap_record::access): New method.
+ (fixup_mmaps_after_fork): Take process handle as parameter.
+ In case of FILE_MAP_COPY access, copy valid memory regions to child.
+ * pinfo.h (fixup_mmaps_after_fork): Change prototype accordingly.
+
+2002-03-07 Corinna Vinschen <corinna@vinschen.de>
+
+ * autoload.cc (NetGetDCName): Add symbol.
+ (NetServerEnum): Remove symbol.
+ * security.cc (get_lsa_srv_inf): Call NetGetDCName() instead of
+ NetServerEnum() since it's faster. Don't call it at all if machine
+ is not a domain member.
+
+2002-03-06 Christopher Faylor <cgf@redhat.com>
+
+ * path.cc (normalize_posix_path): Avoid runs of '.'s > 2.
+
+2002-03-05 Christopher Faylor <cgf@redhat.com>
+
+ * errno.cc: Change EPERM associated text to "Operation not permitted"
+ throughout.
+
+2002-03-05 Christopher Faylor <cgf@redhat.com>
+
+ * fhandler_socket.cc (fhandler_socket::close): Respond to signals while
+ looping, waiting for socket to close. Superstitiously clear last error
+ when WSAEWOULDBLOCK.
+
+2002-03-05 Robert Collins <rbtcollins@hotmail.com>
+
+ * cygserver_transport_pipes.cc (transport_layer_pipes::transport_layer_pipes):
+ Always init - until static members work correctly.
+ * shm.cc (shmget): Initialize the security descriptor - thanks Corinna!
+ * include/sys/ipc.h: Make the ipc control constants partitioned off from the sem
+ control constants.
+
+2002-03-04 Christian Lestrade <christian.lestrade@free.fr>
+
+ * include/sys/termios.h: Define _POSIX_VDISABLE. Define CCEQ macro.
+ * fhandler_termios.cc: Include <sys/termios.h>.
+ (line_edit): Recognize disabled c_cc[] chars. Ignore VDISCARD when
+ not in ICANON mode.
+
+2002-03-04 Dmitry Timoshkov <dmitry@baikal.ru>
+
+ * syscalls.cc (truncate64): Use ftruncate64 directly to not lose
+ upper 32 bits.
+
+2002-03-04 Robert Collins <rbtcollins@hotmail.com>
+
+ * cygserver_shm.cc (delete_shmnode): New function.
+ (client_request_shm::serve): Use it.
+
+2002-03-04 Robert Collins <rbtcollins@hotmail.com>
+
+ * cygserver_shm.cc (client_request_shm::serve): Implement SHM_DETACH.
+ * shm.cc (shmdt): Implement.
+
+2002-03-04 Robert Collins <rbtcollins@hotmail.com>
+
+ * cygserver_shm.cc: Run indent.
+ (deleted_head): New global for storing shm id's pending deletion.
+ (client_request_shm::serve): Return ENOSYS for invalid request types.
+ Implement SHM_DEL - delete a shm id.
+ * cygserver_shm.h (SHM_DEL): New type value.
+ * shm.cc (delete_inprocess_shmds): New function, does what it's name implies.
+ (shmctl): Implement shm_rmid control type.
+
+2002-03-04 Robert Collins <rbtcollins@hotmail.com>
+
+ * Makefile.in (install): Remove install-bin to allow make install to work.
+
+2002-03-03 Robert Collins <rbtcollins@hotmail.com>
+
+ * shm.cc (shmat): Prevent a compile error.
+ (shmdt): Set errno as this function is incomplete.
+
2002-02-28 Christopher Faylor <cgf@redhat.com>
* times.cc: Remove if 0'd code. Clean up slightly.
@@ -18,7 +1383,7 @@
2002-01-17 Robert Collins <rbtcollins@hotmail.com>
- * cygserver.cc (check_and_dup_handle): Consolidate the two variants for
+ * cygserver.cc (check_and_dup_handle): Consolidate the two variants for
simplicity.
Add Some basic debug output.
(client_request_attach_tty::serve): Use the new debug_printf for clarity.
@@ -56,7 +1421,7 @@ Mon Oct 8 7:41:00 2001 Robert Collins <rbtcollins@hotmail.com>
* shm.cc: Globally rename client_request_shm_get to client_request_shm.
(client_request_shm::client_request_shm): New constructor for attach requests.
(shmat): Use it.
- * include/cygwin/cygserver_process.h (class process_request): Rename to
+ * include/cygwin/cygserver_process.h (class process_request): Rename to
process_cleanup.
(class cleanup_routine): New class.
(class process): New members and methods to allow calling back when the process
@@ -101,7 +1466,7 @@ Tue Oct 2 23:24:00 2001 Robert Collins <rbtcollins@hotmail.com>
(queue_process_param::~queue_process_param): Ditto.
(queue_process_param::start): Ditto.
(queue_process_param::stop): Ditto.
- * threaded_queue.h (class queue_process_param): Add support for
+ * threaded_queue.h (class queue_process_param): Add support for
interruptible request loops.
* cygwin/include/cygwin/cygserver_process.h (class process_cache): Add
destructor.
@@ -119,7 +1484,7 @@ Tue Oct 2 23:00:00 2001 Robert Collins <rbtcollins@hotmail.com>
Tue Oct 2 16:06:00 2001 Robert Collins <rbtcollins@hotmail.com>
- * Makefile.in: Remove cygserver_shm.o from cygwin1.dll.
+ * Makefile.in: Remove cygserver_shm.o from cygwin1.dll.
Rename cygserver_shm_outside.o to cygserver_shm.o.
* cygserver.cc (server_request::process): Use the new client_request
constructor.
@@ -129,7 +1494,7 @@ Tue Oct 2 16:06:00 2001 Robert Collins <rbtcollins@hotmail.com>
client_request constructor.
(client_request_shutdown::client_request_shutdown): Ditto.
(client_request::client_request): Ditto.
- * cygserver_shm.cc (client_request_shm_get::serve): Remove the
+ * cygserver_shm.cc (client_request_shm_get::serve): Remove the
#ifdef'd stub for in-cygwin builds.
(client_request_shm_get::client_request_shm_get): Use the new
client_request constructor, and remove the in-cygwin variants.
@@ -137,7 +1502,7 @@ Tue Oct 2 16:06:00 2001 Robert Collins <rbtcollins@hotmail.com>
serve method - it's only used in cygserver.
* shm.cc (client_request_shm_get::client_request_shm_get): New function.
* include/cygwin/cygserver.h (request_header): New constructor.
- (class client_request): Use it.
+ (class client_request): Use it.
New constructor accepting the header size.
#ifndef test the server method - it's only used within cygserver.
(client_request_get_version): #ifdef test the server method.
@@ -152,7 +1517,7 @@ Tue Oct 2 9:57:00 2001 Robert Collins <rbtcollins@hotmail.com>
(class server_process_param): Inherit from queue_process_param.
(class server_request_queue): Inherit from threaded_queue.
(request_loop): Adjust for new types.
- (server_request_queue::process_requests): Remove guts to
+ (server_request_queue::process_requests): Remove guts to
threaded_queue::process_requests.
(server_request::server_request): Adjust for new types.
(worker_function): Delete.
@@ -167,10 +1532,10 @@ Mon Oct 1 12:38:00 2001 Robert Collins <rbtcollins@hotmail.com>
* cygserver.cc (client_request::serve): New function.
* cygserver_process.cc: Inlude <pthread.h> for pthread_once.
(process_cache::process_cache): Initialise a crtiical section for write access.
- (process_cache::process): Use the critical section. Also add missing entries to
+ (process_cache::process): Use the critical section. Also add missing entries to
the cache.
(do_process_init): New function to initalise class process static variables.
- (process::process): Ensure that the process access critical section is
+ (process::process): Ensure that the process access critical section is
initialised.
(process::handle): Close the handle of old process's when they have terminated
and we are returning the handle for a process with the same pid.
@@ -179,13 +1544,13 @@ Mon Oct 1 12:38:00 2001 Robert Collins <rbtcollins@hotmail.com>
(client_request_shm_get::serve): New parameter for process cache support.
Use the process cache, not OpenProcess to get a handle to the originating process.
Fix a handle leak with token_handle.
- * cygserver_shm.h (class client_request_shm_get): Update ::serve for process
+ * cygserver_shm.h (class client_request_shm_get): Update ::serve for process
cache support.
* cygserver_transport_pipes.cc: Redefine debug_printf to be conditional on DEBUG.
- * include/cygwin/cygserver.h: Do not implement client_request::serve in the
+ * include/cygwin/cygserver.h: Do not implement client_request::serve in the
header.
- * include/cygwin/cygserver_process.h (class process_cache): Add a write access
- critical section to prevent races when requests from a multithreaded
+ * include/cygwin/cygserver_process.h (class process_cache): Add a write access
+ critical section to prevent races when requests from a multithreaded
application arrive.
Sun Sep 30 23:41:00 2001 Robert Collins <rbtcollins@hotmail.com>
@@ -205,7 +1570,7 @@ Sun Sep 30 23:41:00 2001 Robert Collins <rbtcollins@hotmail.com>
(server_request_queue::process_requests): Initiator for threaded request loops.
(client_request_shutdown::serve): Add beginning of process cache support.
(server_request::server_request): Ditto.
- (server_request::process): Use debug_printf. Add beginning of process cache
+ (server_request::process): Use debug_printf. Add beginning of process cache
support.
(server_request_queue::cleanup): Kill off any request loop threads.
(server_request_queue::add): Add beginning of process cache support.
@@ -214,7 +1579,7 @@ Sun Sep 30 23:41:00 2001 Robert Collins <rbtcollins@hotmail.com>
Add process cache support.
Spawn a separate thread for the transport request loop, thus allowing concurrent
support for multiple transports.
- * cygserver_client.cc (client_request_get_version::serve): Add process cache
+ * cygserver_client.cc (client_request_get_version::serve): Add process cache
support.
(client_request_attach_tty::serve): Add process cache support.
(client_request_shutdown::serve): Add process cache support.
@@ -251,7 +1616,7 @@ Sat Sep 29 20:40:00 2001 Robert Collins <rbtcollins@hotmail.com>
(transport_layer_base::read): Ditto.
(transport_layer_base::write): Ditto.
(transport_layer_base::connect): Ditto.
- * cygserver_transport_pipes.cc: Include new header
+ * cygserver_transport_pipes.cc: Include new header
"cygwin/cygserver_transport_pipes.h".
* cygserver_transport_sockets.cc: New file.
* dcrt0.cc: No need to include <sys/socket.h> now.
@@ -653,7 +2018,7 @@ Tue Sep 25 16:22:00 2001 Robert Collins <rbtcollins@hotmail.com>
2002-01-21 DJ Delorie <dj@redhat.com>
* Makefile.in (libpthread.a): Pass the assembler also.
- (libm.a): Ditto.
+ (libm.a): Ditto.
(libc.a): Ditto.
* speclib: Specify the assembler to dlltool.
@@ -718,9 +2083,9 @@ Tue Sep 25 16:22:00 2001 Robert Collins <rbtcollins@hotmail.com>
2002-01-19 Mark Bradshaw <bradshaw@staff.crosswalk.com>
- * cygwin.din: Add recvmsg and sendmsg.
- * net.cc: Add cygwin_recvmsg and cygwin_sendmsg.
- * /usr/include/sys/socket.h: Add recvmsg and sendmsg.
+ * cygwin.din: Add recvmsg and sendmsg.
+ * net.cc: Add cygwin_recvmsg and cygwin_sendmsg.
+ * /usr/include/sys/socket.h: Add recvmsg and sendmsg.
2002-01-19 Corinna Vinschen <corinna@vinschen.de>
@@ -772,7 +2137,7 @@ Tue Sep 25 16:22:00 2001 Robert Collins <rbtcollins@hotmail.com>
file parameter.
2002-01-09 Christopher Faylor <cgf@redhat.com>
- Robert Collins <rbtcollins@hotmail.com>
+ Robert Collins <rbtcollins@hotmail.com>
* exceptions.cc (early_stuff_init): Rename from misnamed
set_console_handler.
@@ -849,7 +2214,7 @@ Tue Sep 25 16:22:00 2001 Robert Collins <rbtcollins@hotmail.com>
2002-01-01 Christopher Faylor <cgf@redhat.com>
- * speclib: Remove temp files automatically.
+ * speclib: Remove temp files automatically.
2002-01-01 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (fhandler_socket::sun_path): New private member.
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index 30cf31fdd..d10bdf2b5 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -51,7 +51,7 @@ CC:=@CC@
# FIXME: Which is it, CC or CC_FOR_TARGET?
CC_FOR_TARGET:=$(CC)
CFLAGS:=@CFLAGS@
-CFLAGS+=-MMD -fbuiltin
+override CFLAGS+=-MMD -fbuiltin
CXX:=@CXX@
CXXFLAGS:=@CXXFLAGS@
@@ -117,22 +117,23 @@ MALLOC_OFILES=@MALLOC_OFILES@
DLL_IMPORTS:=$(w32api_lib)/libkernel32.a
-# Please maintain this list in sorted order, with maximum files per line
+# Please maintain this list in sorted order, with maximum files per 80 col line
DLL_OFILES:=assert.o autoload.o cygheap.o cygserver_client.o cygserver_transport.o \
cygserver_transport_pipes.o cygserver_transport_sockets.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_random.o fhandler_raw.o fhandler_serial.o fhandler_socket.o \
- fhandler_tape.o fhandler_termios.o fhandler_tty.o fhandler_windows.o \
- fhandler_zero.o fnmatch.o fork.o glob.o grp.o heap.o init.o ioctl.o ipc.o \
- localtime.o malloc.o miscfuncs.o mmap.o net.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 shared.o shm.o shortcut.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 \
+ 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 glob.o grp.o \
+ heap.o init.o ioctl.o ipc.o localtime.o malloc.o miscfuncs.o mmap.o \
+ net.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 shared.o shm.o shortcut.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
@@ -165,10 +166,10 @@ all_host: new-$(LIB_NAME) cygrun.exe
force:
-install: install-bin install-libs install-headers install-man install_target \
+install: install-libs install-headers install-man install_target \
$(install_host) $(install_target)
-uninstall: uninstall-libs uninstall-headers uninstall-man
+uninstall: uninstall-libs uninstall-headers uninstall-man
install-libs: $(TARGET_LIBS)
$(INSTALL_DATA) new-$(DLL_NAME) $(bindir)/$(DLL_NAME); \
@@ -275,10 +276,10 @@ version.cc winver.o: winver_stamp
@ :
shared_info_magic.h: cygmagic shared_info.h
- /bin/sh ${word 1,$^} $@ "$(CC)" ${word 2,$^} MOUNT_MAGIC 'class mount_info' SHARED_MAGIC 'class shared_info'
+ /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)" ${word 2,$^} CHILD_INFO_MAGIC 'class child_info'
+ /bin/sh ${word 1,$^} $@ "$(CC) -x c" ${word 2,$^} CHILD_INFO_MAGIC 'class child_info'
dcrt0.o sigproc.o: child_info_magic.h
@@ -321,7 +322,7 @@ cygserver_client_outside.o: cygserver_client.cc
cygserver_shm.o: cygserver_shm.cc
$(COMPILE_CXX) -D__OUTSIDE_CYGWIN__ -o $@ $<
-cygserver.exe: cygserver.o cygserver_shm.o cygserver_transport_outside.o cygserver_transport_pipes_outside.o cygserver_transport_sockets_outside.o cygserver_client_outside.o cygserver_process.o threaded_queue.o wincap.o version.o smallprint.o
+cygserver.exe: cygserver.o cygserver_shm.o cygserver_transport_outside.o cygserver_transport_pipes_outside.o cygserver_transport_sockets_outside.o cygserver_client_outside.o cygserver_process.o threaded_queue.o wincap.o version.o smallprint.o
$(CXX) -o $@ $^
#ifdef VERBOSE
# $(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,3,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS)
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index ec71b6641..9bae17deb 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -1,6 +1,6 @@
/* autoload.cc: all dynamic load stuff.
- Copyright 2000, 2001 Red Hat, Inc.
+ Copyright 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -72,9 +72,10 @@ details. */
/* Standard DLL load macro. Invokes a fatal warning if the function isn't
found. */
#define LoadDLLfunc(name, n, dllname) LoadDLLfuncEx (name, n, dllname, 0)
+#define LoadDLLfuncEx(name, n, dllname, notimp) LoadDLLfuncEx2(name, n, dllname, notimp, 0)
/* Main DLL setup stuff. */
-#define LoadDLLfuncEx(name, n, dllname, notimp) \
+#define LoadDLLfuncEx2(name, n, dllname, notimp, err) \
LoadDLLprime (dllname, dll_func_load) \
__asm__ (" \n\
.section ." #dllname "_text,\"wx\" \n\
@@ -86,7 +87,7 @@ _win32_" mangle (name, n) ": \n\
movl (1f),%eax \n\
call *(%eax) \n\
1:.long ." #dllname "_info \n\
- .long " #n "+" #notimp " \n\
+ .long (" #n "+" #notimp ") | " #err "<<16 \n\
.asciz \"" #name "\" \n\
.text \n\
");
@@ -121,11 +122,15 @@ noload: \n\
jz 1f # Nope. \n\
decl %eax # Yes. This is the # of bytes + 1 \n\
popl %edx # Caller's caller \n\
+ movl %eax,%ebx # For manipulation \n\
+ andl $0xffff,%eax # Only want lower word \n\
addl %eax,%esp # Pop off bytes \n\
+ pushl %ebx # Save for later \n\
movl $127,%eax # ERROR_PROC_NOT_FOUND \n\
pushl %eax # First argument \n\
call _SetLastError@4 # Set it \n\
- xor %eax,%eax # Zero functional return \n\
+ popl %eax # Get back argument \n\
+ shrl $16,%eax # return value in high order word \n\
jmp *%edx # Return \n\
1: \n\
movl (%edx),%eax # Handle value \n\
@@ -316,6 +321,7 @@ LoadDLLfuncEx (DuplicateTokenEx, 24, advapi32, 1)
LoadDLLfunc (EqualSid, 8, advapi32)
LoadDLLfunc (GetAce, 12, advapi32)
LoadDLLfunc (GetFileSecurityA, 20, advapi32)
+LoadDLLfunc (GetKernelObjectSecurity, 20, advapi32)
LoadDLLfunc (GetLengthSid, 4, advapi32)
LoadDLLfunc (GetSecurityDescriptorDacl, 16, advapi32)
LoadDLLfunc (GetSecurityDescriptorGroup, 12, advapi32)
@@ -365,9 +371,9 @@ LoadDLLfunc (SetSecurityDescriptorOwner, 12, advapi32)
LoadDLLfunc (SetTokenInformation, 16, advapi32)
LoadDLLfunc (NetApiBufferFree, 4, netapi32)
+LoadDLLfunc (NetGetDCName, 12, netapi32)
LoadDLLfunc (NetLocalGroupEnum, 28, netapi32)
LoadDLLfunc (NetLocalGroupGetMembers, 32, netapi32)
-LoadDLLfunc (NetServerEnum, 36, netapi32)
LoadDLLfunc (NetUserGetGroups, 28, netapi32)
LoadDLLfunc (NetUserGetInfo, 16, netapi32)
LoadDLLfunc (NetWkstaUserGetInfo, 12, netapi32)
@@ -376,11 +382,14 @@ LoadDLLfuncEx (NtCreateToken, 52, ntdll, 1)
LoadDLLfuncEx (NtMapViewOfSection, 40, ntdll, 1)
LoadDLLfuncEx (NtOpenFile, 24, ntdll, 1)
LoadDLLfuncEx (NtOpenSection, 12, ntdll, 1)
+LoadDLLfuncEx (NtQueryInformationFile, 20, ntdll, 1)
+LoadDLLfuncEx (NtQueryInformationProcess, 20, ntdll, 1)
+LoadDLLfuncEx2 (NtQueryObject, 20, ntdll, 1, 1)
LoadDLLfuncEx (NtQuerySystemInformation, 16, ntdll, 1)
+LoadDLLfuncEx (NtQueryVirtualMemory, 24, ntdll, 1)
LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1)
LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
-LoadDLLfuncEx (ZwQuerySystemInformation, 16, ntdll, 1)
LoadDLLfuncEx (GetProcessMemoryInfo, 12, psapi, 1)
@@ -480,7 +489,7 @@ LoadDLLfunc (CoCreateInstance, 20, ole32)
LoadDLLfuncEx (CancelIo, 4, kernel32, 1)
LoadDLLfuncEx (CreateHardLinkA, 12, kernel32, 1)
LoadDLLfuncEx (CreateToolhelp32Snapshot, 8, kernel32, 1)
-LoadDLLfuncEx (IsDebuggerPresent, 0, kernel32, 1)
+LoadDLLfuncEx2 (IsDebuggerPresent, 0, kernel32, 1, 1)
LoadDLLfuncEx (Process32First, 8, kernel32, 1)
LoadDLLfuncEx (Process32Next, 8, kernel32, 1)
LoadDLLfuncEx (SignalObjectAndWait, 16, kernel32, 1)
@@ -495,4 +504,8 @@ LoadDLLfuncEx (waveOutSetVolume, 8, winmm, 1)
LoadDLLfuncEx (waveOutUnprepareHeader, 12, winmm, 1)
LoadDLLfuncEx (waveOutPrepareHeader, 12, winmm, 1)
LoadDLLfuncEx (waveOutWrite, 12, winmm, 1)
+LoadDLLfuncEx (timeGetDevCaps, 8, winmm, 1)
+LoadDLLfuncEx (timeGetTime, 0, winmm, 1)
+LoadDLLfuncEx (timeBeginPeriod, 4, winmm, 1)
+LoadDLLfuncEx (timeEndPeriod, 4, winmm, 1)
}
diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h
index e79ca3947..fdfaa28ca 100644
--- a/winsup/cygwin/child_info.h
+++ b/winsup/cygwin/child_info.h
@@ -70,7 +70,7 @@ class fhandler_base;
class cygheap_exec_info
{
public:
- __uid16_t uid;
+ __uid32_t uid;
char *old_title;
int argc;
char **argv;
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index 5d770746b..3fd2aacc9 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -1,6 +1,6 @@
/* cygheap.cc: Cygwin heap manager.
- Copyright 2000, 2001 Red Hat, Inc.
+ Copyright 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -429,7 +429,7 @@ cygheap_user::~cygheap_user ()
if (pname)
cfree (pname);
if (plogsrv)
- cfree (plogsrv);
+ cfree (plogsrv - 2);
if (pdomain)
cfree (pdomain);
if (psid)
@@ -449,8 +449,14 @@ void
cygheap_user::set_logsrv (const char *new_logsrv)
{
if (plogsrv)
- cfree (plogsrv);
- plogsrv = (new_logsrv && *new_logsrv) ? cstrdup (new_logsrv) : NULL;
+ cfree (plogsrv - 2);
+ if (!new_logsrv || !*new_logsrv)
+ plogsrv = NULL;
+ else
+ {
+ plogsrv = (char *) cmalloc (HEAP_STR, strlen (new_logsrv) + 3) + 2;
+ strcpy (plogsrv, new_logsrv);
+ }
}
void
@@ -468,13 +474,23 @@ cygheap_user::set_sid (PSID new_sid)
{
if (psid)
cfree (psid);
+ if (orig_psid)
+ cfree (orig_psid);
psid = NULL;
+ orig_psid = NULL;
return TRUE;
}
else
{
if (!psid)
- psid = cmalloc (HEAP_STR, MAX_SID_LEN);
+ {
+ if (!orig_psid)
+ {
+ orig_psid = cmalloc (HEAP_STR, MAX_SID_LEN);
+ CopySid (MAX_SID_LEN, orig_psid, new_sid);
+ }
+ psid = cmalloc (HEAP_STR, MAX_SID_LEN);
+ }
return CopySid (MAX_SID_LEN, psid, new_sid);
}
}
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index ec7624bea..71c00aca8 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -48,7 +48,6 @@ struct cygheap_root_mount_info
/* CGF: FIXME This doesn't belong here */
-int path_prefix_p (const char *path1, const char *path2, int len1) __attribute__ ((regparm (3)));
class cygheap_root
{
/* Root directory information.
@@ -86,6 +85,14 @@ public:
const char *native_path () const { return m->native_path; }
};
+enum homebodies
+{
+ CH_HOMEDRIVE,
+ CH_HOMEPATH,
+ CH_HOME
+};
+
+struct passwd;
class cygheap_user
{
/* Extendend user information.
@@ -94,12 +101,15 @@ class cygheap_user
char *pname; /* user's name */
char *plogsrv; /* Logon server, may be FQDN */
char *pdomain; /* Logon domain of the user */
+ char *homedrive; /* User's home drive */
+ char *homepath; /* User's home path */
PSID psid; /* buffer for user's SID */
+ PSID orig_psid; /* Remains intact even after impersonation */
public:
- __uid16_t orig_uid; /* Remains intact even after impersonation */
- __uid16_t orig_gid; /* Ditto */
- __uid16_t real_uid; /* Remains intact on seteuid, replaced by setuid */
- __gid16_t real_gid; /* Ditto */
+ __uid32_t orig_uid; /* Remains intact even after impersonation */
+ __gid32_t orig_gid; /* Ditto */
+ __uid32_t real_uid; /* Remains intact on seteuid, replaced by setuid */
+ __gid32_t real_gid; /* Ditto */
/* token is needed if set(e)uid should be called. It can be set by a call
to `set_impersonation_token()'. */
@@ -107,6 +117,7 @@ public:
BOOL impersonated;
cygheap_user () : pname (NULL), plogsrv (NULL), pdomain (NULL),
+ homedrive (NULL), homepath (NULL),
psid (NULL), token (INVALID_HANDLE_VALUE) {}
~cygheap_user ();
@@ -116,11 +127,17 @@ public:
void set_logsrv (const char *new_logsrv);
const char *logsrv () const { return plogsrv; }
+ const char *env_logsrv ();
+ const char *env_homepath ();
+ const char *env_homedrive ();
+ const char *env_userprofile ();
+
void set_domain (const char *new_domain);
const char *domain () const { return pdomain; }
BOOL set_sid (PSID new_sid);
PSID sid () const { return psid; }
+ PSID orig_sid () const { return orig_psid; }
void operator =(cygheap_user &user)
{
@@ -129,6 +146,7 @@ public:
set_domain (user.domain ());
set_sid (user.sid ());
}
+ const char *ontherange (homebodies what, struct passwd * = NULL);
};
/* cwd cache stuff. */
diff --git a/winsup/cygwin/cygserver.cc b/winsup/cygwin/cygserver.cc
index 57f92c2ac..af9cee93e 100755
--- a/winsup/cygwin/cygserver.cc
+++ b/winsup/cygwin/cygserver.cc
@@ -1,6 +1,6 @@
/* cygserver.cc
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Egor Duda <deo@logos-m.ru>
@@ -18,6 +18,7 @@
#include <sys/socket.h>
#include <netdb.h>
#include <signal.h>
+#include <stdlib.h>
#include "wincap.h"
#include "cygwin_version.h"
@@ -47,26 +48,26 @@ setup_privileges ()
HANDLE hToken = NULL;
TOKEN_PRIVILEGES sPrivileges;
- rc = OpenProcessToken ( GetCurrentProcess() , TOKEN_ALL_ACCESS , &hToken ) ;
- if ( !rc )
+ rc = OpenProcessToken (GetCurrentProcess() , TOKEN_ALL_ACCESS , &hToken) ;
+ if (!rc)
{
- printf ( "error opening process token (%lu)\n", GetLastError () );
+ printf ("error opening process token (%lu)\n", GetLastError ());
ret_val = FALSE;
goto out;
}
- rc = LookupPrivilegeValue ( NULL, SE_DEBUG_NAME, &sPrivileges.Privileges[0].Luid );
- if ( !rc )
+ rc = LookupPrivilegeValue (NULL, SE_DEBUG_NAME, &sPrivileges.Privileges[0].Luid);
+ if (!rc)
{
- printf ( "error getting prigilege luid (%lu)\n", GetLastError () );
+ printf ("error getting prigilege luid (%lu)\n", GetLastError ());
ret_val = FALSE;
goto out;
}
sPrivileges.PrivilegeCount = 1 ;
sPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED ;
- rc = AdjustTokenPrivileges ( hToken, FALSE, &sPrivileges, 0, NULL, NULL ) ;
- if ( !rc )
+ rc = AdjustTokenPrivileges (hToken, FALSE, &sPrivileges, 0, NULL, NULL) ;
+ if (!rc)
{
- printf ( "error adjusting prigilege level. (%lu)\n", GetLastError () );
+ printf ("error adjusting prigilege level. (%lu)\n", GetLastError ());
ret_val = FALSE;
goto out;
}
@@ -79,16 +80,16 @@ setup_privileges ()
ret_val = TRUE;
out:
- CloseHandle ( hToken );
+ CloseHandle (hToken);
return ret_val;
}
int
check_and_dup_handle (HANDLE from_process, HANDLE to_process,
HANDLE from_process_token,
- DWORD access,
- HANDLE from_handle,
- HANDLE* to_handle_ptr, BOOL bInheritHandle = FALSE)
+ DWORD access,
+ HANDLE from_handle,
+ HANDLE* to_handle_ptr, BOOL bInheritHandle = FALSE)
{
HANDLE local_handle = NULL;
int ret_val = EACCES;
@@ -100,53 +101,53 @@ check_and_dup_handle (HANDLE from_process, HANDLE to_process,
BOOL status;
if (from_process != GetCurrentProcess ())
-{
+ {
if (!DuplicateHandle (from_process, from_handle,
- GetCurrentProcess (), &local_handle,
- 0, bInheritHandle,
- DUPLICATE_SAME_ACCESS))
+ GetCurrentProcess (), &local_handle,
+ 0, bInheritHandle,
+ DUPLICATE_SAME_ACCESS))
{
- printf ( "error getting handle(%u) to server (%lu)\n", (unsigned int)from_handle, GetLastError ());
+ printf ("error getting handle(%u) to server (%lu)\n", (unsigned int)from_handle, GetLastError ());
goto out;
}
} else
local_handle = from_handle;
if (!GetKernelObjectSecurity (local_handle,
- OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+ OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
sd, sizeof (sd_buf), &bytes_needed))
{
- printf ( "error getting handle SD (%lu)\n", GetLastError ());
+ printf ("error getting handle SD (%lu)\n", GetLastError ());
goto out;
}
MapGenericMask (&access, &access_mapping);
if (!AccessCheck (sd, from_process_token, access, &access_mapping,
- &ps, &ps_len, &access, &status))
+ &ps, &ps_len, &access, &status))
{
- printf ( "error checking access rights (%lu)\n", GetLastError ());
+ printf ("error checking access rights (%lu)\n", GetLastError ());
goto out;
}
if (!status)
{
- printf ( "access to object denied\n");
+ printf ("access to object denied\n");
goto out;
}
if (!DuplicateHandle (from_process, from_handle,
- to_process, to_handle_ptr,
- access, bInheritHandle, 0))
+ to_process, to_handle_ptr,
+ access, bInheritHandle, 0))
{
- printf ( "error getting handle to client (%lu)\n", GetLastError ());
+ printf ("error getting handle to client (%lu)\n", GetLastError ());
goto out;
}
debug_printf ("Duplicated %p to %p\n", from_handle, *to_handle_ptr);
ret_val = 0;
-
+
out:
if (local_handle && from_process != GetCurrentProcess ())
CloseHandle (local_handle);
@@ -178,7 +179,7 @@ client_request_attach_tty::serve(transport_layer_base *conn, class process_cache
}
debug_printf ("pid %ld:(%p,%p) -> pid %ld\n", req.master_pid,
- req.from_master, req.to_master,
+ req.from_master, req.to_master,
req.pid);
debug_printf ("opening process %ld\n", req.master_pid);
@@ -194,11 +195,11 @@ client_request_attach_tty::serve(transport_layer_base *conn, class process_cache
debug_printf ("Impersonating client\n");
conn->impersonate_client ();
-
+
debug_printf ("about to open thread token\n");
rc = OpenThreadToken (GetCurrentThread (),
- TOKEN_QUERY,
- TRUE,
+ TOKEN_QUERY,
+ TRUE,
&token_handle);
debug_printf ("opened thread token, rc=%lu\n", rc);
@@ -212,10 +213,10 @@ client_request_attach_tty::serve(transport_layer_base *conn, class process_cache
}
if (check_and_dup_handle (from_process_handle, to_process_handle,
- token_handle,
- GENERIC_READ,
- req.from_master,
- &req.from_master, TRUE) != 0)
+ token_handle,
+ GENERIC_READ,
+ req.from_master,
+ &req.from_master, TRUE) != 0)
{
printf ("error duplicating from_master handle (%lu)\n", GetLastError ());
header.error_code = EACCES;
@@ -238,7 +239,7 @@ client_request_attach_tty::serve(transport_layer_base *conn, class process_cache
#if DEBUG
printf ("%ld -> %ld(%p,%p)\n", req.master_pid, req.pid,
- req.from_master, req.to_master);
+ req.from_master, req.to_master);
#endif
header.error_code = 0;
@@ -309,7 +310,7 @@ request_loop (LPVOID LpParam)
* _AFTER_ the shutdown request. And sending ourselves a request is ugly
*/
if (new_conn && queue->active)
- queue->add (new_conn);
+ queue->add (new_conn);
}
return 0;
}
@@ -382,10 +383,10 @@ server_request::process ()
bytes_read = conn->read (req->buffer, req->header.cb);
if (bytes_read != req->header.cb)
- {
- debug_printf ("error reading from connection (%lu)\n", GetLastError ());
- goto out;
- }
+ {
+ debug_printf ("error reading from connection (%lu)\n", GetLastError ());
+ goto out;
+ }
debug_printf ("got body (%ld)\n",bytes_read);
}
@@ -458,10 +459,10 @@ main (int argc, char **argv)
switch (i)
{
case 's':
- shutdown = 1;
- break;
+ shutdown = 1;
+ break;
default:
- break;
+ break;
/*NOTREACHED*/
}
@@ -489,17 +490,17 @@ main (int argc, char **argv)
char version[200];
/* Cygwin dll release */
snprintf (version, 200, "%d.%d.%d(%d.%d/%d/%d)-(%d.%d.%d.%d) %s",
- cygwin_version.dll_major / 1000,
- cygwin_version.dll_major % 1000,
- cygwin_version.dll_minor,
- cygwin_version.api_major,
- cygwin_version.api_minor,
- cygwin_version.shared_data,
+ cygwin_version.dll_major / 1000,
+ cygwin_version.dll_major % 1000,
+ cygwin_version.dll_minor,
+ cygwin_version.api_major,
+ cygwin_version.api_minor,
+ cygwin_version.shared_data,
CYGWIN_SERVER_VERSION_MAJOR,
CYGWIN_SERVER_VERSION_API,
CYGWIN_SERVER_VERSION_MINOR,
CYGWIN_SERVER_VERSION_PATCH,
- cygwin_version.mount_registry,
+ cygwin_version.mount_registry,
cygwin_version.dll_build_date);
setbuf (stdout, NULL);
printf ("daemon version %s starting up", version);
@@ -533,7 +534,7 @@ main (int argc, char **argv)
/* WaitForMultipleObjects abort && request_queue && process_queue && signal
-- if signal event then retrigger it
*/
- while (1 && request_queue.active)
+ while (1 && request_queue.active)
{
sleep (1);
}
diff --git a/winsup/cygwin/cygserver_client.cc b/winsup/cygwin/cygserver_client.cc
index 8a1eeafef..1df23ad9f 100755
--- a/winsup/cygwin/cygserver_client.cc
+++ b/winsup/cygwin/cygserver_client.cc
@@ -1,6 +1,6 @@
/* cygserver_client.cc
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Egor Duda <deo@logos-m.ru>
@@ -98,7 +98,7 @@ client_request::send (transport_layer_base *conn)
if ((bytes_read = conn->read ((char *)&header, sizeof (header)))
!= sizeof (header) || (header.cb &&
- (bytes_read = conn->read (buffer, header.cb) ) != header.cb))
+ (bytes_read = conn->read (buffer, header.cb)) != header.cb))
{
header.error_code = -1;
debug_printf("failed reading response \n");
@@ -180,7 +180,7 @@ cygserver_init ()
if (cygserver_running==CYGSERVER_OK)
return;
- client_request_get_version *req =
+ client_request_get_version *req =
new client_request_get_version ();
rc = cygserver_request (req);
@@ -188,11 +188,11 @@ cygserver_init ()
if (rc < 0)
cygserver_running = CYGSERVER_DEAD;
else if (rc > 0)
- api_fatal ( "error connecting to cygwin server. error: %d", rc );
+ api_fatal ("error connecting to cygwin server. error: %d", rc);
else if (req->version.major != CYGWIN_SERVER_VERSION_MAJOR ||
req->version.api != CYGWIN_SERVER_VERSION_API ||
req->version.minor > CYGWIN_SERVER_VERSION_MINOR)
- api_fatal ( "incompatible version of cygwin server.\n\
+ api_fatal ("incompatible version of cygwin server.\n\
client version %d.%d.%d.%d, server version%ld.%ld.%ld.%ld",
CYGWIN_SERVER_VERSION_MAJOR,
CYGWIN_SERVER_VERSION_API,
@@ -201,7 +201,7 @@ cygserver_init ()
req->version.major,
req->version.api,
req->version.minor,
- req->version.patch );
+ req->version.patch);
else
cygserver_running = CYGSERVER_OK;
}
diff --git a/winsup/cygwin/cygserver_process.cc b/winsup/cygwin/cygserver_process.cc
index a5173afd3..dd13f37fb 100755
--- a/winsup/cygwin/cygserver_process.cc
+++ b/winsup/cygwin/cygserver_process.cc
@@ -1,6 +1,6 @@
/* cygserver_process.cc
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Robert Collins <rbtcollins@hotmail.com>
@@ -117,10 +117,10 @@ process_cache::remove_process (class process *theprocess)
{
entry = (class process *) InterlockedExchangePointer (&head, theprocess->next);
if (entry != theprocess)
- {
- printf ("Bug encountered, process cache corrupted\n");
+ {
+ printf ("Bug encountered, process cache corrupted\n");
exit (1);
- }
+ }
}
else
{
@@ -137,11 +137,10 @@ process_cache::remove_process (class process *theprocess)
/* Process any cleanup tasks */
add_task (theprocess);
}
-
-
+
/* copy <= max_copy HANDLEs to dest[], starting at an offset into _our list_ of
* begin_at. (Ie begin_at = 5, the first copied handle is still written to dest[0]
- * NOTE: Thread safe, but not thread guaranteed - a newly added process may be missed.
+ * NOTE: Thread safe, but not thread guaranteed - a newly added process may be missed.
* Who cares - It'll get caught the next time.
*/
int
@@ -227,7 +226,7 @@ process::handle ()
// thehandle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, winpid);
// debug_printf ("Got handle %p when refreshing cache process %ld\n", thehandle, winpid);
// /* FIXME: what if OpenProcess fails ? */
-// if (thehandle)
+// if (thehandle)
// {
// _exit_status = STILL_ACTIVE;
// exit_code ();
@@ -281,7 +280,7 @@ process::add_cleanup_routine (class cleanup_routine *new_cleanup)
if (cleaning_up)
return false;
EnterCriticalSection (&access);
- /* check that we didn't block with ::cleanup ()
+ /* check that we didn't block with ::cleanup ()
* This rigmarole is to get around win9x's glaring missing TryEnterCriticalSection call
* which would be a whole lot easier
*/
diff --git a/winsup/cygwin/cygserver_shm.cc b/winsup/cygwin/cygserver_shm.cc
index c29938bb9..1116bc809 100755
--- a/winsup/cygwin/cygserver_shm.cc
+++ b/winsup/cygwin/cygserver_shm.cc
@@ -1,15 +1,14 @@
/* cygserver_shm.cc: Single unix specification IPC interface for Cygwin
- Copyright 2001 Red Hat, Inc.
+Copyright 2001, 2002 Red Hat, Inc.
- Originally written by Robert Collins <robert.collins@hotmail.com>
+Originally written by Robert Collins <robert.collins@hotmail.com>
- 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 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. */
#ifdef __OUTSIDE_CYGWIN__
#undef __INSIDE_CYGWIN__
@@ -70,20 +69,24 @@ getsystemallocgranularity ()
}
-client_request_shm::client_request_shm ():client_request (CYGSERVER_REQUEST_SHM_GET, sizeof (parameters))
+client_request_shm::client_request_shm ():client_request (CYGSERVER_REQUEST_SHM_GET,
+ sizeof (parameters))
{
buffer = (char *) &parameters;
}
/* FIXME: If building on a 64-bit compiler, the address->int typecast will fail.
- * Solution: manually calculate the next id value
+ * Solution: manually calculate the next id value
*/
#if 0
-extern "C" void *
+extern
+"C" void *
shmat (int shmid, const void *shmaddr, int parameters.in.shmflg)
{
- class shmid_ds *shm = (class shmid_ds *) shmid; //FIXME: verifyable object test
+ class shmid_ds *
+ shm = (class shmid_ds *)
+ shmid; //FIXME: verifyable object test
if (shmaddr)
{
@@ -92,12 +95,14 @@ shmat (int shmid, const void *shmaddr, int parameters.in.shmflg)
return (void *) -1;
}
- void *rv = MapViewOfFile (shm->attachmap,
+ void *
+ rv =
+ MapViewOfFile (shm->attachmap,
- (parameters.in.shmflg & SHM_RDONLY) ?
- FILE_MAP_READ : FILE_MAP_WRITE, 0,
- 0, 0);
+ (parameters.in.shmflg & SHM_RDONLY) ?
+ FILE_MAP_READ : FILE_MAP_WRITE, 0,
+ 0, 0);
if (!rv)
{
@@ -111,7 +116,10 @@ shmat (int shmid, const void *shmaddr, int parameters.in.shmflg)
*/
InterlockedIncrement (&shm->shm_nattch);
- _shmattach *attachnode = new _shmattach;
+ _shmattach *
+ attachnode =
+ new
+ _shmattach;
attachnode->data = rv;
attachnode->next =
@@ -127,7 +135,7 @@ shmat (int shmid, const void *shmaddr, int parameters.in.shmflg)
*/
/* Test result from openbsd: shm ids are persistent cross process if a handle is left
- * open. This could lead to resource starvation: we're not copying that behaviour
+ * open. This could lead to resource starvation: we're not copying that behaviour
* unless we have to. (It will involve acygwin1.dll gloal shared list :[ ).
*/
/* FIXME: shmid should be a verifyable object
@@ -136,7 +144,8 @@ shmat (int shmid, const void *shmaddr, int parameters.in.shmflg)
/* FIXME: on NT we should check everything against the SD. On 95 we just emulate.
*/
-extern GENERIC_MAPPING access_mapping;
+extern GENERIC_MAPPING
+ access_mapping;
extern int
check_and_dup_handle (HANDLE from_process, HANDLE to_process,
@@ -146,21 +155,58 @@ check_and_dup_handle (HANDLE from_process, HANDLE to_process,
HANDLE * to_handle_ptr, BOOL bInheritHandle);
//FIXME: where should this live
-static shmnode *shm_head = NULL;
+static shmnode *
+ shm_head =
+ NULL;
+//FIXME: ditto.
+static shmnode *
+ deleted_head = NULL;
/* must be long for InterlockedIncrement */
-static long new_id = 0;
-static long new_private_key = 0;
+static long
+ new_id =
+ 0;
+static long
+ new_private_key =
+ 0;
+
+static void
+delete_shmnode (shmnode **nodeptr)
+{
+ shmnode *node = *nodeptr;
+
+ // remove from the list
+ if (node == shm_head)
+ shm_head = shm_head->next;
+ else
+ {
+ shmnode *tempnode = shm_head;
+ while (tempnode && tempnode->next != node)
+ tempnode = tempnode->next;
+ if (tempnode)
+ tempnode->next = node->next;
+ // else log the unexpected !
+ }
+
+ // release the shared data view
+ UnmapViewOfFile (node->shmds->mapptr);
+ delete node->shmds;
+ CloseHandle (node->filemap);
+ CloseHandle (node->attachmap);
+
+ // free the memory
+ delete node;
+ nodeptr = NULL;
+}
void
-client_request_shm::serve (transport_layer_base * conn,
- process_cache * cache)
+client_request_shm::serve (transport_layer_base * conn, process_cache * cache)
{
// DWORD sd_size = 4096;
// char sd_buf[4096];
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) parameters.in.sd_buf;
// /* create a sd for our open requests based on shmflag & 0x01ff */
// psd = alloc_sd (getuid (), getgid (), cygheap->user.logsrv (),
-// parameters.in.shmflg & 0x01ff, psd, &sd_size);
+// parameters.in.shmflg & 0x01ff, psd, &sd_size);
HANDLE from_process_handle = NULL;
HANDLE token_handle = NULL;
@@ -169,8 +215,8 @@ client_request_shm::serve (transport_layer_base * conn,
from_process_handle = cache->process (parameters.in.pid)->handle ();
/* possible TODO: reduce the access on the handle before we use it */
/* Note that unless we do this, we don't need to call CloseHandle - it's kept open
- * by the process cache until the process terminates.
- * We may need a refcount on the cache however...
+ * by the process cache until the process terminates.
+ * We may need a refcount on the cache however...
*/
if (!from_process_handle)
{
@@ -196,7 +242,7 @@ client_request_shm::serve (transport_layer_base * conn,
/* we trust the clients request - we will be doing it as them, and
- * the worst they can do is open their own permissions
+ * the worst they can do is open their own permissions
*/
@@ -257,296 +303,363 @@ client_request_shm::serve (transport_layer_base * conn,
{
shmnode *tempnode = shm_head;
while (tempnode)
- {
- if (tempnode->shm_id == parameters.in.shm_id)
- {
+ {
+ if (tempnode->shm_id == parameters.in.shm_id)
+ {
InterlockedIncrement (&tempnode->shmds->shm_nattch);
header.error_code = 0;
- CloseHandle (token_handle);
- return;
- }
- tempnode = tempnode->next;
- }
+ CloseHandle (token_handle);
+ return;
+ }
+ tempnode = tempnode->next;
+ }
header.error_code = EINVAL;
CloseHandle (token_handle);
return;
}
- /* it's a original request from the users */
-
- /* FIXME: enter the checking for existing keys mutex. This mutex _must_ be system wide
- * to prevent races on shmget.
- */
-
- if (parameters.in.key == IPC_PRIVATE)
+ /* Someone detached */
+ if (parameters.in.type == SHM_DETACH)
{
- /* create the mapping name (CYGWINSHMKPRIVATE_0x01234567 */
- /* The K refers to Key, the actual mapped area has D */
- long private_key = (int) InterlockedIncrement (&new_private_key);
- snprintf (stringbuf, 29, "CYGWINSHMKPRIVATE_0x%0x", private_key);
- shmname = stringbuf;
- snprintf (stringbuf1, 29, "CYGWINSHMDPRIVATE_0x%0x", private_key);
- shmaname = stringbuf1;
+ shmnode *tempnode = shm_head;
+ while (tempnode)
+ {
+ if (tempnode->shm_id == parameters.in.shm_id)
+ {
+ InterlockedDecrement (&tempnode->shmds->shm_nattch);
+ header.error_code = 0;
+ CloseHandle (token_handle);
+ return;
+ }
+ tempnode = tempnode->next;
+ }
+ header.error_code = EINVAL;
+ CloseHandle (token_handle);
+ return;
}
- else
+
+ /* Someone wants the ID removed. */
+ if (parameters.in.type == SHM_DEL)
{
- /* create the mapping name (CYGWINSHMK0x0123456789abcdef */
- /* The K refers to Key, the actual mapped area has D */
-
- snprintf (stringbuf, 29, "CYGWINSHMK0x%0qx", parameters.in.key);
- shmname = stringbuf;
- snprintf (stringbuf1, 29, "CYGWINSHMD0x%0qx", parameters.in.key);
- shmaname = stringbuf1;
- debug_printf ("system id strings are \n%s\n%s\n", shmname, shmaname);
- debug_printf ("key input value is 0x%0qx\n", parameters.in.key);
+ shmnode **tempnode = &shm_head;
+ while (*tempnode)
+ {
+ if ((*tempnode)->shm_id == parameters.in.shm_id)
+ {
+ // unlink from the accessible node list
+ shmnode *temp2 = *tempnode;
+ *tempnode = temp2->next;
+ // link into the deleted list
+ temp2->next = deleted_head;
+ deleted_head = temp2;
+
+ // FIXME: when/where do we delete the handles?
+ if (temp2->shmds->shm_nattch)
+ {
+ // FIXME: add to a pending queue?
+ }
+ else
+ {
+ delete_shmnode (&temp2);
+ }
+
+ header.error_code = 0;
+ CloseHandle (token_handle);
+ return;
+ }
+ tempnode = &(*tempnode)->next;
+ }
+ header.error_code = EINVAL;
+ CloseHandle (token_handle);
+ return;
}
- /* attempt to open the key */
- /* get an existing key */
- /* On unix the same shmid identifier is returned on multiple calls to shm_get
- * with the same key and size. Different modes is a ?.
- */
+ if (parameters.in.type == SHM_CREATE)
+ {
+ /* FIXME: enter the checking for existing keys mutex. This mutex _must_ be system wide
+ * to prevent races on shmget.
+ */
+ if (parameters.in.key == IPC_PRIVATE)
+ {
+ /* create the mapping name (CYGWINSHMKPRIVATE_0x01234567 */
+ /* The K refers to Key, the actual mapped area has D */
+ long private_key = (int) InterlockedIncrement (&new_private_key);
+ snprintf (stringbuf, 29, "CYGWINSHMKPRIVATE_0x%0x", private_key);
+ shmname = stringbuf;
+ snprintf (stringbuf1, 29, "CYGWINSHMDPRIVATE_0x%0x", private_key);
+ shmaname = stringbuf1;
+ }
+ else
+ {
+ /* create the mapping name (CYGWINSHMK0x0123456789abcdef */
+ /* The K refers to Key, the actual mapped area has D */
+
+ snprintf (stringbuf, 29, "CYGWINSHMK0x%0qx", parameters.in.key);
+ shmname = stringbuf;
+ snprintf (stringbuf1, 29, "CYGWINSHMD0x%0qx", parameters.in.key);
+ shmaname = stringbuf1;
+ debug_printf ("system id strings are \n%s\n%s\n", shmname,
+ shmaname);
+ debug_printf ("key input value is 0x%0qx\n", parameters.in.key);
+ }
+ /* attempt to open the key */
- /* walk the list of known keys and return the id if found. remember, we are
- * authoritative...
- */
+ /* get an existing key */
+ /* On unix the same shmid identifier is returned on multiple calls to shm_get
+ * with the same key and size. Different modes is a ?.
+ */
- shmnode *tempnode = shm_head;
- while (tempnode)
- {
- if (tempnode->key == parameters.in.key
- && parameters.in.key != IPC_PRIVATE)
+
+
+ /* walk the list of known keys and return the id if found. remember, we are
+ * authoritative...
+ */
+
+ shmnode *tempnode = shm_head;
+ while (tempnode)
{
- // FIXME: free the mutex
- if (parameters.in.size
- && tempnode->shmds->shm_segsz < parameters.in.size)
+ if (tempnode->key == parameters.in.key
+ && parameters.in.key != IPC_PRIVATE)
{
- header.error_code = EINVAL;
+ // FIXME: free the mutex
+ if (parameters.in.size
+ && tempnode->shmds->shm_segsz < parameters.in.size)
+ {
+ header.error_code = EINVAL;
+ CloseHandle (token_handle);
+ return;
+ }
+ /* FIXME: can the same process call this twice without error ? test
+ * on unix
+ */
+ if ((parameters.in.shmflg & IPC_CREAT)
+ && (parameters.in.shmflg & IPC_EXCL))
+ {
+ header.error_code = EEXIST;
+ debug_printf
+ ("attempt to exclusively create already created shm_area with key 0x%0qx\n",
+ parameters.in.key);
+ // FIXME: free the mutex
+ CloseHandle (token_handle);
+ return;
+ }
+ // FIXME: do we need to other tests of the requested mode with the
+ // tempnode->shm_id mode ? testcase on unix needed.
+ // FIXME how do we do the security test? or
+ // do we wait for shmat to bother with that?
+ /* One possibly solution: impersonate the client, and then test we can
+ * reopen the area. In fact we'll probably have to do that to get
+ * handles back to them, alternatively just tell them the id, and then
+ * let them attempt the open.
+ */
+ parameters.out.shm_id = tempnode->shm_id;
+ if (check_and_dup_handle
+ (GetCurrentProcess (), from_process_handle, token_handle,
+ DUPLICATE_SAME_ACCESS, tempnode->filemap,
+ &parameters.out.filemap, TRUE) != 0)
+ {
+ printf ("error duplicating filemap handle (%lu)\n",
+ GetLastError ());
+ header.error_code = EACCES;
+/*mutex*/
+ CloseHandle (token_handle);
+ return;
+ }
+ if (check_and_dup_handle
+ (GetCurrentProcess (), from_process_handle, token_handle,
+ DUPLICATE_SAME_ACCESS, tempnode->attachmap,
+ &parameters.out.attachmap, TRUE) != 0)
+ {
+ printf ("error duplicating attachmap handle (%lu)\n",
+ GetLastError ());
+ header.error_code = EACCES;
+/*mutex*/
+ CloseHandle (token_handle);
+ return;
+ }
+
CloseHandle (token_handle);
return;
}
- /* FIXME: can the same process call this twice without error ? test
- * on unix
- */
+ tempnode = tempnode->next;
+ }
+ /* couldn't find a currently open shm area. */
+
+ /* create one */
+ /* do this as the client */
+ conn->impersonate_client ();
+ /* This may need sh_none... it's only a control structure */
+ HANDLE filemap = CreateFileMapping (INVALID_HANDLE_VALUE, // system pagefile.
+ &sa,
+ PAGE_READWRITE, // protection
+ 0x00000000,
+ getsystemallocgranularity (),
+ shmname // object name
+ );
+ int lasterr = GetLastError ();
+ conn->revert_to_self ();
+
+ if (filemap == NULL)
+ {
+ /* We failed to open the filemapping ? */
+ system_printf ("failed to open file mapping: %lu\n",
+ GetLastError ());
+ // free the mutex
+ // we can assume that it exists, and that it was an access problem.
+ header.error_code = EACCES;
+ CloseHandle (token_handle);
+ return;
+ }
+
+ /* successfully opened the control region mapping */
+ /* did we create it ? */
+ int oldmapping = lasterr == ERROR_ALREADY_EXISTS;
+ if (oldmapping)
+ {
+ /* should never happen - we are the global daemon! */
+#if 0
if ((parameters.in.shmflg & IPC_CREAT)
&& (parameters.in.shmflg & IPC_EXCL))
+#endif
{
+ /* FIXME free mutex */
+ CloseHandle (filemap);
header.error_code = EEXIST;
- debug_printf
- ("attempt to exclusively create already created shm_area with key 0x%0qx\n",
- parameters.in.key);
- // FIXME: free the mutex
- CloseHandle (token_handle);
- return;
- }
- // FIXME: do we need to other tests of the requested mode with the
- // tempnode->shm_id mode ? testcase on unix needed.
- // FIXME how do we do the security test? or
- // do we wait for shmat to bother with that?
- /* One possibly solution: impersonate the client, and then test we can
- * reopen the area. In fact we'll probably have to do that to get
- * handles back to them, alternatively just tell them the id, and then
- * let them attempt the open.
- */
- parameters.out.shm_id = tempnode->shm_id;
- if (check_and_dup_handle (GetCurrentProcess (), from_process_handle,
- token_handle,
- DUPLICATE_SAME_ACCESS,
- tempnode->filemap,
- &parameters.out.filemap, TRUE) != 0)
- {
- printf ("error duplicating filemap handle (%lu)\n",
- GetLastError ());
- header.error_code = EACCES;
-/*mutex*/
- CloseHandle (token_handle);
- return;
- }
- if (check_and_dup_handle (GetCurrentProcess (), from_process_handle,
- token_handle,
- DUPLICATE_SAME_ACCESS,
- tempnode->attachmap,
- &parameters.out.attachmap, TRUE) != 0)
- {
- printf ("error duplicating attachmap handle (%lu)\n",
- GetLastError ());
- header.error_code = EACCES;
-/*mutex*/
CloseHandle (token_handle);
return;
}
+ }
+ /* we created a new mapping */
+ if (parameters.in.key != IPC_PRIVATE &&
+ (parameters.in.shmflg & IPC_CREAT) == 0)
+ {
+ CloseHandle (filemap);
+ /* FIXME free mutex */
+ header.error_code = ENOENT;
CloseHandle (token_handle);
return;
}
- tempnode = tempnode->next;
- }
- /* couldn't find a currently open shm area. */
- /* create one */
- /* do this as the client */
- conn->impersonate_client ();
- /* This may need sh_none... it's only a control structure */
- HANDLE filemap = CreateFileMapping (INVALID_HANDLE_VALUE, // system pagefile.
- &sa,
- PAGE_READWRITE, // protection
- 0x00000000,
- getsystemallocgranularity (),
- shmname // object name
- );
- int lasterr = GetLastError ();
- conn->revert_to_self ();
+ conn->impersonate_client ();
+ void *mapptr = MapViewOfFile (filemap, FILE_MAP_WRITE, 0, 0, 0);
+ conn->revert_to_self ();
- if (filemap == NULL)
- {
- /* We failed to open the filemapping ? */
- system_printf ("failed to open file mapping: %lu\n", GetLastError ());
- // free the mutex
- // we can assume that it exists, and that it was an access problem.
- header.error_code = EACCES;
- CloseHandle (token_handle);
- return;
- }
-
- /* successfully opened the control region mapping */
- /* did we create it ? */
- int oldmapping = lasterr == ERROR_ALREADY_EXISTS;
- if (oldmapping)
- {
- /* should never happen - we are the global daemon! */
-#if 0
- if ((parameters.in.shmflg & IPC_CREAT)
- && (parameters.in.shmflg & IPC_EXCL))
-#endif
+ if (!mapptr)
{
- /* FIXME free mutex */
CloseHandle (filemap);
- header.error_code = EEXIST;
+ //FIXME: close filemap and free the mutex
+ /* we couldn't access the mapped area with the requested permissions */
+ header.error_code = EACCES;
CloseHandle (token_handle);
return;
}
- }
- /* we created a new mapping */
- if (parameters.in.key != IPC_PRIVATE &&
- (parameters.in.shmflg & IPC_CREAT) == 0)
- {
- CloseHandle (filemap);
- /* FIXME free mutex */
- header.error_code = ENOENT;
- CloseHandle (token_handle);
- return;
- }
-
- conn->impersonate_client ();
- void *mapptr = MapViewOfFile (filemap, FILE_MAP_WRITE, 0, 0, 0);
- conn->revert_to_self ();
-
- if (!mapptr)
- {
- CloseHandle (filemap);
- //FIXME: close filemap and free the mutex
- /* we couldn't access the mapped area with the requested permissions */
- header.error_code = EACCES;
- CloseHandle (token_handle);
- return;
- }
+ conn->impersonate_client ();
+ /* Now get the user data */
+ HANDLE attachmap = CreateFileMapping (INVALID_HANDLE_VALUE, // system pagefile
+ &sa,
+ PAGE_READWRITE, // protection (FIXME)
+ 0x00000000,
+ parameters.in.size +
+ parameters.in.size %
+ getsystemallocgranularity (),
+ shmaname // object name
+ );
+ conn->revert_to_self ();
+
+ if (attachmap == NULL)
+ {
+ system_printf ("failed to get shm attachmap\n");
+ header.error_code = ENOMEM;
+ UnmapViewOfFile (mapptr);
+ CloseHandle (filemap);
+ /* FIXME exit the mutex */
+ CloseHandle (token_handle);
+ return;
+ }
- conn->impersonate_client ();
- /* Now get the user data */
- HANDLE attachmap = CreateFileMapping (INVALID_HANDLE_VALUE, // system pagefile
- &sa,
- PAGE_READWRITE, // protection (FIXME)
- 0x00000000,
- parameters.in.size +
- parameters.in.size %
- getsystemallocgranularity (),
- shmaname // object name
- );
- conn->revert_to_self ();
+ shmid_ds *shmtemp = new shmid_ds;
+ if (!shmtemp)
+ {
+ system_printf ("failed to malloc shm node\n");
+ header.error_code = ENOMEM;
+ UnmapViewOfFile (mapptr);
+ CloseHandle (filemap);
+ CloseHandle (attachmap);
+ /* FIXME exit mutex */
+ CloseHandle (token_handle);
+ return;
+ }
- if (attachmap == NULL)
- {
- system_printf ("failed to get shm attachmap\n");
- header.error_code = ENOMEM;
- UnmapViewOfFile (mapptr);
- CloseHandle (filemap);
- /* FIXME exit the mutex */
+ /* fill out the node data */
+ shmtemp->shm_perm.cuid = getuid ();
+ shmtemp->shm_perm.uid = shmtemp->shm_perm.cuid;
+ shmtemp->shm_perm.cgid = getgid ();
+ shmtemp->shm_perm.gid = shmtemp->shm_perm.cgid;
+ shmtemp->shm_perm.mode = parameters.in.shmflg & 0x01ff;
+ shmtemp->shm_lpid = 0;
+ shmtemp->shm_nattch = 0;
+ shmtemp->shm_atime = 0;
+ shmtemp->shm_dtime = 0;
+ shmtemp->shm_ctime = time (NULL);
+ shmtemp->shm_segsz = parameters.in.size;
+ *(shmid_ds *) mapptr = *shmtemp;
+ shmtemp->mapptr = mapptr;
+
+ /* no need for InterlockedExchange here, we're serialised by the global mutex */
+ tempnode = new shmnode;
+ tempnode->shmds = shmtemp;
+ tempnode->shm_id = (int) InterlockedIncrement (&new_id);
+ tempnode->key = parameters.in.key;
+ tempnode->filemap = filemap;
+ tempnode->attachmap = attachmap;
+ tempnode->next = shm_head;
+ shm_head = tempnode;
+
+ /* we now have the area in the daemon list, opened.
+
+ FIXME: leave the system wide shm mutex */
+
+ parameters.out.shm_id = tempnode->shm_id;
+ if (check_and_dup_handle (GetCurrentProcess (), from_process_handle,
+ token_handle,
+ DUPLICATE_SAME_ACCESS,
+ tempnode->filemap, &parameters.out.filemap,
+ TRUE) != 0)
+ {
+ printf ("error duplicating filemap handle (%lu)\n",
+ GetLastError ());
+ header.error_code = EACCES;
+ CloseHandle (token_handle);
+/* mutex et al */
+ return;
+ }
+ if (check_and_dup_handle (GetCurrentProcess (), from_process_handle,
+ token_handle,
+ DUPLICATE_SAME_ACCESS,
+ tempnode->attachmap,
+ &parameters.out.attachmap, TRUE) != 0)
+ {
+ printf ("error duplicating attachmap handle (%lu)\n",
+ GetLastError ());
+ header.error_code = EACCES;
+ CloseHandle (from_process_handle);
+ CloseHandle (token_handle);
+/* more cleanup... yay! */
+ return;
+ }
CloseHandle (token_handle);
- return;
- }
- shmid_ds *shmtemp = new shmid_ds;
- if (!shmtemp)
- {
- system_printf ("failed to malloc shm node\n");
- header.error_code = ENOMEM;
- UnmapViewOfFile (mapptr);
- CloseHandle (filemap);
- CloseHandle (attachmap);
- /* FIXME exit mutex */
- CloseHandle (token_handle);
return;
}
- /* fill out the node data */
- shmtemp->shm_perm.cuid = getuid ();
- shmtemp->shm_perm.uid = shmtemp->shm_perm.cuid;
- shmtemp->shm_perm.cgid = getgid ();
- shmtemp->shm_perm.gid = shmtemp->shm_perm.cgid;
- shmtemp->shm_perm.mode = parameters.in.shmflg & 0x01ff;
- shmtemp->shm_lpid = 0;
- shmtemp->shm_nattch = 0;
- shmtemp->shm_atime = 0;
- shmtemp->shm_dtime = 0;
- shmtemp->shm_ctime = time (NULL);
- shmtemp->shm_segsz = parameters.in.size;
- *(shmid_ds *) mapptr = *shmtemp;
- shmtemp->mapptr = mapptr;
-
- /* no need for InterlockedExchange here, we're serialised by the global mutex */
- tempnode = new shmnode;
- tempnode->shmds = shmtemp;
- tempnode->shm_id = (int) InterlockedIncrement (&new_id);
- tempnode->key = parameters.in.key;
- tempnode->filemap = filemap;
- tempnode->attachmap = attachmap;
- tempnode->next = shm_head;
- shm_head = tempnode;
-
- /* we now have the area in the daemon list, opened.
-
- FIXME: leave the system wide shm mutex */
-
- parameters.out.shm_id = tempnode->shm_id;
- if (check_and_dup_handle (GetCurrentProcess (), from_process_handle,
- token_handle,
- DUPLICATE_SAME_ACCESS,
- tempnode->filemap, &parameters.out.filemap,
- TRUE) != 0)
- {
- printf ("error duplicating filemap handle (%lu)\n", GetLastError ());
- header.error_code = EACCES;
- CloseHandle (token_handle);
-/* mutex et al */
- return;
- }
- if (check_and_dup_handle (GetCurrentProcess (), from_process_handle,
- token_handle,
- DUPLICATE_SAME_ACCESS,
- tempnode->attachmap, &parameters.out.attachmap,
- TRUE) != 0)
- {
- printf ("error duplicating attachmap handle (%lu)\n", GetLastError ());
- header.error_code = EACCES;
- CloseHandle (from_process_handle);
- CloseHandle (token_handle);
-/* more cleanup... yay! */
- return;
- }
+ header.error_code = ENOSYS;
CloseHandle (token_handle);
+
+
return;
}
diff --git a/winsup/cygwin/cygserver_shm.h b/winsup/cygwin/cygserver_shm.h
index 32947f8ec..f1dcaa53f 100644
--- a/winsup/cygwin/cygserver_shm.h
+++ b/winsup/cygwin/cygserver_shm.h
@@ -1,6 +1,6 @@
/* cygserver_shm.h
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Robert Collins <rbtcollins@hotmail.com>
This file is part of Cygwin.
@@ -17,6 +17,7 @@ details. */
#define SHM_REATTACH 1
#define SHM_ATTACH 2
#define SHM_DETACH 3
+#define SHM_DEL 4
class client_request_shm : public client_request
diff --git a/winsup/cygwin/cygserver_transport.cc b/winsup/cygwin/cygserver_transport.cc
index 7c6e5fe00..01f044406 100755
--- a/winsup/cygwin/cygserver_transport.cc
+++ b/winsup/cygwin/cygserver_transport.cc
@@ -1,6 +1,6 @@
/* cygserver_transport.cc
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Robert Collins <rbtcollins@hotmail.com>
@@ -37,7 +37,7 @@ class transport_layer_base *create_server_transport()
if (wincap.is_winnt ())
temp = new transport_layer_pipes ();
else
- temp = new transport_layer_base ();
+ temp = new transport_layer_sockets ();
return temp;
}
diff --git a/winsup/cygwin/cygserver_transport_pipes.cc b/winsup/cygwin/cygserver_transport_pipes.cc
index 5b5a017c9..f2221700f 100755
--- a/winsup/cygwin/cygserver_transport_pipes.cc
+++ b/winsup/cygwin/cygserver_transport_pipes.cc
@@ -1,6 +1,6 @@
/* cygserver_transport_pipes.cc
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Robert Collins <rbtcollins@hotmail.com>
@@ -29,22 +29,27 @@
#define debug_printf if (DEBUG) printf
#endif
+//SECURITY_DESCRIPTOR transport_layer_pipes::sd;
+//SECURITY_ATTRIBUTES transport_layer_pipes::sec_none_nih, transport_layer_pipes::sec_all_nih;
+//bool transport_layer_pipes::inited = false;
+
transport_layer_pipes::transport_layer_pipes (HANDLE new_pipe)
{
+ inited = false; //FIXME: allow inited, sd, all_nih_.. to be static members
pipe = new_pipe;
if (inited != true)
init_security();
};
-transport_layer_pipes::transport_layer_pipes ()
+transport_layer_pipes::transport_layer_pipes ()
{
+ inited = false;
pipe = NULL;
strcpy(pipe_name, "\\\\.\\pipe\\cygwin_lpc");
if (inited != true)
init_security();
}
-
void
transport_layer_pipes::init_security()
{
@@ -75,11 +80,11 @@ transport_layer_pipes::accept ()
}
pipe = CreateNamedPipe (pipe_name,
- PIPE_ACCESS_DUPLEX,
- PIPE_TYPE_BYTE | PIPE_WAIT,
- PIPE_UNLIMITED_INSTANCES,
- 0, 0, 1000,
- &sec_all_nih );
+ PIPE_ACCESS_DUPLEX,
+ PIPE_TYPE_BYTE | PIPE_WAIT,
+ PIPE_UNLIMITED_INSTANCES,
+ 0, 0, 1000,
+ &sec_all_nih );
if (pipe == INVALID_HANDLE_VALUE)
{
debug_printf ("error creating pipe (%lu)\n.", GetLastError ());
@@ -94,11 +99,11 @@ transport_layer_pipes::accept ()
pipe = NULL;
return NULL;
}
-
+
transport_layer_pipes *new_conn = new transport_layer_pipes (pipe);
pipe = NULL;
- return new_conn;
+ return new_conn;
}
void
@@ -159,27 +164,27 @@ transport_layer_pipes::connect ()
while (1)
{
pipe = CreateFile (pipe_name,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- &sec_all_nih,
- OPEN_EXISTING,
- 0, NULL);
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ &sec_all_nih,
+ OPEN_EXISTING,
+ 0, NULL);
if (pipe != INVALID_HANDLE_VALUE)
/* got the pipe */
- return true;
+ return true;
if (GetLastError () != ERROR_PIPE_BUSY)
- {
- debug_printf ("Error opening the pipe (%lu)\n", GetLastError ());
- pipe = NULL;
- return false;
- }
+ {
+ debug_printf ("Error opening the pipe (%lu)\n", GetLastError ());
+ pipe = NULL;
+ return false;
+ }
if (!WaitNamedPipe (pipe_name, 20000))
- debug_printf ( "error connecting to server pipe after 20 seconds (%lu)\n", GetLastError () );
+ debug_printf ( "error connecting to server pipe after 20 seconds (%lu)\n", GetLastError () );
/* We loop here, because the pipe exists but is busy. If it doesn't exist
* the != ERROR_PIPE_BUSY will catch it.
- */
+ */
}
}
@@ -199,7 +204,7 @@ transport_layer_pipes::impersonate_client ()
void
transport_layer_pipes::revert_to_self ()
{
- RevertToSelf ();
+ RevertToSelf ();
debug_printf("I am who I yam\n");
}
diff --git a/winsup/cygwin/cygserver_transport_sockets.cc b/winsup/cygwin/cygserver_transport_sockets.cc
index 6b75365b4..a3a98b3e5 100755
--- a/winsup/cygwin/cygserver_transport_sockets.cc
+++ b/winsup/cygwin/cygserver_transport_sockets.cc
@@ -1,6 +1,6 @@
/* cygserver_transport_sockets.cc
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Robert Collins <rbtcollins@hotmail.com>
@@ -28,7 +28,7 @@ extern "C" int
cygwin_socket (int af, int type, int protocol);
extern "C" int
cygwin_connect (int fd,
- const struct sockaddr *name,
+ const struct sockaddr *name,
int namelen);
extern "C" int
cygwin_accept (int fd, struct sockaddr *peer, int *len);
@@ -86,10 +86,10 @@ transport_layer_sockets::accept ()
printf ("Nup, could' accept. %d\n",errno);
return NULL;
}
-
+
transport_layer_sockets *new_conn = new transport_layer_sockets (new_fd);
- return new_conn;
+ return new_conn;
}
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index 927d44395..d9a488bc9 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -100,13 +100,14 @@ chmod
_chmod = chmod
chown
_chown = chown
+chown32
cleanup_glue
clearerr
_clearerr = clearerr
clock
_clock = clock
-close
-_close = close
+_close
+close = _close
closedir
_closedir = closedir
copysign
@@ -205,10 +206,11 @@ fchmod
_fchmod = fchmod
fchown
_fchown = fchown
+fchown32
fclose
_fclose = fclose
-fcntl
-_fcntl = fcntl
+_fcntl
+fcntl = _fcntl
fcvt
_fcvt = fcvt
fcvtbuf
@@ -302,8 +304,8 @@ fseek
_fseek = fseek
fsetpos
_fsetpos = fsetpos
-fstat
-_fstat = fstat
+_fstat
+fstat = _fstat
fstat64
fstatfs
_fstatfs = fstatfs
@@ -344,16 +346,22 @@ getdtablesize
_getdtablesize = getdtablesize
getegid
_getegid = getegid
+getegid32
geteuid
_geteuid = geteuid
+geteuid32
getgid
_getgid = getgid
+getgid32
getgrgid
_getgrgid = getgrgid
+getgrgid32
getgrnam
_getgrnam = getgrnam
+getgrnam32
getgroups
_getgroups = getgroups
+getgroups32
gethostname = cygwin_gethostname
_gethostname = cygwin_gethostname
getlogin
@@ -382,6 +390,7 @@ gettimeofday
_gettimeofday = gettimeofday
getuid
_getuid = getuid
+getuid32
getutent
_getutent = getutent
getutid
@@ -412,6 +421,7 @@ _infinity = infinity
infinityf
_infinityf = infinityf
initgroups
+initgroups32
ioctl
_ioctl = ioctl
iprintf
@@ -462,12 +472,13 @@ jn
_jn = jn
jnf
_jnf = jnf
-kill
-_kill = kill
+_kill
+kill = _kill
labs
_labs = labs
lchown
_lchown = lchown
+lchown32
ldexp
_ldexp = ldexp
ldexpf
@@ -510,8 +521,8 @@ login
logout
longjmp
_longjmp = longjmp
-lseek
-_lseek = lseek
+_lseek
+lseek = _lseek
lseek64
lstat = cygwin_lstat
_lstat = cygwin_lstat
@@ -564,8 +575,8 @@ nextafter
_nextafter = nextafter
nextafterf
_nextafterf = nextafterf
-open
-_open = open
+_open
+open = _open
opendir
_opendir = opendir
pathconf
@@ -599,8 +610,8 @@ _rand = rand
random
initstate
setstate
-read
-_read = read
+_read
+read = read
readdir
_readdir = readdir
readlink
@@ -619,8 +630,8 @@ remainderf
_remainderf = remainderf
remove
_remove = remove
-rename
-_rename = rename
+_rename
+rename = _rename
rewind
_rewind = rewind
rewinddir
@@ -658,6 +669,7 @@ setdtablesize
_setdtablesize = setdtablesize
setgid
_setgid = setgid
+setgid32
setjmp
_setjmp = setjmp
setlocale
@@ -672,10 +684,13 @@ settimeofday
_settimeofday = settimeofday
seteuid
_seteuid = seteuid
+seteuid32
setegid
_setegid = setegid
+setegid32
setuid
_setuid = setuid
+setuid32
setutent
_setutent = setutent
chroot
@@ -749,8 +764,8 @@ sscanf
_sscanf = sscanf
_sscanf_r
sscanf_r = _sscanf_r
-stat
-_stat = stat
+_stat
+stat = _stat
stat64
statfs
_statfs = statfs
@@ -853,8 +868,8 @@ tempnam
_tempnam = tempnam
time
_time = time
-times
-_times = times
+_times
+times = _times
timezone
tmpfile
_tmpfile = tmpfile
@@ -881,8 +896,8 @@ uname
_uname = uname
ungetc
_ungetc = ungetc
-unlink
-_unlink = unlink
+_unlink
+unlink = _unlink
usleep
_usleep = usleep
utime
@@ -915,8 +930,8 @@ vsscanf
_vsscanf = vsscanf
_vsscanf_r
vsscanf_r = _vsscanf_r
-wait
-_wait = wait
+_wait
+wait = _wait
waitpid
_waitpid = waitpid
wait3
@@ -925,8 +940,8 @@ wcstombs
_wcstombs = wcstombs
wctomb
_wctomb = wctomb
-write
-_write = write
+_write
+write = _write
barfly = write
writev
_writev = writev
@@ -967,6 +982,12 @@ pclose
_pclose = pclose
strftime
_strftime = strftime
+strlcat
+_strlcat = strlcat
+strlcpy
+_strlcpy = strlcpy
+strptime
+_strptime = strptime
setgrent
_setgrent = setgrent
cuserid
@@ -1002,11 +1023,14 @@ _getpwnam = getpwnam
getpwnam_r
getpwuid
_getpwuid = getpwuid
+getpwuid32
getpwuid_r
+getpwuid_r32
getpgrp
_getpgrp = getpgrp
getgrent
_getgrent = getgrent
+getgrent32
ntohl
_ntohl = ntohl
htonl
@@ -1120,14 +1144,14 @@ _tzname DATA
ptsname
grantpt
unlockpt
-sexecve
-sexecl
-sexecle
-sexeclp
-sexeclpe
-sexecv
-sexecp
-sexecvpe
+sexecve = sexecve_is_bad
+sexecl = sexecve_is_bad
+sexecle = sexecve_is_bad
+sexeclp = sexecve_is_bad
+sexeclpe = sexecve_is_bad
+sexecv = sexecve_is_bad
+sexecp = sexecve_is_bad
+sexecvpe = sexecve_is_bad
ttyslot
rcmd = cygwin_rcmd
rresvport = cygwin_rresvport
@@ -1162,6 +1186,8 @@ pthread_attr_setschedpolicy
pthread_attr_setscope
pthread_attr_setstacksize
pthread_cancel
+_pthread_cleanup_push
+_pthread_cleanup_pop
pthread_cond_broadcast
pthread_cond_destroy
pthread_cond_init
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 38b1df06d..6a358992d 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -18,10 +18,8 @@ details. */
#include <wingdi.h>
#include <winuser.h>
#include <errno.h>
-#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
-#include "heap.h"
#include "cygerrno.h"
#define NEED_VFORK
#include "perprocess.h"
@@ -557,12 +555,12 @@ dll_crt0_1 ()
/* Initialize SIGSEGV handling, etc. */
init_exceptions (&cygwin_except_entry);
- do_global_ctors (&__CTOR_LIST__, 1);
-
/* 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
diff --git a/winsup/cygwin/debug.cc b/winsup/cygwin/debug.cc
index abb4457d4..5d3d63bbc 100644
--- a/winsup/cygwin/debug.cc
+++ b/winsup/cygwin/debug.cc
@@ -1,6 +1,6 @@
/* debug.cc
- Copyright 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
diff --git a/winsup/cygwin/debug.h b/winsup/cygwin/debug.h
index 0b7e53359..1b6e0fa1a 100644
--- a/winsup/cygwin/debug.h
+++ b/winsup/cygwin/debug.h
@@ -28,6 +28,9 @@ DWORD __stdcall WFMO (DWORD, CONST HANDLE *, BOOL, DWORD) __attribute__ ((regpar
#if !defined(_DEBUG_H_)
#define _DEBUG_H_
+#define being_debugged() \
+ (IsDebuggerPresent () /* || GetLastError () == ERROR_PROC_NOT_FOUND*/)
+
void threadname_init ();
HANDLE __stdcall makethread (LPTHREAD_START_ROUTINE, LPVOID, DWORD, const char *) __attribute__ ((regparm(3)));
const char * __stdcall threadname (DWORD, int lockit = TRUE) __attribute__ ((regparm(2)));
diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc
index 0294c09ca..45ba57ff6 100644
--- a/winsup/cygwin/dir.cc
+++ b/winsup/cygwin/dir.cc
@@ -9,7 +9,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
-#include <sys/fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
@@ -18,13 +17,10 @@ details. */
#define _COMPILING_NEWLIB
#include <dirent.h>
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "cygerrno.h"
#include "security.h"
#include "fhandler.h"
-#include "perprocess.h"
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
@@ -115,7 +111,42 @@ readdir (DIR *dir)
return NULL;
}
- return ((fhandler_base *) dir->__d_u.__d_data.__fh)->readdir (dir);
+ dirent *res = ((fhandler_base *) dir->__d_u.__d_data.__fh)->readdir (dir);
+
+ if (res)
+ {
+ /* Compute d_ino by combining filename hash with the directory hash
+ (which was stored in dir->__d_dirhash when opendir was called). */
+ if (res->d_name[0] == '.')
+ {
+ if (res->d_name[1] == '\0')
+ dir->__d_dirent->d_ino = dir->__d_dirhash;
+ else if (res->d_name[1] != '.' || res->d_name[2] != '\0')
+ goto hashit;
+ else
+ {
+ char *p, up[strlen (dir->__d_dirname) + 1];
+ strcpy (up, dir->__d_dirname);
+ if (!(p = strrchr (up, '\\')))
+ goto hashit;
+ *p = '\0';
+ if (!(p = strrchr (up, '\\')))
+ dir->__d_dirent->d_ino = hash_path_name (0, ".");
+ else
+ {
+ *p = '\0';
+ dir->__d_dirent->d_ino = hash_path_name (0, up);
+ }
+ }
+ }
+ else
+ {
+ hashit:
+ ino_t dino = hash_path_name (dir->__d_dirhash, "\\");
+ dir->__d_dirent->d_ino = hash_path_name (dino, res->d_name);
+ }
+ }
+ return res;
}
extern "C" __off64_t
@@ -225,7 +256,7 @@ mkdir (const char *dir, mode_t mode)
#ifdef HIDDEN_DOT_FILES
char *c = strrchr (real_dir.get_win32 (), '\\');
if ((c && c[1] == '.') || *real_dir.get_win32 () == '.')
- SetFileAttributes (real_dir.get_win32 (), FILE_ATTRIBUTE_HIDDEN);
+ SetFileAttributes (real_dir.get_win32 (), FILE_ATTRIBUTE_HIDDEN);
#endif
res = 0;
}
@@ -242,24 +273,19 @@ extern "C" int
rmdir (const char *dir)
{
int res = -1;
+ DWORD devn;
path_conv real_dir (dir, PC_SYM_NOFOLLOW);
if (real_dir.error)
- {
- set_errno (real_dir.error);
- res = -1;
- }
+ set_errno (real_dir.error);
+ else if ((devn = real_dir.get_devn ()) == FH_PROC || devn == FH_REGISTRY
+ || devn == FH_PROCESS)
+ set_errno (EROFS);
else if (!real_dir.exists ())
- {
- set_errno (ENOENT);
- res = -1;
- }
+ set_errno (ENOENT);
else if (!real_dir.isdir ())
- {
- set_errno (ENOTDIR);
- res = -1;
- }
+ set_errno (ENOTDIR);
else
{
/* Even own directories can't be removed if R/O attribute is set. */
@@ -299,22 +325,20 @@ rmdir (const char *dir)
else if ((res = rmdir (dir)))
SetCurrentDirectory (cygheap->cwd.win32);
}
- if (GetLastError () == ERROR_ACCESS_DENIED)
+ if (res)
{
-
- /* On 9X ERROR_ACCESS_DENIED is returned if you try to remove
- a non-empty directory. */
- if (wincap.access_denied_on_delete ())
- set_errno (ENOTEMPTY);
- else
+ if (GetLastError () != ERROR_ACCESS_DENIED
+ || !wincap.access_denied_on_delete ())
__seterrno ();
- }
- else
- __seterrno ();
+ else
+ set_errno (ENOTEMPTY); /* On 9X ERROR_ACCESS_DENIED is
+ returned if you try to remove a
+ non-empty directory. */
- /* If directory still exists, restore R/O attribute. */
- if (real_dir.has_attribute (FILE_ATTRIBUTE_READONLY))
- SetFileAttributes (real_dir, real_dir);
+ /* If directory still exists, restore R/O attribute. */
+ if (real_dir.has_attribute (FILE_ATTRIBUTE_READONLY))
+ SetFileAttributes (real_dir, real_dir);
+ }
}
}
diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc
index e5e650fa9..5a5b165dc 100644
--- a/winsup/cygwin/dll_init.cc
+++ b/winsup/cygwin/dll_init.cc
@@ -1,6 +1,6 @@
/* dll_init.cc
- Copyright 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
@@ -9,7 +9,6 @@ details. */
#include "winsup.h"
#include <stdlib.h>
#include <errno.h>
-#include "exceptions.h"
#include "cygerrno.h"
#include "perprocess.h"
#include "dll_init.h"
@@ -19,6 +18,7 @@ details. */
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
+#include "pinfo.h"
extern void __stdcall check_sanity_and_sync (per_process *);
@@ -184,6 +184,9 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
void
dll_list::detach (dll *d)
{
+ if (!myself || myself->process_state == PID_EXITED)
+ return;
+
if (d->count <= 0)
system_printf ("WARNING: try to detach an already detached dll ...\n");
else if (--d->count == 0)
@@ -204,7 +207,6 @@ dll_list::detach (dll *d)
void
dll_list::init ()
{
- debug_printf ("here");
/* Make sure that destructors are called on exit. */
if (!dll_global_dtors_recorded)
{
diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc
index f70e41599..241528a3d 100644
--- a/winsup/cygwin/dtable.cc
+++ b/winsup/cygwin/dtable.cc
@@ -16,14 +16,13 @@ details. */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
-#include <fcntl.h>
#include <sys/cygwin.h>
#include <assert.h>
+#include <ntdef.h>
+#include <winnls.h>
#define USE_SYS_TYPES_FD_SET
#include <winsock.h>
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "cygerrno.h"
#include "perprocess.h"
@@ -32,10 +31,13 @@ details. */
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
+#include "ntdll.h"
static const NO_COPY DWORD std_consts[] = {STD_INPUT_HANDLE, STD_OUTPUT_HANDLE,
STD_ERROR_HANDLE};
+static char *handle_to_fn (HANDLE, char *);
+
/* Set aside space for the table of fds */
void
dtable_init (void)
@@ -93,7 +95,7 @@ dtable::extend (int howmuch)
void
dtable::get_debugger_info ()
{
- if (IsDebuggerPresent ())
+ if (being_debugged ())
{
char std[3][sizeof ("/dev/ttyNNNN")];
std[0][0] = std[1][0] = std [2][0] = '\0';
@@ -213,7 +215,6 @@ cygwin_attach_handle_to_fd (char *name, int fd, HANDLE handle, mode_t bin,
void
dtable::init_std_file_from_handle (int fd, HANDLE handle, DWORD myaccess)
{
- int bin;
const char *name;
CONSOLE_SCREEN_BUFFER_INFO buf;
struct sockaddr sa;
@@ -225,76 +226,86 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle, DWORD myaccess)
if (!not_open (fd))
return;
- if (!handle || handle == INVALID_HANDLE_VALUE)
- {
- fds[fd] = NULL;
- return;
- }
-
- if (__fmode)
- bin = __fmode;
+ SetLastError (0);
+ DWORD ft = GetFileType (handle);
+ if (ft == FILE_TYPE_UNKNOWN && GetLastError () == ERROR_INVALID_HANDLE)
+ name = NULL;
else
- bin = binmode ?: 0;
-
- /* See if we can consoleify it - if it is a console,
- don't open it in binary. That will screw up our crlfs*/
- if (GetConsoleScreenBufferInfo (handle, &buf))
{
- if (ISSTATE (myself, PID_USETTY))
- name = "/dev/tty";
- else
- name = "/dev/conout";
- bin = 0;
- }
- else if (GetNumberOfConsoleInputEvents (handle, (DWORD *) &buf))
- {
- if (ISSTATE (myself, PID_USETTY))
- name = "/dev/tty";
+ /* See if we can consoleify it */
+ if (GetConsoleScreenBufferInfo (handle, &buf))
+ {
+ if (ISSTATE (myself, PID_USETTY))
+ name = "/dev/tty";
+ else
+ name = "/dev/conout";
+ }
+ else if (GetNumberOfConsoleInputEvents (handle, (DWORD *) &buf))
+ {
+ if (ISSTATE (myself, PID_USETTY))
+ name = "/dev/tty";
+ else
+ name = "/dev/conin";
+ }
+ else if (ft == FILE_TYPE_PIPE)
+ {
+ if (fd == 0)
+ name = "/dev/piper";
+ else
+ name = "/dev/pipew";
+ }
+ else if (wsock_started && getpeername ((SOCKET) handle, &sa, &sal) == 0)
+ name = "/dev/socket";
+ else if (GetCommState (handle, &dcb))
+ name = "/dev/ttyS0"; // FIXME - determine correct device
else
- name = "/dev/conin";
- bin = 0;
+ name = handle_to_fn (handle, (char *) alloca (MAX_PATH + 100));
}
- else if (GetFileType (handle) == FILE_TYPE_PIPE)
+
+ if (!name)
+ fds[fd] = NULL;
+ else
{
- if (fd == 0)
- name = "/dev/piper";
- else
- name = "/dev/pipew";
- if (bin == 0)
- bin = O_BINARY;
+ path_conv pc;
+ build_fhandler_from_name (fd, name, handle, pc)->init (handle, myaccess,
+ pc.binmode ());
+ set_std_handle (fd);
+ paranoid_printf ("fd %d, handle %p", fd, handle);
}
- else if (wsock_started && getpeername ((SOCKET) handle, &sa, &sal) == 0)
- name = "/dev/socket";
- else if (GetCommState (handle, &dcb))
- name = "/dev/ttyS0"; // FIXME - determine correct device
- else
- name = "unknown disk file";
-
- path_conv pc;
- build_fhandler_from_name (fd, name, handle, pc)->init (handle, myaccess, bin);
- set_std_handle (fd);
- paranoid_printf ("fd %d, handle %p", fd, handle);
}
fhandler_base *
dtable::build_fhandler_from_name (int fd, const char *name, HANDLE handle,
path_conv& pc, unsigned opt, suffix_info *si)
{
- pc.check (name, opt | PC_NULLEMPTY | PC_FULL, si);
+ pc.check (name, opt | PC_NULLEMPTY | PC_FULL | PC_POSIX, si);
if (pc.error)
{
set_errno (pc.error);
return NULL;
}
- return build_fhandler (fd, pc.get_devn (), name, pc, pc.get_unitn ());
+ if (!pc.exists () && handle)
+ pc.fillin (handle);
+
+ fhandler_base *fh = build_fhandler (fd, pc.get_devn (),
+ pc.return_and_clear_normalized_path (),
+ pc, pc.get_unitn ());
+ return fh;
}
-#define cnew(name) new ((void *) ccalloc (HEAP_FHANDLER, 1, sizeof (name))) name
fhandler_base *
dtable::build_fhandler (int fd, DWORD dev, const char *unix_name,
const char *win32_name, int unit)
{
+ return build_fhandler (fd, dev, cstrdup (unix_name), win32_name, unit);
+}
+
+#define cnew(name) new ((void *) ccalloc (HEAP_FHANDLER, 1, sizeof (name))) name
+fhandler_base *
+dtable::build_fhandler (int fd, DWORD dev, char *unix_name,
+ const char *win32_name, int unit)
+{
fhandler_base *fh;
dev &= FH_DEVMASK;
@@ -363,6 +374,15 @@ dtable::build_fhandler (int fd, DWORD dev, const char *unix_name,
case FH_OSS_DSP:
fh = cnew (fhandler_dev_dsp) ();
break;
+ case FH_PROC:
+ fh = cnew (fhandler_proc) ();
+ break;
+ case FH_REGISTRY:
+ fh = cnew (fhandler_registry) ();
+ break;
+ case FH_PROCESS:
+ fh = cnew (fhandler_process) ();
+ break;
default:
system_printf ("internal error -- unknown device - %p", dev);
fh = NULL;
@@ -389,7 +409,7 @@ dtable::build_fhandler (int fd, DWORD dev, const char *unix_name,
fhandler_base *
dtable::dup_worker (fhandler_base *oldfh)
{
- fhandler_base *newfh = build_fhandler (-1, oldfh->get_device (), NULL);
+ fhandler_base *newfh = build_fhandler (-1, oldfh->get_device ());
*newfh = *oldfh;
newfh->set_io_handle (NULL);
if (oldfh->dup (newfh))
@@ -467,14 +487,6 @@ done:
return res;
}
-void
-dtable::reset_unix_path_name (int fd, const char *name)
-{
- SetResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "reset_unix_name");
- fds[fd]->reset_unix_path_name (name);
- ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "reset_unix_name");
-}
-
select_record *
dtable::select_read (int fd, select_record *s)
{
@@ -621,14 +633,14 @@ dtable::vfork_child_dup ()
goto out;
}
- /* Restore impersonation */
- if (cygheap->user.impersonated && cygheap->user.token != INVALID_HANDLE_VALUE)
- ImpersonateLoggedOnUser (cygheap->user.token);
-
fds_on_hold = fds;
fds = newtable;
out:
+ /* Restore impersonation */
+ if (cygheap->user.impersonated && cygheap->user.token != INVALID_HANDLE_VALUE)
+ ImpersonateLoggedOnUser (cygheap->user.token);
+
ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup");
return 1;
}
@@ -678,3 +690,128 @@ dtable::vfork_child_fixup ()
return;
}
+
+#if 0
+static char *
+handle_to_fn (HANDLE h, char *posix_fn)
+{
+ IO_STATUS_BLOCK io;
+ FILE_NAME_INFORMATION ntfn;
+
+ io.Status = 0;
+ io.Information = 0;
+
+ SetLastError (0);
+ DWORD res = NtQueryInformationFile (h, &io, &ntfn, sizeof (ntfn), 9);
+ if (res || GetLastError () == ERROR_PROC_NOT_FOUND)
+ {
+ strcpy (posix_fn, "some disk file");
+ return posix_fn;
+ }
+ ntfn.FileName[ntfn.FileNameLength / sizeof (WCHAR)] = 0;
+
+ char win32_fn[MAX_PATH + 100];
+ sys_wcstombs (win32_fn, ntfn.FileName, ntfn.FileNameLength);
+ cygwin_conv_to_full_posix_path (win32_fn, posix_fn);
+ return posix_fn;
+}
+#else
+#define DEVICE_PREFIX "\\device\\"
+#define DEVICE_PREFIX_LEN sizeof(DEVICE_PREFIX) - 1
+#define REMOTE "\\Device\\LanmanRedirector\\"
+#define REMOTE_LEN sizeof (REMOTE) - 1
+
+static char *
+handle_to_fn (HANDLE h, char *posix_fn)
+{
+ OBJECT_NAME_INFORMATION *ntfn;
+ char fnbuf[32768];
+
+ memset (fnbuf, 0, sizeof (fnbuf));
+ ntfn = (OBJECT_NAME_INFORMATION *) fnbuf;
+ ntfn->Name.MaximumLength = sizeof (fnbuf) - sizeof (*ntfn);
+ ntfn->Name.Buffer = (WCHAR *) (ntfn + 1);
+
+ DWORD res = NtQueryObject (h, ObjectNameInformation, ntfn, sizeof (fnbuf), NULL);
+
+ if (res)
+ {
+ strcpy (posix_fn, "some disk file");
+ debug_printf ("NtQueryObject failed");
+ return posix_fn;
+ }
+
+ // NT seems to do this on an unopened file
+ if (!ntfn->Name.Buffer)
+ {
+ debug_printf ("nt->Name.Buffer == NULL");
+ return NULL;
+ }
+
+ ntfn->Name.Buffer[ntfn->Name.Length / sizeof (WCHAR)] = 0;
+
+ char win32_fn[MAX_PATH + 100];
+ sys_wcstombs (win32_fn, ntfn->Name.Buffer, ntfn->Name.Length);
+ debug_printf ("nt name '%s'", win32_fn);
+ if (!strncasematch (win32_fn, DEVICE_PREFIX, DEVICE_PREFIX_LEN)
+ || !QueryDosDevice (NULL, fnbuf, sizeof (fnbuf)))
+ return strcpy (posix_fn, win32_fn);
+
+ char *p = strchr (win32_fn + DEVICE_PREFIX_LEN, '\\');
+ if (!p)
+ p = strchr (win32_fn + DEVICE_PREFIX_LEN, '\0');
+
+ int n = p - win32_fn;
+ int maxmatchlen = 0;
+ char *maxmatchdos = NULL;
+ for (char *s = fnbuf; *s; s = strchr (s, '\0') + 1)
+ {
+ char device[MAX_PATH + 10];
+ device[MAX_PATH + 9] = '\0';
+ if (strchr (s, ':') == NULL)
+ continue;
+ if (!QueryDosDevice (s, device, sizeof (device) - 1))
+ continue;
+ char *q = strrchr (device, ';');
+ if (q)
+ {
+ char *r = strchr (q, '\\');
+ if (r)
+ strcpy (q, r + 1);
+ }
+ int devlen = strlen (device);
+ if (device[devlen - 1] == '\\')
+ device[--devlen] = '\0';
+ if (devlen < maxmatchlen)
+ continue;
+ if (!strncasematch (device, win32_fn, devlen) ||
+ (win32_fn[devlen] != '\0' && win32_fn[devlen] != '\\'))
+ continue;
+ maxmatchlen = devlen;
+ maxmatchdos = s;
+ debug_printf ("current match '%s'", device);
+ }
+
+ char *w32 = win32_fn;
+ if (maxmatchlen)
+ {
+ n = strlen (maxmatchdos);
+ if (maxmatchdos[n - 1] == '\\')
+ n--;
+ w32 += maxmatchlen - n;
+ memcpy (w32, maxmatchdos, n);
+ w32[n] = '\\';
+ }
+ else if (strncasematch (w32, REMOTE, REMOTE_LEN))
+ {
+ w32 += REMOTE_LEN - 2;
+ *w32 = '\\';
+ debug_printf ("remote drive");
+ }
+
+
+ debug_printf ("derived path '%s'", w32);
+ cygwin_conv_to_full_posix_path (w32, posix_fn);
+ return posix_fn;
+}
+#endif
diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h
index 47e0a3b78..5a8f5697a 100644
--- a/winsup/cygwin/dtable.h
+++ b/winsup/cygwin/dtable.h
@@ -50,6 +50,8 @@ public:
void fixup_after_fork (HANDLE);
fhandler_base *build_fhandler (int fd, DWORD dev, const char *unix_name,
const char *win32_name = NULL, int unit = -1);
+ fhandler_base *build_fhandler (int fd, DWORD dev, char *unix_name = NULL,
+ const char *win32_name = NULL, int unit = -1);
fhandler_base *build_fhandler_from_name (int fd, const char *name, HANDLE h,
path_conv& pc,
unsigned opts = PC_SYM_FOLLOW,
@@ -63,7 +65,6 @@ public:
ReleaseResourceLock (LOCK_FD_LIST, READ_LOCK, "not open");
return res;
}
- void reset_unix_path_name (int fd, const char *name);
int find_unused_handle (int start);
int find_unused_handle () { return find_unused_handle (first_fd_for_open);}
void release (int fd);
diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index 3857c4496..da96b5245 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -1,7 +1,7 @@
/* environ.cc: Cygwin-adopted functions from newlib to manipulate
process's environment.
- Copyright 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
@@ -12,11 +12,9 @@ details. */
#include <stdlib.h>
#include <stddef.h>
#include <ctype.h>
-#include <fcntl.h>
+#include <assert.h>
#include <sys/cygwin.h>
#include <cygwin/version.h>
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "perprocess.h"
#include "security.h"
@@ -99,10 +97,9 @@ win_env::add_cache (const char *in_posix, const char *in_native)
/* Check for a "special" environment variable name. *env is the pointer
- * to the beginning of the environment variable name. n is the length
- * of the name including a mandatory '='. Returns a pointer to the
- * appropriate conversion structure.
- */
+ to the beginning of the environment variable name. *in_posix is any
+ known posix value for the environment variable. Returns a pointer to
+ the appropriate conversion structure. */
win_env * __stdcall
getwinenv (const char *env, const char *in_posix)
{
@@ -114,7 +111,7 @@ getwinenv (const char *env, const char *in_posix)
{
win_env * const we = conv_envvars + i;
const char *val;
- if (!cur_environ () || !(val = in_posix ?: getenv(we->name)))
+ if (!cur_environ () || !(val = in_posix ?: getenv (we->name)))
debug_printf ("can't set native for %s since no environ yet",
we->name);
else if (!envcache || !we->posix || strcmp (val, we->posix) != 0)
@@ -198,13 +195,12 @@ getenv (const char *name)
return my_findenv (name, &offset);
}
-extern int __stdcall
-envsize (const char * const *in_envp, int debug_print)
+static int __stdcall
+envsize (const char * const *in_envp)
{
const char * const *envp;
for (envp = in_envp; *envp; envp++)
- if (debug_print)
- debug_printf ("%s", *envp);
+ continue;
return (1 + envp - in_envp) * sizeof (const char *);
}
@@ -676,6 +672,8 @@ environ_init (char **envp, int envc)
envp_passed_in = 0;
else
{
+ envc++;
+ envc *= sizeof (char *);
char **newenv = (char **) malloc (envc);
memcpy (newenv, envp, envc);
cfree (envp);
@@ -752,107 +750,184 @@ env_sort (const void *a, const void *b)
return strcmp (*p, *q);
}
+struct spenv
+{
+ const char *name;
+ const char * (cygheap_user::*from_cygheap) ();
+ char *retrieve (bool, const char * const = NULL, int = 0);
+};
+
/* Keep this list in upper case and sorted */
-static const NO_COPY char* forced_winenv_vars [] =
- {
- "SYSTEMDRIVE",
- "SYSTEMROOT",
- NULL
- };
+static NO_COPY spenv spenvs[] =
+{
+ {"HOMEPATH=", &cygheap_user::env_homepath},
+ {"HOMEDRIVE=", &cygheap_user::env_homedrive},
+ {"LOGONSERVER=", &cygheap_user::env_logsrv},
+ {"SYSTEMDRIVE=", NULL},
+ {"SYSTEMROOT=", NULL},
+ {"USERPROFILE=", &cygheap_user::env_userprofile},
+};
+
+char *
+spenv::retrieve (bool no_envblock, const char *const envname, int len)
+{
+ if (len && !strncasematch (envname, name, len))
+ return NULL;
+ if (from_cygheap)
+ {
+ const char *p;
+ if (!len)
+ return NULL; /* No need to force these into the
+ environment */
+
+ if (no_envblock)
+ return cstrdup1 (envname); /* Don't really care what it's set to
+ if we're calling a cygwin program */
+
+ /* Make a FOO=BAR entry from the value returned by the cygheap_user
+ method. */
+ p = (cygheap->user.*from_cygheap) ();
+ int namelen = strlen (name);
+ char *s = (char *) cmalloc (HEAP_1_STR, namelen + strlen (p) + 1);
+ strcpy (s, name);
+ (void) strcpy (s + namelen, p);
+ return s;
+ }
+
+ if (len)
+ return cstrdup1 (envname);
+
+ char dum[1];
+ int vallen = GetEnvironmentVariable (name, dum, 0);
+ if (vallen > 0)
+ {
+ int namelen = strlen (name);
+ char *p = (char *) cmalloc (HEAP_1_STR, namelen + ++vallen);
+ strcpy (p, name);
+ if (GetEnvironmentVariable (name, p + namelen, vallen))
+ return p;
+ else
+ cfree (p);
+ }
-#define FORCED_WINENV_SIZE (sizeof (forced_winenv_vars) / sizeof (forced_winenv_vars[0]))
+ debug_printf ("warning: %s not present in environment", name);
+ return NULL;
+}
+
+#define SPENVS_SIZE (sizeof (spenvs) / sizeof (spenvs[0]))
/* Create a Windows-style environment block, i.e. a typical character buffer
filled with null terminated strings, terminated by double null characters.
Converts environment variables noted in conv_envvars into win32 form
prior to placing them in the string. */
-char * __stdcall
-winenv (const char * const *envp, int keep_posix)
+char ** __stdcall
+build_env (const char * const *envp, char *&envblock, int &envc,
+ bool no_envblock)
{
- int len, n, tl;
+ int len, n;
const char * const *srcp;
- const char **dstp;
- bool saw_forced_winenv[FORCED_WINENV_SIZE] = {0};
- char *p;
-
- debug_printf ("envp %p, keep_posix %d", envp, keep_posix);
+ char **dstp;
+ bool saw_spenv[SPENVS_SIZE] = {0};
- tl = 0;
+ debug_printf ("envp %p", envp);
+ /* How many elements? */
for (n = 0; envp[n]; n++)
continue;
- const char *newenvp[n + 1 + FORCED_WINENV_SIZE];
+ /* Allocate a new "argv-style" environ list with room for extra stuff. */
+ char **newenv = (char **) cmalloc (HEAP_1_ARGV, sizeof (char *) *
+ (n + SPENVS_SIZE + 1));
- for (srcp = envp, dstp = newenvp; *srcp; srcp++, dstp++)
+ int tl = 0;
+ /* Iterate over input list, generating a new environment list and refreshing
+ "special" entries, if necessary. */
+ for (srcp = envp, dstp = newenv; *srcp; srcp++, dstp++)
{
- len = strcspn (*srcp, "=");
- win_env *conv;
+ len = strcspn (*srcp, "=") + 1;
- if (keep_posix || !(conv = getwinenv (*srcp, *srcp + len + 1)))
- *dstp = *srcp;
- else
- {
- p = (char *) alloca (strlen (conv->native) + 1);
- strcpy (p, conv->native);
- *dstp = p;
- }
- tl += strlen (*dstp) + 1;
- if ((*dstp)[0] == '!' && isdrive ((*dstp) + 1) && (*dstp)[3] == '=')
- {
- p = (char *) alloca (strlen (*dstp) + 1);
- strcpy (p, *dstp);
- *p = '=';
- *dstp = p;
- }
+ /* Look for entries that require special attention */
+ for (unsigned i = 0; i < SPENVS_SIZE; i++)
+ if (!saw_spenv[i]
+ && (*dstp = spenvs[i].retrieve (no_envblock, *srcp, len)))
+ {
+ saw_spenv[i] = 1;
+ goto next;
+ }
+
+ *dstp = cstrdup1 (*srcp);
- for (int i = 0; forced_winenv_vars[i]; i++)
- if (!saw_forced_winenv[i])
- saw_forced_winenv[i] = strncasematch (forced_winenv_vars[i], *srcp, len);
+ next:
+ if (!no_envblock)
+ tl += strlen (*dstp) + 1;
}
- char dum[1];
- for (int i = 0; forced_winenv_vars[i]; i++)
- if (!saw_forced_winenv[i])
+ /* Fill in any required-but-missing environment variables. */
+ for (unsigned i = 0; i < SPENVS_SIZE; i++)
+ if (!saw_spenv[i])
{
- int vallen = GetEnvironmentVariable (forced_winenv_vars[i], dum, 0);
- if (vallen > 0)
+ *dstp = spenvs[i].retrieve (no_envblock);
+ if (*dstp)
{
- int namelen = strlen (forced_winenv_vars[i]) + 1;
- p = (char *) alloca (namelen + ++vallen);
- strcpy (p, forced_winenv_vars[i]);
- strcat (p, "=");
- if (!GetEnvironmentVariable (forced_winenv_vars[i], p + namelen,
- vallen))
- debug_printf ("warning: %s not present in environment", *srcp);
- else
- {
- *dstp++ = p;
- tl += strlen (p) + 1;
- }
+ if (!no_envblock)
+ tl += strlen (*dstp) + 1;
+ dstp++;
}
}
- *dstp = NULL; /* Terminate */
+ envc = dstp - newenv;
+ *dstp = NULL; /* Terminate */
- int envlen = dstp - newenvp;
- debug_printf ("env count %d, bytes %d", envlen, tl);
+ if (no_envblock)
+ envblock = NULL;
+ else
+ {
+ debug_printf ("env count %d, bytes %d", envc, tl);
- /* Windows programs expect the environment block to be sorted. */
- qsort (newenvp, envlen, sizeof (char *), env_sort);
+ /* Windows programs expect the environment block to be sorted. */
+ qsort (newenv, envc, sizeof (char *), env_sort);
- /* Create an environment block suitable for passing to CreateProcess. */
- char *ptr, *envblock;
- envblock = (char *) malloc (tl + 2);
- for (srcp = newenvp, ptr = envblock; *srcp; srcp++)
- {
- len = strlen (*srcp);
- memcpy (ptr, *srcp, len + 1);
- ptr += len + 1;
+ /* Create an environment block suitable for passing to CreateProcess. */
+ char *s;
+ envblock = (char *) malloc (2 + tl);
+ int new_tl = 0;
+ for (srcp = newenv, s = envblock; *srcp; srcp++)
+ {
+ const char *p;
+ win_env *conv;
+ len = strcspn (*srcp, "=") + 1;
+
+ /* See if this entry requires posix->win32 conversion. */
+ conv = getwinenv (*srcp, *srcp + len);
+ if (conv)
+ p = conv->native; /* Use win32 path */
+ else
+ p = *srcp; /* Don't worry about it */
+
+ len = strlen (p);
+ new_tl += len + 1; /* Keep running total of block length so far */
+
+ /* See if we need to increase the size of the block. */
+ if (new_tl > tl)
+ envblock = (char *) realloc (envblock, 2 + (tl += len + 100));
+
+ memcpy (s, p, len + 1);
+
+ /* See if environment variable is "special" in a Windows sense.
+ Under NT, the current directories for visited drives are stored
+ as =C:=\bar. Cygwin converts the '=' to '!' for hopefully obvious
+ reasons. We need to convert it back when building the envblock */
+ if (s[0] == '!' && (isdrive (s + 1) || (s[1] == ':' && s[2] == ':'))
+ && s[3] == '=')
+ *s = '=';
+ s += len + 1;
+ }
+ *s = '\0'; /* Two null bytes at the end */
+ assert ((s - envblock) <= tl); /* Detect if we somehow ran over end
+ of buffer */
}
- *ptr = '\0'; /* Two null bytes at the end */
- return envblock;
+ return newenv;
}
/* This idiocy is necessary because the early implementers of cygwin
diff --git a/winsup/cygwin/environ.h b/winsup/cygwin/environ.h
index 86f70f675..3f372b17c 100644
--- a/winsup/cygwin/environ.h
+++ b/winsup/cygwin/environ.h
@@ -1,6 +1,6 @@
/* environ.h: Declarations for environ manipulation
- Copyright 2000 Red Hat, Inc.
+ Copyright 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -12,11 +12,10 @@ details. */
void environ_init (char **, int);
/* The structure below is used to control conversion to/from posix-style
- * file specs. Currently, only PATH and HOME are converted, but PATH
- * needs to use a "convert path list" function while HOME needs a simple
- * "convert to posix/win32". For the simple case, where a calculated length
- * is required, just return MAX_PATH. *FIXME*
- */
+ file specs. Currently, only PATH and HOME are converted, but PATH
+ needs to use a "convert path list" function while HOME needs a simple
+ "convert to posix/win32". For the simple case, where a calculated length
+ is required, just return MAX_PATH. *FIXME* */
struct win_env
{
const char *name;
@@ -35,7 +34,7 @@ struct win_env
win_env * __stdcall getwinenv (const char *name, const char *posix = NULL);
void __stdcall update_envptrs ();
-char * __stdcall winenv (const char * const *, int);
extern char **__cygwin_environ, ***main_environ;
extern "C" char __stdcall **cur_environ ();
-int __stdcall envsize (const char * const *, int debug_print = 0);
+char ** __stdcall build_env (const char * const *envp, char *&envblock,
+ int &envc, bool need_envblock);
diff --git a/winsup/cygwin/errno.cc b/winsup/cygwin/errno.cc
index 0643647b2..3ad7b3d4a 100644
--- a/winsup/cygwin/errno.cc
+++ b/winsup/cygwin/errno.cc
@@ -1,6 +1,6 @@
/* errno.cc: errno-related functions
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -153,7 +153,7 @@ extern "C" {
const NO_COPY char __declspec(dllexport) * const _sys_errlist[]=
{
/* NOERROR 0 */ "No error",
-/* EPERM 1 */ "Not super-user",
+/* EPERM 1 */ "Operation not permitted",
/* ENOENT 2 */ "No such file or directory",
/* ESRCH 3 */ "No such process",
/* EINTR 4 */ "Interrupted system call",
@@ -308,10 +308,13 @@ extern "C" char *
strerror (int errnum)
{
const char *error;
+ if (errnum < _sys_nerr)
+ error = _sys_errlist [errnum];
+ else
switch (errnum)
{
case EPERM:
- error = "Not owner";
+ error = "Operation not permitted";
break;
case ENOENT:
error = "No such file or directory";
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 1bca810dd..1eb3fbac2 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -393,7 +393,7 @@ try_to_debug (bool waitloop)
if (!waitloop)
return 1;
SetThreadPriority (hMainThread, THREAD_PRIORITY_IDLE);
- while (!IsDebuggerPresent ())
+ while (!being_debugged ())
/* spin */;
Sleep (4000);
small_printf ("*** continuing from debugger call\n");
@@ -1013,7 +1013,7 @@ sig_handle (int sig, bool thisproc)
if (handler == (void *) SIG_DFL)
{
if (sig == SIGCHLD || sig == SIGIO || sig == SIGCONT || sig == SIGWINCH
- || sig == SIGURG || (thisproc && hExeced && sig == SIGINT))
+ || sig == SIGURG || (thisproc && hExeced && sig == SIGINT))
{
sigproc_printf ("default signal %d ignored", sig);
goto done;
diff --git a/winsup/cygwin/exec.cc b/winsup/cygwin/exec.cc
index 21b18cfcf..942b79d83 100644
--- a/winsup/cygwin/exec.cc
+++ b/winsup/cygwin/exec.cc
@@ -1,6 +1,6 @@
/* exec.cc: exec system call support.
- Copyright 1996, 1997, 1998, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -17,10 +17,9 @@ details. */
#include "security.h"
#include "fhandler.h"
#include "path.h"
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "environ.h"
+#include "cygerrno.h"
/* This is called _execve and not execve because the real execve is defined
in libc/posix/execve.c. It calls us. */
@@ -32,7 +31,7 @@ _execve (const char *path, char *const argv[], char *const envp[])
MALLOC_CHECK;
if (!envp)
envp = empty_env;
- return _spawnve (NULL, _P_OVERLAY, path, argv, envp);
+ return spawnve (_P_OVERLAY, path, argv, envp);
}
extern "C" int
@@ -60,116 +59,11 @@ execv (const char *path, char * const *argv)
return _execve (path, (char * const *) argv, cur_environ ());
}
-/* the same as a standard exec() calls family, but with NT security support */
-
extern "C" pid_t
-sexecve (HANDLE hToken, const char *path, const char *const argv[],
- const char *const envp[])
-{
- _spawnve (hToken, _P_OVERLAY, path, argv, envp);
- return -1;
-}
-
-extern "C" int
-sexecl (HANDLE hToken, const char *path, const char *arg0, ...)
-{
- int i;
- va_list args;
- const char *argv[1024];
-
- va_start (args, arg0);
- argv[0] = arg0;
- i = 1;
-
- do
- argv[i] = va_arg (args, const char *);
- while (argv[i++] != NULL);
-
- va_end (args);
-
- MALLOC_CHECK;
- return sexecve (hToken, path, (char * const *) argv, cur_environ ());
-}
-
-extern "C" int
-sexecle (HANDLE hToken, const char *path, const char *arg0, ...)
+sexecve_is_bad ()
{
- int i;
- va_list args;
- const char * const *envp;
- const char *argv[1024];
-
- va_start (args, arg0);
- argv[0] = arg0;
- i = 1;
-
- do
- argv[i] = va_arg (args, const char *);
- while (argv[i++] != NULL);
-
- envp = va_arg (args, const char * const *);
- va_end (args);
-
- MALLOC_CHECK;
- return sexecve(hToken, path, (char * const *) argv, (char * const *) envp);
-}
-
-extern "C" int
-sexeclp (HANDLE hToken, const char *path, const char *arg0, ...)
-{
- int i;
- va_list args;
- const char *argv[1024];
-
- va_start (args, arg0);
- argv[0] = arg0;
- i = 1;
-
- do
- argv[i] = va_arg (args, const char *);
- while (argv[i++] != NULL);
-
- va_end (args);
-
- MALLOC_CHECK;
- return sexecvpe (hToken, path, (const char * const *) argv, cur_environ ());
-}
-
-extern "C" int
-sexeclpe (HANDLE hToken, const char *path, const char *arg0, ...)
-{
- int i;
- va_list args;
- const char * const *envp;
- const char *argv[1024];
-
- va_start (args, arg0);
- argv[0] = arg0;
- i = 1;
-
- do
- argv[i] = va_arg (args, const char *);
- while (argv[i++] != NULL);
-
- envp = va_arg (args, const char * const *);
- va_end (args);
-
- MALLOC_CHECK;
- return sexecvpe (hToken, path, argv, envp);
-}
-
-extern "C" int
-sexecv (HANDLE hToken, const char *path, const char * const *argv)
-{
- MALLOC_CHECK;
- return sexecve (hToken, path, argv, cur_environ ());
-}
-
-extern "C" int
-sexecp (HANDLE hToken, const char *path, const char * const *argv)
-{
- MALLOC_CHECK;
- return sexecvpe (hToken, path, argv, cur_environ ());
+ set_errno (ENOSYS);
+ return 0;
}
/*
@@ -190,15 +84,6 @@ strccpy (char *s1, const char **s2, char c)
}
extern "C" int
-sexecvpe (HANDLE hToken, const char *file, const char * const *argv,
- const char *const *envp)
-{
- path_conv buf;
- MALLOC_CHECK;
- return sexecve (hToken, find_exec (file, buf), argv, envp);
-}
-
-extern "C" int
execvp (const char *path, char * const *argv)
{
path_conv buf;
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index 06f131f24..bc61027a0 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -1,6 +1,6 @@
/* external.cc: Interface to Cygwin internals from external programs.
- Copyright 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
Written by Christopher Faylor <cgf@cygnus.com>
@@ -14,7 +14,6 @@ details. */
#include <errno.h>
#include "security.h"
#include "fhandler.h"
-#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include <exceptions.h>
@@ -84,9 +83,12 @@ fillout_pinfo (pid_t pid, int winpid)
ep.rusage_children = p->rusage_children;
strcpy (ep.progname, p->progname);
ep.strace_mask = 0;
- ep.strace_file = 0;
+ ep.version = EXTERNAL_PINFO_VERSION;
ep.process_state = p->process_state;
+
+ ep.uid32 = p->uid;
+ ep.gid32 = p->gid;
break;
}
}
@@ -159,9 +161,8 @@ cygwin_internal (cygwin_getinfo_types t, ...)
return (DWORD) cygwin_version_strings;
case CW_READ_V1_MOUNT_TABLES:
- /* Upgrade old v1 registry mounts to new location. */
- mount_table->import_v1_mounts ();
- return 0;
+ set_errno (ENOSYS);
+ return 1;
case CW_USER_DATA:
return (DWORD) &__cygwin_user_data;
@@ -232,6 +233,14 @@ cygwin_internal (cygwin_getinfo_types t, ...)
pinfo p (va_arg (arg, pid_t));
return p ? p->dwProcessId : 0;
}
+ case CW_EXTRACT_DOMAIN_AND_USER:
+ {
+ struct passwd *pw = va_arg (arg, struct passwd *);
+ char *domain = va_arg (arg, char *);
+ char *user = va_arg (arg, char *);
+ extract_nt_dom_user (pw, domain, user);
+ return 0;
+ }
default:
return (DWORD) -1;
}
diff --git a/winsup/cygwin/fcntl.cc b/winsup/cygwin/fcntl.cc
index 95b622c04..0ba704991 100644
--- a/winsup/cygwin/fcntl.cc
+++ b/winsup/cygwin/fcntl.cc
@@ -1,6 +1,6 @@
/* fcntl.cc: fcntl syscall
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -9,7 +9,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
-#include <fcntl.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index cb74ffa28..1ccc93d7e 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -9,7 +9,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
-#include <sys/fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
@@ -24,7 +23,6 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "shared_info.h"
-#include "sigproc.h"
#include "pinfo.h"
#include <assert.h>
#include <limits.h>
@@ -59,6 +57,33 @@ fhandler_base::puts_readahead (const char *s, size_t len)
return success;
}
+void
+fhandler_base::set_flags (int flags, int supplied_bin)
+{
+ int bin;
+ int fmode;
+ debug_printf ("flags %p, supplied_bin %p", flags, supplied_bin);
+ if ((bin = flags & (O_BINARY | O_TEXT)))
+ debug_printf ("O_TEXT/O_BINARY set in flags %p", bin);
+ else if (get_r_binset () && get_w_binset ())
+ bin = get_r_binary () ? O_BINARY : O_TEXT; // FIXME: Not quite right
+ else if (supplied_bin)
+ bin = supplied_bin;
+ else if ((fmode = get_default_fmode (flags)) & O_BINARY)
+ bin = O_BINARY;
+ else if (fmode & O_TEXT)
+ bin = O_TEXT;
+ else
+ bin = get_w_binary () || get_r_binary () || (binmode != O_TEXT) ?
+ O_BINARY : O_TEXT;
+
+ openflags = flags | bin;
+
+ set_r_binary (bin & O_BINARY);
+ set_w_binary (bin & O_BINARY);
+ syscall_printf ("filemode set to %s", bin ? "binary" : "text");
+}
+
int
fhandler_base::put_readahead (char value)
{
@@ -148,7 +173,8 @@ fhandler_base::get_readahead_into_buffer (char *buf, size_t buflen)
/* Record the file name.
Filenames are used mostly for debugging messages, and it's hoped that
in cases where the name is really required, the filename wouldn't ever
- be too long (e.g. devices or some such). */
+ be too long (e.g. devices or some such).
+ The unix_path_name is also used by virtual fhandlers. */
void
fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit)
{
@@ -160,8 +186,9 @@ fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit
else
{
const char *fmt = get_native_name ();
- win32_path_name = (char *) cmalloc (HEAP_STR, strlen(fmt) + 16);
- __small_sprintf (win32_path_name, fmt, unit);
+ char *w = (char *) cmalloc (HEAP_STR, strlen(fmt) + 16);
+ __small_sprintf (w, fmt, unit);
+ win32_path_name = w;
}
if (win32_path_name == NULL)
@@ -177,12 +204,15 @@ fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit
path_conv. Ideally, we should pass in a format string and build the
unix_path, too. */
if (!is_device () || *win32_path_name != '\\')
- unix_path_name = cstrdup (unix_path);
+ unix_path_name = unix_path;
else
{
- unix_path_name = cstrdup (win32_path_name);
- for (char *p = unix_path_name; (p = strchr (p, '\\')); p++)
- *p = '/';
+ char *p = cstrdup (win32_path_name);
+ unix_path_name = p;
+ while ((p = strchr (p, '\\')) != NULL)
+ *p++ = '/';
+ if (unix_path)
+ cfree ((void *) unix_path);
}
if (unix_path_name == NULL)
@@ -193,13 +223,6 @@ fhandler_base::set_name (const char *unix_path, const char *win32_path, int unit
namehash = hash_path_name (0, win32_path_name);
}
-void
-fhandler_base::reset_unix_path_name (const char *unix_path)
-{
- cfree (unix_path_name);
- unix_path_name = cstrdup (unix_path);
-}
-
/* Detect if we are sitting at EOF for conditions where Windows
returns an error but UNIX doesn't. */
static int __stdcall
@@ -311,7 +334,7 @@ fhandler_base::get_default_fmode (int flags)
/* Open system call handler function. */
int
-fhandler_base::open (path_conv *, int flags, mode_t mode)
+fhandler_base::open (path_conv *pc, int flags, mode_t mode)
{
int res = 0;
HANDLE x;
@@ -320,7 +343,7 @@ fhandler_base::open (path_conv *, int flags, mode_t mode)
int creation_distribution;
SECURITY_ATTRIBUTES sa = sec_none;
- syscall_printf ("(%s, %p)", get_win32_name (), flags);
+ syscall_printf ("(%s, %p) query_open %d", get_win32_name (), flags, get_query_open ());
if (get_win32_name () == NULL)
{
@@ -377,22 +400,24 @@ fhandler_base::open (path_conv *, int flags, mode_t mode)
{
char *c = strrchr (get_win32_name (), '\\');
if ((c && c[1] == '.') || *get_win32_name () == '.')
- file_attributes |= FILE_ATTRIBUTE_HIDDEN;
+ file_attributes |= FILE_ATTRIBUTE_HIDDEN;
}
#endif
/* CreateFile() with dwDesiredAccess == 0 when called on remote
share returns some handle, even if file doesn't exist. This code
works around this bug. */
- if (get_query_open () &&
- isremote () &&
- creation_distribution == OPEN_EXISTING &&
- GetFileAttributes (get_win32_name ()) == INVALID_FILE_ATTRIBUTES)
+ if (get_query_open () && isremote () &&
+ creation_distribution == OPEN_EXISTING && pc && !pc->exists ())
{
set_errno (ENOENT);
goto done;
}
+ /* If mode has no write bits set, we set the R/O attribute. */
+ if (!(mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
+ file_attributes |= FILE_ATTRIBUTE_READONLY;
+
/* If the file should actually be created and ntsec is on,
set files attributes. */
if (flags & O_CREAT && get_device () == FH_DISK && allow_ntsec && has_acls ())
@@ -423,37 +448,7 @@ fhandler_base::open (path_conv *, int flags, mode_t mode)
set_file_attribute (has_acls (), get_win32_name (), mode);
set_io_handle (x);
- int bin;
- int fmode;
- if ((bin = flags & (O_BINARY | O_TEXT)))
- /* nothing to do */;
- else if ((fmode = get_default_fmode (flags)) & O_BINARY)
- bin = O_BINARY;
- else if (fmode & O_TEXT)
- bin = O_TEXT;
- else if (get_device () == FH_DISK)
- bin = get_w_binary () || get_r_binary ();
- else
- bin = (binmode == O_BINARY) || get_w_binary () || get_r_binary ();
-
- if (bin & O_TEXT)
- bin = 0;
-
- set_flags (flags | (bin ? O_BINARY : O_TEXT));
-
- set_r_binary (bin);
- set_w_binary (bin);
- syscall_printf ("filemode set to %s", bin ? "binary" : "text");
-
- if (get_device () != FH_TAPE
- && get_device () != FH_FLOPPY
- && get_device () != FH_SERIAL)
- {
- if (flags & O_APPEND)
- SetFilePointer (get_handle(), 0, 0, FILE_END);
- else
- SetFilePointer (get_handle(), 0, 0, FILE_BEGIN);
- }
+ set_flags (flags, pc ? pc->binmode () : 0);
res = 1;
set_open_status ();
@@ -727,9 +722,17 @@ fhandler_base::lseek (__off64_t offset, int whence)
: (whence == SEEK_CUR ? FILE_CURRENT : FILE_END);
LONG off_low = offset & 0xffffffff;
- LONG off_high = wincap.has_64bit_file_access () ? offset >> 32 : 0;
+ LONG *poff_high, off_high;
+ if (!wincap.has_64bit_file_access ())
+ poff_high = NULL;
+ else
+ {
+ off_high = offset >> 32;
+ poff_high = &off_high;
+ }
- res = SetFilePointer (get_handle(), off_low, &off_high, win32_whence);
+ debug_printf ("setting file pointer to %u (high), %u (low)", off_high, off_low);
+ res = SetFilePointer (get_handle(), off_low, poff_high, win32_whence);
if (res == INVALID_SET_FILE_POINTER && GetLastError ())
{
__seterrno ();
@@ -839,9 +842,8 @@ fhandler_base::fstat (struct __stat64 *buf, path_conv *)
buf->st_mode |= get_device () == FH_FLOPPY ? S_IFBLK : S_IFCHR;
buf->st_nlink = 1;
buf->st_blksize = S_BLKSIZE;
- buf->st_dev = buf->st_rdev = FHDEVN (get_device ()) << 8 | (get_unit () & 0xff);
- buf->st_ino = get_namehash ();
- buf->st_atime = buf->st_mtime = buf->st_ctime = time (NULL) - 1;
+ time_as_timestruc_t (&buf->st_ctim);
+ buf->st_atim = buf->st_mtim = buf->st_ctim;
return 0;
}
@@ -849,18 +851,18 @@ void
fhandler_base::init (HANDLE f, DWORD a, mode_t bin)
{
set_io_handle (f);
- set_r_binary (bin);
- set_w_binary (bin);
access = a;
a &= GENERIC_READ | GENERIC_WRITE;
+ int flags = 0;
if (a == GENERIC_READ)
- set_flags (O_RDONLY);
- if (a == GENERIC_WRITE)
- set_flags (O_WRONLY);
- if (a == (GENERIC_READ | GENERIC_WRITE))
- set_flags (O_RDWR);
+ flags = O_RDONLY;
+ else if (a == GENERIC_WRITE)
+ flags = O_WRONLY;
+ else if (a == (GENERIC_READ | GENERIC_WRITE))
+ flags = O_RDWR;
+ set_flags (flags, bin);
set_open_status ();
- debug_printf ("created new fhandler_base for handle %p", f);
+ debug_printf ("created new fhandler_base for handle %p, bin %d", f, get_r_binary ());
}
void
@@ -1020,23 +1022,15 @@ fhandler_base::fhandler_base (DWORD devtype, int unit):
win32_path_name (NULL),
open_status (0)
{
- int bin = __fmode & O_TEXT ? 0 : 1;
- if (status != FH_DISK && status != FH_CONSOLE)
- {
- if (!get_r_binset ())
- set_r_binary (bin);
- if (!get_w_binset ())
- set_w_binary (bin);
- }
}
/* Normal I/O destructor */
fhandler_base::~fhandler_base (void)
{
if (unix_path_name != NULL)
- cfree (unix_path_name);
+ cfree ((void *) unix_path_name);
if (win32_path_name != NULL)
- cfree (win32_path_name);
+ cfree ((void *) win32_path_name);
if (rabuf)
free (rabuf);
unix_path_name = win32_path_name = NULL;
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 9cab1903b..08bb273a4 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -12,6 +12,7 @@ details. */
#define _FHANDLER_H_
#include <sys/ioctl.h>
+#include <fcntl.h>
enum
{
@@ -70,8 +71,11 @@ enum
FH_CLIPBOARD = 0x00000017, /* is a clipboard device */
FH_OSS_DSP = 0x00000018, /* is a dsp audio device */
FH_CYGDRIVE= 0x00000019, /* /cygdrive/x */
+ FH_PROC = 0x0000001a, /* /proc */
+ FH_REGISTRY =0x0000001b, /* /proc/registry */
+ FH_PROCESS = 0x0000001c, /* /proc/<n> */
- FH_NDEV = 0x0000001a, /* Maximum number of devices */
+ FH_NDEV = 0x0000001d, /* Maximum number of devices */
FH_DEVMASK = 0x00000fff, /* devices live here */
FH_BAD = 0xffffffff
};
@@ -100,6 +104,8 @@ enum
extern const char *windows_device_names[];
extern struct __cygwin_perfile *perfile_table;
#define __fmode (*(user_data->fmode_ptr))
+extern const char proc[];
+extern const int proc_len;
class select_record;
class path_conv;
@@ -118,8 +124,8 @@ enum bg_check_types
enum executable_states
{
is_executable,
- not_executable,
dont_care_if_executable,
+ not_executable = dont_care_if_executable,
dont_know_if_executable
};
@@ -144,15 +150,13 @@ class fhandler_base
size_t raixput;
size_t rabuflen;
- char *unix_path_name;
- char *win32_path_name;
+ const char *unix_path_name;
+ const char *win32_path_name;
DWORD open_status;
public:
- void set_name (const char * unix_path, const char * win32_path = NULL,
- int unit = 0);
+ void set_name (const char * unix_path, const char *win32_path = NULL, int unit = 0);
- void reset_unix_path_name (const char *);
virtual fhandler_base& operator =(fhandler_base &x);
fhandler_base (DWORD dev, int unit = 0);
virtual ~fhandler_base ();
@@ -171,13 +175,13 @@ class fhandler_base
void set_async (int x) { FHCONDSETF (x, ASYNC); }
int get_flags () { return openflags; }
- void set_flags (int x) { openflags = x; }
+ void set_flags (int x, int supplied_bin = 0);
bool is_nonblocking ();
void set_nonblocking (int yes);
- bool get_w_binary () { return FHISSETF (WBINARY); }
- bool get_r_binary () { return FHISSETF (RBINARY); }
+ bool get_w_binary () { return FHISSETF (WBINSET) ? FHISSETF (WBINARY) : 1; }
+ bool get_r_binary () { return FHISSETF (RBINSET) ? FHISSETF (RBINARY) : 1; }
bool get_w_binset () { return FHISSETF (WBINSET); }
bool get_r_binset () { return FHISSETF (RBINSET); }
@@ -194,9 +198,9 @@ class fhandler_base
DWORD get_open_status () {return open_status;}
void reset_to_open_binmode ()
{
- status = status & ~(FH_WBINARY | FH_WBINSET | FH_RBINARY | FH_RBINSET);
- status = status | ((FH_WBINARY | FH_WBINSET | FH_RBINARY | FH_RBINSET)
- & open_status);
+ set_flags ((get_flags () & ~(O_TEXT | O_BINARY))
+ | ((open_status & (FH_WBINARY | FH_RBINARY)
+ ? O_BINARY : O_TEXT)));
}
int get_default_fmode (int flags);
@@ -243,13 +247,14 @@ class fhandler_base
}
void set_execable_p () { FHSETF (EXECABL); }
bool dont_care_if_execable () { return FHISSETF (DCEXEC); }
+ bool exec_state_isknown () { return FHISSETF (DCEXEC) || FHISSETF (EXECABL); }
bool get_append_p () { return FHISSETF (APPEND); }
void set_append_p (int val) { FHCONDSETF (val, APPEND); }
void set_append_p () { FHSETF (APPEND); }
bool get_query_open () { return FHISSETF (QUERYOPEN); }
- void set_query_open (int val) { FHCONDSETF (val, QUERYOPEN); }
+ void set_query_open (bool val) { FHCONDSETF (val, QUERYOPEN); }
bool get_readahead_valid () { return raixget < ralen; }
int puts_readahead (const char *s, size_t len = (size_t) -1);
@@ -280,7 +285,7 @@ class fhandler_base
/* fixup fd possibly non-inherited handles after fork */
void fork_fixup (HANDLE parent, HANDLE &h, const char *name);
- virtual int open (path_conv * real_path, int flags, mode_t mode = 0);
+ virtual int open (path_conv *real_path, int flags, mode_t mode = 0);
virtual int close ();
virtual int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
virtual int ioctl (unsigned int cmd, void *);
@@ -357,6 +362,7 @@ class fhandler_socket: public fhandler_base
{
private:
int addr_family;
+ int type;
int connect_secret [4];
HANDLE secret_event;
struct _WSAPROTOCOL_INFOA *prot_info_ptr;
@@ -397,6 +403,8 @@ class fhandler_socket: public fhandler_base
select_record *select_except (select_record *s);
void set_addr_family (int af) {addr_family = af;}
int get_addr_family () {return addr_family;}
+ void set_socket_type (int st) { type = st;}
+ int get_socket_type () {return type;}
void set_sun_path (const char *path);
char *get_sun_path () {return sun_path;}
void set_connect_secret ();
@@ -509,16 +517,16 @@ class fhandler_dev_tape: public fhandler_dev_raw
public:
fhandler_dev_tape (int unit);
- int open (path_conv *, int flags, mode_t mode = 0);
- int close (void);
+ virtual int open (path_conv *, int flags, mode_t mode = 0);
+ virtual int close (void);
- __off64_t lseek (__off64_t offset, int whence);
+ virtual __off64_t lseek (__off64_t offset, int whence);
- int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
+ virtual int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
- int dup (fhandler_base *child);
+ virtual int dup (fhandler_base *child);
- int ioctl (unsigned int cmd, void *buf);
+ virtual int ioctl (unsigned int cmd, void *buf);
private:
int tape_write_marks (int marktype, DWORD len);
@@ -546,7 +554,18 @@ class fhandler_disk_file: public fhandler_base
int lock (int, struct flock *);
BOOL is_device () { return FALSE; }
int __stdcall fstat (struct __stat64 *buf, path_conv *pc) __attribute__ ((regparm (3)));
- int __stdcall fstat_helper (struct __stat64 *buf) __attribute__ ((regparm (2)));
+ int __stdcall fstat_helper (struct __stat64 *buf, path_conv *pc,
+ FILETIME ftCreateionTime,
+ FILETIME ftLastAccessTime,
+ FILETIME ftLastWriteTime,
+ DWORD nFileSizeHigh,
+ DWORD nFileSizeLow,
+ DWORD nFileIndexHigh = 0,
+ DWORD nFileIndexLow = 0,
+ DWORD nNumberOfLinks = 1)
+ __attribute__ ((regparm (3)));
+ int __stdcall fstat_by_handle (struct __stat64 *buf, path_conv *pc) __attribute__ ((regparm (3)));
+ int __stdcall fstat_by_name (struct __stat64 *buf, path_conv *pc) __attribute__ ((regparm (3)));
HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, __off64_t off);
int munmap (HANDLE h, caddr_t addr, size_t len);
@@ -657,6 +676,7 @@ class fhandler_termios: public fhandler_base
void fixup_after_fork (HANDLE);
void fixup_after_exec (HANDLE parent) { fixup_after_fork (parent); }
void echo_erase (int force = 0);
+ virtual __off64_t lseek (__off64_t, int);
};
enum ansi_intensity
@@ -1030,6 +1050,78 @@ class fhandler_dev_dsp : public fhandler_base
void fixup_after_exec (HANDLE);
};
+class fhandler_virtual : public fhandler_base
+{
+ protected:
+ char *filebuf;
+ size_t bufalloc, filesize;
+ __off64_t position;
+ int fileid; // unique within each class
+ public:
+
+ fhandler_virtual (DWORD devtype);
+ virtual ~fhandler_virtual();
+
+ virtual int exists();
+ DIR *opendir (path_conv& pc);
+ __off64_t telldir (DIR *);
+ void seekdir (DIR *, __off64_t);
+ void rewinddir (DIR *);
+ int closedir (DIR *);
+ int write (const void *ptr, size_t len);
+ int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3)));
+ __off64_t lseek (__off64_t, int);
+ int dup (fhandler_base * child);
+ int open (path_conv *, int flags, mode_t mode = 0);
+ int close (void);
+ int __stdcall fstat (struct stat *buf, path_conv *pc) __attribute__ ((regparm (3)));
+ virtual void fill_filebuf ();
+};
+
+class fhandler_proc: public fhandler_virtual
+{
+ public:
+ fhandler_proc ();
+ fhandler_proc (DWORD devtype);
+ int exists();
+ struct dirent *readdir (DIR *);
+ static DWORD get_proc_fhandler(const char *path);
+
+ int open (path_conv *real_path, int flags, mode_t mode = 0);
+ int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
+ void fill_filebuf ();
+};
+
+class pinfo;
+class fhandler_registry: public fhandler_proc
+{
+ public:
+ fhandler_registry ();
+ int exists();
+ struct dirent *readdir (DIR *);
+ __off64_t telldir (DIR *);
+ void seekdir (DIR *, __off64_t);
+ void rewinddir (DIR *);
+ int closedir (DIR *);
+
+ int open (path_conv *real_path, int flags, mode_t mode = 0);
+ int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
+ HKEY open_key(const char *name, REGSAM access = KEY_READ, bool isValue = false);
+ void fill_filebuf ();
+};
+
+struct _pinfo;
+class fhandler_process: public fhandler_proc
+{
+ public:
+ fhandler_process ();
+ int exists();
+ struct dirent *readdir (DIR *);
+ int open (path_conv *real_path, int flags, mode_t mode = 0);
+ int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
+ void fill_filebuf (pinfo& p);
+};
+
typedef union
{
char base[sizeof(fhandler_base)];
@@ -1045,7 +1137,10 @@ typedef union
char dev_zero[sizeof(fhandler_dev_zero)];
char disk_file[sizeof(fhandler_disk_file)];
char pipe[sizeof(fhandler_pipe)];
+ char proc[sizeof(fhandler_proc)];
+ char process[sizeof(fhandler_process)];
char pty_master[sizeof(fhandler_pty_master)];
+ char registry[sizeof(fhandler_registry)];
char serial[sizeof(fhandler_serial)];
char socket[sizeof(fhandler_socket)];
char termios[sizeof(fhandler_termios)];
diff --git a/winsup/cygwin/fhandler_clipboard.cc b/winsup/cygwin/fhandler_clipboard.cc
index 266114fe3..e3b26c9fa 100644
--- a/winsup/cygwin/fhandler_clipboard.cc
+++ b/winsup/cygwin/fhandler_clipboard.cc
@@ -65,7 +65,7 @@ fhandler_dev_clipboard::dup (fhandler_base * child)
int
fhandler_dev_clipboard::open (path_conv *, int flags, mode_t)
{
- set_flags (flags);
+ set_flags (flags, O_TEXT);
eof = false;
pos = 0;
if (membuffer)
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index 3598810cb..cc948d3d0 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -1,6 +1,6 @@
/* fhandler_console.cc
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -12,7 +12,6 @@ details. */
#include <sys/termios.h>
#include <stdio.h>
#include <stdlib.h>
-#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <wingdi.h>
@@ -27,7 +26,6 @@ details. */
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
-#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "shared_info.h"
@@ -548,7 +546,7 @@ fhandler_console::open (path_conv *, int flags, mode_t)
set_io_handle (INVALID_HANDLE_VALUE);
set_output_handle (INVALID_HANDLE_VALUE);
- set_flags (flags);
+ set_flags (flags & ~O_TEXT, O_BINARY);
/* Open the input handle as handle_ */
h = CreateFileA ("CONIN$", GENERIC_READ|GENERIC_WRITE,
@@ -715,12 +713,6 @@ fhandler_console::tcflush (int queue)
int
fhandler_console::output_tcsetattr (int, struct termios const *t)
{
- /* Ignore the optional_actions stuff, since all output is emitted
- instantly */
-
- /* Enable/disable LF -> CRLF conversions */
- set_w_binary ((t->c_oflag & ONLCR) ? 0 : 1);
-
/* All the output bits we can ignore */
DWORD flags = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
@@ -743,8 +735,10 @@ fhandler_console::input_tcsetattr (int, struct termios const *t)
oflags = 0;
DWORD flags = 0;
+#if 0
/* Enable/disable LF -> CRLF conversions */
set_r_binary ((t->c_iflag & INLCR) ? 0 : 1);
+#endif
/* There's some disparity between what we need and what's
available. We've got ECHO and ICANON, they've
@@ -819,13 +813,6 @@ fhandler_console::tcgetattr (struct termios *t)
t->c_cflag |= CS8;
-#if 0
- if (!get_r_binary ())
- t->c_iflag |= IGNCR;
- if (!get_w_binary ())
- t->c_oflag |= ONLCR;
-#endif
-
DWORD flags;
if (!GetConsoleMode (get_io_handle (), &flags))
@@ -1195,7 +1182,7 @@ fhandler_console::char_command (char c)
ReadConsoleOutputA (get_output_handle (), savebuf,
savebufsiz, cob, &now.srWindow);
}
- else /* restore */
+ else /* restore */
{
CONSOLE_SCREEN_BUFFER_INFO now;
COORD cob = { 0, 0 };
@@ -1444,21 +1431,19 @@ fhandler_console::write_normal (const unsigned char *src,
case ESC:
state_ = gotesc;
break;
- case DWN: /* WriteFile ("\n") always adds CR... */
+ case DWN:
cursor_get (&x, &y);
if (y >= srBottom)
{
- if (y < info.winBottom || scroll_region.Top)
+ if (y >= info.winBottom && !scroll_region.Top)
+ WriteFile (get_output_handle (), "\n", 1, &done, 0);
+ else
{
scroll_screen (0, srTop + 1, -1, srBottom, 0, srTop);
y--;
}
- else
- WriteFile (get_output_handle (), "\n", 1, &done, 0);
}
- if (!get_w_binary ())
- x = 0;
- cursor_set (FALSE, x, y + 1);
+ cursor_set (FALSE, ((tc->ti.c_oflag & ONLCR) ? 0 : x), y + 1);
break;
case BAK:
cursor_rel (-1, 0);
@@ -1699,19 +1684,18 @@ get_nonascii_key (INPUT_RECORD& input_rec, char *tmp)
void
fhandler_console::init (HANDLE f, DWORD a, mode_t bin)
{
- this->fhandler_termios::init (f, bin, a);
-
+ // this->fhandler_termios::init (f, mode, bin);
/* Ensure both input and output console handles are open */
- int mode = 0;
+ int flags = 0;
a &= GENERIC_READ | GENERIC_WRITE;
if (a == GENERIC_READ)
- mode = O_RDONLY;
+ flags = O_RDONLY;
if (a == GENERIC_WRITE)
- mode = O_WRONLY;
+ flags = O_WRONLY;
if (a == (GENERIC_READ | GENERIC_WRITE))
- mode = O_RDWR;
- open ((path_conv *) NULL, mode);
+ flags = O_RDWR;
+ open ((path_conv *) NULL, flags | O_BINARY);
if (f != INVALID_HANDLE_VALUE)
CloseHandle (f); /* Reopened by open */
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index c251ed3cf..443612ff4 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -9,7 +9,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
-#include <sys/fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
@@ -24,14 +23,13 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "shared_info.h"
-#include "sigproc.h"
#include "pinfo.h"
#include <assert.h>
#define _COMPILING_NEWLIB
#include <dirent.h>
-static int
+static int __stdcall
num_entries (const char *win32_name)
{
WIN32_FIND_DATA buf;
@@ -60,27 +58,102 @@ num_entries (const char *win32_name)
return count;
}
-int
+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 ())
+ {
+ set_errno (ENOENT);
+ res = -1;
+ }
+ else if ((handle = FindFirstFile (pc->get_win32 (), &local)) == INVALID_HANDLE_VALUE)
+ {
+ __seterrno ();
+ res = -1;
+ }
+ else
+ {
+ FindClose (handle);
+ res = fstat_helper (buf, pc,
+ local.ftCreationTime,
+ local.ftLastAccessTime,
+ local.ftLastWriteTime,
+ local.nFileSizeHigh,
+ local.nFileSizeLow);
+ }
+ return res;
+}
+
+int __stdcall
fhandler_disk_file::fstat (struct __stat64 *buf, path_conv *pc)
{
int res = -1;
int oret;
- __uid16_t uid;
- __gid16_t gid;
+ __uid32_t uid;
+ __gid32_t gid;
int open_flags = O_RDONLY | O_BINARY | O_DIROPEN;
+ bool query_open_already;
- if (!pc)
- return fstat_helper (buf);
+ if (get_io_handle ())
+ return fstat_by_handle (buf, pc);
- if ((oret = open (pc, open_flags, 0)))
- /* ok */;
+ /* 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)))
{
int ntsec_atts = 0;
/* 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. */
- set_query_open (TRUE);
- if ((oret = open (pc, open_flags, 0)))
+ set_query_open (true);
+ if (!query_open_already && (oret = open (pc, open_flags, 0)))
/* ok */;
else if (allow_ntsec && pc->has_acls () && get_errno () == EACCES
&& !get_file_attribute (TRUE, get_win32_name (), &ntsec_atts, &uid, &gid)
@@ -96,151 +169,54 @@ fhandler_disk_file::fstat (struct __stat64 *buf, path_conv *pc)
set_file_attribute (TRUE, get_win32_name (), ntsec_atts);
}
}
- if (oret)
- {
- res = fstat_helper (buf);
- /* 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 and
- set the number of links to 2. */
- /* Unfortunately the count of 2 confuses `find (1)' command. So
- let's try it with `1' as link count. */
- if (pc->isdir ())
- buf->st_nlink = (pc->isremote ()
- ? 1 : num_entries (pc->get_win32 ()));
+
+ if (!oret)
+ res = fstat_by_name (buf, pc);
+ else
+ {
+ res = fstat_by_handle (buf, pc);
close ();
}
- else if (pc->exists ())
- {
- /* Unfortunately, the above open may fail if the file exists, though.
- So we have to care for this case here, too. */
- WIN32_FIND_DATA wfd;
- HANDLE handle;
- buf->st_nlink = 1;
- if (pc->isdir () && pc->isremote ())
- buf->st_nlink = num_entries (pc->get_win32 ());
- buf->st_dev = FHDEVN (FH_DISK) << 8;
- buf->st_ino = hash_path_name (0, pc->get_win32 ());
- if (pc->isdir ())
- buf->st_mode = S_IFDIR;
- else if (pc->issymlink ())
- buf->st_mode = S_IFLNK;
- else if (pc->issocket ())
- buf->st_mode = S_IFSOCK;
- else
- buf->st_mode = S_IFREG;
- if (!pc->has_acls ()
- || get_file_attribute (TRUE, pc->get_win32 (),
- &buf->st_mode, &uid, &gid))
- {
- buf->st_mode |= STD_RBITS | STD_XBITS;
- if (!(pc->has_attribute (FILE_ATTRIBUTE_READONLY)))
- buf->st_mode |= STD_WBITS;
- if (pc->issymlink ())
- buf->st_mode |= S_IRWXU | S_IRWXG | S_IRWXO;
- get_file_attribute (FALSE, pc->get_win32 (), NULL, &uid, &gid);
- }
- buf->st_uid = uid;
- buf->st_gid = gid;
- if ((handle = FindFirstFile (pc->get_win32 (), &wfd))
- != INVALID_HANDLE_VALUE)
- {
- /* This is for FAT filesystems, which don't support atime/ctime */
- if (wfd.ftLastAccessTime.dwLowDateTime == 0
- && wfd.ftLastAccessTime.dwHighDateTime == 0)
- wfd.ftLastAccessTime = wfd.ftLastWriteTime;
- if (wfd.ftCreationTime.dwLowDateTime == 0
- && wfd.ftCreationTime.dwHighDateTime == 0)
- wfd.ftCreationTime = wfd.ftLastWriteTime;
-
- buf->st_atime = to_time_t (&wfd.ftLastAccessTime);
- buf->st_mtime = to_time_t (&wfd.ftLastWriteTime);
- buf->st_ctime = to_time_t (&wfd.ftCreationTime);
- buf->st_size = wfd.nFileSizeLow;
- buf->st_size = ((__off64_t)wfd.nFileSizeHigh << 32)
- + wfd.nFileSizeLow;
- buf->st_blksize = S_BLKSIZE;
- buf->st_blocks = (buf->st_size + S_BLKSIZE-1) / S_BLKSIZE;
- FindClose (handle);
- }
- res = 0;
- }
return res;
}
-int
-fhandler_disk_file::fstat_helper (struct __stat64 *buf)
+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)
{
- int res = 0; // avoid a compiler warning
- BY_HANDLE_FILE_INFORMATION local;
- save_errno saved_errno;
-
- /* 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*/
- DWORD lsize, hsize;
-
- if (GetFileType (get_handle ()) != FILE_TYPE_DISK)
- buf->st_mode = S_IFCHR;
-
- lsize = GetFileSize (get_handle (), &hsize);
- if (lsize == 0xffffffff && GetLastError () != NO_ERROR)
- buf->st_mode = S_IFCHR;
- else
- buf->st_size = ((__off64_t)hsize << 32) + lsize;
- /* We expect these to fail! */
- buf->st_mode |= STD_RBITS | STD_WBITS;
- buf->st_blksize = S_BLKSIZE;
- buf->st_ino = get_namehash ();
- syscall_printf ("0 = fstat (, %p)", buf);
- return 0;
- }
-
- if (!get_win32_name ())
- {
- saved_errno.set (ENOENT);
- return -1;
- }
-
/* This is for FAT filesystems, which don't support atime/ctime */
- if (local.ftLastAccessTime.dwLowDateTime == 0
- && local.ftLastAccessTime.dwHighDateTime == 0)
- local.ftLastAccessTime = local.ftLastWriteTime;
- if (local.ftCreationTime.dwLowDateTime == 0
- && local.ftCreationTime.dwHighDateTime == 0)
- local.ftCreationTime = local.ftLastWriteTime;
-
- buf->st_atime = to_time_t (&local.ftLastAccessTime);
- buf->st_mtime = to_time_t (&local.ftLastWriteTime);
- buf->st_ctime = to_time_t (&local.ftCreationTime);
- buf->st_nlink = local.nNumberOfLinks;
- buf->st_dev = local.dwVolumeSerialNumber;
- buf->st_size = ((__off64_t)local.nFileSizeHigh << 32)
- + local.nFileSizeLow;
-
- /* Allocate some place to determine the root directory. Need to allocate
- enough so that rootdir can add a trailing slash if path starts with \\. */
- char root[strlen (get_win32_name ()) + 3];
- strcpy (root, get_win32_name ());
+ 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;
+ /* Unfortunately the count of 2 confuses `find (1)' command. So
+ let's try it with `1' as link count. */
+ if (pc->isdir () && !pc->isremote () && nNumberOfLinks == 1)
+ buf->st_nlink = num_entries (pc->get_win32 ());
+ else
+ buf->st_nlink = 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 (has_acls () ? GetDriveType (rootdir (root)) : DRIVE_UNKNOWN)
+ switch (pc->has_acls () && (nFileIndexHigh || nFileIndexLow)
+ ? pc->drive_type () : DRIVE_UNKNOWN)
{
case DRIVE_FIXED:
case DRIVE_REMOVABLE:
@@ -248,7 +224,7 @@ fhandler_disk_file::fstat_helper (struct __stat64 *buf)
case DRIVE_RAMDISK:
/* Although the documentation indicates otherwise, it seems like
"inodes" on these devices are persistent, at least across reboots. */
- buf->st_ino = local.nFileIndexHigh | local.nFileIndexLow;
+ buf->st_ino = nFileIndexHigh | nFileIndexLow;
break;
default:
/* Either the nFileIndex* fields are unreliable or unavailable. Use the
@@ -258,38 +234,35 @@ fhandler_disk_file::fstat_helper (struct __stat64 *buf)
}
buf->st_blksize = S_BLKSIZE;
- buf->st_blocks = (buf->st_size + S_BLKSIZE-1) / S_BLKSIZE;
+ 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 (local.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ if (pc->fileattr & FILE_ATTRIBUTE_DIRECTORY)
buf->st_mode = S_IFDIR;
- else if (get_symlink_p ())
+ else if (pc->issymlink ())
buf->st_mode = S_IFLNK;
- else if (get_socket_p ())
+ else if (pc->issocket ())
buf->st_mode = S_IFSOCK;
- __uid16_t uid;
- __gid16_t gid;
- if (get_file_attribute (has_acls (), get_win32_name (), &buf->st_mode,
+
+ __uid32_t uid;
+ __gid32_t gid;
+ if (get_file_attribute (pc->has_acls (), get_win32_name (), &buf->st_mode,
&uid, &gid) == 0)
{
/* If read-only attribute is set, modify ntsec return value */
- if ((local.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
- && !get_symlink_p ())
+ if ((pc->fileattr & 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;
-
- buf->st_uid = uid;
- buf->st_gid = gid;
}
else
{
buf->st_mode |= STD_RBITS;
- if (!(local.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
+ if (!(pc->fileattr & FILE_ATTRIBUTE_READONLY))
buf->st_mode |= STD_WBITS;
/* | S_IWGRP | S_IWOTH; we don't give write to group etc */
@@ -297,51 +270,52 @@ fhandler_disk_file::fstat_helper (struct __stat64 *buf)
buf->st_mode |= S_IFDIR | STD_XBITS;
else if (buf->st_mode & S_IFMT)
/* nothing */;
- else if (get_socket_p ())
+ else if (pc->issocket ())
buf->st_mode |= S_IFSOCK;
else
- switch (GetFileType (get_handle ()))
- {
- case FILE_TYPE_CHAR:
- case FILE_TYPE_UNKNOWN:
- buf->st_mode |= S_IFCHR;
- break;
- case FILE_TYPE_DISK:
- buf->st_mode |= S_IFREG;
- if (!dont_care_if_execable () && !get_execable_p ())
- {
- 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 ();
- SetFilePointer (get_handle(), cur, NULL, FILE_BEGIN);
- }
- }
- if (get_execable_p ())
- buf->st_mode |= STD_XBITS;
- break;
- case FILE_TYPE_PIPE:
- buf->st_mode |= S_IFSOCK;
- break;
- }
+ {
+ 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 ();
+ }
+ SetFilePointer (get_handle(), cur, NULL, FILE_BEGIN);
+ }
+ }
+ if (pc->exec_state () == is_executable)
+ buf->st_mode |= STD_XBITS;
+ }
}
- 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));
+ buf->st_uid = uid;
+ buf->st_gid = gid;
+
+ /* 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 and
+ set the number of links to 2. */
+ 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;
}
@@ -365,19 +339,17 @@ fhandler_disk_file::open (path_conv *real_path, int flags, mode_t mode)
return 0;
}
- if (real_path->isbinary ())
- {
- set_r_binary (1);
- set_w_binary (1);
- }
-
set_has_acls (real_path->has_acls ());
set_isremote (real_path->isremote ());
- if (real_path->isdir ())
- flags |= O_DIROPEN;
-
- int res = this->fhandler_base::open (real_path, flags, mode);
+ int res;
+ if (!real_path->isdir () || wincap.can_open_directories ())
+ res = this->fhandler_base::open (real_path, flags | O_DIROPEN, mode);
+ else
+ {
+ set_errno (EISDIR);
+ res = 0;
+ }
if (!res)
goto out;
@@ -388,8 +360,7 @@ fhandler_disk_file::open (path_conv *real_path, int flags, mode_t mode)
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 ()
- && GetFileAttributes (win32_path_name) == INVALID_FILE_ATTRIBUTES)
+ if (real_path->has_buggy_open () && !real_path->exists ())
{
debug_printf ("Buggy open detected.");
close ();
@@ -684,37 +655,6 @@ fhandler_disk_file::readdir (DIR *dir)
}
}
- /* Compute d_ino by combining filename hash with the directory hash
- (which was stored in dir->__d_dirhash when opendir was called). */
- if (buf.cFileName[0] == '.')
- {
- if (buf.cFileName[1] == '\0')
- dir->__d_dirent->d_ino = dir->__d_dirhash;
- else if (buf.cFileName[1] != '.' || buf.cFileName[2] != '\0')
- goto hashit;
- else
- {
- char *p, up[strlen (dir->__d_dirname) + 1];
- strcpy (up, dir->__d_dirname);
- if (!(p = strrchr (up, '\\')))
- goto hashit;
- *p = '\0';
- if (!(p = strrchr (up, '\\')))
- dir->__d_dirent->d_ino = hash_path_name (0, ".");
- else
- {
- *p = '\0';
- dir->__d_dirent->d_ino = hash_path_name (0, up);
- }
- }
- }
- else
- {
- hashit:
- ino_t dino = hash_path_name (dir->__d_dirhash, "\\");
- dir->__d_dirent->d_ino = hash_path_name (dino, buf.cFileName);
- }
-
dir->__d_position++;
res = dir->__d_dirent;
syscall_printf ("%p = readdir (%p) (%s)",
@@ -772,10 +712,10 @@ void
fhandler_cygdrive::set_drives ()
{
const int len = 1 + 26 * DRVSZ;
- win32_path_name = (char *) crealloc (win32_path_name, len);
+ char *p = (char *) crealloc ((void *) win32_path_name, len);
- ndrives = GetLogicalDriveStrings (len, win32_path_name) / DRVSZ;
- pdrive = win32_path_name;
+ win32_path_name = pdrive = p;
+ ndrives = GetLogicalDriveStrings (len, p) / DRVSZ;
}
int
@@ -812,13 +752,26 @@ fhandler_cygdrive::readdir (DIR *dir)
set_errno (ENMFILE);
return NULL;
}
- if (GetFileAttributes (pdrive) == INVALID_FILE_ATTRIBUTES)
+ if (dir->__d_position == 0)
+ {
+ *dir->__d_dirent->d_name = '.';
+ dir->__d_dirent->d_name[1] = '\0';
+ }
+ else if (dir->__d_position == 1)
+ {
+ dir->__d_dirent->d_name[0] = dir->__d_dirent->d_name[1] = '.';
+ dir->__d_dirent->d_name[2] = '\0';
+ }
+ else if (GetFileAttributes (pdrive) == INVALID_FILE_ATTRIBUTES)
{
pdrive += DRVSZ;
return readdir (dir);
}
- *dir->__d_dirent->d_name = cyg_tolower (*pdrive);
- dir->__d_dirent->d_name[1] = '\0';
+ else
+ {
+ *dir->__d_dirent->d_name = cyg_tolower (*pdrive);
+ dir->__d_dirent->d_name[1] = '\0';
+ }
dir->__d_position++;
pdrive += DRVSZ;
syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir,
diff --git a/winsup/cygwin/fhandler_dsp.cc b/winsup/cygwin/fhandler_dsp.cc
index 6ea8f3cbd..f809b93cc 100644
--- a/winsup/cygwin/fhandler_dsp.cc
+++ b/winsup/cygwin/fhandler_dsp.cc
@@ -15,7 +15,6 @@ details. */
#include <errno.h>
#include <windows.h>
#include <sys/soundcard.h>
-#include <sys/fcntl.h>
#include <mmsystem.h>
#include "cygerrno.h"
#include "security.h"
@@ -434,9 +433,12 @@ fhandler_dev_dsp::open (path_conv *, int flags, mode_t mode)
{
// currently we only support writing
if ((flags & (O_WRONLY | O_RDONLY | O_RDWR)) != O_WRONLY)
- return 0;
+ {
+ set_errno (EACCES);
+ return 0;
+ }
- set_flags (flags);
+ set_flags (flags & ~O_TEXT, O_BINARY);
if (!s_audio)
s_audio = new (audio_buf) Audio;
@@ -448,14 +450,17 @@ fhandler_dev_dsp::open (path_conv *, int flags, mode_t mode)
audiobits_ = 8;
audiochannels_ = 1;
+ int res;
if (!s_audio->open (audiofreq_, audiobits_, audiochannels_))
- debug_printf ("/dev/dsp: failed to open\n");
+ res = 0;
else
{
set_open_status ();
- debug_printf ("/dev/dsp: successfully opened\n");
+ res = 1;
}
- return 1;
+
+ debug_printf ("returns %d", res);
+ return res;
}
int
diff --git a/winsup/cygwin/fhandler_floppy.cc b/winsup/cygwin/fhandler_floppy.cc
index 43daf9d99..3804fdf74 100644
--- a/winsup/cygwin/fhandler_floppy.cc
+++ b/winsup/cygwin/fhandler_floppy.cc
@@ -11,7 +11,6 @@ details. */
#include "winsup.h"
#include <sys/termios.h>
-#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <winioctl.h>
diff --git a/winsup/cygwin/fhandler_mem.cc b/winsup/cygwin/fhandler_mem.cc
index e5b99526e..9a53b1a22 100644
--- a/winsup/cygwin/fhandler_mem.cc
+++ b/winsup/cygwin/fhandler_mem.cc
@@ -9,7 +9,6 @@
details. */
#include "winsup.h"
-#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/mman.h>
diff --git a/winsup/cygwin/fhandler_random.cc b/winsup/cygwin/fhandler_random.cc
index 33ccaddea..42481d6eb 100644
--- a/winsup/cygwin/fhandler_random.cc
+++ b/winsup/cygwin/fhandler_random.cc
@@ -31,7 +31,7 @@ fhandler_dev_random::fhandler_dev_random (int nunit)
int
fhandler_dev_random::open (path_conv *, int flags, mode_t)
{
- set_flags (flags);
+ set_flags (flags & ~O_TEXT, O_BINARY);
set_open_status ();
return 1;
}
diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc
index 7cbbe0a53..c692214ae 100644
--- a/winsup/cygwin/fhandler_raw.cc
+++ b/winsup/cygwin/fhandler_raw.cc
@@ -1,6 +1,6 @@
/* fhandler_raw.cc. See fhandler.h for a description of the fhandler classes.
- Copyright 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -10,7 +10,6 @@
#include "winsup.h"
#include <sys/termios.h>
-#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
@@ -171,15 +170,12 @@ fhandler_dev_raw::open (path_conv *real_path, int flags, mode_t)
FILE_SYNCHRONOUS_IO_NONALERT);
if (!NT_SUCCESS (status))
{
- set_errno (RtlNtStatusToDosError (status));
- debug_printf ("NtOpenFile: NTSTATUS: %d, Win32: %E", status);
+ __seterrno_from_win_error (RtlNtStatusToDosError (status));
return 0;
}
set_io_handle (h);
- set_flags (flags);
- set_r_binary (O_BINARY);
- set_w_binary (O_BINARY);
+ set_flags (flags & ~O_TEXT, O_BINARY);
if (devbufsiz > 1L)
devbuf = new char [devbufsiz];
diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc
index b4a813b04..e63de26d3 100644
--- a/winsup/cygwin/fhandler_serial.cc
+++ b/winsup/cygwin/fhandler_serial.cc
@@ -1,6 +1,6 @@
/* fhandler_serial.cc
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -9,14 +9,12 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
-#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include "cygerrno.h"
#include "security.h"
#include "fhandler.h"
-#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include <sys/termios.h>
@@ -202,8 +200,7 @@ fhandler_serial::dump (void)
void
fhandler_serial::init (HANDLE f, DWORD flags, mode_t bin)
{
- fhandler_base::init (f, flags, bin);
- (void) open (NULL, flags, bin ? O_BINARY : 0);
+ (void) open (NULL, flags, bin & (O_BINARY | O_TEXT));
}
int
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index cf8ec1c24..3ef35687e 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -19,7 +19,6 @@
#include <stdlib.h>
#include <unistd.h>
-#include <fcntl.h>
#define USE_SYS_TYPES_FD_SET
#include <winsock2.h>
#include "cygerrno.h"
@@ -247,9 +246,10 @@ fhandler_socket::dup (fhandler_base *child)
int __stdcall
fhandler_socket::fstat (struct __stat64 *buf, path_conv *pc)
{
- fhandler_disk_file fh;
- fh.set_name (get_name (), get_win32_name ());
- return fh.fstat (buf, pc);
+ int res = fhandler_base::fstat (buf, pc);
+ if (!res)
+ buf->st_ino = (ino_t) get_handle ();
+ return res;
}
int
@@ -352,13 +352,21 @@ fhandler_socket::close ()
setsockopt (get_socket (), SOL_SOCKET, SO_LINGER,
(const char *)&linger, sizeof linger);
- while ((res = closesocket (get_socket ()))
- && WSAGetLastError () == WSAEWOULDBLOCK)
- continue;
- if (res)
+ while ((res = closesocket (get_socket ())) != 0)
{
- set_winsock_errno ();
- res = -1;
+ if (WSAGetLastError () != WSAEWOULDBLOCK)
+ {
+ set_winsock_errno ();
+ res = -1;
+ break;
+ }
+ if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
+ {
+ set_errno (EINTR);
+ res = -1;
+ break;
+ }
+ WSASetLastError (0);
}
close_secret_event ();
diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc
index 6b9bd1f4d..aaf1ed751 100644
--- a/winsup/cygwin/fhandler_tape.cc
+++ b/winsup/cygwin/fhandler_tape.cc
@@ -11,7 +11,6 @@ details. */
#include "winsup.h"
#include <sys/termios.h>
-#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/mtio.h>
@@ -155,10 +154,8 @@ fhandler_dev_tape::fstat (struct __stat64 *buf, path_conv *pc)
{
struct mtget get;
- if (! ioctl (MTIOCGET, &get))
- {
- buf->st_blocks = get.mt_capacity / buf->st_blksize;
- }
+ if (!ioctl (MTIOCGET, &get))
+ buf->st_blocks = get.mt_capacity / buf->st_blksize;
}
return ret;
diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc
index 2407238e7..778c09651 100644
--- a/winsup/cygwin/fhandler_termios.cc
+++ b/winsup/cygwin/fhandler_termios.cc
@@ -1,6 +1,6 @@
/* fhandler_termios.cc
- Copyright 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -9,15 +9,14 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
+#include <sys/termios.h>
#include <stdlib.h>
-#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include "cygerrno.h"
#include "security.h"
#include "fhandler.h"
-#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "tty.h"
@@ -100,7 +99,7 @@ tty_min::kill_pgrp (int sig)
if (killself)
sig_send (myself, sig);
}
-
+
void
tty_min::set_ctty (int ttynum, int flags)
{
@@ -226,11 +225,11 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
if (tc->ti.c_lflag & ISIG)
{
int sig;
- if (c == tc->ti.c_cc[VINTR])
+ if (CCEQ(tc->ti.c_cc[VINTR], c))
sig = SIGINT;
- else if (c == tc->ti.c_cc[VQUIT])
+ else if (CCEQ(tc->ti.c_cc[VQUIT], c))
sig = SIGQUIT;
- else if (c == tc->ti.c_cc[VSUSP])
+ else if (CCEQ(tc->ti.c_cc[VSUSP], c))
sig = SIGTSTP;
else
goto not_a_sig;
@@ -245,7 +244,7 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
not_a_sig:
if (tc->ti.c_iflag & IXON)
{
- if (c == tc->ti.c_cc[VSTOP])
+ if (CCEQ(tc->ti.c_cc[VSTOP], c))
{
if (!tc->output_stopped)
{
@@ -254,7 +253,7 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
}
continue;
}
- else if (c == tc->ti.c_cc[VSTART])
+ else if (CCEQ(tc->ti.c_cc[VSTART], c))
{
restart_output:
tc->output_stopped = 0;
@@ -264,20 +263,20 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
else if ((tc->ti.c_iflag & IXANY) && tc->output_stopped)
goto restart_output;
}
- if (tc->ti.c_lflag & IEXTEN && c == tc->ti.c_cc[VDISCARD])
+ if (iscanon && tc->ti.c_lflag & IEXTEN && CCEQ(tc->ti.c_cc[VDISCARD], c))
{
tc->ti.c_lflag ^= FLUSHO;
continue;
}
if (!iscanon)
/* nothing */;
- else if (c == tc->ti.c_cc[VERASE])
+ else if (CCEQ(tc->ti.c_cc[VERASE], c))
{
if (eat_readahead (1))
echo_erase ();
continue;
}
- else if (c == tc->ti.c_cc[VWERASE])
+ else if (CCEQ(tc->ti.c_cc[VWERASE], c))
{
int ch;
do
@@ -288,7 +287,7 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
while ((ch = peek_readahead (1)) >= 0 && !isspace (ch));
continue;
}
- else if (c == tc->ti.c_cc[VKILL])
+ else if (CCEQ(tc->ti.c_cc[VKILL], c))
{
int nchars = eat_readahead (-1);
if (tc->ti.c_lflag & ECHO)
@@ -296,7 +295,7 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
echo_erase (1);
continue;
}
- else if (c == tc->ti.c_cc[VREPRINT])
+ else if (CCEQ(tc->ti.c_cc[VREPRINT], c))
{
if (tc->ti.c_lflag & ECHO)
{
@@ -305,14 +304,14 @@ fhandler_termios::line_edit (const char *rptr, int nread, int always_accept)
}
continue;
}
- else if (c == tc->ti.c_cc[VEOF])
+ else if (CCEQ(tc->ti.c_cc[VEOF], c))
{
termios_printf ("EOF");
input_done = 1;
continue;
}
- else if (c == tc->ti.c_cc[VEOL] ||
- c == tc->ti.c_cc[VEOL2] ||
+ else if (CCEQ(tc->ti.c_cc[VEOL], c) ||
+ CCEQ(tc->ti.c_cc[VEOL2], c) ||
c == '\n')
{
set_input_done (1);
@@ -344,3 +343,10 @@ fhandler_termios::fixup_after_fork (HANDLE parent)
this->fhandler_base::fixup_after_fork (parent);
fork_fixup (parent, get_output_handle (), "output_handle");
}
+
+__off64_t
+fhandler_termios::lseek (__off64_t, int)
+{
+ set_errno (ESPIPE);
+ return -1;
+}
diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc
index 648135012..758d6eaec 100644
--- a/winsup/cygwin/fhandler_tty.cc
+++ b/winsup/cygwin/fhandler_tty.cc
@@ -1,6 +1,6 @@
/* fhandler_tty.cc
- Copyright 1997, 1998, 2000, 2001 Red Hat, Inc.
+ Copyright 1997, 1998, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -10,7 +10,6 @@ details. */
#include "winsup.h"
#include <stdio.h>
-#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
@@ -21,7 +20,6 @@ details. */
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
-#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
@@ -456,7 +454,7 @@ fhandler_tty_slave::open (path_conv *, int flags, mode_t)
attach_tty (ttynum);
tc->set_ctty (ttynum, flags);
- set_flags (flags);
+ set_flags (flags & ~O_TEXT, O_BINARY);
/* Create synchronisation events */
char buf[40];
@@ -521,33 +519,33 @@ fhandler_tty_slave::open (path_conv *, int flags, mode_t)
termios_printf ("cannot dup handles via server. using old method.");
HANDLE tty_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE,
- get_ttyp ()->master_pid);
+ get_ttyp ()->master_pid);
termios_printf ("tty own handle %p",tty_owner);
if (tty_owner == NULL)
- {
- termios_printf ("can't open tty (%d) handle process %d",
- ttynum, get_ttyp ()->master_pid);
- __seterrno ();
- return 0;
- }
-
- if (!DuplicateHandle (tty_owner, get_ttyp ()->from_master,
- hMainProc, &from_master_local, 0, TRUE,
+ {
+ termios_printf ("can't open tty (%d) handle process %d",
+ ttynum, get_ttyp ()->master_pid);
+ __seterrno ();
+ return 0;
+ }
+
+ if (!DuplicateHandle (tty_owner, get_ttyp ()->from_master,
+ hMainProc, &from_master_local, 0, TRUE,
DUPLICATE_SAME_ACCESS))
- {
- termios_printf ("can't duplicate input, %E");
- __seterrno ();
- return 0;
- }
+ {
+ termios_printf ("can't duplicate input, %E");
+ __seterrno ();
+ return 0;
+ }
- if (!DuplicateHandle (tty_owner, get_ttyp ()->to_master,
+ if (!DuplicateHandle (tty_owner, get_ttyp ()->to_master,
hMainProc, &to_master_local, 0, TRUE,
DUPLICATE_SAME_ACCESS))
- {
- termios_printf ("can't duplicate output, %E");
- __seterrno ();
- return 0;
- }
+ {
+ termios_printf ("can't duplicate output, %E");
+ __seterrno ();
+ return 0;
+ }
CloseHandle (tty_owner);
}
@@ -569,12 +567,12 @@ fhandler_tty_slave::open (path_conv *, int flags, mode_t)
int
fhandler_tty_slave::cygserver_attach_tty (LPHANDLE from_master_ptr,
- LPHANDLE to_master_ptr)
+ LPHANDLE to_master_ptr)
{
if (!from_master_ptr || !to_master_ptr)
return 0;
- client_request_attach_tty *request =
+ client_request_attach_tty *request =
new client_request_attach_tty ((DWORD) GetCurrentProcessId (),
(DWORD) get_ttyp ()->master_pid,
(HANDLE) get_ttyp ()->from_master,
@@ -689,7 +687,9 @@ fhandler_tty_slave::read (void *ptr, size_t len)
if (!(get_ttyp ()->ti.c_lflag & ICANON))
{
- vmin = min (INP_BUFFER_SIZE, get_ttyp ()->ti.c_cc[VMIN]);
+ vmin = get_ttyp ()->ti.c_cc[VMIN];
+ if (vmin > INP_BUFFER_SIZE)
+ vmin = INP_BUFFER_SIZE;
vtime = get_ttyp ()->ti.c_cc[VTIME];
if (vmin < 0) vmin = 0;
if (vtime < 0) vtime = 0;
@@ -1006,7 +1006,7 @@ fhandler_pty_master::open (path_conv *, int flags, mode_t)
cygwin_shared->tty[ttynum]->common_init (this);
inuse = get_ttyp ()->create_inuse (TTY_MASTER_ALIVE);
- set_flags (flags);
+ set_flags (flags & ~O_TEXT, O_BINARY);
set_open_status ();
termios_printf ("opened pty master tty%d<%p>", ttynum, this);
diff --git a/winsup/cygwin/fhandler_windows.cc b/winsup/cygwin/fhandler_windows.cc
index 861ddefa1..591f2c704 100644
--- a/winsup/cygwin/fhandler_windows.cc
+++ b/winsup/cygwin/fhandler_windows.cc
@@ -1,6 +1,6 @@
/* fhandler_windows.cc: code to access windows message queues.
- Copyright 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
Written by Sergey S. Okhapkin (sos@prospect.com.ru).
Feedback and testing by Andy Piper (andyp@parallax.co.uk).
@@ -54,7 +54,7 @@ fhandler_windows::fhandler_windows ()
int
fhandler_windows::open (path_conv *, int flags, mode_t)
{
- set_flags (flags);
+ set_flags (flags & ~O_TEXT, O_BINARY);
set_close_on_exec_flag (1);
set_open_status ();
return 1;
diff --git a/winsup/cygwin/fhandler_zero.cc b/winsup/cygwin/fhandler_zero.cc
index 50b34abab..ff8271344 100644
--- a/winsup/cygwin/fhandler_zero.cc
+++ b/winsup/cygwin/fhandler_zero.cc
@@ -23,7 +23,7 @@ fhandler_dev_zero::fhandler_dev_zero ()
int
fhandler_dev_zero::open (path_conv *, int flags, mode_t)
{
- set_flags (flags);
+ set_flags (flags & ~O_TEXT, O_BINARY);
set_open_status ();
return 1;
}
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index f7133df6b..ff464f038 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -1,6 +1,6 @@
/* fork.cc
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -12,7 +12,6 @@ details. */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
-#include <fcntl.h>
#include <stdarg.h>
#include <errno.h>
#include "security.h"
@@ -20,7 +19,6 @@ details. */
#include "path.h"
#include "dtable.h"
#include "cygerrno.h"
-#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
@@ -284,6 +282,9 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
MALLOC_CHECK;
+ if (fixup_mmaps_after_fork (hParent))
+ api_fatal ("recreate_mmaps_after_fork_failed");
+
/* If we haven't dynamically loaded any dlls, just signal
the parent. Otherwise, load all the dlls, tell the parent
that we're done, and wait for the parent to fill in the.
@@ -300,9 +301,6 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls)
(void) ForceCloseHandle (child_proc_info->subproc_ready);
(void) ForceCloseHandle (child_proc_info->forker_finished);
- if (fixup_mmaps_after_fork ())
- api_fatal ("recreate_mmaps_after_fork_failed");
-
if (fixup_shms_after_fork ())
api_fatal ("recreate_shm areas after fork failed");
@@ -466,6 +464,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
#endif
char sa_buf[1024];
+ PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf);
syscall_printf ("CreateProcess (%s, %s, 0, 0, 1, %x, 0, 0, %p, %p)",
myself->progname, myself->progname, c_flags, &si, &pi);
__malloc_lock (_reent_clib ());
@@ -473,8 +472,8 @@ fork_parent (HANDLE& hParent, dll *&first_dll,
newheap = cygheap_setup_for_child (&ch,cygheap->fdtab.need_fixup_before ());
rc = CreateProcess (myself->progname, /* image to run */
myself->progname, /* what we send in arg0 */
- sec_user_nih (sa_buf),
- sec_user_nih (sa_buf),
+ sec_attribs,
+ sec_attribs,
TRUE, /* inherit handles from parent */
c_flags,
NULL, /* environment filled in later */
diff --git a/winsup/cygwin/glob.c b/winsup/cygwin/glob.c
index cdb30a855..971b3092e 100644
--- a/winsup/cygwin/glob.c
+++ b/winsup/cygwin/glob.c
@@ -807,17 +807,51 @@ g_opendir(str, pglob)
return(opendir(buf));
}
+static void
+stat32_to_STAT (struct __stat32 *src, struct STAT *dst)
+{
+ dst->st_dev = src->st_dev;
+ dst->st_ino = src->st_ino;
+ dst->st_mode = src->st_mode;
+ dst->st_nlink = src->st_nlink;
+ dst->st_uid = src->st_uid;
+ dst->st_gid = src->st_gid;
+ dst->st_rdev = src->st_rdev;
+ dst->st_size = src->st_size;
+ dst->st_atim = src->st_atim;
+ dst->st_mtim = src->st_mtim;
+ dst->st_ctim = src->st_ctim;
+ dst->st_blksize = src->st_blksize;
+ dst->st_blocks = src->st_blocks;
+}
+
static int
g_lstat(fn, sb, pglob)
register Char *fn;
struct STAT *sb;
glob_t *pglob;
{
+ /* FIXME: This only works as long as the application uses the old
+ struct stat with 32 bit off_t types!!!
+
+ As soon as we switch over to 64 bit, we have to decide by
+ the applications API minor version number, whether to use
+ a pointer to a __stat64 or a _stat32 struct to the
+ pglob->gl_lstat function. */
+#ifdef __CYGWIN_USE_BIG_TYPES__
+#error FIXME check apps API minor and use correct struct stat
+#endif
char buf[MAXPATHLEN];
g_Ctoc(fn, buf);
- if (pglob->gl_flags & GLOB_ALTDIRFUNC)
- return((*pglob->gl_lstat)(buf, sb));
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC) {
+ struct __stat32 lsb;
+ int ret;
+
+ if (!(ret = (*pglob->gl_lstat)(buf, &lsb)))
+ stat32_to_STAT (&lsb, sb);
+ return ret;
+ }
#ifdef __INSIDE_CYGWIN__
return(lstat64(buf, sb));
#else
@@ -831,11 +865,27 @@ g_stat(fn, sb, pglob)
struct STAT *sb;
glob_t *pglob;
{
+ /* FIXME: This only works as long as the application uses the old
+ struct stat with 32 bit off_t types!!!
+
+ As soon as we switch over to 64 bit, we have to decide by
+ the applications API minor version number, whether to use
+ a pointer to a __stat64 or a _stat32 struct to the
+ pglob->gl_stat function. */
+#ifdef __CYGWIN_USE_BIG_TYPES__
+#error FIXME check apps API minor and use correct struct stat
+#endif
char buf[MAXPATHLEN];
g_Ctoc(fn, buf);
- if (pglob->gl_flags & GLOB_ALTDIRFUNC)
- return((*pglob->gl_stat)(buf, sb));
+ if (pglob->gl_flags & GLOB_ALTDIRFUNC) {
+ struct __stat32 lsb;
+ int ret;
+
+ if (!(ret = (*pglob->gl_stat)(buf, &lsb)))
+ stat32_to_STAT (&lsb, sb);
+ return ret;
+ }
#ifdef __INSIDE_CYGWIN__
return(stat64(buf, sb));
#else
diff --git a/winsup/cygwin/gmon.c b/winsup/cygwin/gmon.c
index 95a7f430e..048ef0df1 100644
--- a/winsup/cygwin/gmon.c
+++ b/winsup/cygwin/gmon.c
@@ -44,6 +44,7 @@ static char rcsid[] = "$OpenBSD: gmon.c,v 1.8 1997/07/23 21:11:27 kstailey Exp $
#include <gmon.h>
#include <profil.h>
+#include <windows.h>
/* XXX needed? */
//extern char *minbrk __asm ("minbrk");
@@ -61,7 +62,11 @@ void moncontrol __P((int));
static void *
fake_sbrk(int size)
{
- return malloc(size);
+ void *rv = malloc(size);
+ if (rv)
+ return rv;
+ else
+ return (void *) -1;
}
void
diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc
index d88deb994..54725c227 100644
--- a/winsup/cygwin/grp.cc
+++ b/winsup/cygwin/grp.cc
@@ -17,8 +17,6 @@ details. */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "security.h"
#include "fhandler.h"
@@ -31,8 +29,7 @@ details. */
/* Read /etc/group only once for better performance. This is done
on the first call that needs information from it. */
-static const char *etc_group NO_COPY = "/etc/group";
-static struct __group16 *group_buf; /* group contents in memory */
+static struct __group32 *group_buf; /* group contents in memory */
static int curr_lines;
static int max_lines;
@@ -46,22 +43,19 @@ static int grp_pos = 0;
static pwdgrp_check group_state;
static int
-parse_grp (struct __group16 &grp, const char *line)
+parse_grp (struct __group32 &grp, char *line)
{
int len = strlen(line);
- char *newline = (char *) malloc (len + 1);
- (void) memcpy (newline, line, len + 1);
+ if (line[--len] == '\r')
+ line[len] = '\0';
- if (newline[--len] == '\n')
- newline[len] = '\0';
-
- char *dp = strchr (newline, ':');
+ char *dp = strchr (line, ':');
if (!dp)
return 0;
*dp++ = '\0';
- grp.gr_name = newline;
+ grp.gr_name = line;
grp.gr_passwd = dp;
dp = strchr (grp.gr_passwd, ':');
@@ -106,12 +100,12 @@ parse_grp (struct __group16 &grp, const char *line)
/* Read one line from /etc/group into the group cache */
static void
-add_grp_line (const char *line)
+add_grp_line (char *line)
{
if (curr_lines == max_lines)
{
max_lines += 10;
- group_buf = (struct __group16 *) realloc (group_buf, max_lines * sizeof (struct __group16));
+ group_buf = (struct __group32 *) realloc (group_buf, max_lines * sizeof (struct __group32));
}
if (parse_grp (group_buf[curr_lines], line))
curr_lines++;
@@ -145,11 +139,7 @@ pthread_mutex_t NO_COPY group_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INIT
void
read_etc_group ()
{
- char linebuf [200];
- char group_name [UNLEN + 1];
- DWORD group_name_len = UNLEN + 1;
-
- strncpy (group_name, "Administrators", sizeof (group_name));
+ static pwdgrp_read gr;
group_lock here (cygwin_finished_initializing);
@@ -160,62 +150,98 @@ read_etc_group ()
if (group_state != initializing)
{
group_state = initializing;
- if (max_lines) /* When rereading, free allocated memory first. */
+ if (gr.open ("/etc/group"))
{
- for (int i = 0; i < curr_lines; ++i)
- {
- free (group_buf[i].gr_name);
- free (group_buf[i].gr_mem);
- }
- curr_lines = 0;
- }
+ char *line;
+ while ((line = gr.gets ()) != NULL)
+ if (strlen (line))
+ add_grp_line (line);
- FILE *f = fopen (etc_group, "rt");
-
- if (f)
- {
- while (fgets (linebuf, sizeof (linebuf), f) != NULL)
- {
- if (strlen (linebuf))
- add_grp_line (linebuf);
- }
-
- group_state.set_last_modified (f);
- fclose (f);
+ group_state.set_last_modified (gr.get_fhandle(), gr.get_fname ());
group_state = loaded;
+ gr.close ();
+ debug_printf ("Read /etc/group, %d lines", curr_lines);
}
else /* /etc/group doesn't exist -- create default one in memory */
{
+ char group_name [UNLEN + 1];
+ DWORD group_name_len = UNLEN + 1;
char domain_name [INTERNET_MAX_HOST_NAME_LENGTH + 1];
DWORD domain_name_len = INTERNET_MAX_HOST_NAME_LENGTH + 1;
SID_NAME_USE acType;
- debug_printf ("Emulating /etc/group");
- if (! LookupAccountSidA (NULL ,
- well_known_admins_sid,
- group_name,
- &group_name_len,
- domain_name,
- &domain_name_len,
- &acType))
+ static char linebuf [200];
+
+ if (wincap.has_security ())
{
- strcpy (group_name, "unknown");
- debug_printf ("Failed to get local admins group name. %E");
+ HANDLE ptok;
+ cygsid tg;
+ DWORD siz;
+
+ if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok))
+ {
+ if (GetTokenInformation (ptok, TokenPrimaryGroup, &tg,
+ sizeof tg, &siz)
+ && LookupAccountSidA (NULL, tg, group_name,
+ &group_name_len, domain_name,
+ &domain_name_len, &acType))
+ {
+ char strbuf[100];
+ snprintf (linebuf, sizeof (linebuf), "%s:%s:%lu:",
+ group_name,
+ tg.string (strbuf),
+ *GetSidSubAuthority(tg,
+ *GetSidSubAuthorityCount(tg) - 1));
+ debug_printf ("Emulating /etc/group: %s", linebuf);
+ add_grp_line (linebuf);
+ group_state = emulated;
+ }
+ CloseHandle (ptok);
+ }
+ }
+ if (group_state != emulated)
+ {
+ strncpy (group_name, "Administrators", sizeof (group_name));
+ if (!LookupAccountSidA (NULL, well_known_admins_sid, group_name,
+ &group_name_len, domain_name,
+ &domain_name_len, &acType))
+ {
+ strcpy (group_name, "unknown");
+ debug_printf ("Failed to get local admins group name. %E");
+ }
+ snprintf (linebuf, sizeof (linebuf), "%s::%u:", group_name,
+ (unsigned) DEFAULT_GID);
+ debug_printf ("Emulating /etc/group: %s", linebuf);
+ add_grp_line (linebuf);
+ group_state = emulated;
}
-
- snprintf (linebuf, sizeof (linebuf), "%s::%u:\n", group_name, (unsigned) DEFAULT_GID);
- add_grp_line (linebuf);
- group_state = emulated;
}
}
return;
}
-extern "C"
+static
struct __group16 *
-getgrgid (__gid16_t gid)
+grp32togrp16 (struct __group16 *gp16, struct __group32 *gp32)
{
- struct __group16 * default_grp = NULL;
+ if (!gp16 || !gp32)
+ return NULL;
+
+ /* Copying the pointers is actually unnecessary. Just having the correct
+ return type is important. */
+ gp16->gr_name = gp32->gr_name;
+ gp16->gr_passwd = gp32->gr_passwd;
+ gp16->gr_gid = (__gid16_t) gp32->gr_gid; /* Not loss-free */
+ gp16->gr_mem = gp32->gr_mem;
+
+ return gp16;
+}
+
+extern "C"
+struct __group32 *
+getgrgid32 (__gid32_t gid)
+{
+ struct __group32 * default_grp = NULL;
if (group_state <= initializing)
read_etc_group();
@@ -232,7 +258,16 @@ getgrgid (__gid16_t gid)
extern "C"
struct __group16 *
-getgrnam (const char *name)
+getgrgid (__gid16_t gid)
+{
+ static struct __group16 g16;
+
+ return grp32togrp16 (&g16, getgrgid32 ((__gid32_t) gid));
+}
+
+extern "C"
+struct __group32 *
+getgrnam32 (const char *name)
{
if (group_state <= initializing)
read_etc_group();
@@ -246,6 +281,15 @@ getgrnam (const char *name)
}
extern "C"
+struct __group16 *
+getgrnam (const char *name)
+{
+ static struct __group16 g16;
+
+ return grp32togrp16 (&g16, getgrnam32 (name));
+}
+
+extern "C"
void
endgrent()
{
@@ -253,8 +297,8 @@ endgrent()
}
extern "C"
-struct __group16 *
-getgrent()
+struct __group32 *
+getgrent32()
{
if (group_state <= initializing)
read_etc_group();
@@ -266,6 +310,15 @@ getgrent()
}
extern "C"
+struct __group16 *
+getgrent()
+{
+ static struct __group16 g16;
+
+ return grp32togrp16 (&g16, getgrent32 ());
+}
+
+extern "C"
void
setgrent ()
{
@@ -273,7 +326,7 @@ setgrent ()
}
/* Internal function. ONLY USE THIS INTERNALLY, NEVER `getgrent'!!! */
-struct __group16 *
+struct __group32 *
internal_getgrent (int pos)
{
if (group_state <= initializing)
@@ -285,12 +338,13 @@ internal_getgrent (int pos)
}
int
-getgroups (int gidsetsize, __gid16_t *grouplist, __gid16_t gid, const char *username)
+getgroups32 (int gidsetsize, __gid32_t *grouplist, __gid32_t gid,
+ const char *username)
{
HANDLE hToken = NULL;
DWORD size;
int cnt = 0;
- struct __group16 *gr;
+ struct __group32 *gr;
if (group_state <= initializing)
read_etc_group();
@@ -360,9 +414,41 @@ error:
extern "C"
int
+getgroups32 (int gidsetsize, __gid32_t *grouplist)
+{
+ return getgroups32 (gidsetsize, grouplist, myself->gid,
+ cygheap->user.name ());
+}
+
+extern "C"
+int
getgroups (int gidsetsize, __gid16_t *grouplist)
{
- return getgroups (gidsetsize, grouplist, myself->gid, cygheap->user.name ());
+ __gid32_t *grouplist32 = NULL;
+
+ if (gidsetsize < 0)
+ {
+ set_errno (EINVAL);
+ return -1;
+ }
+ if (gidsetsize > 0 && grouplist)
+ grouplist32 = (__gid32_t *) alloca (gidsetsize * sizeof (__gid32_t));
+
+ int ret = getgroups32 (gidsetsize, grouplist32, myself->gid,
+ cygheap->user.name ());
+
+ if (gidsetsize > 0 && grouplist)
+ for (int i = 0; i < ret; ++ i)
+ grouplist[i] = grouplist32[i];
+
+ return ret;
+}
+
+extern "C"
+int
+initgroups32 (const char *, __gid32_t)
+{
+ return 0;
}
extern "C"
diff --git a/winsup/cygwin/heap.cc b/winsup/cygwin/heap.cc
index 9a3e2b87a..5c301cc16 100644
--- a/winsup/cygwin/heap.cc
+++ b/winsup/cygwin/heap.cc
@@ -1,6 +1,6 @@
/* heap.cc: Cygwin heap manager.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -11,7 +11,6 @@ details. */
#include "winsup.h"
#include <errno.h>
#include "cygerrno.h"
-#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "heap.h"
diff --git a/winsup/cygwin/hires.h b/winsup/cygwin/hires.h
index c341aa287..611b2df0d 100644
--- a/winsup/cygwin/hires.h
+++ b/winsup/cygwin/hires.h
@@ -11,14 +11,37 @@ details. */
#ifndef __HIRES_H__
#define __HIRES_H__
-class hires
+#include <mmsystem.h>
+
+class hires_base
{
+ protected:
int inited;
+ virtual void prime () {}
+ public:
+ virtual LONGLONG usecs (bool justdelta) {return 0LL;}
+ virtual ~hires_base () {}
+};
+
+class hires_us : hires_base
+{
LARGE_INTEGER primed_ft;
LARGE_INTEGER primed_pc;
double freq;
- void prime () __attribute__ ((regparm (1)));
+ void prime ();
+ public:
+ LONGLONG usecs (bool justdelta);
+};
+
+class hires_ms : hires_base
+{
+ DWORD initime_ms;
+ LARGE_INTEGER initime_us;
+ UINT minperiod;
+ void prime ();
public:
- LONGLONG usecs (bool justdelta) __attribute__ ((regparm (2)));
+ LONGLONG usecs (bool justdelta);
+ ~hires_ms ();
};
+
#endif /*__HIRES_H__*/
diff --git a/winsup/cygwin/how-fhandlers-work.txt b/winsup/cygwin/how-fhandlers-work.txt
index 5e810a780..cef46fedc 100644
--- a/winsup/cygwin/how-fhandlers-work.txt
+++ b/winsup/cygwin/how-fhandlers-work.txt
@@ -63,3 +63,13 @@ cannot.
For an example step-by-step to create a new fhandler, see
../doc/fhandler-tut.txt
+
+Note: In most case, it is safe to assume that using new/delete (or
+malloc/free) in an fhandler is dangerous and to be avoided. The reason
+for this is that memory allocated to fhandlers is copied between execed
+processes in the cygwin heap. Memory allocated in new/delete is only
+copied to forked processes. So use cmalloc/cfree.
+
+Obviously it is possible to use new/delete in some situations but if you're
+seeing strange core dumps with usages like cat < /my/newfhandler then the
+above may well be the culprit.
diff --git a/winsup/cygwin/include/cygwin/cygserver.h b/winsup/cygwin/include/cygwin/cygserver.h
index 3751863f5..c7a04929f 100755
--- a/winsup/cygwin/include/cygwin/cygserver.h
+++ b/winsup/cygwin/include/cygwin/cygserver.h
@@ -1,6 +1,6 @@
/* cygserver.h
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Egor Duda <deo@logos-m.ru>
diff --git a/winsup/cygwin/include/cygwin/cygserver_process.h b/winsup/cygwin/include/cygwin/cygserver_process.h
index 4a49212b2..c8ff40b09 100755
--- a/winsup/cygwin/include/cygwin/cygserver_process.h
+++ b/winsup/cygwin/include/cygwin/cygserver_process.h
@@ -1,6 +1,6 @@
/* cygserver_process.h
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Robert Collins <rbtcollins@hotmail.com>
diff --git a/winsup/cygwin/include/cygwin/cygserver_transport.h b/winsup/cygwin/include/cygwin/cygserver_transport.h
index 1ed16edf7..493c9b530 100755
--- a/winsup/cygwin/include/cygwin/cygserver_transport.h
+++ b/winsup/cygwin/include/cygwin/cygserver_transport.h
@@ -1,6 +1,6 @@
/* cygserver.cc
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Robert Collins <rbtcollins@hotmail.com>
diff --git a/winsup/cygwin/include/cygwin/cygserver_transport_pipes.h b/winsup/cygwin/include/cygwin/cygserver_transport_pipes.h
index 9afeebfef..9ebeee2a4 100755
--- a/winsup/cygwin/include/cygwin/cygserver_transport_pipes.h
+++ b/winsup/cygwin/include/cygwin/cygserver_transport_pipes.h
@@ -1,6 +1,6 @@
/* cygserver.cc
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Robert Collins <rbtcollins@hotmail.com>
diff --git a/winsup/cygwin/include/cygwin/cygserver_transport_sockets.h b/winsup/cygwin/include/cygwin/cygserver_transport_sockets.h
index 94dc43e38..9881ca2bb 100755
--- a/winsup/cygwin/include/cygwin/cygserver_transport_sockets.h
+++ b/winsup/cygwin/include/cygwin/cygserver_transport_sockets.h
@@ -1,6 +1,6 @@
/* cygserver.cc
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Robert Collins <rbtcollins@hotmail.com>
diff --git a/winsup/cygwin/include/cygwin/grp.h b/winsup/cygwin/include/cygwin/grp.h
index 3a58e2058..7dcae637d 100644
--- a/winsup/cygwin/include/cygwin/grp.h
+++ b/winsup/cygwin/include/cygwin/grp.h
@@ -35,8 +35,10 @@ struct __group32
char **gr_mem;
};
-struct __group16 * getgrgid (__gid16_t gid);
-struct __group16 * getgrnam (const char *name);
+struct __group32 * getgrgid32 (__gid32_t gid);
+struct __group32 * getgrnam32 (const char *name);
+__gid32_t getgid32 ();
+__gid32_t getegid32 ();
#endif
#ifdef __cplusplus
diff --git a/winsup/cygwin/include/cygwin/ip.h b/winsup/cygwin/include/cygwin/ip.h
deleted file mode 100644
index e4f23c753..000000000
--- a/winsup/cygwin/include/cygwin/ip.h
+++ /dev/null
@@ -1 +0,0 @@
-/* ip.h */
diff --git a/winsup/cygwin/include/cygwin/socket.h b/winsup/cygwin/include/cygwin/socket.h
index da747fd3d..b66c38f73 100644
--- a/winsup/cygwin/include/cygwin/socket.h
+++ b/winsup/cygwin/include/cygwin/socket.h
@@ -123,9 +123,11 @@ struct msghdr
#define SOL_UDP 17
/* IP options */
+#ifndef IPTOS_LOWDELAY
#define IPTOS_LOWDELAY 0x10
#define IPTOS_THROUGHPUT 0x08
#define IPTOS_RELIABILITY 0x04
+#endif
/* These need to appear somewhere around here */
#define IP_DEFAULT_MULTICAST_TTL 1
@@ -148,8 +150,10 @@ struct msghdr
#define IPX_TYPE 1
/* TCP options - this way around because someone left a set in the c library includes */
+#ifndef TCP_NODELAY
#define TCP_NODELAY 0x0001
#define TCP_MAXSEG 2
+#endif
/* The various priorities. */
#define SOPRI_INTERACTIVE 0
diff --git a/winsup/cygwin/include/cygwin/stat.h b/winsup/cygwin/include/cygwin/stat.h
index 90abc3999..5772a3754 100644
--- a/winsup/cygwin/include/cygwin/stat.h
+++ b/winsup/cygwin/include/cygwin/stat.h
@@ -19,20 +19,17 @@ extern "C" {
#ifdef __INSIDE_CYGWIN__
struct __stat32
{
- dev_t st_dev;
+ __dev16_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
__uid16_t st_uid;
__gid16_t st_gid;
- dev_t st_rdev;
+ __dev16_t st_rdev;
__off32_t st_size;
- time_t st_atime;
- long st_spare1;
- time_t st_mtime;
- long st_spare2;
- time_t st_ctime;
- long st_spare3;
+ timestruc_t st_atim;
+ timestruc_t st_mtim;
+ timestruc_t st_ctim;
blksize_t st_blksize;
__blkcnt32_t st_blocks;
long st_spare4[2];
@@ -40,20 +37,17 @@ struct __stat32
struct __stat64
{
- dev_t st_dev;
+ __dev32_t st_dev;
ino_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
__uid32_t st_uid;
__gid32_t st_gid;
- dev_t st_rdev;
+ __dev32_t st_rdev;
__off64_t st_size;
- time_t st_atime;
- long st_spare1;
- time_t st_mtime;
- long st_spare2;
- time_t st_ctime;
- long st_spare3;
+ timestruc_t st_atim;
+ timestruc_t st_mtim;
+ timestruc_t st_ctim;
blksize_t st_blksize;
__blkcnt64_t st_blocks;
long st_spare4[2];
@@ -75,17 +69,18 @@ struct stat
gid_t st_gid;
dev_t st_rdev;
off_t st_size;
- time_t st_atime;
- long st_spare1;
- time_t st_mtime;
- long st_spare2;
- time_t st_ctime;
- long st_spare3;
+ timestruc_t st_atim;
+ timestruc_t st_mtim;
+ timestruc_t st_ctim;
blksize_t st_blksize;
blkcnt_t st_blocks;
long st_spare4[2];
};
+#define st_atime st_atim.tv_sec
+#define st_mtime st_mtim.tv_sec
+#define st_ctime st_ctim.tv_sec
+
#ifdef __cplusplus
}
#endif
diff --git a/winsup/cygwin/include/cygwin/types.h b/winsup/cygwin/include/cygwin/types.h
index 296a11a9c..69bfa2056 100644
--- a/winsup/cygwin/include/cygwin/types.h
+++ b/winsup/cygwin/include/cygwin/types.h
@@ -17,6 +17,10 @@ extern "C"
#ifndef _CYGWIN_TYPES_H
#define _CYGWIN_TYPES_H
+#include <sys/sysmacros.h>
+
+typedef struct timespec timespec_t, timestruc_t;
+
typedef long __off32_t;
typedef long long __off64_t;
#ifdef __CYGWIN_USE_BIG_TYPES__
@@ -25,6 +29,14 @@ typedef __off64_t off_t;
typedef __off32_t off_t;
#endif
+typedef short __dev16_t;
+typedef unsigned long __dev32_t;
+#ifdef __CYGWIN_USE_BIG_TYPES__
+typedef __dev32_t dev_t;
+#else
+typedef __dev16_t dev_t;
+#endif
+
typedef long blksize_t;
typedef long __blkcnt32_t;
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 5bf5663dc..6ab596e09 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -149,12 +149,14 @@ details. */
49: Export setutent, endutent, utmpname, getutent, getutid, getutline.
50: Export fnmatch.
51: Export recvmsg, sendmsg.
+ 52: Export strptime
+ 53: Export strlcat, strlcpy.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 51
+#define CYGWIN_VERSION_API_MINOR 53
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible
diff --git a/winsup/cygwin/include/glob.h b/winsup/cygwin/include/glob.h
index e6e648f11..6a393f004 100644
--- a/winsup/cygwin/include/glob.h
+++ b/winsup/cygwin/include/glob.h
@@ -66,9 +66,14 @@ typedef struct {
int (*gl_lstat) __P((const char *, struct stat12 *));
int (*gl_stat) __P((const char *, struct stat12 *));
#else
+#if defined (__INSIDE_CYGWIN__)
+ int (*gl_lstat) ();
+ int (*gl_stat) ();
+#else
int (*gl_lstat) __P((const char *, struct stat *));
int (*gl_stat) __P((const char *, struct stat *));
#endif
+#endif
} glob_t;
#define GLOB_APPEND 0x0001 /* Append to output from previous call. */
diff --git a/winsup/cygwin/include/netinet/ip.h b/winsup/cygwin/include/netinet/ip.h
index 33c59f87a..a8dac5b67 100644
--- a/winsup/cygwin/include/netinet/ip.h
+++ b/winsup/cygwin/include/netinet/ip.h
@@ -1,16 +1,199 @@
-/* netinet/ip.h
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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 University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)ip.h 8.2 (Berkeley) 6/1/94
+ * $FreeBSD: src/sys/netinet/ip.h,v 1.17 1999/12/22 19:13:20 shin Exp $
+ */
- Copyright 1998, 2001 Red Hat, Inc.
+#ifndef _NETINET_IP_H
+#define _NETINET_IP_H
-This file is part of Cygwin.
+/* Added by Wu Yongwei */
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
+#define BIG_ENDIAN 4321
+#endif
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
+/*
+ * Definitions for internet protocol version 4.
+ * Per RFC 791, September 1981.
+ */
+#define IPVERSION 4
-#ifndef _NETINET_IP_H
-#define _NETINET_IP_H
+/*
+ * Structure of an internet header, naked of options.
+ */
+struct ip {
+#ifdef _IP_VHL
+ u_char ip_vhl; /* version << 4 | header length >> 2 */
+#else
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int ip_hl:4, /* header length */
+ ip_v:4; /* version */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int ip_v:4, /* version */
+ ip_hl:4; /* header length */
+#endif
+#endif /* not _IP_VHL */
+ u_char ip_tos; /* type of service */
+ u_short ip_len; /* total length */
+ u_short ip_id; /* identification */
+ u_short ip_off; /* fragment offset field */
+#define IP_RF 0x8000 /* reserved fragment flag */
+#define IP_DF 0x4000 /* dont fragment flag */
+#define IP_MF 0x2000 /* more fragments flag */
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ u_char ip_ttl; /* time to live */
+ u_char ip_p; /* protocol */
+ u_short ip_sum; /* checksum */
+ struct in_addr ip_src,ip_dst; /* source and dest address */
+};
+
+#ifdef _IP_VHL
+#define IP_MAKE_VHL(v, hl) ((v) << 4 | (hl))
+#define IP_VHL_HL(vhl) ((vhl) & 0x0f)
+#define IP_VHL_V(vhl) ((vhl) >> 4)
+#define IP_VHL_BORING 0x45
+#endif
+
+#define IP_MAXPACKET 65535 /* maximum packet size */
+
+/*
+ * Definitions for IP type of service (ip_tos)
+ */
+#ifndef IPTOS_LOWDELAY
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_RELIABILITY 0x04
+#endif
+#define IPTOS_MINCOST 0x02
+/* ECN bits proposed by Sally Floyd */
+#define IPTOS_CE 0x01 /* congestion experienced */
+#define IPTOS_ECT 0x02 /* ECN-capable transport */
+
+
+/*
+ * Definitions for IP precedence (also in ip_tos) (hopefully unused)
+ */
+#define IPTOS_PREC_NETCONTROL 0xe0
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+#define IPTOS_PREC_CRITIC_ECP 0xa0
+#define IPTOS_PREC_FLASHOVERRIDE 0x80
+#define IPTOS_PREC_FLASH 0x60
+#define IPTOS_PREC_IMMEDIATE 0x40
+#define IPTOS_PREC_PRIORITY 0x20
+#define IPTOS_PREC_ROUTINE 0x00
+
+/*
+ * Definitions for options.
+ */
+#define IPOPT_COPIED(o) ((o)&0x80)
+#define IPOPT_CLASS(o) ((o)&0x60)
+#define IPOPT_NUMBER(o) ((o)&0x1f)
+
+#define IPOPT_CONTROL 0x00
+#define IPOPT_RESERVED1 0x20
+#define IPOPT_DEBMEAS 0x40
+#define IPOPT_RESERVED2 0x60
+
+#define IPOPT_EOL 0 /* end of option list */
+#define IPOPT_NOP 1 /* no operation */
+
+#define IPOPT_RR 7 /* record packet route */
+#define IPOPT_TS 68 /* timestamp */
+#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
+#define IPOPT_LSRR 131 /* loose source route */
+#define IPOPT_SATID 136 /* satnet id */
+#define IPOPT_SSRR 137 /* strict source route */
+#define IPOPT_RA 148 /* router alert */
+
+/*
+ * Offsets to fields in options other than EOL and NOP.
+ */
+#define IPOPT_OPTVAL 0 /* option ID */
+#define IPOPT_OLEN 1 /* option length */
+#define IPOPT_OFFSET 2 /* offset within option */
+#define IPOPT_MINOFF 4 /* min value of above */
+
+/*
+ * Time stamp option structure.
+ */
+struct ip_timestamp {
+ u_char ipt_code; /* IPOPT_TS */
+ u_char ipt_len; /* size of structure (variable) */
+ u_char ipt_ptr; /* index of current entry */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int ipt_flg:4, /* flags, see below */
+ ipt_oflw:4; /* overflow counter */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int ipt_oflw:4, /* overflow counter */
+ ipt_flg:4; /* flags, see below */
+#endif
+ union ipt_timestamp {
+ n_long ipt_time[1];
+ struct ipt_ta {
+ struct in_addr ipt_addr;
+ n_long ipt_time;
+ } ipt_ta[1];
+ } ipt_timestamp;
+};
+
+/* flag bits for ipt_flg */
+#define IPOPT_TS_TSONLY 0 /* timestamps only */
+#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
+#define IPOPT_TS_PRESPEC 3 /* specified modules only */
+
+/* bits for security (not byte swapped) */
+#define IPOPT_SECUR_UNCLASS 0x0000
+#define IPOPT_SECUR_CONFID 0xf135
+#define IPOPT_SECUR_EFTO 0x789a
+#define IPOPT_SECUR_MMMM 0xbc4d
+#define IPOPT_SECUR_RESTR 0xaf13
+#define IPOPT_SECUR_SECRET 0xd788
+#define IPOPT_SECUR_TOPSECRET 0x6bc5
+
+/*
+ * Internet implementation parameters.
+ */
+#define MAXTTL 255 /* maximum time to live (seconds) */
+#define IPDEFTTL 64 /* default ttl, from RFC 1340 */
+#define IPFRAGTTL 60 /* time to live for frags, slowhz */
+#define IPTTLDEC 1 /* subtracted when forwarding */
-#include <cygwin/ip.h>
+#define IP_MSS 576 /* default maximum segment size */
-#endif /* _NETINET_IP_H */
+#endif
diff --git a/winsup/cygwin/include/netinet/tcp.h b/winsup/cygwin/include/netinet/tcp.h
index eef9a6116..9fcee6c71 100644
--- a/winsup/cygwin/include/netinet/tcp.h
+++ b/winsup/cygwin/include/netinet/tcp.h
@@ -1,16 +1,144 @@
-/* netinet/tcp.h
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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 University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)tcp.h 8.1 (Berkeley) 6/10/93
+ * $FreeBSD: src/sys/netinet/tcp.h,v 1.13 2000/01/09 19:17:25 shin Exp $
+ */
- Copyright 2000, 2001 Red Hat, Inc.
+#ifndef _NETINET_TCP_H
+#define _NETINET_TCP_H
-This file is part of Cygwin.
+/* Added by Wu Yongwei */
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN 1234
+#define BIG_ENDIAN 4321
+#endif
+#ifndef BYTE_ORDER
+#define BYTE_ORDER LITTLE_ENDIAN
+#endif
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
+typedef u_int32_t tcp_seq;
+typedef u_int32_t tcp_cc; /* connection count per rfc1644 */
-#ifndef _NETINET_TCP_H
-#define _NETINET_TCP_H
+#define tcp6_seq tcp_seq /* for KAME src sync over BSD*'s */
+#define tcp6hdr tcphdr /* for KAME src sync over BSD*'s */
+
+/*
+ * TCP header.
+ * Per RFC 793, September, 1981.
+ */
+struct tcphdr {
+ u_short th_sport; /* source port */
+ u_short th_dport; /* destination port */
+ tcp_seq th_seq; /* sequence number */
+ tcp_seq th_ack; /* acknowledgement number */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ u_int th_x2:4, /* (unused) */
+ th_off:4; /* data offset */
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ u_int th_off:4, /* data offset */
+ th_x2:4; /* (unused) */
+#endif
+ u_char th_flags;
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG)
-/* Maybe add some definitions, someday */
+ u_short th_win; /* window */
+ u_short th_sum; /* checksum */
+ u_short th_urp; /* urgent pointer */
+};
+
+#define TCPOPT_EOL 0
+#define TCPOPT_NOP 1
+#define TCPOPT_MAXSEG 2
+#define TCPOLEN_MAXSEG 4
+#define TCPOPT_WINDOW 3
+#define TCPOLEN_WINDOW 3
+#define TCPOPT_SACK_PERMITTED 4 /* Experimental */
+#define TCPOLEN_SACK_PERMITTED 2
+#define TCPOPT_SACK 5 /* Experimental */
+#define TCPOPT_TIMESTAMP 8
+#define TCPOLEN_TIMESTAMP 10
+#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
+#define TCPOPT_TSTAMP_HDR \
+ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
+
+#define TCPOPT_CC 11 /* CC options: RFC-1644 */
+#define TCPOPT_CCNEW 12
+#define TCPOPT_CCECHO 13
+#define TCPOLEN_CC 6
+#define TCPOLEN_CC_APPA (TCPOLEN_CC+2)
+#define TCPOPT_CC_HDR(ccopt) \
+ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|(ccopt)<<8|TCPOLEN_CC)
+
+/*
+ * Default maximum segment size for TCP.
+ * With an IP MSS of 576, this is 536,
+ * but 512 is probably more convenient.
+ * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
+ */
+#define TCP_MSS 512
+
+/*
+ * Default maximum segment size for TCP6.
+ * With an IP6 MSS of 1280, this is 1220,
+ * but 1024 is probably more convenient. (xxx kazu in doubt)
+ * This should be defined as MIN(1024, IP6_MSS - sizeof (struct tcpip6hdr))
+ */
+#define TCP6_MSS 1024
+
+#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */
+#define TTCP_CLIENT_SND_WND 4096 /* dflt send window for T/TCP client */
+
+#define TCP_MAX_WINSHIFT 14 /* maximum window shift */
+
+#define TCP_MAXHLEN (0xf<<2) /* max length of header in bytes */
+#define TCP_MAXOLEN (TCP_MAXHLEN - sizeof(struct tcphdr))
+ /* max space left for options */
+
+/*
+ * User-settable options (used with setsockopt).
+ */
+#ifndef TCP_NODELAY
+#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
+#define TCP_MAXSEG 0x02 /* set maximum segment size */
+#endif
+#define TCP_NOPUSH 0x04 /* don't push last block of write */
+#define TCP_NOOPT 0x08 /* don't use TCP options */
#endif
diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h
index 102ba650c..acdde4fc3 100644
--- a/winsup/cygwin/include/pthread.h
+++ b/winsup/cygwin/include/pthread.h
@@ -103,10 +103,20 @@ void pthread_cleanup_push (void (*routine)(void*), void *arg);
void pthread_cleanup_pop (int execute);
*/
typedef void (*__cleanup_routine_type) (void *);
-
-#define pthread_cleanup_push(fn, arg) { __cleanup_routine_type __cleanup_routine=fn; \
-void *__cleanup_param=arg;
-#define pthread_cleanup_pop(execute) if (execute) __cleanup_routine(__cleanup_param); }
+typedef struct _pthread_cleanup_handler
+{
+ __cleanup_routine_type function;
+ void *arg;
+ struct _pthread_cleanup_handler *next;
+} __pthread_cleanup_handler;
+
+void _pthread_cleanup_push (__pthread_cleanup_handler *handler);
+void _pthread_cleanup_pop (int execute);
+
+#define pthread_cleanup_push(_fn, _arg) { __pthread_cleanup_handler __cleanup_handler = \
+ { _fn, _arg, NULL }; \
+ _pthread_cleanup_push( &__cleanup_handler );
+#define pthread_cleanup_pop(_execute) _pthread_cleanup_pop( _execute ); }
/* Condition variables */
int pthread_cond_broadcast (pthread_cond_t *);
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index de3b3d4ea..f8feda4c7 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -1,6 +1,6 @@
/* sys/cygwin.h
- Copyright 1997, 1998, 2000, 2001 Red Hat, Inc.
+ Copyright 1997, 1998, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -69,7 +69,8 @@ typedef enum
CW_GET_CYGWIN_REGISTRY_NAME,
CW_STRACE_TOGGLE,
CW_STRACE_ACTIVE,
- CW_CYGWIN_PID_TO_WINPID
+ CW_CYGWIN_PID_TO_WINPID,
+ CW_EXTRACT_DOMAIN_AND_USER
} cygwin_getinfo_types;
#define CW_NEXTPID 0x80000000 // or with pid to get next one
@@ -94,7 +95,7 @@ enum
PID_USETTY = 0x1000, // Setting this enables or disables cygwin's
// tty support. This is inherited by
// all execed or forked processes.
- PID_UNUSED2 = 0x2000, // child has execed
+ PID_ALLPIDS = 0x2000, // child has execed
PID_EXECED = 0x4000, // redirect to original pid info block
PID_NOREDIR = 0x8000, // don't redirect if execed
PID_EXITED = 0x80000000 // Free entry.
@@ -208,9 +209,15 @@ extern int cygwin_attach_handle_to_fd (char *, int, HANDLE, mode_t, DWORD);
#define TTY_CONSOLE 0x40000000
+#define EXTERNAL_PINFO_VERSION_16_BIT 0
+#define EXTERNAL_PINFO_VERSION_32_BIT 1
+#define EXTERNAL_PINFO_VERSION EXTERNAL_PINFO_VERSION_32_BIT
+
#ifndef _SYS_TYPES_H
typedef unsigned short __uid16_t;
typedef unsigned short __gid16_t;
+typedef unsigned long __uid32_t;
+typedef unsigned long __gid32_t;
#endif
struct external_pinfo
@@ -233,9 +240,13 @@ struct external_pinfo
char progname[MAX_PATH];
DWORD strace_mask;
- HANDLE strace_file;
+ DWORD version;
DWORD process_state;
+
+ /* Only available if version >= EXTERNAL_PINFO_VERSION_32_BIT */
+ __uid32_t uid32;
+ __gid32_t gid32;
};
DWORD cygwin_internal (cygwin_getinfo_types, ...);
diff --git a/winsup/cygwin/include/sys/ipc.h b/winsup/cygwin/include/sys/ipc.h
index 8ddec6d50..c718a173a 100644
--- a/winsup/cygwin/include/sys/ipc.h
+++ b/winsup/cygwin/include/sys/ipc.h
@@ -39,9 +39,10 @@ struct ipc_perm {
/* this is a value that will _never_ be a valid key from ftok */
#define IPC_PRIVATE -2
-#define IPC_RMID 0x0003
-#define IPC_SET 0x0002
-#define IPC_STAT 0x0001
+/* ctl commands 1000-1fff is ipc reserved */
+#define IPC_RMID 0x1003
+#define IPC_SET 0x1002
+#define IPC_STAT 0x1001
key_t ftok(const char *, int);
diff --git a/winsup/cygwin/include/sys/mount.h b/winsup/cygwin/include/sys/mount.h
index 00b7a0137..26e02cba2 100644
--- a/winsup/cygwin/include/sys/mount.h
+++ b/winsup/cygwin/include/sys/mount.h
@@ -21,10 +21,14 @@ enum
MOUNT_BINARY = 0x002, /* "binary" format read/writes */
MOUNT_SYSTEM = 0x008, /* mount point came from system table */
MOUNT_EXEC = 0x010, /* Any file in the mounted directory gets 'x' bit */
- MOUNT_AUTO = 0x020, /* mount point refers to auto device mount */
+ MOUNT_CYGDRIVE = 0x020, /* mount point refers to cygdriv device mount */
MOUNT_CYGWIN_EXEC = 0x040, /* file or directory is or contains a cygwin
executable */
- MOUNT_MIXED = 0x080, /* reads are text, writes are binary */
+ MOUNT_MIXED = 0x080, /* reads are text, writes are binary
+ not yet implemented */
+ MOUNT_NOTEXEC = 0x100, /* don't check files for executable magic */
+ MOUNT_DEVFS = 0x200, /* /device "filesystem" */
+ MOUNT_PROC = 0x400 /* /proc "filesystem" */
};
int mount (const char *, const char *, unsigned __flags);
diff --git a/winsup/cygwin/include/sys/strace.h b/winsup/cygwin/include/sys/strace.h
index 955d77a1e..b43ab886f 100644
--- a/winsup/cygwin/include/sys/strace.h
+++ b/winsup/cygwin/include/sys/strace.h
@@ -44,7 +44,6 @@ public:
int lmicrosec;
int execing;
int inited;
- strace() : version(1) {}
void hello ();
void prntf (unsigned, const char *func, const char *, ...) /*__attribute__ ((regparm(3)))*/;
void vprntf (unsigned, const char *func, const char *, va_list ap) /*__attribute__ ((regparm(3)))*/;
diff --git a/winsup/cygwin/include/sys/sysmacros.h b/winsup/cygwin/include/sys/sysmacros.h
index cc3a69160..2c9c69923 100644
--- a/winsup/cygwin/include/sys/sysmacros.h
+++ b/winsup/cygwin/include/sys/sysmacros.h
@@ -11,8 +11,14 @@ details. */
#ifndef _SYS_SYSMACROS_H
#define _SYS_SYSMACROS_H
+#ifdef __CYGWIN_USE_BIG_TYPES__
+#define major(dev) ((int)(((dev) >> 16) & 0xffff))
+#define minor(dev) ((int)((dev) & 0xffff))
+#define makedev(major, minor) (((major) << 16) | ((minor) & 0xffff))
+#else
#define major(dev) ((int)(((dev) >> 8) & 0xff))
#define minor(dev) ((int)((dev) & 0xff))
-#define makedev(major, minor) (((major) << 8) | (minor))
+#define makedev(major, minor) (((major) << 8) | ((minor) & 0xff))
+#endif
#endif /* _SYS_SYSMACROS_H */
diff --git a/winsup/cygwin/include/sys/termios.h b/winsup/cygwin/include/sys/termios.h
index a87f10627..c37776111 100644
--- a/winsup/cygwin/include/sys/termios.h
+++ b/winsup/cygwin/include/sys/termios.h
@@ -195,6 +195,14 @@ details. */
#define NCCS 18
+/* `c_cc' member of 'struct termios' structure can be disabled by
+ using the value _POSIX_VDISABLE. */
+#define _POSIX_VDISABLE '\0'
+
+/* Compare a character C to a value VAL from the `c_cc' array in a
+ `struct termios'. If VAL is _POSIX_VDISABLE, no character can match it. */
+#define CCEQ(val, c) ((c) == (val) && (val) != _POSIX_VDISABLE)
+
typedef unsigned char cc_t;
typedef unsigned int tcflag_t;
typedef unsigned int speed_t;
diff --git a/winsup/cygwin/include/sys/vfs.h b/winsup/cygwin/include/sys/vfs.h
index f0f3eb96c..57b6f9232 100644
--- a/winsup/cygwin/include/sys/vfs.h
+++ b/winsup/cygwin/include/sys/vfs.h
@@ -12,7 +12,7 @@ details. */
#define _SYS_VFS_H_
struct statfs {
- long f_type; /* type of filesystem (see below) */
+ long f_type; /* type of filesystem */
long f_bsize; /* optimal transfer block size */
long f_blocks; /* total data blocks in file system */
long f_bfree; /* free blocks in fs */
diff --git a/winsup/cygwin/include/wchar.h b/winsup/cygwin/include/wchar.h
index eabdaa725..bf3f017a2 100644
--- a/winsup/cygwin/include/wchar.h
+++ b/winsup/cygwin/include/wchar.h
@@ -16,6 +16,7 @@ details. */
/* Get wchar_t and wint_t from <stddef.h>. */
#define __need_wchar_t
#define __need_wint_t
+#define __need_size_t
#include <stddef.h>
__BEGIN_DECLS
diff --git a/winsup/cygwin/ipc.cc b/winsup/cygwin/ipc.cc
index 192a124d5..1f496d328 100644
--- a/winsup/cygwin/ipc.cc
+++ b/winsup/cygwin/ipc.cc
@@ -1,6 +1,6 @@
/* ipc.cc: Single unix specification IPC interface for Cygwin
- Copyright 2001 Red Hat, Inc.
+ Copyright 2001, 2002 Red Hat, Inc.
Originally written by Robert Collins <robert.collins@hotmail.com>
@@ -27,11 +27,11 @@ ftok(const char *path, int id)
/* stat set the appropriate errno for us */
return (key_t) -1;
}
-
- /* dev_t is short for cygwin
+
+ /* dev_t is short for cygwin
* ino_t is long for cygwin
* and we need 8 bits for the id.
- * thus key_t is long long.
+ * thus key_t is long long.
*/
return ((long long) statbuf.st_dev << (5*8)) | (statbuf.st_ino << (8) ) | (id & 0x00ff);
}
diff --git a/winsup/cygwin/localtime.cc b/winsup/cygwin/localtime.cc
index 48006e25a..8267bdebb 100644
--- a/winsup/cygwin/localtime.cc
+++ b/winsup/cygwin/localtime.cc
@@ -1396,10 +1396,10 @@ tzsetwall P((void))
dst = cp = buf;
for (src = tz.StandardName; *src; src++)
if (is_upper(*src)) *dst++ = *src;
- if (cp == dst)
+ if ((dst - cp) < 3)
{
- /* In Asian Windows, tz.StandardName may not contain
- the timezone name. */
+ /* In non-english Windows, converted tz.StandardName
+ may not contain a valid standard timezone name. */
strcpy(cp, wildabbr);
cp += strlen(wildabbr);
}
@@ -1414,11 +1414,11 @@ tzsetwall P((void))
dst = cp;
for (src = tz.DaylightName; *src; src++)
if (is_upper(*src)) *dst++ = *src;
- if (cp == dst)
+ if ((dst - cp) < 3)
{
- /* In Asian Windows, tz.StandardName may not contain
- the daylight name. */
- strcpy(buf, wildabbr);
+ /* In non-english Windows, converted tz.DaylightName
+ may not contain a valid daylight timezone name. */
+ strcpy(cp, wildabbr);
cp += strlen(wildabbr);
}
else
diff --git a/winsup/cygwin/malloc_wrapper.cc b/winsup/cygwin/malloc_wrapper.cc
index 054d77b8c..ee039f30f 100644
--- a/winsup/cygwin/malloc_wrapper.cc
+++ b/winsup/cygwin/malloc_wrapper.cc
@@ -1,6 +1,6 @@
/* malloc.cc
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
Originally written by Steve Chamberlain of Cygnus Support
sac@cygnus.com
diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc
index 57bd82795..c89cf4c7b 100644
--- a/winsup/cygwin/mmap.cc
+++ b/winsup/cygwin/mmap.cc
@@ -20,8 +20,6 @@ details. */
#include "dtable.h"
#include "cygerrno.h"
#include "cygheap.h"
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "sys/cygwin.h"
@@ -98,6 +96,7 @@ class mmap_record
__off64_t map_map (__off64_t off, DWORD len);
BOOL unmap_map (caddr_t addr, DWORD len);
void fixup_map (void);
+ int access (char *address);
fhandler_base *alloc_fh ();
void free_fh (fhandler_base *fh);
@@ -150,7 +149,10 @@ mmap_record::map_map (__off64_t off, DWORD len)
if (wincap.virtual_protect_works_on_shared_pages ()
&& !VirtualProtect (base_address_ + off * getpagesize (),
len * getpagesize (), prot, &old_prot))
- syscall_printf ("-1 = map_map (): %E");
+ {
+ debug_printf ("-1 = map_map (): %E");
+ return (__off64_t)-1;
+ }
while (len-- > 0)
MAP_SET (off + len);
@@ -163,7 +165,10 @@ mmap_record::map_map (__off64_t off, DWORD len)
if (wincap.virtual_protect_works_on_shared_pages ()
&& !VirtualProtect (base_address_ + start * getpagesize (),
len * getpagesize (), prot, &old_prot))
- syscall_printf ("-1 = map_map (): %E");
+ {
+ debug_printf ("-1 = map_map (): %E");
+ return (__off64_t)-1;
+ }
for (; len-- > 0; ++start)
MAP_SET (start);
@@ -219,6 +224,15 @@ mmap_record::fixup_map ()
&old_prot);
}
+int
+mmap_record::access (char *address)
+{
+ if (address < base_address_ || address >= base_address_ + size_to_map_)
+ return 0;
+ DWORD off = (address - base_address_) / getpagesize ();
+ return MAP_ISSET (off);
+}
+
static fhandler_disk_file fh_paging_file;
fhandler_base *
@@ -235,7 +249,7 @@ mmap_record::alloc_fh ()
the call to fork(). This requires creating a fhandler
of the correct type to be sure to call the method of the
correct class. */
- return cygheap->fdtab.build_fhandler (-1, get_device (), NULL);
+ return cygheap->fdtab.build_fhandler (-1, get_device ());
}
void
@@ -255,6 +269,7 @@ public:
~list ();
mmap_record *add_record (mmap_record r);
void erase (int i);
+ void erase ();
mmap_record *match (__off64_t off, DWORD len);
long match (caddr_t addr, DWORD len, long start);
};
@@ -326,6 +341,12 @@ list::erase (int i)
nrecs--;
}
+void
+list::erase ()
+{
+ erase (nrecs-1);
+}
+
class map {
public:
list **lists;
@@ -491,7 +512,13 @@ mmap64 (caddr_t addr, size_t len, int prot, int flags, int fd, __off64_t off)
mmap_record *rec;
if ((rec = l->match (off, len)) != NULL)
{
- off = rec->map_map (off, len);
+ if ((off = rec->map_map (off, len)) == (__off64_t)-1)
+ {
+ set_errno (ENOMEM);
+ syscall_printf ("-1 = mmap(): ENOMEM");
+ ReleaseResourceLock(LOCK_MMAP_LIST, READ_LOCK|WRITE_LOCK, "mmap");
+ return MAP_FAILED;
+ }
caddr_t ret = rec->get_address () + off;
syscall_printf ("%x = mmap() succeeded", ret);
ReleaseResourceLock(LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK, "mmap");
@@ -549,7 +576,15 @@ mmap64 (caddr_t addr, size_t len, int prot, int flags, int fd, __off64_t off)
/* Insert into the list */
mmap_record *rec = l->add_record (mmap_rec);
- off = rec->map_map (off, len);
+ if ((off = rec->map_map (off, len)) == (__off64_t)-1)
+ {
+ fh->munmap (h, base, gran_len);
+ l->erase ();
+ set_errno (ENOMEM);
+ syscall_printf ("-1 = mmap(): ENOMEM");
+ ReleaseResourceLock(LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK, "mmap");
+ return MAP_FAILED;
+ }
caddr_t ret = rec->get_address () + off;
syscall_printf ("%x = mmap() succeeded", ret);
ReleaseResourceLock(LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK, "mmap");
@@ -664,8 +699,12 @@ msync (caddr_t addr, size_t len, int flags)
for (int li = 0; li < l->nrecs; ++li)
{
mmap_record *rec = l->recs + li;
- if (rec->get_address () == addr)
+ if (rec->access (addr))
{
+ /* Check whole area given by len. */
+ for (DWORD i = getpagesize (); i < len; ++i)
+ if (!rec->access (addr + i))
+ goto invalid_address_range;
fhandler_base *fh = rec->alloc_fh ();
int ret = fh->msync (rec->get_handle (), addr, len, flags);
rec->free_fh (fh);
@@ -678,10 +717,11 @@ msync (caddr_t addr, size_t len, int flags)
ReleaseResourceLock(LOCK_MMAP_LIST, WRITE_LOCK | READ_LOCK, "msync");
return 0;
}
- }
- }
- }
+ }
+ }
+ }
+invalid_address_range:
/* SUSv2: Return code if indicated memory was not mapped is ENOMEM. */
set_errno (ENOMEM);
syscall_printf ("-1 = msync(): ENOMEM");
@@ -887,7 +927,7 @@ mprotect (caddr_t addr, size_t len, int prot)
*/
int __stdcall
-fixup_mmaps_after_fork ()
+fixup_mmaps_after_fork (HANDLE parent)
{
debug_printf ("recreate_mmaps_after_fork, mmapped_areas %p", mmapped_areas);
@@ -925,6 +965,20 @@ fixup_mmaps_after_fork ()
rec->get_address ());
return -1;
}
+ if (rec->get_access () == FILE_MAP_COPY)
+ {
+ for (char *address = rec->get_address ();
+ address < rec->get_address () + rec->get_size ();
+ address += getpagesize ())
+ if (rec->access (address)
+ && !ReadProcessMemory (parent, address, address,
+ getpagesize (), NULL))
+ {
+ system_printf ("ReadProcessMemory failed for MAP_PRIVATE address %p, %E",
+ rec->get_address ());
+ return -1;
+ }
+ }
rec->fixup_map ();
}
}
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index 2008bbe74..32e930392 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -21,7 +21,6 @@ details. */
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
-#include <fcntl.h>
#define USE_SYS_TYPES_FD_SET
#include <winsock2.h>
#include "cygerrno.h"
@@ -30,7 +29,6 @@ details. */
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
-#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "registry.h"
@@ -503,11 +501,17 @@ fdsock (int& fd, const char *name, SOCKET soc)
{
if (!winsock2_active)
soc = set_socket_inheritance (soc);
+ else if (wincap.has_set_handle_information ())
+ {
+ /* NT systems apparently set sockets to inheritable by default */
+ SetHandleInformation ((HANDLE)soc, HANDLE_FLAG_INHERIT, 0);
+ debug_printf ("reset socket inheritance since winsock2_active %d", winsock2_active);
+ }
else
debug_printf ("not setting socket inheritance since winsock2_active %d", winsock2_active);
fhandler_socket *fh = (fhandler_socket *) cygheap->fdtab.build_fhandler (fd, FH_SOCKET, name);
fh->set_io_handle ((HANDLE) soc);
- fh->set_flags (O_RDWR);
+ fh->set_flags (O_RDWR, O_BINARY);
debug_printf ("fd %d, name '%s', soc %p", fd, name, soc);
return fh;
}
@@ -518,6 +522,7 @@ cygwin_socket (int af, int type, int protocol)
{
int res = -1;
SOCKET soc = 0;
+ fhandler_socket* fh = NULL;
cygheap_fdnew fd;
@@ -539,7 +544,12 @@ cygwin_socket (int af, int type, int protocol)
else
name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket");
- fdsock (fd, name, soc)->set_addr_family (af);
+ fh = fdsock (fd, name, soc);
+ if (fh)
+ {
+ fh->set_addr_family (af);
+ fh->set_socket_type (type);
+ }
res = fd;
}
@@ -881,7 +891,8 @@ cygwin_connect (int fd,
}
set_winsock_errno ();
}
- if (sock->get_addr_family () == AF_LOCAL)
+ if (sock->get_addr_family () == AF_LOCAL &&
+ sock->get_socket_type () == SOCK_STREAM)
{
if (!res || in_progress)
{
@@ -1112,7 +1123,7 @@ cygwin_gethostbyname (const char *name)
tmp_addr[1] = b;
tmp_addr[2] = c;
tmp_addr[3] = d;
- tmp_addr_list[0] = (char *)tmp_addr;
+ tmp_addr_list[0] = (char *) tmp_addr;
tmp.h_name = name;
tmp.h_aliases = tmp_aliases;
tmp.h_addrtype = 2;
@@ -1199,7 +1210,8 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len)
WSAGetLastError () == WSAEWOULDBLOCK)
in_progress = TRUE;
- if (sock->get_addr_family () == AF_LOCAL)
+ if (sock->get_addr_family () == AF_LOCAL &&
+ sock->get_socket_type () == SOCK_STREAM)
{
if ((SOCKET) res != (SOCKET) INVALID_SOCKET || in_progress)
{
@@ -1242,6 +1254,7 @@ cygwin_accept (int fd, struct sockaddr *peer, int *len)
if (sock->get_addr_family () == AF_LOCAL)
res_fh->set_sun_path (sock->get_sun_path ());
res_fh->set_addr_family (sock->get_addr_family ());
+ res_fh->set_socket_type (sock->get_socket_type ());
res = res_fd;
}
}
@@ -1541,7 +1554,7 @@ cygwin_send (int fd, const void *buf, int len, unsigned int flags)
/* getdomainname: standards? */
extern "C" int
-getdomainname (char *domain, int len)
+getdomainname (char *domain, size_t len)
{
/*
* This works for Win95 only if the machine is configured to use MS-TCP.
@@ -1615,7 +1628,7 @@ get_2k_ifconf (struct ifconf *ifc, int what)
switch (ift->table[if_cnt].dwType)
{
case MIB_IF_TYPE_TOKENRING:
- ++*tok;
+ ++*tok;
strcpy (ifr->ifr_name, "tok");
strcat (ifr->ifr_name, tok);
break;
@@ -2266,6 +2279,7 @@ socketpair (int family, int type, int protocol, int *sb)
struct sockaddr_in sock_in, sock_out;
int len;
cygheap_fdnew sb0;
+ fhandler_socket *fh;
if (__check_null_invalid_struct_errno (sb, 2 * sizeof(int)))
return -1;
@@ -2417,25 +2431,30 @@ socketpair (int family, int type, int protocol, int *sb)
if (family == AF_LOCAL)
{
- fhandler_socket *fh;
fh = fdsock (sb[0],
type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket",
insock);
fh->set_sun_path ("");
fh->set_addr_family (AF_LOCAL);
+ fh->set_socket_type (type);
fh = fdsock (sb[1],
type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket",
outsock);
fh->set_sun_path ("");
fh->set_addr_family (AF_LOCAL);
+ fh->set_socket_type (type);
}
else
{
- fdsock (sb[0], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp",
- insock)->set_addr_family (AF_INET);
- fdsock (sb[1], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp",
- outsock)->set_addr_family (AF_INET);
+ fh = fdsock (sb[0], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp",
+ insock);
+ fh->set_addr_family (AF_INET);
+ fh->set_socket_type (type);
+ fh = fdsock (sb[1], type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp",
+ outsock);
+ fh->set_addr_family (AF_INET);
+ fh->set_socket_type (type);
}
done:
@@ -2456,7 +2475,7 @@ endhostent (void)
}
/* exported as recvmsg: standards? */
-extern "C" int
+extern "C" int
cygwin_recvmsg(int s, struct msghdr *msg, int flags)
{
int ret, nb;
@@ -2468,21 +2487,23 @@ cygwin_recvmsg(int s, struct msghdr *msg, int flags)
for(i = 0; i < msg->msg_iovlen; ++i)
tot += iov[i].iov_len;
buf = (char *) malloc(tot);
- if (tot != 0 && buf == NULL) {
+ if (tot != 0 && buf == NULL)
+ {
errno = ENOMEM;
return -1;
- }
- nb = ret = cygwin_recvfrom (s, buf, tot, flags,
+ }
+ nb = ret = cygwin_recvfrom (s, buf, tot, flags,
(struct sockaddr *) msg->msg_name, (int *) &msg->msg_namelen);
p = buf;
- while (nb > 0) {
+ while (nb > 0)
+ {
ssize_t cnt = min(nb, iov->iov_len);
memcpy (iov->iov_base, p, cnt);
p += cnt;
nb -= cnt;
++iov;
- }
+ }
free(buf);
return ret;
}
@@ -2500,16 +2521,18 @@ cygwin_sendmsg(int s, const struct msghdr *msg, int flags)
for(i = 0; i < msg->msg_iovlen; ++i)
tot += iov[i].iov_len;
buf = (char *) malloc(tot);
- if (tot != 0 && buf == NULL) {
+ if (tot != 0 && buf == NULL)
+ {
errno = ENOMEM;
return -1;
- }
+ }
p = buf;
- for (i = 0; i < msg->msg_iovlen; ++i) {
+ for (i = 0; i < msg->msg_iovlen; ++i)
+ {
memcpy (p, iov[i].iov_base, iov[i].iov_len);
p += iov[i].iov_len;
- }
- ret = cygwin_sendto (s, buf, tot, flags,
+ }
+ ret = cygwin_sendto (s, buf, tot, flags,
(struct sockaddr *) msg->msg_name, msg->msg_namelen);
free (buf);
return ret;
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index e1ec33bc1..f10d27dcf 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -10,11 +10,28 @@
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
#define FILE_SYNCHRONOUS_IO_NONALERT 32
+#define PDI_MODULES 0x01
+#define PDI_HEAPS 0x04
+#define LDRP_IMAGE_DLL 0x00000004
+#define WSLE_PAGE_READONLY 0x001
+#define WSLE_PAGE_EXECUTE 0x002
+#define WSLE_PAGE_EXECUTE_READ 0x003
+#define WSLE_PAGE_READWRITE 0x004
+#define WSLE_PAGE_WRITECOPY 0x005
+#define WSLE_PAGE_EXECUTE_READWRITE 0x006
+#define WSLE_PAGE_EXECUTE_WRITECOPY 0x007
+#define WSLE_PAGE_SHARE_COUNT_MASK 0x0E0
+#define WSLE_PAGE_SHAREABLE 0x100
+
+typedef ULONG KAFFINITY;
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation = 0,
+ SystemPerformanceInformation = 2,
+ SystemTimeOfDayInformation = 3,
SystemProcessesAndThreadsInformation = 5,
+ SystemProcessorTimes = 8,
/* There are a lot more of these... */
} SYSTEM_INFORMATION_CLASS;
@@ -30,9 +47,19 @@ typedef struct _SYSTEM_BASIC_INFORMATION
ULONG LowestUserAddress;
ULONG HighestUserAddress;
ULONG ActiveProcessors;
- ULONG NumberProcessors;
+ UCHAR NumberProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
+typedef struct _SYSTEM_PROCESSOR_TIMES
+{
+ LARGE_INTEGER IdleTime;
+ LARGE_INTEGER KernelTime;
+ LARGE_INTEGER UserTime;
+ LARGE_INTEGER DpcTime;
+ LARGE_INTEGER InterruptTime;
+ ULONG InterruptCount;
+} SYSTEM_PROCESSOR_TIMES, *PSYSTEM_PROCESSOR_TIMES;
+
typedef LONG KPRIORITY;
typedef struct _VM_COUNTERS
{
@@ -112,12 +139,13 @@ typedef struct _SYSTEM_THREADS
ULONG ContextSwitchCount;
THREAD_STATE State;
KWAIT_REASON WaitReason;
+ DWORD Reserved;
} SYSTEM_THREADS, *PSYSTEM_THREADS;
typedef struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta;
- ULONG Threadcount;
+ ULONG ThreadCount;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
@@ -139,6 +167,200 @@ typedef struct _IO_STATUS_BLOCK
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
+typedef struct _SYSTEM_PERFORMANCE_INFORMATION
+{
+ LARGE_INTEGER IdleTime;
+ LARGE_INTEGER ReadTransferCount;
+ LARGE_INTEGER WriteTransferCount;
+ LARGE_INTEGER OtherTransferCount;
+ ULONG ReadOperationCount;
+ ULONG WriteOperationCount;
+ ULONG OtherOperationCount;
+ ULONG AvailablePages;
+ ULONG TotalCommittedPages;
+ ULONG TotalCommitLimit;
+ ULONG PeakCommitment;
+ ULONG PageFaults;
+ ULONG WriteCopyFaults;
+ ULONG TransitionFaults;
+ ULONG Reserved1;
+ ULONG DemandZeroFaults;
+ ULONG PagesRead;
+ ULONG PageReadIos;
+ ULONG Reserved2[2];
+ ULONG PagefilePagesWritten;
+ ULONG PagefilePageWriteIos;
+ ULONG MappedFilePagesWritten;
+ ULONG MappedFilePageWriteIos;
+ ULONG PagedPoolUsage;
+ ULONG NonPagedPoolUsage;
+ ULONG PagedPoolAllocs;
+ ULONG PagedPoolFrees;
+ ULONG NonPagedPoolAllocs;
+ ULONG NonPagedPoolFrees;
+ ULONG TotalFreeSystemPtes;
+ ULONG SystemCodePage;
+ ULONG TotalSystemDriverPages;
+ ULONG TotalSystemCodePages;
+ ULONG SmallNonPagedLookasideListAllocateHits;
+ ULONG SmallPagedLookasideListAllocateHits;
+ ULONG Reserved3;
+ ULONG MmSystemCachePage;
+ ULONG PagedPoolPage;
+ ULONG SystemDriverPage;
+ ULONG FastReadNoWait;
+ ULONG FastReadWait;
+ ULONG FastReadResourceMiss;
+ ULONG FastReadNotPossible;
+ ULONG FastMdlReadNoWait;
+ ULONG FastMdlReadWait;
+ ULONG FastMdlReadResourceMiss;
+ ULONG FastMdlReadNotPossible;
+ ULONG MapDataNoWait;
+ ULONG MapDataWait;
+ ULONG MapDataNoWaitMiss;
+ ULONG MapDataWaitMiss;
+ ULONG PinMappedDataCount;
+ ULONG PinReadNoWait;
+ ULONG PinReadWait;
+ ULONG PinReadNoWaitMiss;
+ ULONG PinReadWaitMiss;
+ ULONG CopyReadNoWait;
+ ULONG CopyReadWait;
+ ULONG CopyReadNoWaitMiss;
+ ULONG CopyReadWaitMiss;
+ ULONG MdlReadNoWait;
+ ULONG MdlReadWait;
+ ULONG MdlReadNoWaitMiss;
+ ULONG MdlReadWaitMiss;
+ ULONG ReadAheadIos;
+ ULONG LazyWriteIos;
+ ULONG LazyWritePages;
+ ULONG DataFlushes;
+ ULONG DataPages;
+ ULONG ContextSwitches;
+ ULONG FirstLevelTbFills;
+ ULONG SecondLevelTbFills;
+ ULONG SystemCalls;
+} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;
+
+typedef struct _SYSTEM_TIME_OF_DAY_INFORMATION
+{
+ LARGE_INTEGER BootTime;
+ LARGE_INTEGER CurrentTime;
+ LARGE_INTEGER TimeZoneBias;
+ ULONG CurrentTimeZoneId;
+} SYSTEM_TIME_OF_DAY_INFORMATION, *PSYSTEM_TIME_OF_DAY_INFORMATION;
+
+typedef enum _PROCESSINFOCLASS
+{
+ ProcessBasicInformation = 0,
+ ProcessQuotaLimits = 1,
+ ProcessVmCounters = 3,
+ ProcessTimes =4,
+} PROCESSINFOCLASS;
+
+typedef struct _DEBUG_BUFFER
+{
+ HANDLE SectionHandle;
+ PVOID SectionBase;
+ PVOID RemoteSectionBase;
+ ULONG SectionBaseDelta;
+ HANDLE EventPairHandle;
+ ULONG Unknown[2];
+ HANDLE RemoteThreadHandle;
+ ULONG InfoClassMask;
+ ULONG SizeOfInfo;
+ ULONG AllocatedSize;
+ ULONG SectionSize;
+ PVOID ModuleInformation;
+ PVOID BackTraceInformation;
+ PVOID HeapInformation;
+ PVOID LockInformation;
+ PVOID Reserved[9];
+} DEBUG_BUFFER, *PDEBUG_BUFFER;
+
+typedef struct _DEBUG_HEAP_INFORMATION
+{
+ ULONG Base;
+ ULONG Flags;
+ USHORT Granularity;
+ USHORT Unknown;
+ ULONG Allocated;
+ ULONG Committed;
+ ULONG TagCount;
+ ULONG BlockCount;
+ ULONG Reserved[7];
+ PVOID Tags;
+ PVOID Blocks;
+} DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION;
+
+typedef struct _DEBUG_MODULE_INFORMATION
+{
+ ULONG Reserved[2];
+ ULONG Base;
+ ULONG Size;
+ ULONG Flags;
+ USHORT Index;
+ USHORT Unknown;
+ USHORT LoadCount;
+ USHORT ModuleNameOffset;
+ CHAR ImageName[256];
+} DEBUG_MODULE_INFORMATION, *PDEBUG_MODULE_INFORMATION;
+
+typedef struct _KERNEL_USER_TIMES
+{
+ LARGE_INTEGER CreateTime;
+ LARGE_INTEGER ExitTime;
+ LARGE_INTEGER KernelTime;
+ LARGE_INTEGER UserTime;
+} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES;
+
+typedef void *PPEB;
+
+typedef struct _PROCESS_BASIC_INFORMATION
+{
+ NTSTATUS ExitStatus;
+ PPEB PebBaseAddress;
+ KAFFINITY AffinityMask;
+ KPRIORITY BasePriority;
+ ULONG UniqueProcessId;
+ ULONG InheritedFromUniqueProcessId;
+} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
+
+typedef enum _MEMORY_INFORMATION_CLASS
+{
+ MemoryBasicInformation,
+ MemoryWorkingSetList,
+ MemorySectionName,
+ MemoryBaiscVlmInformation
+} MEMORY_INFORMATION_CLASS;
+
+typedef struct _MEMORY_WORKING_SET_LIST
+{
+ ULONG NumberOfPages;
+ ULONG WorkingSetList[1];
+} MEMORY_WORKING_SET_LIST, *PMEMORY_WORKING_SET_LIST;
+
+typedef struct _FILE_NAME_INFORMATION
+{
+ DWORD FileNameLength;
+ WCHAR FileName[MAX_PATH + 100];
+} FILE_NAME_INFORMATION;
+
+typedef enum _OBJECT_INFORMATION_CLASS
+{
+ ObjectBasicInformation = 0,
+ ObjectNameInformation = 1,
+ ObjectHandleInformation = 4
+ // and many more
+} OBJECT_INFORMATION_CLASS;
+
+typedef struct _OBJECT_NAME_INFORMATION
+{
+ UNICODE_STRING Name;
+} OBJECT_NAME_INFORMATION;
+
/* Function declarations for ntdll.dll. These don't appear in any
standard Win32 header. */
extern "C"
@@ -154,12 +376,17 @@ extern "C"
NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
PIO_STATUS_BLOCK, ULONG, ULONG);
NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
+ NTSTATUS NTAPI NtQueryInformationFile (HANDLE, IO_STATUS_BLOCK *, VOID *,
+ DWORD, DWORD);
+ NTSTATUS NTAPI NtQueryInformationProcess (HANDLE, PROCESSINFOCLASS,
+ PVOID, ULONG, PULONG);
+ NTSTATUS NTAPI NtQueryObject (HANDLE, OBJECT_INFORMATION_CLASS, VOID *,
+ ULONG, ULONG *);
NTSTATUS NTAPI NtQuerySystemInformation (SYSTEM_INFORMATION_CLASS,
PVOID, ULONG, PULONG);
+ NTSTATUS NTAPI NtQueryVirtualMemory (HANDLE, PVOID, MEMORY_INFORMATION_CLASS,
+ PVOID, ULONG, PULONG);
NTSTATUS NTAPI NtUnmapViewOfSection (HANDLE, PVOID);
VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR);
ULONG NTAPI RtlNtStatusToDosError (NTSTATUS);
- NTSTATUS NTAPI ZwQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS,
- IN OUT PVOID, IN ULONG,
- OUT PULONG);
}
diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc
index dfabd1b7f..a3df1219e 100644
--- a/winsup/cygwin/passwd.cc
+++ b/winsup/cygwin/passwd.cc
@@ -18,8 +18,6 @@ details. */
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
#include <sys/termios.h>
@@ -82,19 +80,17 @@ parse_pwd (struct passwd &res, char *buf)
/* Allocate enough room for the passwd struct and all the strings
in it in one go */
size_t len = strlen (buf);
- char *mybuf = (char *) malloc (len + 1);
- (void) memcpy (mybuf, buf, len + 1);
- if (mybuf[--len] == '\n')
- mybuf[len] = '\0';
-
- res.pw_name = grab_string (&mybuf);
- res.pw_passwd = grab_string (&mybuf);
- res.pw_uid = grab_int (&mybuf);
- res.pw_gid = grab_int (&mybuf);
+ if (buf[--len] == '\r')
+ buf[len] = '\0';
+
+ res.pw_name = grab_string (&buf);
+ res.pw_passwd = grab_string (&buf);
+ res.pw_uid = grab_int (&buf);
+ res.pw_gid = grab_int (&buf);
res.pw_comment = 0;
- res.pw_gecos = grab_string (&mybuf);
- res.pw_dir = grab_string (&mybuf);
- res.pw_shell = grab_string (&mybuf);
+ res.pw_gecos = grab_string (&buf);
+ res.pw_dir = grab_string (&buf);
+ res.pw_shell = grab_string (&buf);
}
/* Add one line from /etc/passwd into the password cache */
@@ -135,51 +131,78 @@ pthread_mutex_t NO_COPY passwd_lock::mutex = (pthread_mutex_t) PTHREAD_MUTEX_INI
void
read_etc_passwd ()
{
- char linebuf[1024];
- /* A mutex is ok for speed here - pthreads will use critical sections not mutex's
- * for non-shared mutexs in the future. Also, this function will at most be called
- * once from each thread, after that the passwd_state test will succeed
- */
- passwd_lock here (cygwin_finished_initializing);
-
- /* if we got blocked by the mutex, then etc_passwd may have been processed */
- if (passwd_state != uninitialized)
- return;
-
- if (passwd_state != initializing)
- {
- passwd_state = initializing;
- if (max_lines) /* When rereading, free allocated memory first. */
- {
- for (int i = 0; i < curr_lines; ++i)
- free (passwd_buf[i].pw_name);
- curr_lines = 0;
- }
-
- FILE *f = fopen ("/etc/passwd", "rt");
-
- if (f)
- {
- while (fgets (linebuf, sizeof (linebuf), f) != NULL)
- {
- if (strlen (linebuf))
- add_pwd_line (linebuf);
- }
-
- passwd_state.set_last_modified (f);
- fclose (f);
- passwd_state = loaded;
- }
- else
- {
- debug_printf ("Emulating /etc/passwd");
- snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh", cygheap->user.name (),
- (unsigned) DEFAULT_UID, (unsigned) DEFAULT_GID, getenv ("HOME") ?: "/");
- add_pwd_line (linebuf);
- passwd_state = emulated;
- }
+ static pwdgrp_read pr;
- }
+ /* A mutex is ok for speed here - pthreads will use critical sections not
+ * mutexes for non-shared mutexes in the future. Also, this function will
+ * at most be called once from each thread, after that the passwd_state
+ * test will succeed */
+ passwd_lock here (cygwin_finished_initializing);
+
+ /* if we got blocked by the mutex, then etc_passwd may have been processed */
+ if (passwd_state != uninitialized)
+ return;
+
+ if (passwd_state != initializing)
+ {
+ passwd_state = initializing;
+ if (pr.open ("/etc/passwd"))
+ {
+ char *line;
+ while ((line = pr.gets ()) != NULL)
+ if (strlen (line))
+ add_pwd_line (line);
+
+ passwd_state.set_last_modified (pr.get_fhandle(), pr.get_fname ());
+ passwd_state = loaded;
+ pr.close ();
+ debug_printf ("Read /etc/passwd, %d lines", curr_lines);
+ }
+ else
+ {
+ static char linebuf[1024];
+
+ if (wincap.has_security ())
+ {
+ HANDLE ptok;
+ cygsid tu, tg;
+ DWORD siz;
+
+ if (OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok))
+ {
+ if (GetTokenInformation (ptok, TokenUser, &tu, sizeof tu,
+ &siz)
+ && GetTokenInformation (ptok, TokenPrimaryGroup, &tg,
+ sizeof tg, &siz))
+ {
+ char strbuf[100];
+ snprintf (linebuf, sizeof (linebuf),
+ "%s::%lu:%lu:%s:%s:/bin/sh",
+ cygheap->user.name (),
+ *GetSidSubAuthority(tu,
+ *GetSidSubAuthorityCount(tu) - 1),
+ *GetSidSubAuthority(tg,
+ *GetSidSubAuthorityCount(tg) - 1),
+ tu.string (strbuf), getenv ("HOME") ?: "/");
+ debug_printf ("Emulating /etc/passwd: %s", linebuf);
+ add_pwd_line (linebuf);
+ passwd_state = emulated;
+ }
+ CloseHandle (ptok);
+ }
+ }
+ if (passwd_state != emulated)
+ {
+ snprintf (linebuf, sizeof (linebuf), "%s::%u:%u::%s:/bin/sh",
+ cygheap->user.name (), (unsigned) DEFAULT_UID,
+ (unsigned) DEFAULT_GID, getenv ("HOME") ?: "/");
+ debug_printf ("Emulating /etc/passwd: %s", linebuf);
+ add_pwd_line (linebuf);
+ passwd_state = emulated;
+ }
+ }
+
+ }
return;
}
@@ -187,7 +210,7 @@ read_etc_passwd ()
/* Cygwin internal */
/* If this ever becomes non-reentrant, update all the getpw*_r functions */
static struct passwd *
-search_for (__uid16_t uid, const char *name)
+search_for (__uid32_t uid, const char *name)
{
struct passwd *res = 0;
struct passwd *default_pw = 0;
@@ -203,7 +226,7 @@ search_for (__uid16_t uid, const char *name)
if (strcasematch (name, res->pw_name))
return res;
}
- else if (uid == res->pw_uid)
+ else if (uid == (__uid32_t) res->pw_uid)
return res;
}
@@ -218,7 +241,7 @@ search_for (__uid16_t uid, const char *name)
}
extern "C" struct passwd *
-getpwuid (__uid16_t uid)
+getpwuid32 (__uid32_t uid)
{
if (passwd_state <= initializing)
read_etc_passwd ();
@@ -228,8 +251,14 @@ getpwuid (__uid16_t uid)
return search_for (uid, 0);
}
+extern "C" struct passwd *
+getpwuid (__uid16_t uid)
+{
+ return getpwuid32 (uid16touid32 (uid));
+}
+
extern "C" int
-getpwuid_r (__uid16_t uid, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result)
+getpwuid_r32 (__uid32_t uid, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result)
{
*result = NULL;
@@ -270,6 +299,12 @@ getpwuid_r (__uid16_t uid, struct passwd *pwd, char *buffer, size_t bufsize, str
return 0;
}
+extern "C" int
+getpwuid_r (__uid16_t uid, struct passwd *pwd, char *buffer, size_t bufsize, struct passwd **result)
+{
+ return getpwuid_r32 (uid16touid32 (uid), pwd, buffer, bufsize, result);
+}
+
extern "C" struct passwd *
getpwnam (const char *name)
{
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 01798209f..cfa3ef241 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -52,7 +52,6 @@ details. */
#include <stdlib.h>
#include <sys/mount.h>
#include <mntent.h>
-#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
@@ -64,7 +63,6 @@ details. */
#include <sys/cygwin.h>
#include <cygwin/version.h>
#include "cygerrno.h"
-#include "perprocess.h"
#include "security.h"
#include "fhandler.h"
#include "path.h"
@@ -118,6 +116,12 @@ int pcheck_case = PCHECK_RELAXED; /* Determines the case check behaviour. */
(isdirsep(path[mount_table->cygdrive_len + 1]) || \
!path[mount_table->cygdrive_len + 1]))
+#define isproc(path) \
+ (path_prefix_p (proc, (path), proc_len))
+
+#define isvirtual_dev(devn) \
+ (devn == FH_CYGDRIVE || devn == FH_PROC || devn == FH_REGISTRY || devn == FH_PROCESS)
+
/* Return non-zero if PATH1 is a prefix of PATH2.
Both are assumed to be of the same path style and / vs \ usage.
Neither may be "".
@@ -173,7 +177,7 @@ pathmatch (const char *path1, const char *path2)
#define isslash(c) ((c) == '/')
-int
+static int
normalize_posix_path (const char *src, char *dst)
{
const char *src_start = src;
@@ -249,7 +253,11 @@ normalize_posix_path (const char *src, char *dst)
break;
}
else if (src[2] && !isslash (src[2]))
- break;
+ {
+ if (src[2] == '.')
+ return ENOENT;
+ break;
+ }
else
{
while (dst > dst_start && !isslash (*--dst))
@@ -314,8 +322,8 @@ mkrelpath (char *path)
strcpy (path, ".");
}
-void
-path_conv::update_fs_info (const char* win32_path)
+bool
+fs_info::update (const char *win32_path)
{
char tmp_buf [MAX_PATH];
strncpy (tmp_buf, win32_path, MAX_PATH);
@@ -323,41 +331,64 @@ path_conv::update_fs_info (const char* win32_path)
if (!rootdir (tmp_buf))
{
debug_printf ("Cannot get root component of path %s", win32_path);
- root_dir [0] = fs_name [0] = '\0';
- fs_flags = fs_serial = 0;
- sym_opt = 0;
- return;
+ name [0] = '\0';
+ sym_opt = flags = serial = 0;
+ return false;
}
- if (strcmp (tmp_buf, root_dir) != 0)
- {
- strncpy (root_dir, tmp_buf, MAX_PATH);
- drive_type = GetDriveType (root_dir);
- if (drive_type == DRIVE_REMOTE || (drive_type == DRIVE_UNKNOWN && (root_dir[0] == '\\' && root_dir[1] == '\\')))
- is_remote_drive = 1;
- else
- is_remote_drive = 0;
+ if (strcmp (tmp_buf, root_dir) == 0)
+ return 1;
- if (!GetVolumeInformation (root_dir, NULL, 0, &fs_serial, NULL, &fs_flags,
- fs_name, sizeof (fs_name)))
- {
- debug_printf ("Cannot get volume information (%s), %E", root_dir);
- fs_name [0] = '\0';
- fs_flags = fs_serial = 0;
- sym_opt = 0;
- }
- else
- {
- /* FIXME: Samba by default returns "NTFS" in file system name, but
- * doesn't support Extended Attributes. If there's some fast way to
- * distinguish between samba and real ntfs, it should be implemented
- * here.
- */
- sym_opt = (!is_remote_drive && strcmp (fs_name, "NTFS") == 0) ? PC_CHECK_EA : 0;
- }
+ strncpy (root_dir, tmp_buf, MAX_PATH);
+ drive_type = GetDriveType (root_dir);
+ if (drive_type == DRIVE_REMOTE || (drive_type == DRIVE_UNKNOWN && (root_dir[0] == '\\' && root_dir[1] == '\\')))
+ is_remote_drive = 1;
+ else
+ is_remote_drive = 0;
+
+ if (!GetVolumeInformation (root_dir, NULL, 0, &serial, NULL, &flags,
+ name, sizeof (name)))
+ {
+ debug_printf ("Cannot get volume information (%s), %E", root_dir);
+ name [0] = '\0';
+ sym_opt = flags = serial = 0;
+ return false;
}
+ /* FIXME: Samba by default returns "NTFS" in file system name, but
+ * doesn't support Extended Attributes. If there's some fast way to
+ * distinguish between samba and real ntfs, it should be implemented
+ * here.
+ */
+ sym_opt = (!is_remote_drive && strcmp (name, "NTFS") == 0) ? PC_CHECK_EA : 0;
+
+ return true;
}
+char *
+path_conv::return_and_clear_normalized_path ()
+{
+ char *s = normalized_path;
+ normalized_path = NULL;
+ return s;
+}
+
+void
+path_conv::fillin (HANDLE h)
+{
+ BY_HANDLE_FILE_INFORMATION local;
+ if (!GetFileInformationByHandle (h, &local))
+ {
+ fileattr = INVALID_FILE_ATTRIBUTES;
+ fs.serial = 0;
+ }
+ else
+ {
+ fileattr = local.dwFileAttributes;
+ fs.serial = local.dwVolumeSerialNumber;
+ }
+ fs.drive_type = DRIVE_UNKNOWN;
+}
+
/* Convert an arbitrary path SRC to a pure Win32 path, suitable for
passing to Win32 API routines.
@@ -384,6 +415,7 @@ path_conv::check (const char *src, unsigned opt,
bool need_directory = 0;
bool saw_symlinks = 0;
int is_relpath;
+ char *tail;
sigframe thisframe (mainthread);
#if 0
@@ -403,12 +435,13 @@ path_conv::check (const char *src, unsigned opt,
fileattr = INVALID_FILE_ATTRIBUTES;
case_clash = false;
devn = unit = 0;
- root_dir[0] = '\0';
- fs_name[0] = '\0';
- fs_flags = fs_serial = 0;
- sym_opt = 0;
- drive_type = 0;
- is_remote_drive = 0;
+ fs.root_dir[0] = '\0';
+ fs.name[0] = '\0';
+ fs.flags = fs.serial = 0;
+ fs.sym_opt = 0;
+ fs.drive_type = 0;
+ fs.is_remote_drive = 0;
+ normalized_path = NULL;
if (!(opt & PC_NULLEMPTY))
error = 0;
@@ -438,7 +471,7 @@ path_conv::check (const char *src, unsigned opt,
if (error)
return;
- char *tail = strchr (path_copy, '\0'); // Point to end of copy
+ tail = strchr (path_copy, '\0'); // Point to end of copy
char *path_end = tail;
tail[1] = '\0';
@@ -490,6 +523,28 @@ path_conv::check (const char *src, unsigned opt,
}
goto out;
}
+ else if (isvirtual_dev (devn))
+ {
+ /* FIXME: Calling build_fhandler here is not the right way to handle this. */
+ fhandler_virtual *fh =
+ (fhandler_virtual *) cygheap->fdtab.build_fhandler (-1, devn, (const char *) path_copy, NULL, unit);
+ int file_type = fh->exists ();
+ switch (file_type)
+ {
+ case 1:
+ case 2:
+ fileattr = FILE_ATTRIBUTE_DIRECTORY;
+ break;
+ case -1:
+ fileattr = 0;
+ break;
+ default:
+ fileattr = INVALID_FILE_ATTRIBUTES;
+ break;
+ }
+ delete fh;
+ goto out;
+ }
/* devn should not be a device. If it is, then stop parsing now. */
else if (devn != FH_BAD)
{
@@ -502,7 +557,8 @@ path_conv::check (const char *src, unsigned opt,
goto out; /* Found a device. Stop parsing. */
}
- update_fs_info (full_path);
+ if (!fs.update (full_path))
+ fs.root_dir[0] = '\0';
/* Eat trailing slashes */
char *dostail = strchr (full_path, '\0');
@@ -526,7 +582,7 @@ path_conv::check (const char *src, unsigned opt,
goto out;
}
- int len = sym.check (full_path, suff, opt | sym_opt);
+ int len = sym.check (full_path, suff, opt | fs.sym_opt);
if (sym.case_clash)
{
@@ -679,6 +735,12 @@ path_conv::check (const char *src, unsigned opt,
add_ext_from_sym (sym);
out:
+ if (opt & PC_POSIX)
+ {
+ if (tail[1] != '\0')
+ *tail = '/';
+ normalized_path = cstrdup (path_copy);
+ }
/* Deal with Windows stupidity which considers filename\. to be valid
even when "filename" is not a directory. */
if (!need_directory || error)
@@ -694,9 +756,9 @@ out:
if (devn == FH_BAD)
{
- update_fs_info (path);
- if (!fs_name[0])
+ if (!fs.update (path))
{
+ fs.root_dir[0] = '\0';
set_has_acls (false);
set_has_buggy_open (false);
}
@@ -704,14 +766,14 @@ out:
{
set_isdisk ();
debug_printf ("root_dir(%s), this->path(%s), set_has_acls(%d)",
- root_dir, this->path, fs_flags & FS_PERSISTENT_ACLS);
- if (!allow_smbntsec && is_remote_drive)
+ fs.root_dir, this->path, fs.flags & FS_PERSISTENT_ACLS);
+ if (!allow_smbntsec && fs.is_remote_drive)
set_has_acls (false);
else
- set_has_acls (fs_flags & FS_PERSISTENT_ACLS);
+ set_has_acls (fs.flags & FS_PERSISTENT_ACLS);
/* Known file systems with buggy open calls. Further explanation
in fhandler.cc (fhandler_disk_file::open). */
- set_has_buggy_open (strcmp (fs_name, "SUNWNFS") == 0);
+ set_has_buggy_open (strcmp (fs.name, "SUNWNFS") == 0);
}
}
#if 0
@@ -740,7 +802,7 @@ out:
if (saw_symlinks)
set_has_symlinks ();
- if (!error && !(path_flags & (PATH_ALL_EXEC | PATH_NOTEXEC)))
+ if (!error && !isdir () && !(path_flags & PATH_ALL_EXEC))
{
const char *p = strchr (path, '\0') - 4;
if (p >= path &&
@@ -854,7 +916,7 @@ get_devn (const char *name, int &unit)
devn = FH_MEM;
unit = 4;
}
- else if (deveqn ("com", 3) && (unit = digits (name + 3)) >= 0)
+ else if (deveqn ("com", 3) && (unit = digits (name + 3)) >= 0 && unit < 100)
devn = FH_SERIAL;
else if (deveqn ("ttyS", 4) && (unit = digits (name + 4)) >= 0)
{
@@ -1008,7 +1070,7 @@ get_device_number (const char *unix_path, const char *w32_path, int &unit)
if (p)
unix_path = p + 1;
if (udeveqn ("com", 3)
- && (unit = digits (unix_path + 3)) >= 0)
+ && (unit = digits (unix_path + 3)) >= 0 && unit < 100)
devn = FH_SERIAL;
}
@@ -1230,14 +1292,7 @@ slash_unc_prefix_p (const char *path)
return ret && isalnum (p[1]);
}
-/* conv_path_list: Convert a list of path names to/from Win32/POSIX.
-
- SRC is not a const char * because we temporarily modify it to ease
- the implementation.
-
- I believe Win32 always has '.' in $PATH. POSIX obviously doesn't.
- We certainly don't want to handle that here, but it is something for
- the caller to think about. */
+/* conv_path_list: Convert a list of path names to/from Win32/POSIX. */
static void
conv_path_list (const char *src, char *dst, int to_posix_p)
@@ -1272,13 +1327,20 @@ void
mount_info::init ()
{
nmounts = 0;
- had_to_create_mount_areas = 0;
/* Fetch the mount table and cygdrive-related information from
the registry. */
from_registry ();
}
+static void
+set_flags (unsigned *flags, unsigned val)
+{
+ *flags = val;
+ if (!(*flags & PATH_BINARY))
+ *flags = PATH_TEXT;
+}
+
/* conv_to_win32_path: Ensure src_path is a pure Win32 path and store
the result in win32_path.
@@ -1341,7 +1403,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
return rc;
}
- *flags = set_flags_from_win32_path (dst);
+ set_flags (flags, (unsigned) set_flags_from_win32_path (dst));
goto out;
}
@@ -1370,7 +1432,6 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
if (rc)
{
debug_printf ("%d = conv_to_win32_path (%s)", rc, src_path);
- *flags = 0;
return rc;
}
}
@@ -1386,7 +1447,13 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
/* Check if the cygdrive prefix was specified. If so, just strip
off the prefix and transform it into an MS-DOS path. */
MALLOC_CHECK;
- if (iscygdrive (pathbuf))
+ if (isproc (pathbuf))
+ {
+ devn = fhandler_proc::get_proc_fhandler (pathbuf);
+ if (devn == FH_BAD)
+ return ENOENT;
+ }
+ else if (iscygdrive (pathbuf))
{
int n = mount_table->cygdrive_len - 1;
if (!pathbuf[n] ||
@@ -1399,7 +1466,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
}
else if (cygdrive_win32_path (pathbuf, dst, unit))
{
- *flags = cygdrive_flags;
+ set_flags (flags, (unsigned) cygdrive_flags);
goto out;
}
else if (mount_table->cygdrive_len > 1)
@@ -1439,7 +1506,7 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
if (i >= nmounts)
{
backslashify (pathbuf, dst, 0); /* just convert */
- *flags = 0;
+ set_flags (flags, PATH_BINARY);
}
else
{
@@ -1469,10 +1536,10 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst,
dst[n++] = '\\';
strcpy (dst + n, p);
backslashify (dst, dst, 0);
- *flags = mi->flags;
+ set_flags (flags, (unsigned) mi->flags);
}
- if (devn != FH_CYGDRIVE)
+ if (!isvirtual_dev (devn))
win32_device_name (src_path, dst, devn, unit);
out:
@@ -1683,7 +1750,7 @@ mount_info::set_flags_from_win32_path (const char *p)
if (path_prefix_p (mi.native_path, p, mi.native_pathlen))
return mi.flags;
}
- return 0;
+ return PATH_BINARY;
}
/* read_mounts: Given a specific regkey, read mounts from under its
@@ -1760,11 +1827,6 @@ mount_info::from_registry ()
CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME,
NULL);
read_mounts (r1);
-
- /* If we had to create both user and system mount areas, import
- old mounts. */
- if (had_to_create_mount_areas == 2)
- import_v1_mounts ();
}
/* add_reg_mount: Add mount item to registry. Return zero on success,
@@ -1887,15 +1949,15 @@ mount_info::read_cygdrive_info_from_registry ()
if (r2.get_string (CYGWIN_INFO_CYGDRIVE_PREFIX, cygdrive,
sizeof (cygdrive), ""))
strcpy (cygdrive, CYGWIN_INFO_CYGDRIVE_DEFAULT_PREFIX);
- cygdrive_flags = r2.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_AUTO);
+ cygdrive_flags = r2.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_CYGDRIVE);
slashify (cygdrive, cygdrive, 1);
cygdrive_len = strlen (cygdrive);
}
else
{
- /* Fetch user cygdrive_flags from registry; returns MOUNT_AUTO on
+ /* Fetch user cygdrive_flags from registry; returns MOUNT_CYGDRIVE on
error. */
- cygdrive_flags = r.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_AUTO);
+ cygdrive_flags = r.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_CYGDRIVE);
slashify (cygdrive, cygdrive, 1);
cygdrive_len = strlen(cygdrive);
}
@@ -2002,7 +2064,7 @@ mount_info::get_cygdrive_info (char *user, char *system, char* user_flags,
/* Get the user flags, if appropriate */
if (res == ERROR_SUCCESS)
{
- int flags = r.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_AUTO);
+ int flags = r.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_CYGDRIVE);
strcpy (user_flags, (flags & MOUNT_BINARY) ? "binmode" : "textmode");
}
@@ -2016,7 +2078,7 @@ mount_info::get_cygdrive_info (char *user, char *system, char* user_flags,
/* Get the system flags, if appropriate */
if (res2 == ERROR_SUCCESS)
{
- int flags = r2.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_AUTO);
+ int flags = r2.get_int (CYGWIN_INFO_CYGDRIVE_FLAGS, MOUNT_CYGDRIVE);
strcpy (system_flags, (flags & MOUNT_BINARY) ? "binmode" : "textmode");
}
@@ -2240,81 +2302,6 @@ mount_info::del_item (const char *path, unsigned flags, int reg_p)
return -1;
}
-/* read_v1_mounts: Given a reg_key to an old mount table registry area,
- read in the mounts. The "which" arg contains zero if we're reading
- the user area and MOUNT_SYSTEM if we're reading the system area.
- This way we can store the mounts read in the appropriate place when
- they are written back to the new registry layout. */
-
-void
-mount_info::read_v1_mounts (reg_key r, unsigned which)
-{
- unsigned mountflags = 0;
-
- /* MAX_MOUNTS was 30 when we stopped using the v1 layout */
- for (int i = 0; i < 30; i++)
- {
- char key_name[10];
- char win32path[MAX_PATH];
- char unixpath[MAX_PATH];
-
- __small_sprintf (key_name, "%02x", i);
-
- reg_key k (r.get_key (), KEY_ALL_ACCESS, key_name, NULL);
-
- /* The registry names are historical but useful so are left alone. */
- k.get_string ("native", win32path, sizeof (win32path), "");
- k.get_string ("unix", unixpath, sizeof (unixpath), "");
-
- /* Does this entry contain something? */
- if (*win32path != 0)
- {
- mountflags = 0;
-
- if (k.get_int ("fbinary", 0))
- mountflags |= MOUNT_BINARY;
-
- /* Or in zero or MOUNT_SYSTEM depending on which table
- we're reading. */
- mountflags |= which;
-
- int res = mount_table->add_item (win32path, unixpath, mountflags, TRUE);
- if (res && get_errno () == EMFILE)
- break; /* The number of entries exceeds MAX_MOUNTS */
- }
- }
-}
-
-/* import_v1_mounts: If v1 mounts are present, load them and write
- the new entries to the new registry area. */
-
-void
-mount_info::import_v1_mounts ()
-{
- reg_key r (HKEY_CURRENT_USER, KEY_ALL_ACCESS,
- "SOFTWARE",
- "Cygnus Solutions",
- "CYGWIN.DLL setup",
- "b15.0",
- "mounts",
- NULL);
-
- nmounts = 0;
-
- /* First read mounts from user's table. */
- read_v1_mounts (r, 0);
-
- /* Then read mounts from system-wide mount table. */
- reg_key r1 (HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS,
- "SOFTWARE",
- "Cygnus Solutions",
- "CYGWIN.DLL setup",
- "b15.0",
- "mounts",
- NULL);
- read_v1_mounts (r1, MOUNT_SYSTEM);
-}
-
/************************* mount_item class ****************************/
static mntent *
@@ -2364,8 +2351,10 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
strcat (_reent_winsup ()->mnt_opts, (char *) ",cygexec");
else if (flags & MOUNT_EXEC)
strcat (_reent_winsup ()->mnt_opts, (char *) ",exec");
+ else if (flags & MOUNT_NOTEXEC)
+ strcat (_reent_winsup ()->mnt_opts, (char *) ",noexec");
- if ((flags & MOUNT_AUTO)) /* cygdrive */
+ if ((flags & MOUNT_CYGDRIVE)) /* cygdrive */
strcat (_reent_winsup ()->mnt_opts, (char *) ",noumount");
ret.mnt_opts = _reent_winsup ()->mnt_opts;
@@ -2448,9 +2437,9 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
{
int res = -1;
- if (flags & MOUNT_AUTO) /* normal mount */
+ if (flags & MOUNT_CYGDRIVE) /* normal mount */
{
- /* When flags include MOUNT_AUTO, take this to mean that
+ /* When flags include MOUNT_CYGDRIVE, take this to mean that
we actually want to change the cygdrive prefix and flags
without actually mounting anything. */
res = mount_table->write_cygdrive_info_to_registry (posix_path, flags);
@@ -2483,9 +2472,9 @@ cygwin_umount (const char *path, unsigned flags)
{
int res = -1;
- if (flags & MOUNT_AUTO)
+ if (flags & MOUNT_CYGDRIVE)
{
- /* When flags include MOUNT_AUTO, take this to mean that we actually want
+ /* When flags include MOUNT_CYGDRIVE, take this to mean that we actually want
to remove the cygdrive prefix and flags without actually unmounting
anything. */
res = mount_table->remove_cygdrive_info_from_registry (path, flags);
@@ -2627,7 +2616,7 @@ symlink (const char *topath, const char *frompath)
&sa, alloca (4096), 4096);
h = CreateFileA(win32_path, GENERIC_WRITE, 0, &sa,
- CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
+ CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
if (h == INVALID_HANDLE_VALUE)
__seterrno ();
else
@@ -2675,7 +2664,7 @@ symlink (const char *topath, const char *frompath)
S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO);
DWORD attr = allow_winsymlinks ? FILE_ATTRIBUTE_READONLY
- : FILE_ATTRIBUTE_SYSTEM;
+ : FILE_ATTRIBUTE_SYSTEM;
#ifdef HIDDEN_DOT_FILES
cp = strrchr (win32_path, '\\');
if ((cp && cp[1] == '.') || *win32_path == '.')
@@ -3132,7 +3121,7 @@ hash_path_name (unsigned long hash, const char *name)
hash = cygheap->cwd.get_hash ();
if (name[0] == '.' && name[1] == '\0')
return hash;
- hash += hash_path_name (hash, "\\");
+ hash = (hash << 5) - hash + '\\';
}
}
@@ -3142,8 +3131,7 @@ hashit:
do
{
int ch = cyg_tolower(*name);
- hash += ch + (ch << 17);
- hash ^= hash >> 2;
+ hash = (hash << 5) - hash + ch;
}
while (*++name != '\0' &&
!(*name == '\\' && (!name[1] || (name[1] == '.' && !name[2]))));
@@ -3233,15 +3221,26 @@ chdir (const char *in_dir)
path.get_win32 ()[3] = '\0';
}
int res;
- if (path.get_devn () != FH_CYGDRIVE)
+ int devn = path.get_devn();
+ if (!isvirtual_dev (devn))
res = SetCurrentDirectory (native_dir) ? 0 : -1;
+ else if (!path.exists ())
+ {
+ set_errno (ENOENT);
+ return -1;
+ }
+ else if (!path.isdir ())
+ {
+ set_errno (ENOTDIR);
+ return -1;
+ }
else
{
native_dir = "c:\\";
res = 0;
}
- /* If res < 0, we didn't change to a new directory.
+ /* If res != 0, we didn't change to a new directory.
Otherwise, set the current windows and posix directory cache from input.
If the specified directory is a MS-DOS style directory or if the directory
was symlinked, convert the MS-DOS path back to posix style. Otherwise just
@@ -3251,10 +3250,10 @@ chdir (const char *in_dir)
do when we detect a symlink? Should we instead rebuild the posix path from
the input by traversing links? This would be an expensive operation but
we'll see if Cygwin mailing list users whine about the current behavior. */
- if (res == -1)
+ if (res)
__seterrno ();
- else if (!path.has_symlinks () && strpbrk (dir, ":\\") == NULL
- && pcheck_case == PCHECK_RELAXED)
+ else if ((!path.has_symlinks () && strpbrk (dir, ":\\") == NULL
+ && pcheck_case == PCHECK_RELAXED) || isvirtual_dev (devn))
cygheap->cwd.set (native_dir, dir);
else
cygheap->cwd.set (native_dir, NULL);
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index ea3a6545a..50c5a743c 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -23,7 +23,8 @@ enum pathconv_arg
PC_SYM_CONTENTS = 0x0008,
PC_FULL = 0x0010,
PC_NULLEMPTY = 0x0020,
- PC_CHECK_EA = 0x0040
+ PC_CHECK_EA = 0x0040,
+ PC_POSIX = 0x0080
};
enum case_checking
@@ -43,10 +44,11 @@ enum path_types
PATH_SYMLINK = MOUNT_SYMLINK,
PATH_BINARY = MOUNT_BINARY,
PATH_EXEC = MOUNT_EXEC,
+ PATH_NOTEXEC = MOUNT_NOTEXEC,
PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC,
PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC),
+ PATH_TEXT = 0x02000000,
PATH_ISDISK = 0x04000000,
- PATH_NOTEXEC = 0x08000000,
PATH_HAS_SYMLINKS = 0x10000000,
PATH_HASBUGGYOPEN = 0x20000000,
PATH_SOCKET = 0x40000000,
@@ -54,18 +56,22 @@ enum path_types
};
class symlink_info;
-class path_conv
+struct fs_info
{
- char path[MAX_PATH];
+ char name[MAX_PATH];
char root_dir[MAX_PATH];
- char fs_name[MAX_PATH];
- DWORD fs_flags;
- DWORD fs_serial;
+ DWORD flags;
+ DWORD serial;
DWORD sym_opt; /* additional options to pass to symlink_info resolver */
- void add_ext_from_sym (symlink_info&);
- void update_fs_info (const char*);
+ DWORD is_remote_drive;
DWORD drive_type;
- bool is_remote_drive;
+ bool update (const char *);
+};
+class path_conv
+{
+ char path[MAX_PATH];
+ fs_info fs;
+ void add_ext_from_sym (symlink_info&);
public:
unsigned path_flags;
@@ -75,14 +81,22 @@ class path_conv
int unit;
DWORD fileattr;
BOOL case_clash;
+ char *normalized_path;
int isdisk () const { return path_flags & PATH_ISDISK;}
- int isremote () const {return is_remote_drive;}
+ int isremote () const {return fs.is_remote_drive;}
int has_acls () const {return path_flags & PATH_HASACLS;}
int has_symlinks () const {return path_flags & PATH_HAS_SYMLINKS;}
int hasgood_inode () const {return path_flags & PATH_HASACLS;} // Not strictly correct
int has_buggy_open () const {return path_flags & PATH_HASBUGGYOPEN;}
- int isbinary () const {return path_flags & PATH_BINARY;}
+ int binmode () const
+ {
+ if (path_flags & PATH_BINARY)
+ return O_BINARY;
+ if (path_flags & PATH_TEXT)
+ return O_TEXT;
+ return 0;
+ }
int issymlink () const {return path_flags & PATH_SYMLINK;}
int issocket () const {return path_flags & PATH_SOCKET;}
int iscygexec () const {return path_flags & PATH_CYGWIN_EXEC;}
@@ -124,19 +138,27 @@ class path_conv
check (src, opt | PC_NULLEMPTY, suffixes);
}
- path_conv (): path_flags (0), known_suffix (NULL), error (0), devn (0), unit (0), fileattr (INVALID_FILE_ATTRIBUTES) {path[0] = '\0';}
+ path_conv (): path_flags (0), known_suffix (NULL), error (0), devn (0),
+ unit (0), fileattr (INVALID_FILE_ATTRIBUTES),
+ normalized_path (NULL) {path[0] = '\0';}
inline char *get_win32 () { return path; }
- operator char *() {return path; }
- operator DWORD &() {return fileattr; }
+ operator char *() {return path;}
+ operator const char *() {return path;}
+ operator DWORD &() {return fileattr;}
operator int &() {return (int) fileattr; }
BOOL is_device () {return devn != FH_BAD && devn != FH_DISK;}
DWORD get_devn () {return devn == FH_BAD ? (DWORD) FH_DISK : devn;}
short get_unitn () {return devn == FH_BAD ? 0 : unit;}
DWORD file_attributes () {return fileattr;}
- DWORD get_drive_type () {return drive_type;}
- BOOL fs_fast_ea () {return sym_opt & PC_CHECK_EA;}
+ DWORD drive_type () {return fs.drive_type;}
+ BOOL fs_fast_ea () {return fs.sym_opt & PC_CHECK_EA;}
void set_path (const char *p) {strcpy (path, p);}
+ char *return_and_clear_normalized_path ();
+ const char * root_dir () { return fs.root_dir; }
+ DWORD volser () { return fs.serial; }
+ const char *volname () {return fs.name; }
+ void fillin (HANDLE h);
};
/* Symlink marker */
@@ -178,3 +200,5 @@ has_exec_chars (const char *buf, int len)
int pathmatch (const char *path1, const char *path2) __attribute__ ((regparm (2)));
int pathnmatch (const char *path1, const char *path2, int len) __attribute__ ((regparm (2)));
+
+int path_prefix_p (const char *path1, const char *path2, int len1) __attribute__ ((regparm (3)));
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 1bc4ac411..44ca1df46 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -18,7 +18,6 @@ details. */
#include "path.h"
#include "dtable.h"
#include "cygerrno.h"
-#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include "cygwin_version.h"
@@ -28,7 +27,7 @@ details. */
#include <ntdef.h>
#include "ntdll.h"
-static char NO_COPY pinfo_dummy[sizeof(pinfo)] = {0};
+static char NO_COPY pinfo_dummy[sizeof (_pinfo)] = {0};
pinfo NO_COPY myself ((_pinfo *)&pinfo_dummy); // Avoid myself != NULL checks
@@ -183,6 +182,11 @@ pinfo::init (pid_t n, DWORD flag, HANDLE in_h)
api_fatal ("retrieval of execed process info for pid %d failed due to recursion.", n);
n = realpid;
release ();
+ if (flag & PID_ALLPIDS)
+ {
+ set_errno (ENOENT);
+ break;
+ }
continue;
}
@@ -282,7 +286,7 @@ winpids::add (DWORD& nelem, bool winpid, DWORD pid)
pinfolist = (pinfo *) realloc (pinfolist, size_pinfolist (npidlist + 1));
}
- pinfolist[nelem].init (cygpid, PID_NOREDIR);
+ pinfolist[nelem].init (cygpid, PID_NOREDIR | (winpid ? PID_ALLPIDS : 0));
if (winpid)
/* nothing to do */;
else if (!pinfolist[nelem])
@@ -314,7 +318,7 @@ winpids::enumNT (bool winpid)
NTSTATUS res;
for (;;)
{
- res = ZwQuerySystemInformation (SystemProcessesAndThreadsInformation,
+ res = NtQuerySystemInformation (SystemProcessesAndThreadsInformation,
procs, szprocs, NULL);
if (res == 0)
break;
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index 1bc2f7919..8a090cfd9 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -8,6 +8,8 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
+#ifndef _PINFO_H
+#define _PINFO_H
/* Signal constants (have to define them here, unfortunately) */
enum
@@ -39,7 +41,7 @@ public:
we only use this handle from the parent. */
HANDLE hProcess;
-#define PINFO_REDIR_SIZE ((DWORD) &(((_pinfo *)NULL)->hProcess) + sizeof (DWORD))
+#define PINFO_REDIR_SIZE ((char *) &myself.procinfo->hProcess - (char *) myself.procinfo)
/* Handle associated with initial Windows pid which started it all. */
HANDLE pid_handle;
@@ -65,8 +67,8 @@ public:
if not found. This data resides in the shared data area (allowing
tasks to store whatever they want here) so it's for informational
purposes only. */
- __uid16_t uid; /* User ID */
- __gid16_t gid; /* Group ID */
+ __uid32_t uid; /* User ID */
+ __gid32_t gid; /* Group ID */
pid_t pgid; /* Process group ID */
pid_t sid; /* Session ID */
int ctty; /* Control tty */
@@ -95,7 +97,7 @@ public:
return thread2signal ? thread2signal->sigs[sig] : sigs[sig];
}
- inline void copysigs (_pinfo *p) {sigs = p->sigs;}
+ inline void copysigs (_pinfo *p) {memcpy (sigs, p->sigs, sizeof (sigs));}
inline sigset_t& getsigmask ()
{
@@ -152,7 +154,11 @@ public:
_pinfo *operator * () const {return procinfo;}
operator _pinfo * () const {return procinfo;}
// operator bool () const {return (int) h;}
+#ifdef _SIGPROC_H
int remember () {destroy = 0; return proc_subproc (PROC_ADDCHILD, (DWORD) this);}
+#else
+ int remember () {system_printf ("remember is not here"); return 0;}
+#endif
HANDLE shared_handle () {return h;}
};
@@ -193,16 +199,14 @@ void __stdcall set_myself (pid_t pid, HANDLE h = NULL);
extern pinfo myself;
#define _P_VFORK 0
-extern "C" int _spawnve (HANDLE hToken, int mode, const char *path,
- const char *const *argv, const char *const *envp);
-
extern void __stdcall pinfo_fixup_after_fork ();
extern HANDLE hexec_proc;
/* For mmaps across fork(). */
-int __stdcall fixup_mmaps_after_fork ();
+int __stdcall fixup_mmaps_after_fork (HANDLE parent);
/* for shm areas across fork (). */
int __stdcall fixup_shms_after_fork ();
void __stdcall fill_rusage (struct rusage *, HANDLE);
void __stdcall add_rusage (struct rusage *, struct rusage *);
+#endif /*_PINFO_H*/
diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc
index b87080792..9313f085c 100644
--- a/winsup/cygwin/pipe.cc
+++ b/winsup/cygwin/pipe.cc
@@ -10,7 +10,6 @@ details. */
#include "winsup.h"
#include <unistd.h>
-#include <sys/fcntl.h>
#include <errno.h>
#include "cygerrno.h"
#include "security.h"
@@ -19,7 +18,6 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "thread.h"
-#include "sigproc.h"
#include "pinfo.h"
static unsigned pipecount;
@@ -149,7 +147,7 @@ make_pipe (int fildes[2], unsigned int psize, int mode)
fhandler_pipe *fhr = (fhandler_pipe *) cygheap->fdtab.build_fhandler (fdr, FH_PIPER, "/dev/piper");
fhandler_pipe *fhw = (fhandler_pipe *) cygheap->fdtab.build_fhandler (fdw, FH_PIPEW, "/dev/pipew");
- int binmode = mode & O_TEXT ? 0 : 1;
+ int binmode = mode & O_TEXT ?: O_BINARY;
fhr->init (r, GENERIC_READ, binmode);
fhw->init (w, GENERIC_WRITE, binmode);
if (mode & O_NOINHERIT)
diff --git a/winsup/cygwin/poll.cc b/winsup/cygwin/poll.cc
index 8b73c5afd..a1c50e8b0 100644
--- a/winsup/cygwin/poll.cc
+++ b/winsup/cygwin/poll.cc
@@ -1,6 +1,6 @@
/* poll.cc. Implements poll(2) via usage of select(2) call.
- Copyright 2000, 2001 Red Hat, Inc.
+ Copyright 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -26,7 +26,7 @@ int
poll (struct pollfd *fds, unsigned int nfds, int timeout)
{
int max_fd = 0;
- fd_set *open_fds, *read_fds, *write_fds, *except_fds;
+ fd_set *read_fds, *write_fds, *except_fds;
struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 };
sigframe thisframe (mainthread);
@@ -36,63 +36,65 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
size_t fds_size = howmany(max_fd + 1, NFDBITS) * sizeof (fd_mask);
- open_fds = (fd_set *) alloca (fds_size);
read_fds = (fd_set *) alloca (fds_size);
write_fds = (fd_set *) alloca (fds_size);
except_fds = (fd_set *) alloca (fds_size);
- if (!open_fds || !read_fds || !write_fds || !except_fds)
+ if (!read_fds || !write_fds || !except_fds)
{
set_errno (ENOMEM);
return -1;
}
- memset (open_fds, 0, fds_size);
memset (read_fds, 0, fds_size);
memset (write_fds, 0, fds_size);
memset (except_fds, 0, fds_size);
- bool valid_fds = false;
- for (unsigned int i = 0; i < nfds; ++i)
- if (!cygheap->fdtab.not_open (fds[i].fd))
- {
- valid_fds = true;
- fds[i].revents = 0;
- FD_SET (fds[i].fd, open_fds);
- if (fds[i].events & POLLIN)
- FD_SET (fds[i].fd, read_fds);
- if (fds[i].events & POLLOUT)
- FD_SET (fds[i].fd, write_fds);
- if (fds[i].events & POLLPRI)
- FD_SET (fds[i].fd, except_fds);
- }
- else
- fds[i].revents = POLLNVAL;
-
- int ret = 0;
- if (valid_fds)
- ret = cygwin_select (max_fd + 1, read_fds, write_fds, except_fds,
- timeout < 0 ? NULL : &tv);
-
+ int invalid_fds = 0;
for (unsigned int i = 0; i < nfds; ++i)
{
- if (fds[i].revents == POLLNVAL && ret >= 0)
- ret++;
- else if (cygheap->fdtab.not_open(fds[i].fd))
- fds[i].revents = POLLHUP;
- else if (ret < 0)
- fds[i].revents = POLLERR;
- else
+ fds[i].revents = 0;
+ if (!cygheap->fdtab.not_open(fds[i].fd))
+ {
+ if (fds[i].events & POLLIN)
+ FD_SET(fds[i].fd, read_fds);
+ if (fds[i].events & POLLOUT)
+ FD_SET(fds[i].fd, write_fds);
+ if (fds[i].events & POLLPRI)
+ FD_SET(fds[i].fd, except_fds);
+ }
+ else if (fds[i].fd >= 0)
{
- fds[i].revents = 0;
- if (FD_ISSET (fds[i].fd, read_fds))
- fds[i].revents |= POLLIN;
- if (FD_ISSET (fds[i].fd, write_fds))
- fds[i].revents |= POLLOUT;
- if (FD_ISSET (fds[i].fd, except_fds))
- fds[i].revents |= POLLPRI;
+ ++invalid_fds;
+ fds[i].revents = POLLNVAL;
}
}
+ if (invalid_fds)
+ return invalid_fds;
+
+ int ret = cygwin_select (max_fd + 1, read_fds, write_fds, except_fds, timeout < 0 ? NULL : &tv);
+
+ if (ret > 0)
+ for (unsigned int i = 0; i < nfds; ++i)
+ {
+ if (fds[i].fd >= 0)
+ {
+ if (cygheap->fdtab.not_open(fds[i].fd))
+ fds[i].revents = POLLHUP;
+ else
+ {
+ if (FD_ISSET(fds[i].fd, read_fds))
+ fds[i].revents |= POLLIN;
+ if (FD_ISSET(fds[i].fd, write_fds))
+ fds[i].revents |= POLLOUT;
+ if (FD_ISSET(fds[i].fd, read_fds) && FD_ISSET(fds[i].fd, write_fds))
+ fds[i].revents |= POLLERR;
+ if (FD_ISSET(fds[i].fd, except_fds))
+ fds[i].revents |= POLLPRI;
+ }
+ }
+ }
+
return ret;
}
diff --git a/winsup/cygwin/pthread.cc b/winsup/cygwin/pthread.cc
index 7d8ca1ae6..ab7fd1fbe 100644
--- a/winsup/cygwin/pthread.cc
+++ b/winsup/cygwin/pthread.cc
@@ -218,7 +218,7 @@ pthread_sigmask (int operation, const sigset_t * set, sigset_t * old_set)
pthread_t pthread_self ()
{
- return __pthread_self ();
+ return pthread::self();
}
int
@@ -425,8 +425,6 @@ pthread_cancel (pthread_t thread)
return __pthread_cancel (thread);
}
-
-
int
pthread_setcancelstate (int state, int *oldstate)
{
@@ -445,6 +443,18 @@ pthread_testcancel (void)
__pthread_testcancel ();
}
+void
+_pthread_cleanup_push (__pthread_cleanup_handler *handler)
+{
+ pthread::self()->push_cleanup_handler(handler);
+}
+
+void
+_pthread_cleanup_pop (int execute)
+{
+ pthread::self()->pop_cleanup_handler (execute);
+}
+
/* Semaphores */
int
sem_init (sem_t * sem, int pshared, unsigned int value)
diff --git a/winsup/cygwin/pwdgrp.h b/winsup/cygwin/pwdgrp.h
index 568259db2..d2dcfcd1a 100644
--- a/winsup/cygwin/pwdgrp.h
+++ b/winsup/cygwin/pwdgrp.h
@@ -44,12 +44,81 @@ public:
{
state = nstate;
}
- void set_last_modified (FILE *f)
+ void set_last_modified (HANDLE fh, const char *name)
{
if (!file_w32[0])
- strcpy (file_w32, cygheap->fdtab[fileno (f)]->get_win32_name ());
-
- GetFileTime (cygheap->fdtab[fileno (f)]->get_handle (),
- NULL, NULL, &last_modified);
+ strcpy (file_w32, name);
+ GetFileTime (fh, NULL, NULL, &last_modified);
}
};
+
+class pwdgrp_read {
+ path_conv pc;
+ HANDLE fh;
+ char *buf;
+ char *lptr, *eptr;
+
+public:
+ pwdgrp_read ()
+ : fh (INVALID_HANDLE_VALUE), buf (NULL), lptr (NULL), eptr (NULL) {}
+ virtual ~pwdgrp_read ()
+ {
+ close ();
+ if (buf)
+ free (buf);
+ }
+
+ bool open (const char *posix_fname)
+ {
+ if (buf)
+ free (buf);
+ buf = lptr = eptr = NULL;
+
+ pc.check (posix_fname);
+ if (pc.error || !pc.exists () || !pc.isdisk () || pc.isdir ())
+ return false;
+
+ fh = CreateFile (pc, GENERIC_READ, wincap.shared (), NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ if (fh)
+ {
+ DWORD size = GetFileSize (fh, NULL), read_bytes;
+ buf = (char *) malloc (size + 1);
+ if (!ReadFile (fh, buf, size, &read_bytes, NULL))
+ {
+ if (buf)
+ free (buf);
+ buf = NULL;
+ CloseHandle (fh);
+ fh = INVALID_HANDLE_VALUE;
+ return false;
+ }
+ buf[read_bytes] = '\0';
+ return true;
+ }
+ return false;
+ }
+ char *gets ()
+ {
+ if (!buf)
+ return NULL;
+ if (!lptr)
+ lptr = buf;
+ else if (!eptr)
+ return lptr = NULL;
+ else
+ lptr = eptr;
+ eptr = strchr (lptr, '\n');
+ if (eptr)
+ *eptr++ = '\0';
+ return lptr;
+ }
+ inline HANDLE get_fhandle () { return fh; }
+ inline const char *get_fname () { return pc; }
+ void close ()
+ {
+ if (fh != INVALID_HANDLE_VALUE)
+ CloseHandle (fh);
+ fh = INVALID_HANDLE_VALUE;
+ }
+};
diff --git a/winsup/cygwin/registry.cc b/winsup/cygwin/registry.cc
index 3ed1a80bb..22fa511a7 100644
--- a/winsup/cygwin/registry.cc
+++ b/winsup/cygwin/registry.cc
@@ -1,6 +1,6 @@
/* registry.cc: registry interface
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -235,12 +235,13 @@ load_registry_hive (PSID psid)
/* Check if user hive is already loaded. */
cygsid csid (psid);
csid.string (sid);
- if (!RegOpenKeyExA (HKEY_USERS, csid.string (sid), 0, KEY_READ, &hkey))
+ if (!RegOpenKeyExA (HKEY_USERS, sid, 0, KEY_READ, &hkey))
{
debug_printf ("User registry hive for %s already exists", sid);
RegCloseKey (hkey);
return;
}
+ set_process_privilege (SE_RESTORE_NAME);
if (get_registry_hive_path (psid, path))
{
strcat (path, "\\NTUSER.DAT");
diff --git a/winsup/cygwin/resource.cc b/winsup/cygwin/resource.cc
index e9121e94c..8d9887158 100644
--- a/winsup/cygwin/resource.cc
+++ b/winsup/cygwin/resource.cc
@@ -1,6 +1,6 @@
/* resource.cc: getrusage () and friends.
- Copyright 1996, 1997, 1998, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 2000, 2001, 2002 Red Hat, Inc.
Written by Steve Chamberlain (sac@cygnus.com), Doug Evans (dje@cygnus.com),
Geoffrey Noer (noer@cygnus.com) of Cygnus Support.
@@ -17,8 +17,6 @@ details. */
#include <unistd.h>
#include <limits.h>
#include "cygerrno.h"
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "psapi.h"
diff --git a/winsup/cygwin/sched.cc b/winsup/cygwin/sched.cc
index 522fb0c02..7b4074d7f 100644
--- a/winsup/cygwin/sched.cc
+++ b/winsup/cygwin/sched.cc
@@ -22,7 +22,6 @@
#include <stdlib.h>
#include <syslog.h>
#include <sched.h>
-#include "sigproc.h"
#include "pinfo.h"
/* for getpid */
#include <unistd.h>
diff --git a/winsup/cygwin/sec_acl.cc b/winsup/cygwin/sec_acl.cc
index 36c31a840..e93073794 100644
--- a/winsup/cygwin/sec_acl.cc
+++ b/winsup/cygwin/sec_acl.cc
@@ -24,13 +24,10 @@ details. */
#include <wingdi.h>
#include <winuser.h>
#include "cygerrno.h"
-#include "perprocess.h"
#include "security.h"
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
@@ -109,7 +106,7 @@ setacl (const char *file, int nentries, __aclent16_t *aclbufp)
cygsid sid;
struct passwd *pw;
- struct __group16 *gr;
+ struct __group32 *gr;
int pos;
if (!InitializeAcl (acl, 3072, ACL_REVISION))
@@ -160,7 +157,7 @@ setacl (const char *file, int nentries, __aclent16_t *aclbufp)
break;
case USER:
case DEF_USER:
- if (!(pw = getpwuid (aclbufp[i].a_id))
+ if (!(pw = getpwuid32 (aclbufp[i].a_id))
|| !sid.getfrompw (pw)
|| !add_access_allowed_ace (acl, ace_off++, allow,
sid, acl_len, inheritance))
@@ -174,7 +171,7 @@ setacl (const char *file, int nentries, __aclent16_t *aclbufp)
break;
case GROUP:
case DEF_GROUP:
- if (!(gr = getgrgid (aclbufp[i].a_id))
+ if (!(gr = getgrgid32 (aclbufp[i].a_id))
|| !sid.getfromgr (gr)
|| !add_access_allowed_ace (acl, ace_off++, allow,
sid, acl_len, inheritance))
@@ -257,8 +254,8 @@ getacl (const char *file, DWORD attr, int nentries, __aclent16_t *aclbufp)
PSID owner_sid;
PSID group_sid;
BOOL dummy;
- __uid16_t uid;
- __gid16_t gid;
+ __uid32_t uid;
+ __gid32_t gid;
if (!GetSecurityDescriptorOwner (psd, &owner_sid, &dummy))
{
@@ -426,9 +423,9 @@ acl_access (const char *path, int flags)
cygsid owner;
cygsid group;
struct passwd *pw;
- struct __group16 *gr = NULL;
+ struct __group32 *gr = NULL;
- if ((pw = getpwuid (acls[i].a_id)) != NULL
+ if ((pw = getpwuid32 (acls[i].a_id)) != NULL
&& owner.getfrompw (pw))
{
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
@@ -996,7 +993,7 @@ aclfromtext (char *acltextp, int *)
c += 5;
if (isalpha (*c))
{
- struct __group16 *gr = getgrnam (c);
+ struct __group32 *gr = getgrnam32 (c);
if (!gr)
{
set_errno (EINVAL);
diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc
index 2f9b9b60c..cfa0fafce 100644
--- a/winsup/cygwin/sec_helper.cc
+++ b/winsup/cygwin/sec_helper.cc
@@ -25,13 +25,10 @@ details. */
#include <winuser.h>
#include <wininet.h>
#include "cygerrno.h"
-#include "perprocess.h"
#include "security.h"
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
@@ -129,7 +126,7 @@ cygsid::getfrompw (const struct passwd *pw)
}
BOOL
-cygsid::getfromgr (const struct __group16 *gr)
+cygsid::getfromgr (const struct __group32 *gr)
{
char *sp = (gr && gr->gr_passwd) ? gr->gr_passwd : NULL;
return (*this = sp ?: "") != NULL;
@@ -176,7 +173,7 @@ cygsid::get_id (BOOL search_grp, int *type)
}
if (search_grp || type)
{
- struct __group16 *gr;
+ struct __group32 *gr;
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
{
if (sid.getfromgr (gr) && sid == psid)
@@ -226,7 +223,7 @@ cygsid::get_id (BOOL search_grp, int *type)
*type = GROUP;
if (id == -1)
{
- struct __group16 *gr = getgrnam (account);
+ struct __group32 *gr = getgrnam32 (account);
if (gr)
id = gr->gr_gid;
}
@@ -246,21 +243,21 @@ cygsid::get_id (BOOL search_grp, int *type)
}
}
if (id == -1)
- id = getuid ();
+ id = getuid32 ();
return id;
}
BOOL
-is_grp_member (__uid16_t uid, __gid16_t gid)
+is_grp_member (__uid32_t uid, __gid32_t gid)
{
- extern int getgroups (int, __gid16_t *, __gid16_t, const char *);
+ extern int getgroups32 (int, __gid32_t *, __gid32_t, const char *);
BOOL grp_member = TRUE;
- struct passwd *pw = getpwuid (uid);
- __gid16_t grps[NGROUPS_MAX];
- int cnt = getgroups (NGROUPS_MAX, grps,
- pw ? pw->pw_gid : myself->gid,
- pw ? pw->pw_name : cygheap->user.name ());
+ struct passwd *pw = getpwuid32 (uid);
+ __gid32_t grps[NGROUPS_MAX];
+ int cnt = getgroups32 (NGROUPS_MAX, grps,
+ pw ? pw->pw_gid : myself->gid,
+ pw ? pw->pw_name : cygheap->user.name ());
int i;
for (i = 0; i < cnt; ++i)
if (grps[i] == gid)
@@ -269,6 +266,7 @@ is_grp_member (__uid16_t uid, __gid16_t gid)
return grp_member;
}
+#if 0 // unused
#define SIDLEN (sidlen = MAX_SID_LEN, &sidlen)
#define DOMLEN (domlen = INTERNET_MAX_HOST_NAME_LENGTH, &domlen)
@@ -337,6 +335,7 @@ got_it:
#undef SIDLEN
#undef DOMLEN
+#endif //unused
int
set_process_privilege (const char *privilege, BOOL enable)
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc
index b33360d1a..490938d50 100644
--- a/winsup/cygwin/security.cc
+++ b/winsup/cygwin/security.cc
@@ -29,13 +29,10 @@ details. */
#include <ntsecapi.h>
#include <subauth.h>
#include "cygerrno.h"
-#include "perprocess.h"
#include "security.h"
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "cygheap.h"
#include <ntdef.h>
@@ -49,8 +46,7 @@ BOOL allow_ntsec;
The default is TRUE to reflect the old behaviour. */
BOOL allow_smbntsec = TRUE;
-extern "C"
-void
+extern "C" void
cygwin_set_impersonation_token (const HANDLE hToken)
{
debug_printf ("set_impersonation_token (%d)", hToken);
@@ -103,8 +99,7 @@ extract_nt_dom_user (const struct passwd *pw, char *domain, char *user)
}
}
-extern "C"
-HANDLE
+extern "C" HANDLE
cygwin_logon_user (const struct passwd *pw, const char *password)
{
if (!wincap.has_security ())
@@ -165,6 +160,7 @@ str2buf2uni (UNICODE_STRING &tgt, WCHAR *buf, const char *srcstr)
sys_mbstowcs (buf, srcstr, tgt.MaximumLength);
}
+#if 0 //unused
static void
lsa2wchar (WCHAR *tgt, LSA_UNICODE_STRING &src, int size)
{
@@ -175,16 +171,26 @@ lsa2wchar (WCHAR *tgt, LSA_UNICODE_STRING &src, int size)
size >>= 1;
tgt[size] = 0;
}
+#endif
+
+static void
+lsa2str (char *tgt, LSA_UNICODE_STRING &src, int size)
+{
+ if (src.Length / 2 < size)
+ size = src.Length / 2;
+ sys_wcstombs (tgt, src.Buffer, size);
+ tgt[size] = 0;
+}
static LSA_HANDLE
open_local_policy ()
{
LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
- LSA_HANDLE lsa = NULL;
+ LSA_HANDLE lsa = INVALID_HANDLE_VALUE;
NTSTATUS ret = LsaOpenPolicy(NULL, &oa, POLICY_EXECUTE, &lsa);
if (ret != STATUS_SUCCESS)
- set_errno (LsaNtStatusToWinError (ret));
+ __seterrno_from_win_error (LsaNtStatusToWinError (ret));
return lsa;
}
@@ -196,12 +202,12 @@ close_local_policy (LSA_HANDLE &lsa)
lsa = INVALID_HANDLE_VALUE;
}
+#if 0 // unused
static BOOL
get_lsa_srv_inf (LSA_HANDLE lsa, char *logonserver, char *domain)
{
NET_API_STATUS ret;
- LPSERVER_INFO_101 buf;
- DWORD cnt, tot;
+ WCHAR *buf;
char name[INTERNET_MAX_HOST_NAME_LENGTH + 1];
WCHAR account[INTERNET_MAX_HOST_NAME_LENGTH + 1];
WCHAR primary[INTERNET_MAX_HOST_NAME_LENGTH + 1];
@@ -211,7 +217,7 @@ get_lsa_srv_inf (LSA_HANDLE lsa, char *logonserver, char *domain)
if ((ret = LsaQueryInformationPolicy (lsa, PolicyAccountDomainInformation,
(PVOID *) &adi)) != STATUS_SUCCESS)
{
- set_errno (LsaNtStatusToWinError(ret));
+ __seterrno_from_win_error (LsaNtStatusToWinError(ret));
return FALSE;
}
lsa2wchar (account, adi->DomainName, INTERNET_MAX_HOST_NAME_LENGTH + 1);
@@ -219,97 +225,106 @@ get_lsa_srv_inf (LSA_HANDLE lsa, char *logonserver, char *domain)
if ((ret = LsaQueryInformationPolicy (lsa, PolicyPrimaryDomainInformation,
(PVOID *) &pdi)) != STATUS_SUCCESS)
{
- set_errno (LsaNtStatusToWinError(ret));
+ __seterrno_from_win_error (LsaNtStatusToWinError(ret));
return FALSE;
}
lsa2wchar (primary, pdi->Name, INTERNET_MAX_HOST_NAME_LENGTH + 1);
LsaFreeMemory (pdi);
- if ((ret = NetServerEnum (NULL, 101, (LPBYTE *) &buf, MAX_PREFERRED_LENGTH,
- &cnt, &tot, SV_TYPE_DOMAIN_CTRL, primary, NULL))
- == STATUS_SUCCESS && cnt > 0)
- {
- sys_wcstombs (name, buf[0].sv101_name, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+ /* If the SID given in the primary domain info is NULL, the machine is
+ not member of a domain. The name in the primary domain info is the
+ name of the workgroup then. */
+ if (pdi->Sid &&
+ (ret = NetGetDCName(NULL, primary, (LPBYTE *) &buf)) == STATUS_SUCCESS)
+ {
+ sys_wcstombs (name, buf, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+ strcpy (logonserver, name);
if (domain)
sys_wcstombs (domain, primary, INTERNET_MAX_HOST_NAME_LENGTH + 1);
}
else
{
sys_wcstombs (name, account, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+ strcpy (logonserver, "\\\\");
+ strcat (logonserver, name);
if (domain)
sys_wcstombs (domain, account, INTERNET_MAX_HOST_NAME_LENGTH + 1);
}
if (ret == STATUS_SUCCESS)
NetApiBufferFree (buf);
- strcpy (logonserver, "\\\\");
- strcat (logonserver, name);
return TRUE;
}
-
-static BOOL
-get_logon_server (LSA_HANDLE lsa, char *logonserver)
-{
- return get_lsa_srv_inf (lsa, logonserver, NULL);
-}
+#endif
BOOL
-get_logon_server_and_user_domain (char *logonserver, char *userdomain)
+get_logon_server (const char *domain, char *server, WCHAR *wserver)
{
- BOOL ret = FALSE;
- LSA_HANDLE lsa = open_local_policy ();
- if (lsa)
+ WCHAR wdomain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ NET_API_STATUS ret;
+ WCHAR * buf;
+ DWORD size = INTERNET_MAX_HOST_NAME_LENGTH + 1;
+
+ if ((GetComputerName (server + 2, &size)) &&
+ strcasematch (domain, server + 2))
{
- ret = get_lsa_srv_inf (lsa, logonserver, userdomain);
- close_local_policy (lsa);
+ server[0] = server[1] = '\\';
+ if (wserver)
+ sys_mbstowcs (wserver, server, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+ return TRUE;
}
- return ret;
+
+ /* Try to get the primary domain controller for the domain */
+ sys_mbstowcs (wdomain, domain, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+ if ((ret = NetGetDCName (NULL, wdomain, (LPBYTE *) &buf)) == STATUS_SUCCESS)
+ {
+ sys_wcstombs (server, buf, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+ if (wserver)
+ for (WCHAR * ptr1 = buf; (*wserver++ = *ptr1++); ) {}
+ NetApiBufferFree (buf);
+ return TRUE;
+ }
+ __seterrno_from_win_error (ret);
+ return FALSE;
}
static BOOL
-get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user)
+get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user, char * domain)
{
+ char dgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2];
WCHAR wuser[UNLEN + 1];
sys_mbstowcs (wuser, user, UNLEN + 1);
LPGROUP_USERS_INFO_0 buf;
- DWORD cnt, tot;
+ DWORD cnt, tot, len;
NET_API_STATUS ret;
+ /* Look only on logonserver */
ret = NetUserGetGroups (wlogonserver, wuser, 0, (LPBYTE *) &buf,
MAX_PREFERRED_LENGTH, &cnt, &tot);
- if (ret == ERROR_BAD_NETPATH || ret == RPC_S_SERVER_UNAVAILABLE)
- ret = NetUserGetGroups (NULL, wuser, 0, (LPBYTE *) &buf,
- MAX_PREFERRED_LENGTH, &cnt, &tot);
if (ret)
{
- debug_printf ("%d = NetUserGetGroups ()", ret);
- set_errno (ret);
+ __seterrno_from_win_error (ret);
/* It's no error when the user name can't be found. */
return ret == NERR_UserNotFound;
}
+ len = strlen(domain);
+ strcpy(dgroup, domain);
+ dgroup[len++] = '\\';
+
for (DWORD i = 0; i < cnt; ++i)
{
cygsid gsid;
- char group[UNLEN + 1];
+ DWORD glen = sizeof (gsid);
char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
- DWORD glen = UNLEN + 1;
- DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
+ DWORD dlen = sizeof (domain);
SID_NAME_USE use = SidTypeInvalid;
- sys_wcstombs (group, buf[i].grui0_name, UNLEN + 1);
- if (!LookupAccountName (NULL, group, gsid, &glen, domain, &dlen, &use))
- debug_printf ("LookupAccountName(%s): %lu\n", group, GetLastError ());
- if (!legal_sid_type (use))
- {
- strcat (strcpy (group, domain), "\\");
- sys_wcstombs (group + strlen (group), buf[i].grui0_name,
- UNLEN + 1 - strlen (group));
- glen = UNLEN + 1;
- dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
- if (!LookupAccountName(NULL, group, gsid, &glen, domain, &dlen, &use))
- debug_printf ("LookupAccountName(%s): %lu\n", group,GetLastError());
- }
- if (legal_sid_type (use))
- grp_list += gsid;
+ sys_wcstombs (dgroup + len, buf[i].grui0_name, GNLEN + 1);
+ if (!LookupAccountName (NULL, dgroup, gsid, &glen, domain, &dlen, &use))
+ debug_printf ("LookupAccountName(%s): %E", dgroup);
+ else if (legal_sid_type (use))
+ grp_list += gsid;
+ else debug_printf("Global group %s invalid. Domain: %s Use: %d",
+ dgroup, domain, use);
}
NetApiBufferFree (buf);
@@ -317,21 +332,21 @@ get_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user)
}
static BOOL
-is_group_member (WCHAR *wlogonserver, WCHAR *wgroup,
- cygsid &usersid, cygsidlist &grp_list)
+is_group_member (WCHAR *wgroup, PSID pusersid, cygsidlist &grp_list)
{
LPLOCALGROUP_MEMBERS_INFO_0 buf;
DWORD cnt, tot;
NET_API_STATUS ret;
BOOL retval = FALSE;
+ /* Members can be users or global groups */
ret = NetLocalGroupGetMembers (NULL, wgroup, 0, (LPBYTE *) &buf,
MAX_PREFERRED_LENGTH, &cnt, &tot, NULL);
if (ret)
return FALSE;
for (DWORD bidx = 0; !retval && bidx < cnt; ++bidx)
- if (EqualSid (usersid, buf[bidx].lgrmi0_sid))
+ if (EqualSid (pusersid, buf[bidx].lgrmi0_sid))
retval = TRUE;
else
for (int glidx = 0; !retval && glidx < grp_list.count; ++glidx)
@@ -343,8 +358,7 @@ is_group_member (WCHAR *wlogonserver, WCHAR *wgroup,
}
static BOOL
-get_user_local_groups (WCHAR *wlogonserver, const char *logonserver,
- cygsidlist &grp_list, cygsid &usersid)
+get_user_local_groups (cygsidlist &grp_list, PSID pusersid)
{
LPLOCALGROUP_INFO_0 buf;
DWORD cnt, tot;
@@ -354,45 +368,43 @@ get_user_local_groups (WCHAR *wlogonserver, const char *logonserver,
MAX_PREFERRED_LENGTH, &cnt, &tot, NULL);
if (ret)
{
- debug_printf ("%d = NetLocalGroupEnum ()", ret);
- set_errno (ret);
+ __seterrno_from_win_error (ret);
return FALSE;
}
+ char bgroup[sizeof ("BUILTIN\\") + GNLEN] = "BUILTIN\\";
+ char lgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2];
+ const DWORD blen = sizeof ("BUILTIN\\") - 1;
+ DWORD llen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
+ if (!GetComputerNameA(lgroup, & llen))
+ {
+ __seterrno();
+ return FALSE;
+ }
+ lgroup[llen++] = '\\';
+
for (DWORD i = 0; i < cnt; ++i)
- if (is_group_member (wlogonserver, buf[i].lgrpi0_name, usersid, grp_list))
+ if (is_group_member (buf[i].lgrpi0_name, pusersid, grp_list))
{
cygsid gsid;
- char group[UNLEN + 1];
+ DWORD glen = sizeof (gsid);
char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
- DWORD glen = UNLEN + 1;
- DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
+ DWORD dlen = sizeof (domain);
SID_NAME_USE use = SidTypeInvalid;
- sys_wcstombs (group, buf[i].lgrpi0_name, UNLEN + 1);
- if (!LookupAccountName (NULL, group, gsid, &glen, domain, &dlen, &use))
+ sys_wcstombs (bgroup + blen, buf[i].lgrpi0_name, GNLEN + 1);
+ if (!LookupAccountName (NULL, bgroup, gsid, &glen, domain, &dlen, &use))
{
- glen = UNLEN + 1;
- dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
- if (!LookupAccountName (logonserver + 2, group,
- gsid, &glen, domain, &dlen, &use))
- debug_printf ("LookupAccountName(%s): %lu\n", group,
- GetLastError ());
- }
- else if (!legal_sid_type (use))
- {
- strcat (strcpy (group, domain), "\\");
- sys_wcstombs (group + strlen (group), buf[i].lgrpi0_name,
- UNLEN + 1 - strlen (group));
- glen = UNLEN + 1;
- dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
- if (!LookupAccountName (NULL, group, gsid, &glen,
- domain, &dlen, &use))
- debug_printf ("LookupAccountName(%s): %lu\n", group,
- GetLastError ());
+ if (GetLastError () != ERROR_NONE_MAPPED)
+ debug_printf ("LookupAccountName(%s): %E", bgroup);
+ strcpy(lgroup + llen, bgroup + blen);
+ if (!LookupAccountName (NULL, lgroup, gsid, &glen,
+ domain, &dlen, &use))
+ debug_printf ("LookupAccountName(%s): %E", lgroup);
}
if (legal_sid_type (use))
grp_list += gsid;
+ else debug_printf("Rejecting local %s. use: %d", bgroup + blen, use);
}
NetApiBufferFree (buf);
@@ -412,7 +424,7 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygsid &sid)
static BOOL
get_user_primary_group (WCHAR *wlogonserver, const char *user,
- cygsid &usersid, cygsid &pgrpsid)
+ PSID pusersid, cygsid &pgrpsid)
{
LPUSER_INFO_3 buf;
WCHAR wuser[UNLEN + 1];
@@ -420,7 +432,7 @@ get_user_primary_group (WCHAR *wlogonserver, const char *user,
BOOL retval = FALSE;
UCHAR count = 0;
- if (usersid == well_known_system_sid)
+ if (pusersid == well_known_system_sid)
{
pgrpsid = well_known_system_sid;
return TRUE;
@@ -428,16 +440,13 @@ get_user_primary_group (WCHAR *wlogonserver, const char *user,
sys_mbstowcs (wuser, user, UNLEN + 1);
ret = NetUserGetInfo (wlogonserver, wuser, 3, (LPBYTE *) &buf);
- if (ret == ERROR_BAD_NETPATH || ret == RPC_S_SERVER_UNAVAILABLE)
- ret = NetUserGetInfo (NULL, wuser, 3, (LPBYTE *) &buf);
if (ret)
{
- debug_printf ("%d = NetUserGetInfo ()", ret);
- set_errno (ret);
+ __seterrno_from_win_error (ret);
return FALSE;
}
- pgrpsid = usersid;
+ pgrpsid = pusersid;
if (IsValidSid (pgrpsid) && (count = *GetSidSubAuthorityCount (pgrpsid)) > 1)
{
*GetSidSubAuthority (pgrpsid, count - 1) = buf->usri3_primary_group_id;
@@ -450,7 +459,7 @@ get_user_primary_group (WCHAR *wlogonserver, const char *user,
static int
get_supplementary_group_sidlist (const char *username, cygsidlist &grp_list)
{
- struct __group16 *gr;
+ struct __group32 *gr;
int cnt = 0;
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
@@ -472,26 +481,28 @@ get_supplementary_group_sidlist (const char *username, cygsidlist &grp_list)
}
static BOOL
-get_group_sidlist (const char *logonserver, cygsidlist &grp_list,
+get_group_sidlist (cygsidlist &grp_list,
cygsid &usersid, cygsid &pgrpsid,
- PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos)
+ PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos,
+ BOOL * special_pgrp)
{
- WCHAR wserver[INTERNET_MAX_HOST_NAME_LENGTH + 1];
- char user[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ char user[UNLEN + 1];
char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
- DWORD ulen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
- DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
+ WCHAR wserver[INTERNET_MAX_HOST_NAME_LENGTH + 3];
+ char server[INTERNET_MAX_HOST_NAME_LENGTH + 3];
+ DWORD ulen = sizeof (user);
+ DWORD dlen = sizeof (domain);
SID_NAME_USE use;
cygsidlist sup_list;
auth_pos = -1;
- sys_mbstowcs (wserver, logonserver, INTERNET_MAX_HOST_NAME_LENGTH + 1);
if (!LookupAccountSid (NULL, usersid, user, &ulen, domain, &dlen, &use))
{
debug_printf ("LookupAccountSid () %E");
__seterrno ();
return FALSE;
}
+
grp_list += well_known_world_sid;
if (usersid == well_known_system_sid)
{
@@ -500,6 +511,8 @@ get_group_sidlist (const char *logonserver, cygsidlist &grp_list,
}
else
{
+ if (!get_logon_server (domain, server, wserver))
+ return FALSE;
if (my_grps)
{
if (sid_in_token_groups (my_grps, well_known_local_sid))
@@ -530,20 +543,26 @@ get_group_sidlist (const char *logonserver, cygsidlist &grp_list,
grp_list += buf;
auth_pos = grp_list.count - 1;
}
+ if (!get_user_groups (wserver, grp_list, user, domain) ||
+ !get_user_local_groups (grp_list, usersid))
+ return FALSE;
}
+ /* special_pgrp true if pgrpsid is not null and not in normal groups */
if (!pgrpsid)
- get_user_primary_group (wserver, user, usersid, pgrpsid);
- if (!get_user_groups (wserver, grp_list, user) ||
- !get_user_local_groups (wserver, logonserver, grp_list, usersid))
- return FALSE;
- if (!grp_list.contains (pgrpsid))
- grp_list += pgrpsid;
+ {
+ * special_pgrp = FALSE;
+ get_user_primary_group (wserver, user, usersid, pgrpsid);
+ }
+ else * special_pgrp = TRUE;
if (get_supplementary_group_sidlist (user, sup_list))
{
for (int i = 0; i < sup_list.count; ++i)
if (!grp_list.contains (sup_list.sids[i]))
grp_list += sup_list.sids[i];
}
+ if (!grp_list.contains (pgrpsid))
+ grp_list += pgrpsid;
+ else * special_pgrp = FALSE;
return TRUE;
}
@@ -625,8 +644,7 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list)
PTOKEN_PRIVILEGES tmp;
DWORD tmp_count;
- sys_wcstombs (buf, privstrs[i].Buffer,
- INTERNET_MAX_HOST_NAME_LENGTH + 1);
+ lsa2str (buf, privstrs[i], sizeof(buf) - 1);
if (!LookupPrivilegeValue (NULL, buf, &priv))
continue;
@@ -661,46 +679,63 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list)
return privs;
}
-#define token_acl_size (sizeof (ACL) + \
- 2 * (sizeof (ACCESS_ALLOWED_ACE) + MAX_SID_LEN))
-
-static BOOL
-get_dacl (PACL acl, cygsid usersid, cygsidlist &grp_list)
+BOOL
+verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL * pintern)
{
- if (!InitializeAcl(acl, token_acl_size, ACL_REVISION))
- {
- __seterrno ();
- return FALSE;
- }
- if (grp_list.contains (well_known_admins_sid))
- {
- if (!AddAccessAllowedAce(acl, ACL_REVISION, GENERIC_ALL,
- well_known_admins_sid))
- {
- __seterrno ();
- return FALSE;
- }
- }
- else if (!AddAccessAllowedAce(acl, ACL_REVISION, GENERIC_ALL, usersid))
- {
- __seterrno ();
- return FALSE;
- }
- if (!AddAccessAllowedAce(acl, ACL_REVISION, GENERIC_ALL,
- well_known_system_sid))
- {
- __seterrno ();
- return FALSE;
- }
- return TRUE;
+ DWORD size;
+ BOOL intern = FALSE;
+
+ if (pintern)
+ {
+ TOKEN_SOURCE ts;
+ if (!GetTokenInformation (cygheap->user.token, TokenSource,
+ &ts, sizeof ts, &size))
+ debug_printf ("GetTokenInformation(): %E");
+ else *pintern = intern = !memcmp (ts.SourceName, "Cygwin.1", 8);
+ }
+ /* Verify usersid */
+ cygsid tok_usersid = NO_SID;
+ if (!GetTokenInformation (token, TokenUser,
+ &tok_usersid, sizeof tok_usersid, &size))
+ debug_printf ("GetTokenInformation(): %E");
+ if (usersid != tok_usersid) return FALSE;
+
+ /* In an internal token, if the sd group is not well_known_null_sid,
+ it must match pgrpsid */
+ if (intern)
+ {
+ char sd_buf[MAX_SID_LEN + sizeof (SECURITY_DESCRIPTOR)];
+ PSID gsid = NO_SID;
+ if (!GetKernelObjectSecurity(token, GROUP_SECURITY_INFORMATION,
+ (PSECURITY_DESCRIPTOR) sd_buf,
+ sizeof sd_buf, &size))
+ debug_printf ("GetKernelObjectSecurity(): %E");
+ else if (!GetSecurityDescriptorGroup((PSECURITY_DESCRIPTOR) sd_buf,
+ &gsid, (BOOL *) &size))
+ debug_printf ("GetSecurityDescriptorGroup(): %E");
+ if (well_known_null_sid != gsid) return pgrpsid == gsid;
+ }
+ /* See if the pgrpsid is in the token groups */
+ PTOKEN_GROUPS my_grps = NULL;
+ BOOL ret = FALSE;
+
+ if (!GetTokenInformation (token, TokenGroups, NULL, 0, &size) &&
+ GetLastError () != ERROR_INSUFFICIENT_BUFFER)
+ debug_printf ("GetTokenInformation(token, TokenGroups): %E\n");
+ else if (!(my_grps = (PTOKEN_GROUPS) malloc (size)))
+ debug_printf ("malloc (my_grps) failed.");
+ else if (!GetTokenInformation (token, TokenGroups, my_grps, size, &size))
+ debug_printf ("GetTokenInformation(my_token, TokenGroups): %E\n");
+ else ret = sid_in_token_groups (my_grps, pgrpsid);
+ if (my_grps) free (my_grps);
+ return ret;
}
HANDLE
create_token (cygsid &usersid, cygsid &pgrpsid)
{
NTSTATUS ret;
- LSA_HANDLE lsa = NULL;
- char logonserver[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ LSA_HANDLE lsa = INVALID_HANDLE_VALUE;
int old_priv_state;
cygsidlist grpsids;
@@ -709,6 +744,8 @@ create_token (cygsid &usersid, cygsid &pgrpsid)
{ sizeof sqos, SecurityImpersonation, SECURITY_STATIC_TRACKING, FALSE };
OBJECT_ATTRIBUTES oa =
{ sizeof oa, 0, 0, 0, 0, &sqos };
+ PSECURITY_ATTRIBUTES psa;
+ BOOL special_pgrp;
char sa_buf[1024];
LUID auth_luid = SYSTEM_LUID;
LARGE_INTEGER exp = { QuadPart:0x7fffffffffffffffLL };
@@ -718,7 +755,7 @@ create_token (cygsid &usersid, cygsid &pgrpsid)
PTOKEN_PRIVILEGES privs = NULL;
TOKEN_OWNER owner;
TOKEN_PRIMARY_GROUP pgrp;
- char acl_buf[token_acl_size];
+ char acl_buf[MAX_DACL_LEN(5)];
TOKEN_DEFAULT_DACL dacl;
TOKEN_SOURCE source;
TOKEN_STATISTICS stats;
@@ -738,11 +775,7 @@ create_token (cygsid &usersid, cygsid &pgrpsid)
goto out;
/* Open policy object. */
- if (!(lsa = open_local_policy ()))
- goto out;
-
- /* Get logon server. */
- if (!get_logon_server (lsa, logonserver))
+ if ((lsa = open_local_policy ()) == INVALID_HANDLE_VALUE)
goto out;
/* User, owner, primary group. */
@@ -783,8 +816,8 @@ create_token (cygsid &usersid, cygsid &pgrpsid)
/* Create list of groups, the user is member in. */
int auth_pos;
- if (!get_group_sidlist (logonserver, grpsids, usersid, pgrpsid,
- my_grps, auth_luid, auth_pos))
+ if (!get_group_sidlist (grpsids, usersid, pgrpsid,
+ my_grps, auth_luid, auth_pos, &special_pgrp))
goto out;
/* Primary group. */
@@ -809,7 +842,8 @@ create_token (cygsid &usersid, cygsid &pgrpsid)
goto out;
/* Create default dacl. */
- if (!get_dacl ((PACL) acl_buf, usersid, grpsids))
+ if (!sec_acl((PACL) acl_buf, FALSE,
+ grpsids.contains (well_known_admins_sid)?well_known_admins_sid:usersid))
goto out;
dacl.DefaultDacl = (PACL) acl_buf;
@@ -818,17 +852,29 @@ create_token (cygsid &usersid, cygsid &pgrpsid)
&auth_luid, &exp, &user, grps, privs, &owner, &pgrp,
&dacl, &source);
if (ret)
- set_errno (RtlNtStatusToDosError (ret));
+ __seterrno_from_win_error (RtlNtStatusToDosError (ret));
else if (GetLastError () == ERROR_PROC_NOT_FOUND)
{
__seterrno ();
debug_printf ("Loading NtCreateToken failed.");
}
-
- /* Convert to primary token. */
- if (!DuplicateTokenEx (token, MAXIMUM_ALLOWED, sec_user (sa_buf, usersid),
- SecurityImpersonation, TokenPrimary, &primary_token))
- __seterrno ();
+ else
+ {
+ /* Set security descriptor and primary group */
+ psa = __sec_user (sa_buf, usersid, TRUE);
+ if (psa->lpSecurityDescriptor &&
+ !SetSecurityDescriptorGroup (
+ (PSECURITY_DESCRIPTOR) psa->lpSecurityDescriptor,
+ special_pgrp?pgrpsid:well_known_null_sid, FALSE))
+ debug_printf ("SetSecurityDescriptorGroup %E");
+ /* Convert to primary token. */
+ if (!DuplicateTokenEx (token, MAXIMUM_ALLOWED, psa,
+ SecurityImpersonation, TokenPrimary, &primary_token))
+ {
+ __seterrno ();
+ debug_printf ("DuplicateTokenEx %E");
+ }
+ }
out:
if (old_priv_state >= 0)
@@ -888,7 +934,7 @@ subauth (struct passwd *pw)
if (ret != STATUS_SUCCESS)
{
debug_printf ("LsaRegisterLogonProcess: %d", ret);
- set_errno (LsaNtStatusToWinError(ret));
+ __seterrno_from_win_error (LsaNtStatusToWinError(ret));
goto out;
}
else if (GetLastError () == ERROR_PROC_NOT_FOUND)
@@ -902,7 +948,7 @@ subauth (struct passwd *pw)
if (ret != STATUS_SUCCESS)
{
debug_printf ("LsaLookupAuthenticationPackage: %d", ret);
- set_errno (LsaNtStatusToWinError(ret));
+ __seterrno_from_win_error (LsaNtStatusToWinError(ret));
LsaDeregisterLogonProcess(lsa_hdl);
goto out;
}
@@ -931,7 +977,7 @@ subauth (struct passwd *pw)
if (ret != STATUS_SUCCESS)
{
debug_printf ("LsaLogonUser: %d", ret);
- set_errno (LsaNtStatusToWinError(ret));
+ __seterrno_from_win_error (LsaNtStatusToWinError(ret));
LsaDeregisterLogonProcess(lsa_hdl);
goto out;
}
@@ -1085,7 +1131,7 @@ write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size)
static int
get_nt_attribute (const char *file, int *attribute,
- __uid16_t *uidret, __gid16_t *gidret)
+ __uid32_t *uidret, __gid32_t *gidret)
{
if (!wincap.has_security ())
return 0;
@@ -1123,8 +1169,8 @@ get_nt_attribute (const char *file, int *attribute,
return -1;
}
- __uid16_t uid = cygsid(owner_sid).get_uid ();
- __gid16_t gid = cygsid(group_sid).get_gid ();
+ __uid32_t uid = cygsid(owner_sid).get_uid ();
+ __gid32_t gid = cygsid(group_sid).get_gid ();
if (uidret)
*uidret = uid;
if (gidret)
@@ -1234,7 +1280,7 @@ get_nt_attribute (const char *file, int *attribute,
int
get_file_attribute (int use_ntsec, const char *file,
- int *attribute, __uid16_t *uidret, __gid16_t *gidret)
+ int *attribute, __uid32_t *uidret, __gid32_t *gidret)
{
int res;
@@ -1247,9 +1293,9 @@ get_file_attribute (int use_ntsec, const char *file,
}
if (uidret)
- *uidret = getuid ();
+ *uidret = getuid32 ();
if (gidret)
- *gidret = getgid ();
+ *gidret = getgid32 ();
if (!attribute)
return 0;
@@ -1305,7 +1351,7 @@ add_access_denied_ace (PACL acl, int offset, DWORD attributes,
}
PSECURITY_DESCRIPTOR
-alloc_sd (__uid16_t uid, __gid16_t gid, const char *logsrv, int attribute,
+alloc_sd (__uid32_t uid, __gid32_t gid, int attribute,
PSECURITY_DESCRIPTOR sd_ret, DWORD *sd_size_ret)
{
BOOL dummy;
@@ -1322,10 +1368,9 @@ alloc_sd (__uid16_t uid, __gid16_t gid, const char *logsrv, int attribute,
/* Get SID and name of new owner. */
char owner[UNLEN + 1];
cygsid owner_sid;
- struct passwd *pw = getpwuid (uid);
+ struct passwd *pw = getpwuid32 (uid);
strcpy (owner, pw ? pw->pw_name : getlogin ());
- if ((!pw || !owner_sid.getfrompw (pw))
- && !lookup_name (owner, logsrv, owner_sid))
+ if (!pw || !owner_sid.getfrompw (pw))
return NULL;
debug_printf ("owner: %s [%d]", owner,
*GetSidSubAuthority(owner_sid,
@@ -1333,11 +1378,10 @@ alloc_sd (__uid16_t uid, __gid16_t gid, const char *logsrv, int attribute,
/* Get SID and name of new group. */
cygsid group_sid (NO_SID);
- struct __group16 *grp = getgrgid (gid);
+ struct __group32 *grp = getgrgid32 (gid);
if (grp)
{
- if ((!grp || !group_sid.getfromgr (grp))
- && !lookup_name (grp->gr_name, logsrv, group_sid))
+ if (!grp || !group_sid.getfromgr (grp))
return NULL;
}
else
@@ -1567,15 +1611,14 @@ set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa,
psa->lpSecurityDescriptor = sd_buf;
InitializeSecurityDescriptor ((PSECURITY_DESCRIPTOR)sd_buf,
SECURITY_DESCRIPTOR_REVISION);
- psa->lpSecurityDescriptor = alloc_sd (geteuid (), getegid (),
- cygheap->user.logsrv (),
+ psa->lpSecurityDescriptor = alloc_sd (geteuid32 (), getegid32 (),
attribute, (PSECURITY_DESCRIPTOR)sd_buf,
&sd_buf_size);
}
static int
-set_nt_attribute (const char *file, __uid16_t uid, __gid16_t gid,
- const char *logsrv, int attribute)
+set_nt_attribute (const char *file, __uid32_t uid, __gid32_t gid,
+ int attribute)
{
if (!wincap.has_security ())
return 0;
@@ -1592,7 +1635,7 @@ set_nt_attribute (const char *file, __uid16_t uid, __gid16_t gid,
}
sd_size = 4096;
- if (!(psd = alloc_sd (uid, gid, logsrv, attribute, psd, &sd_size)))
+ if (!(psd = alloc_sd (uid, gid, attribute, psd, &sd_size)))
return -1;
return write_sd (file, psd, sd_size);
@@ -1600,13 +1643,13 @@ set_nt_attribute (const char *file, __uid16_t uid, __gid16_t gid,
int
set_file_attribute (int use_ntsec, const char *file,
- __uid16_t uid, __gid16_t gid,
- int attribute, const char *logsrv)
+ __uid32_t uid, __gid32_t gid,
+ int attribute)
{
int ret = 0;
if (use_ntsec && allow_ntsec)
- ret = set_nt_attribute (file, uid, gid, logsrv, attribute);
+ ret = set_nt_attribute (file, uid, gid, attribute);
else if (allow_ntea && !NTWriteEA (file, ".UNIXATTR", (char *) &attribute,
sizeof (attribute)))
{
@@ -1623,5 +1666,5 @@ set_file_attribute (int use_ntsec, const char *file, int attribute)
{
return set_file_attribute (use_ntsec, file,
myself->uid, myself->gid,
- attribute, cygheap->user.logsrv ());
+ attribute);
}
diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h
index 220f57168..af4b667f8 100644
--- a/winsup/cygwin/security.h
+++ b/winsup/cygwin/security.h
@@ -16,6 +16,8 @@ details. */
#define DEFAULT_GID DOMAIN_ALIAS_RID_ADMINS
#define MAX_SID_LEN 40
+#define MAX_DACL_LEN(n) (sizeof (ACL) \
+ + (n) * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD) + MAX_SID_LEN))
#define NO_SID ((PSID)NULL)
@@ -55,7 +57,7 @@ public:
inline PSID set () { return psid = (PSID) sbuf; }
BOOL getfrompw (const struct passwd *pw);
- BOOL getfromgr (const struct __group16 *gr);
+ BOOL getfromgr (const struct __group32 *gr);
int get_id (BOOL search_grp, int *type = NULL);
inline int get_uid () { return get_id (FALSE); }
@@ -159,14 +161,14 @@ extern BOOL allow_smbntsec;
and group lists so they are somehow security related. Besides that
I didn't find a better place to declare them. */
extern struct passwd *internal_getpwent (int);
-extern struct __group16 *internal_getgrent (int);
+extern struct __group32 *internal_getgrent (int);
/* File manipulation */
int __stdcall set_process_privileges ();
int __stdcall get_file_attribute (int, const char *, int *,
- __uid16_t * = NULL, __gid16_t * = NULL);
+ __uid32_t * = NULL, __gid32_t * = NULL);
int __stdcall set_file_attribute (int, const char *, int);
-int __stdcall set_file_attribute (int, const char *, __uid16_t, __gid16_t, int, const char *);
+int __stdcall set_file_attribute (int, const char *, __uid32_t, __gid32_t, int);
LONG __stdcall read_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size);
LONG __stdcall write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size);
BOOL __stdcall add_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit);
@@ -179,18 +181,16 @@ void set_security_attribute (int attribute, PSECURITY_ATTRIBUTES psa,
HANDLE subauth (struct passwd *pw);
/* Try creating a token directly. */
HANDLE create_token (cygsid &usersid, cygsid &pgrpsid);
+/* Verify an existing token */
+BOOL verify_token (HANDLE token, cygsid &usersid, cygsid &pgrpsid, BOOL * pintern = NULL);
/* Extract U-domain\user field from passwd entry. */
void extract_nt_dom_user (const struct passwd *pw, char *domain, char *user);
-/* Get default logonserver and domain for this box. */
-BOOL get_logon_server_and_user_domain (char *logonserver, char *domain);
+/* Get default logonserver for a domain. */
+BOOL get_logon_server (const char * domain, char * server, WCHAR *wserver = NULL);
/* sec_helper.cc: Security helper functions. */
-BOOL __stdcall is_grp_member (__uid16_t uid, __gid16_t gid);
-/* `lookup_name' should be called instead of LookupAccountName.
- * logsrv may be NULL, in this case only the local system is used for lookup.
- * The buffer for ret_sid (40 Bytes) has to be allocated by the caller! */
-BOOL __stdcall lookup_name (const char *, const char *, PSID);
+BOOL __stdcall is_grp_member (__uid32_t uid, __gid32_t gid);
int set_process_privilege (const char *privilege, BOOL enable = TRUE);
/* shared.cc: */
@@ -201,10 +201,11 @@ SECURITY_DESCRIPTOR *__stdcall get_null_sd (void);
extern SECURITY_ATTRIBUTES sec_none, sec_none_nih, sec_all, sec_all_nih;
extern SECURITY_ATTRIBUTES *__stdcall __sec_user (PVOID sa_buf, PSID sid2, BOOL inherit)
__attribute__ ((regparm (3)));
+extern BOOL sec_acl (PACL acl, BOOL admins, PSID sid1 = NO_SID, PSID sid2 = NO_SID);
int __stdcall NTReadEA (const char *file, const char *attrname, char *buf, int len);
BOOL __stdcall NTWriteEA (const char *file, const char *attrname, const char *buf, int len);
-PSECURITY_DESCRIPTOR alloc_sd (uid_t uid, gid_t gid, const char *logsrv, int attribute,
+PSECURITY_DESCRIPTOR alloc_sd (__uid32_t uid, __gid32_t gid, int attribute,
PSECURITY_DESCRIPTOR sd_ret, DWORD *sd_size_ret);
extern inline SECURITY_ATTRIBUTES *
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index ebc9c8881..b50ffb1f2 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -1,6 +1,6 @@
/* select.cc
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
Written by Christopher Faylor of Cygnus Solutions
cgf@cygnus.com
@@ -39,7 +39,6 @@ details. */
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
-#include "sync.h"
#include "sigproc.h"
#include "perthread.h"
#include "tty.h"
diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc
index 5f1bc1fdd..2a536824d 100644
--- a/winsup/cygwin/shared.cc
+++ b/winsup/cygwin/shared.cc
@@ -1,6 +1,6 @@
/* shared.cc: shared data area support.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -15,8 +15,6 @@ details. */
#include <grp.h>
#include <pwd.h>
#include <errno.h>
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "security.h"
#include "fhandler.h"
@@ -236,6 +234,39 @@ get_null_sd ()
return null_sdp;
}
+BOOL
+sec_acl (PACL acl, BOOL admins, PSID sid1, PSID sid2)
+{
+ size_t acl_len = MAX_DACL_LEN(5);
+
+ if (!InitializeAcl (acl, acl_len, ACL_REVISION))
+ {
+ debug_printf ("InitializeAcl %E");
+ return FALSE;
+ }
+ if (sid2)
+ if (!AddAccessAllowedAce (acl, ACL_REVISION,
+ GENERIC_ALL, sid2))
+ debug_printf ("AddAccessAllowedAce(sid2) %E");
+ if (sid1)
+ if (!AddAccessAllowedAce (acl, ACL_REVISION,
+ GENERIC_ALL, sid1))
+ debug_printf ("AddAccessAllowedAce(sid1) %E", sid1);
+ if (admins)
+ if (!AddAccessAllowedAce (acl, ACL_REVISION,
+ GENERIC_ALL, well_known_admins_sid))
+ debug_printf ("AddAccessAllowedAce(admin) %E");
+ if (!AddAccessAllowedAce (acl, ACL_REVISION,
+ GENERIC_ALL, well_known_system_sid))
+ debug_printf ("AddAccessAllowedAce(system) %E");
+#if 0 /* Does not seem to help */
+ if (!AddAccessAllowedAce (acl, ACL_REVISION,
+ GENERIC_ALL, well_known_creator_owner_sid))
+ debug_printf ("AddAccessAllowedAce(creator_owner) %E");
+#endif
+ return TRUE;
+}
+
PSECURITY_ATTRIBUTES __stdcall
__sec_user (PVOID sa_buf, PSID sid2, BOOL inherit)
{
@@ -246,50 +277,10 @@ __sec_user (PVOID sa_buf, PSID sid2, BOOL inherit)
cygsid sid;
- if (cygheap->user.sid ())
- sid = cygheap->user.sid ();
- else if (!lookup_name (getlogin (), cygheap->user.logsrv (), sid))
+ if (!(sid = cygheap->user.orig_sid ()) ||
+ (!sec_acl (acl, TRUE, sid, sid2)))
return inherit ? &sec_none : &sec_none_nih;
- size_t acl_len = sizeof (ACL)
- + 4 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD))
- + GetLengthSid (sid)
- + GetLengthSid (well_known_admins_sid)
- + GetLengthSid (well_known_system_sid)
- + GetLengthSid (well_known_creator_owner_sid);
- if (sid2)
- acl_len += sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD)
- + GetLengthSid (sid2);
-
- if (!InitializeAcl (acl, acl_len, ACL_REVISION))
- debug_printf ("InitializeAcl %E");
-
- if (!AddAccessAllowedAce (acl, ACL_REVISION,
- SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
- sid))
- debug_printf ("AddAccessAllowedAce(%s) %E", getlogin ());
-
- if (!AddAccessAllowedAce (acl, ACL_REVISION,
- SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
- well_known_admins_sid))
- debug_printf ("AddAccessAllowedAce(admin) %E");
-
- if (!AddAccessAllowedAce (acl, ACL_REVISION,
- SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
- well_known_system_sid))
- debug_printf ("AddAccessAllowedAce(system) %E");
-
- if (!AddAccessAllowedAce (acl, ACL_REVISION,
- SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
- well_known_creator_owner_sid))
- debug_printf ("AddAccessAllowedAce(creator_owner) %E");
-
- if (sid2)
- if (!AddAccessAllowedAce (acl, ACL_REVISION,
- SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_ALL,
- sid2))
- debug_printf ("AddAccessAllowedAce(sid2) %E");
-
if (!InitializeSecurityDescriptor (psd, SECURITY_DESCRIPTOR_REVISION))
debug_printf ("InitializeSecurityDescriptor %E");
diff --git a/winsup/cygwin/shared_info.h b/winsup/cygwin/shared_info.h
index 16d71eef6..02a12fff5 100644
--- a/winsup/cygwin/shared_info.h
+++ b/winsup/cygwin/shared_info.h
@@ -41,7 +41,7 @@ class mount_item
#define MOUNT_VERSION 27 // increment when mount table changes and
#define MOUNT_VERSION_MAGIC CYGWIN_VERSION_MAGIC (MOUNT_MAGIC, MOUNT_VERSION)
-#define CURR_MOUNT_MAGIC 0x41e0
+#define CURR_MOUNT_MAGIC 0xf4e5
#define MOUNT_INFO_CB 16488
class reg_key;
@@ -94,13 +94,10 @@ class mount_info
int get_cygdrive_info (char *user, char *system, char* user_flags,
char* system_flags);
- void import_v1_mounts ();
-
private:
void sort ();
void read_mounts (reg_key& r);
- void read_v1_mounts (reg_key r, unsigned which);
void mount_slash ();
void to_registry ();
diff --git a/winsup/cygwin/shm.cc b/winsup/cygwin/shm.cc
index dbe9bb0e9..baea3a60e 100644
--- a/winsup/cygwin/shm.cc
+++ b/winsup/cygwin/shm.cc
@@ -1,14 +1,14 @@
/* shm.cc: Single unix specification IPC interface for Cygwin
- Copyright 2001 Red Hat, Inc.
+Copyright 2001, 2002 Red Hat, Inc.
- Originally written by Robert Collins <robert.collins@hotmail.com>
+Originally written by Robert Collins <robert.collins@hotmail.com>
- This file is part of Cygwin.
+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 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 <sys/stat.h>
@@ -23,7 +23,6 @@
#include <stdio.h>
#include "thread.h"
#include <sys/shm.h>
-#include "perprocess.h"
#include "cygserver_shm.h"
// FIXME IS THIS CORRECT
@@ -64,9 +63,9 @@ client_request (CYGSERVER_REQUEST_SHM_GET, sizeof (parameters))
}
client_request_shm::client_request_shm (key_t nkey, size_t nsize,
- int nshmflg,
- char psdbuf[4096],
- pid_t npid):
+ int nshmflg,
+ char psdbuf[4096],
+ pid_t npid):
client_request (CYGSERVER_REQUEST_SHM_GET, sizeof (parameters))
{
buffer = (char *) &parameters;
@@ -134,6 +133,34 @@ build_inprocess_shmds (HANDLE hfilemap, HANDLE hattachmap, key_t key,
return tempnode;
}
+static void
+delete_inprocess_shmds (shmnode **nodeptr)
+{
+ shmnode *node = *nodeptr;
+
+ // remove from the list
+ if (node == shm_head)
+ shm_head = shm_head->next;
+ else
+ {
+ shmnode *tempnode = shm_head;
+ while (tempnode && tempnode->next != node)
+ tempnode = tempnode->next;
+ if (tempnode)
+ tempnode->next = node->next;
+ // else log the unexpected !
+ }
+
+ // release the shared data view
+ UnmapViewOfFile (node->shmds);
+ CloseHandle (node->filemap);
+ CloseHandle (node->attachmap);
+
+ // free the memory
+ delete node;
+ nodeptr = NULL;
+}
+
int __stdcall
fixup_shms_after_fork ()
{
@@ -194,7 +221,7 @@ shmat (int shmid, const void *shmaddr, int shmflg)
if (!tempnode)
{
/* couldn't find a currently open shm control area for the key - probably because
- * shmget hasn't been called.
+ * shmget hasn't been called.
* Allocate a new control block - this has to be handled by the daemon */
client_request_shm *req =
new client_request_shm (SHM_REATTACH, shmid, GetCurrentProcessId ());
@@ -229,7 +256,7 @@ shmat (int shmid, const void *shmaddr, int shmflg)
}
- class shmid_ds *shm = tempnode->shmds;
+ // class shmid_ds *shm = tempnode->shmds;
if (shmaddr)
{
@@ -277,10 +304,40 @@ shmdt (const void *shmaddr)
/* this should be "rare" so a hefty search is ok. If this is common, then we
* should alter the data structs to allow more optimisation
*/
-
+ shmnode *tempnode = shm_head;
+ _shmattach *attachnode;
+ while (tempnode)
+ {
+ // FIXME: Race potential
+ attachnode = tempnode->attachhead;
+ while (attachnode && attachnode->data != shmaddr)
+ attachnode = attachnode->next;
+ if (attachnode)
+ break;
+ tempnode = tempnode->next;
+ }
+ if (!tempnode)
+ {
+ // dt cannot be called by an app that hasn't alreadu at'd
+ set_errno (EINVAL);
+ return -1;
+ }
+
+ UnmapViewOfFile (attachnode->data);
+ /* tell the daemon we have attached */
+ client_request_shm *req =
+ new client_request_shm (SHM_DETACH, tempnode->shm_id);
+ int rc;
+ if ((rc = cygserver_request (req)))
+ {
+ debug_printf ("failed to tell deaemon that we have detached\n");
+ }
+ delete req;
+
+ return 0;
}
-//FIXME: who is allowed to perform STAT?
+//FIXME: who is allowed to perform STAT?
extern "C" int
shmctl (int shmid, int cmd, struct shmid_ds *buf)
{
@@ -338,21 +395,20 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf)
break;
case IPC_RMID:
{
- /* TODO: check permissions. Or possibly, the daemon gets to be the only
+ /* TODO: check permissions. Or possibly, the daemon gets to be the only
* one with write access to the memory area?
*/
if (tempnode->shmds->shm_nattch)
system_printf
("call to shmctl with cmd= IPC_RMID when memory area still has"
" attachees\n");
- /* how does this work?
+ /* how does this work?
* we mark the ds area as "deleted", and the at and get calls all fail from now on
* on, when nattch becomes 0, the mapped data area is destroyed.
- * and each process, as they touch this area detaches. eventually only the
+ * and each process, as they touch this area detaches. eventually only the
* daemon has an attach. The daemon gets asked to detach immediately.
*/
-#if 0
-//waiting for the daemon to handle terminating process's
+ //waiting for the daemon to handle terminating process's
client_request_shm *req =
new client_request_shm (SHM_DEL, shmid, GetCurrentProcessId ());
int rc;
@@ -372,8 +428,9 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf)
/* the daemon has deleted it's references */
/* now for us */
-
-#endif
+
+ // FIXME: create a destructor
+ delete_inprocess_shmds (&tempnode);
}
break;
@@ -385,7 +442,7 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf)
return 0;
}
-/* FIXME: evaluate getuid() and getgid() against the requested mode. Then
+/* FIXME: evaluate getuid32() and getgid32() against the requested mode. Then
* choose PAGE_READWRITE | PAGE_READONLY and FILE_MAP_WRITE | FILE_MAP_READ
* appropriately
*/
@@ -402,7 +459,9 @@ shmget (key_t key, size_t size, int shmflg)
char sd_buf[4096];
PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) sd_buf;
/* create a sd for our open requests based on shmflag & 0x01ff */
- psd = alloc_sd (getuid (), getgid (), cygheap->user.logsrv (),
+ InitializeSecurityDescriptor (psd,
+ SECURITY_DESCRIPTOR_REVISION);
+ psd = alloc_sd (getuid32 (), getgid32 (),
shmflg & 0x01ff, psd, &sd_size);
if (key == (key_t) - 1)
@@ -479,9 +538,9 @@ shmget (key_t key, size_t size, int shmflg)
#if 0
/* fill out the node data */
- shmtemp->shm_perm.cuid = getuid ();
+ shmtemp->shm_perm.cuid = getuid32 ();
shmtemp->shm_perm.uid = shmtemp->shm_perm.cuid;
- shmtemp->shm_perm.cgid = getgid ();
+ shmtemp->shm_perm.cgid = getgid32 ();
shmtemp->shm_perm.gid = shmtemp->shm_perm.cgid;
shmtemp->shm_perm.mode = shmflg & 0x01ff;
shmtemp->shm_lpid = 0;
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index 5a00a7fca..5b42a1ff1 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -16,7 +16,6 @@ details. */
#include <stdlib.h>
#include "cygerrno.h"
#include <sys/cygwin.h>
-#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index b4cc45eb6..0960efae2 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -8,6 +8,8 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
+#ifndef _SIGPROC_H
+#define _SIGPROC_H
#include <signal.h>
#define EXIT_SIGNAL 0x010000
@@ -124,3 +126,4 @@ extern char myself_nowait_nonmain_dummy[];
#define myself_nowait ((_pinfo *)myself_nowait_dummy)
#define myself_nowait_nonmain ((_pinfo *)myself_nowait_nonmain_dummy)
+#endif /*_SIGPROC_H*/
diff --git a/winsup/cygwin/smallprint.c b/winsup/cygwin/smallprint.c
index 97a2b6ce1..d2a365c94 100644
--- a/winsup/cygwin/smallprint.c
+++ b/winsup/cygwin/smallprint.c
@@ -135,6 +135,9 @@ __small_vsprintf (char *dst, const char *fmt, va_list ap)
case 'U':
dst = rn (dst, 10, 0, va_arg (ap, long long), len, pad);
break;
+ case 'o':
+ dst = rn (dst, 8, 0, va_arg (ap, unsigned), len, pad);
+ break;
case 'p':
*dst++ = '0';
*dst++ = 'x';
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index b5dc670ce..e5d9bfe86 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -21,12 +21,10 @@ details. */
#include <ctype.h>
#include "cygerrno.h"
#include <sys/cygwin.h>
-#include "perprocess.h"
#include "security.h"
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
-#include "sync.h"
#include "sigproc.h"
#include "cygheap.h"
#include "child_info.h"
@@ -89,7 +87,7 @@ find_exec (const char *name, path_conv& buf, const char *mywinenv,
{
const char *suffix = "";
debug_printf ("find_exec (%s)", name);
- char *retval = buf;
+ const char *retval = buf;
char tmp[MAX_PATH];
const char *posix = (opt & FE_NATIVE) ? NULL : name;
bool has_slash = strchr (name, '/');
@@ -166,6 +164,8 @@ find_exec (const char *name, path_conv& buf, const char *mywinenv,
retval = NULL;
else if (opt & FE_NATIVE)
buf.check (name);
+ else
+ retval = name;
out:
if (posix)
@@ -316,7 +316,7 @@ av::unshift (const char *what, int conv)
}
static int __stdcall
-spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
+spawn_guts (const char * prog_arg, const char *const *argv,
const char *const envp[], int mode)
{
BOOL rc;
@@ -562,18 +562,14 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
MALLOC_CHECK;
}
+ char *envblock;
newargv.all_calloced ();
ciresrv.moreinfo->argc = newargv.argc;
ciresrv.moreinfo->argv = newargv;
-
- ciresrv.moreinfo->envc = envsize (envp, 1);
- ciresrv.moreinfo->envp = (char **) cmalloc (HEAP_1_ARGV, ciresrv.moreinfo->envc);
ciresrv.hexec_proc = hexec_proc;
- char **c;
- const char * const *e;
- for (c = ciresrv.moreinfo->envp, e = envp; *e;)
- *c++ = cstrdup1 (*e++);
- *c = NULL;
+ ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc,
+ real_path.iscygexec ());
+
if (mode != _P_OVERLAY ||
!DuplicateHandle (hMainProc, myself.shared_handle (), hMainProc,
&ciresrv.moreinfo->myself_pinfo, 0,
@@ -605,43 +601,31 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
flags |= CREATE_SUSPENDED;
- /* Build windows style environment list */
- char *envblock;
- if (real_path.iscygexec ())
- envblock = NULL;
- else
- envblock = winenv (envp, 0);
-
- /* Preallocated buffer for `sec_user' call */
- char sa_buf[1024];
-
- if (!hToken && cygheap->user.impersonated
- && cygheap->user.token != INVALID_HANDLE_VALUE)
- hToken = cygheap->user.token;
-
const char *runpath = null_app_name ? NULL : (const char *) real_path;
- syscall_printf ("spawn_guts null_app_name %d (%s, %.132s)", null_app_name, runpath, one_line.buf);
+ syscall_printf ("null_app_name %d (%s, %.132s)", null_app_name, runpath, one_line.buf);
void *newheap;
+ /* Preallocated buffer for `sec_user' call */
+ char sa_buf[1024];
+
cygbench ("spawn-guts");
- if (!hToken)
+ if (!cygheap->user.impersonated || cygheap->user.token == INVALID_HANDLE_VALUE)
{
- ciresrv.moreinfo->uid = getuid ();
+ PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf);
+ ciresrv.moreinfo->uid = getuid32 ();
/* FIXME: This leaks a handle in the CreateProcessAsUser case since the
child process doesn't know about cygwin_mount_h. */
ciresrv.mount_h = cygwin_mount_h;
newheap = cygheap_setup_for_child (&ciresrv, cygheap->fdtab.need_fixup_before ());
rc = CreateProcess (runpath, /* image name - with full path */
one_line.buf, /* what was passed to exec */
- /* process security attrs */
- sec_user_nih (sa_buf),
- /* thread security attrs */
- sec_user_nih (sa_buf),
- TRUE, /* inherit handles from parent */
+ sec_attribs, /* process security attrs */
+ sec_attribs, /* thread security attrs */
+ TRUE, /* inherit handles from parent */
flags,
- envblock,/* environment */
- 0, /* use current drive/directory */
+ envblock, /* environment */
+ 0, /* use current drive/directory */
&si,
&pi);
}
@@ -649,7 +633,8 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
{
cygsid sid;
DWORD ret_len;
- if (!GetTokenInformation (hToken, TokenUser, &sid, sizeof sid, &ret_len))
+ if (!GetTokenInformation (cygheap->user.token, TokenUser, &sid,
+ sizeof sid, &ret_len))
{
sid = NO_SID;
system_printf ("GetTokenInformation: %E");
@@ -658,17 +643,7 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
since it's value is needed by `sec_user'. */
PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf, sid);
- /* Remove impersonation */
- if (cygheap->user.impersonated
- && cygheap->user.token != INVALID_HANDLE_VALUE)
- RevertToSelf ();
-
- static BOOL first_time = TRUE;
- if (first_time)
- {
- set_process_privilege (SE_RESTORE_NAME);
- first_time = FALSE;
- }
+ RevertToSelf ();
/* Load users registry hive. */
load_registry_hive (sid);
@@ -692,22 +667,20 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
si.lpDesktop = wstname;
newheap = cygheap_setup_for_child (&ciresrv, cygheap->fdtab.need_fixup_before ());
- rc = CreateProcessAsUser (hToken,
+ rc = CreateProcessAsUser (cygheap->user.token,
runpath, /* image name - with full path */
one_line.buf, /* what was passed to exec */
sec_attribs, /* process security attrs */
sec_attribs, /* thread security attrs */
- TRUE, /* inherit handles from parent */
+ TRUE, /* inherit handles from parent */
flags,
- envblock,/* environment */
- 0, /* use current drive/directory */
+ envblock, /* environment */
+ 0, /* use current drive/directory */
&si,
&pi);
/* Restore impersonation. In case of _P_OVERLAY this isn't
allowed since it would overwrite child data. */
- if (mode != _P_OVERLAY
- && cygheap->user.impersonated
- && cygheap->user.token != INVALID_HANDLE_VALUE)
+ if (mode != _P_OVERLAY)
ImpersonateLoggedOnUser (cygheap->user.token);
}
@@ -793,9 +766,6 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv,
sigproc_printf ("spawned windows pid %d", pi.dwProcessId);
- if (hToken && hToken != cygheap->user.token)
- CloseHandle (hToken);
-
DWORD res;
BOOL exited;
@@ -916,8 +886,8 @@ cwait (int *result, int pid, int)
*/
extern "C" int
-_spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv,
- const char *const *envp)
+spawnve (int mode, const char *path, const char *const *argv,
+ const char *const *envp)
{
int ret;
vfork_save *vf = vfork_storage.val ();
@@ -927,14 +897,14 @@ _spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv,
else
vf = NULL;
- syscall_printf ("_spawnve (%s, %s, %x)", path, argv[0], envp);
+ syscall_printf ("spawnve (%s, %s, %x)", path, argv[0], envp);
switch (mode)
{
case _P_OVERLAY:
/* We do not pass _P_SEARCH_PATH here. execve doesn't search PATH.*/
/* Just act as an exec if _P_OVERLAY set. */
- spawn_guts (hToken, path, argv, envp, mode);
+ spawn_guts (path, argv, envp, mode);
/* Errno should be set by spawn_guts. */
ret = -1;
break;
@@ -944,7 +914,7 @@ _spawnve (HANDLE hToken, int mode, const char *path, const char *const *argv,
case _P_WAIT:
case _P_DETACH:
subproc_init ();
- ret = spawn_guts (hToken, path, argv, envp, mode);
+ ret = spawn_guts (path, argv, envp, mode);
if (vf && ret > 0)
{
debug_printf ("longjmping due to vfork");
@@ -982,7 +952,7 @@ spawnl (int mode, const char *path, const char *arg0, ...)
va_end (args);
- return _spawnve (NULL, mode, path, (char * const *) argv, cur_environ ());
+ return spawnve (mode, path, (char * const *) argv, cur_environ ());
}
extern "C" int
@@ -1004,8 +974,7 @@ spawnle (int mode, const char *path, const char *arg0, ...)
envp = va_arg (args, const char * const *);
va_end (args);
- return _spawnve (NULL, mode, path, (char * const *) argv,
- (char * const *) envp);
+ return spawnve (mode, path, (char * const *) argv, (char * const *) envp);
}
extern "C" int
@@ -1053,14 +1022,7 @@ spawnlpe (int mode, const char *path, const char *arg0, ...)
extern "C" int
spawnv (int mode, const char *path, const char * const *argv)
{
- return _spawnve (NULL, mode, path, argv, cur_environ ());
-}
-
-extern "C" int
-spawnve (int mode, const char *path, char * const *argv,
- const char * const *envp)
-{
- return _spawnve (NULL, mode, path, argv, envp);
+ return spawnve (mode, path, argv, cur_environ ());
}
extern "C" int
@@ -1074,5 +1036,5 @@ spawnvpe (int mode, const char *file, const char * const *argv,
const char * const *envp)
{
path_conv buf;
- return _spawnve (NULL, mode, find_exec (file, buf), argv, envp);
+ return spawnve (mode, find_exec (file, buf), argv, envp);
}
diff --git a/winsup/cygwin/strace.cc b/winsup/cygwin/strace.cc
index a3a699327..5a4549161 100644
--- a/winsup/cygwin/strace.cc
+++ b/winsup/cygwin/strace.cc
@@ -1,6 +1,6 @@
/* strace.cc: system/windows tracing
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -14,8 +14,6 @@ details. */
#include <wingdi.h>
#include <winuser.h>
#include <ctype.h>
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "perprocess.h"
#include "cygwin_version.h"
@@ -26,9 +24,6 @@ details. */
class NO_COPY strace strace;
-/* 'twould be nice to declare this in winsup.h but winsup.h doesn't require
- stdarg.h, so we declare it here instead. */
-
#ifndef NOSTRACE
void
@@ -42,6 +37,10 @@ strace::hello()
return;
}
+ inited = 1;
+ if (!being_debugged ())
+ return;
+
__small_sprintf (buf, "cYg%8x %x", _STRACE_INTERFACE_ACTIVATE_ADDR, &active);
OutputDebugString (buf);
@@ -64,7 +63,7 @@ strace::hello()
int
strace::microseconds ()
{
- static hires now;
+ static hires_us now;
return (int) now.usecs (true);
}
diff --git a/winsup/cygwin/sync.cc b/winsup/cygwin/sync.cc
index 333ec193c..b6dec83fa 100644
--- a/winsup/cygwin/sync.cc
+++ b/winsup/cygwin/sync.cc
@@ -4,7 +4,7 @@
which is intended to operate similarly to a mutex but attempts to
avoid making expensive calls to the kernel.
- Copyright 2000, 2001 Red Hat, Inc.
+ Copyright 2000, 2001, 2002 Red Hat, Inc.
Written by Christopher Faylor <cgf@cygnus.com>
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 7c0672e44..f9d9c94cb 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -11,7 +11,6 @@ details. */
#include "winsup.h"
#include <sys/stat.h>
#include <sys/vfs.h> /* needed for statfs */
-#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
#include <stdlib.h>
@@ -32,15 +31,12 @@ details. */
#include "fhandler.h"
#include "path.h"
#include "dtable.h"
-#include "sync.h"
#include "sigproc.h"
#include "pinfo.h"
#include <unistd.h>
#include "shared_info.h"
#include "cygheap.h"
-extern int normalize_posix_path (const char *, char *);
-
SYSTEM_INFO system_info;
/* Close all files and process any queued deletions.
@@ -85,15 +81,7 @@ check_pty_fds (void)
int
dup (int fd)
{
- int res;
- cygheap_fdnew newfd;
-
- if (newfd < 0)
- res = -1;
- else
- res = dup2 (fd, newfd);
-
- return res;
+ return cygheap->fdtab.dup2 (fd, cygheap_fdnew ());
}
int
@@ -106,6 +94,7 @@ extern "C" int
_unlink (const char *ourname)
{
int res = -1;
+ DWORD devn;
sigframe thisframe (mainthread);
path_conv win32_name (ourname, PC_SYM_NOFOLLOW | PC_FULL);
@@ -116,6 +105,13 @@ _unlink (const char *ourname)
goto done;
}
+ if ((devn = win32_name.get_devn ()) == FH_PROC || devn == FH_REGISTRY
+ || devn == FH_PROCESS)
+ {
+ set_errno (EROFS);
+ goto done;
+ }
+
syscall_printf ("_unlink (%s)", win32_name.get_win32 ());
if (!win32_name.exists ())
@@ -206,7 +202,7 @@ _unlink (const char *ourname)
/* Everything is fine if the file has disappeared or if we know that the
FILE_FLAG_DELETE_ON_CLOSE will eventually work. */
if (GetFileAttributes (win32_name) == INVALID_FILE_ATTRIBUTES
- || delete_on_close_ok)
+ || delete_on_close_ok)
goto ok; /* The file is either gone already or will eventually be
deleted by the OS. */
}
@@ -342,6 +338,14 @@ _read (int fd, void *ptr, size_t len)
}
out:
+
+ if (res && get_errno () == EACCES &&
+ !(cfd->get_flags () & (O_RDONLY | O_RDWR)))
+ {
+ set_errno (EBADF);
+ break;
+ }
+
if (res >= 0 || get_errno () != EINTR || !thisframe.call_signal_handler ())
break;
set_errno (e);
@@ -386,6 +390,9 @@ _write (int fd, const void *ptr, size_t len)
myself->process_state |= PID_TTYOU;
res = cfd->write (ptr, len);
myself->process_state &= ~PID_TTYOU;
+ if (res && get_errno () == EACCES &&
+ !(cfd->get_flags () & (O_WRONLY | O_RDWR)))
+ set_errno (EBADF);
}
done:
@@ -750,11 +757,11 @@ done:
* systems, it is only a stub that always returns zero.
*/
static int
-chown_worker (const char *name, unsigned fmode, __uid16_t uid, __gid16_t gid)
+chown_worker (const char *name, unsigned fmode, __uid32_t uid, __gid32_t gid)
{
int res;
- __uid16_t old_uid;
- __gid16_t old_gid;
+ __uid32_t old_uid;
+ __gid32_t old_gid;
if (check_null_empty_str_errno (name))
return -1;
@@ -798,7 +805,7 @@ chown_worker (const char *name, unsigned fmode, __uid16_t uid, __gid16_t gid)
if (win32_path.isdir())
attrib |= S_IFDIR;
res = set_file_attribute (win32_path.has_acls (), win32_path, uid,
- gid, attrib, cygheap->user.logsrv ());
+ gid, attrib);
}
if (res != 0 && (!win32_path.has_acls () || !allow_ntsec))
{
@@ -815,21 +822,35 @@ done:
}
extern "C" int
-chown (const char * name, __uid16_t uid, __gid16_t gid)
+chown32 (const char * name, __uid32_t uid, __gid32_t gid)
{
sigframe thisframe (mainthread);
return chown_worker (name, PC_SYM_FOLLOW, uid, gid);
}
extern "C" int
-lchown (const char * name, __uid16_t uid, __gid16_t gid)
+chown (const char * name, __uid16_t uid, __gid16_t gid)
+{
+ sigframe thisframe (mainthread);
+ return chown_worker (name, PC_SYM_FOLLOW, uid, gid16togid32 (gid));
+}
+
+extern "C" int
+lchown32 (const char * name, __uid32_t uid, __gid32_t gid)
{
sigframe thisframe (mainthread);
return chown_worker (name, PC_SYM_NOFOLLOW, uid, gid);
}
extern "C" int
-fchown (int fd, __uid16_t uid, __gid16_t gid)
+lchown (const char * name, __uid16_t uid, __gid16_t gid)
+{
+ sigframe thisframe (mainthread);
+ return chown_worker (name, PC_SYM_NOFOLLOW, uid, gid16togid32 (gid));
+}
+
+extern "C" int
+fchown32 (int fd, __uid32_t uid, __gid32_t gid)
{
sigframe thisframe (mainthread);
cygheap_fdget cfd (fd);
@@ -853,6 +874,12 @@ fchown (int fd, __uid16_t uid, __gid16_t gid)
return chown_worker (path, PC_SYM_FOLLOW, uid, gid);
}
+extern "C" int
+fchown (int fd, __uid16_t uid, __gid16_t gid)
+{
+ return fchown32 (fd, uid, gid16togid32 (gid));
+}
+
/* umask: POSIX 5.3.3.1 */
extern "C" mode_t
umask (mode_t mask)
@@ -894,8 +921,8 @@ chmod (const char *path, mode_t mode)
/* temporary erase read only bit, to be able to set file security */
SetFileAttributes (win32_path, (DWORD) win32_path & ~FILE_ATTRIBUTE_READONLY);
- __uid16_t uid;
- __gid16_t gid;
+ __uid32_t uid;
+ __gid32_t gid;
if (win32_path.isdir ())
mode |= S_IFDIR;
@@ -906,7 +933,7 @@ chmod (const char *path, mode_t mode)
if (win32_path.isdir ())
mode |= S_IFDIR;
if (!set_file_attribute (win32_path.has_acls (), win32_path, uid, gid,
- mode, cygheap->user.logsrv ())
+ mode)
&& allow_ntsec)
res = 0;
@@ -965,7 +992,7 @@ fchmod (int fd, mode_t mode)
static void
stat64_to_stat32 (struct __stat64 *src, struct __stat32 *dst)
{
- dst->st_dev = src->st_dev;
+ dst->st_dev = ((src->st_dev >> 8) & 0xff00) | (src->st_dev & 0xff);
dst->st_ino = src->st_ino;
dst->st_mode = src->st_mode;
dst->st_nlink = src->st_nlink;
@@ -973,9 +1000,9 @@ stat64_to_stat32 (struct __stat64 *src, struct __stat32 *dst)
dst->st_gid = src->st_gid;
dst->st_rdev = src->st_rdev;
dst->st_size = src->st_size;
- dst->st_atime = src->st_atime;
- dst->st_mtime = src->st_mtime;
- dst->st_ctime = src->st_ctime;
+ dst->st_atim = src->st_atim;
+ dst->st_mtim = src->st_mtim;
+ dst->st_ctim = src->st_ctim;
dst->st_blksize = src->st_blksize;
dst->st_blocks = src->st_blocks;
}
@@ -991,8 +1018,16 @@ fstat64 (int fd, struct __stat64 *buf)
res = -1;
else
{
+ path_conv pc (cfd->get_win32_name ());
memset (buf, 0, sizeof (struct __stat64));
- res = cfd->fstat (buf, NULL);
+ res = cfd->fstat (buf, &pc);
+ if (!res)
+ {
+ if (!buf->st_ino)
+ buf->st_ino = hash_path_name (0, cfd->get_win32_name ());
+ if (!buf->st_dev)
+ buf->st_dev = (cfd->get_device () << 16) | cfd->get_unit ();
+ }
}
syscall_printf ("%d = fstat (%d, %p)", res, fd, buf);
@@ -1052,18 +1087,17 @@ stat_worker (const char *name, struct __stat64 *buf, int nofollow,
path_conv real_path;
fhandler_base *fh = NULL;
- if (!pc)
- pc = &real_path;
-
- MALLOC_CHECK;
if (check_null_invalid_struct_errno (buf))
goto done;
+ if (!pc)
+ pc = &real_path;
+
fh = cygheap->fdtab.build_fhandler_from_name (-1, name, NULL, *pc,
- (nofollow ?
- PC_SYM_NOFOLLOW
- : PC_SYM_FOLLOW)
+ (nofollow ? PC_SYM_NOFOLLOW
+ : PC_SYM_FOLLOW)
| PC_FULL, stat_suffixes);
+
if (pc->error)
{
debug_printf ("got %d error from build_fhandler_from_name", pc->error);
@@ -1073,8 +1107,15 @@ stat_worker (const char *name, struct __stat64 *buf, int nofollow,
{
debug_printf ("(%s, %p, %d, %p), file_attributes %d", name, buf, nofollow,
pc, (DWORD) real_path);
- memset (buf, 0, sizeof (struct __stat64));
+ memset (buf, 0, sizeof (*buf));
res = fh->fstat (buf, pc);
+ if (!res)
+ {
+ if (!buf->st_ino)
+ buf->st_ino = hash_path_name (0, fh->get_win32_name ());
+ if (!buf->st_dev)
+ buf->st_dev = (fh->get_device () << 16) | fh->get_unit ();
+ }
}
done:
@@ -1148,45 +1189,45 @@ access (const char *fn, int flags)
{
if (st.st_uid == myself->uid)
{
- if (! (st.st_mode & S_IRUSR))
+ if (!(st.st_mode & S_IRUSR))
goto done;
}
else if (st.st_gid == myself->gid)
{
- if (! (st.st_mode & S_IRGRP))
+ if (!(st.st_mode & S_IRGRP))
goto done;
}
- else if (! (st.st_mode & S_IROTH))
+ else if (!(st.st_mode & S_IROTH))
goto done;
}
if (flags & W_OK)
{
if (st.st_uid == myself->uid)
{
- if (! (st.st_mode & S_IWUSR))
+ if (!(st.st_mode & S_IWUSR))
goto done;
}
else if (st.st_gid == myself->gid)
{
- if (! (st.st_mode & S_IWGRP))
+ if (!(st.st_mode & S_IWGRP))
goto done;
}
- else if (! (st.st_mode & S_IWOTH))
+ else if (!(st.st_mode & S_IWOTH))
goto done;
}
if (flags & X_OK)
{
if (st.st_uid == myself->uid)
{
- if (! (st.st_mode & S_IXUSR))
+ if (!(st.st_mode & S_IXUSR))
goto done;
}
else if (st.st_gid == myself->gid)
{
- if (! (st.st_mode & S_IXGRP))
+ if (!(st.st_mode & S_IXGRP))
goto done;
}
- else if (! (st.st_mode & S_IXOTH))
+ else if (!(st.st_mode & S_IXOTH))
goto done;
}
r = 0;
@@ -1308,10 +1349,10 @@ done:
#ifdef HIDDEN_DOT_FILES
char *c = strrchr (real_old.get_win32 (), '\\');
if ((c && c[1] == '.') || *real_old.get_win32 () == '.')
- attr &= ~FILE_ATTRIBUTE_HIDDEN;
+ attr &= ~FILE_ATTRIBUTE_HIDDEN;
c = strrchr (real_new.get_win32 (), '\\');
if ((c && c[1] == '.') || *real_new.get_win32 () == '.')
- attr |= FILE_ATTRIBUTE_HIDDEN;
+ attr |= FILE_ATTRIBUTE_HIDDEN;
#endif
SetFileAttributes (real_new, attr);
@@ -1482,7 +1523,7 @@ pathconf (const char *file, int v)
{
case _PC_PATH_MAX:
if (check_null_empty_str_errno (file))
- return -1;
+ return -1;
return PATH_MAX - strlen (file);
case _PC_NAME_MAX:
return PATH_MAX;
@@ -1590,8 +1631,8 @@ setmode_helper (FILE *f)
if (fileno (f) != setmode_file)
return 0;
syscall_printf ("setmode: file was %s now %s\n",
- f->_flags & __SCLE ? "cle" : "raw",
- setmode_mode & O_TEXT ? "cle" : "raw");
+ f->_flags & __SCLE ? "text" : "raw",
+ setmode_mode & O_TEXT ? "text" : "raw");
if (setmode_mode & O_TEXT)
f->_flags |= __SCLE;
else
@@ -1639,16 +1680,8 @@ setmode (int fd, int mode)
if (!mode)
cfd->reset_to_open_binmode ();
- else if (mode & O_BINARY)
- {
- cfd->set_w_binary (1);
- cfd->set_r_binary (1);
- }
else
- {
- cfd->set_w_binary (0);
- cfd->set_r_binary (0);
- }
+ cfd->set_flags ((cfd->get_flags () & ~(O_TEXT | O_BINARY)) | mode);
if (_cygwin_istext_for_stdio (fd))
setmode_mode = O_TEXT;
@@ -1657,9 +1690,8 @@ setmode (int fd, int mode)
setmode_file = fd;
_fwalk (_REENT, setmode_helper);
- syscall_printf ("setmode (%d<%s>, %s) returns %s\n", fd, cfd->get_name (),
- mode & O_TEXT ? "text" : "binary",
- res & O_TEXT ? "text" : "binary");
+ syscall_printf ("setmode (%d<%s>, %p) returns %s\n", fd, cfd->get_name (),
+ mode, res & O_TEXT ? "text" : "binary");
return res;
}
@@ -1720,7 +1752,7 @@ truncate64 (const char *pathname, __off64_t length)
set_errno (EBADF);
else
{
- res = ftruncate (fd, length);
+ res = ftruncate64 (fd, length);
close (fd);
}
syscall_printf ("%d = truncate (%s, %d)", res, pathname, length);
@@ -1911,303 +1943,313 @@ mkfifo (const char *_path, mode_t mode)
return -1;
}
-/* setgid: POSIX 4.2.2.1 */
-extern "C" int
-setgid (__gid16_t gid)
-{
- int ret = setegid (gid);
- if (!ret)
- cygheap->user.real_gid = myself->gid;
- return ret;
-}
-
-/* setuid: POSIX 4.2.2.1 */
-extern "C" int
-setuid (__uid16_t uid)
-{
- int ret = seteuid (uid);
- if (!ret)
- cygheap->user.real_uid = myself->uid;
- debug_printf ("real: %d, effective: %d", cygheap->user.real_uid, myself->uid);
- return ret;
-}
-
extern struct passwd *internal_getlogin (cygheap_user &user);
/* seteuid: standards? */
extern "C" int
-seteuid (__uid16_t uid)
+seteuid32 (__uid32_t uid)
{
+ if (!wincap.has_security ()) return 0;
+
+ if (uid == ILLEGAL_UID)
+ {
+ debug_printf ("new euid == illegal euid, nothing happens");
+ return 0;
+ }
+
sigframe thisframe (mainthread);
- if (wincap.has_security ())
+ DWORD ulen = UNLEN + 1;
+ DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
+ char orig_username[UNLEN + 1];
+ char orig_domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ char username[UNLEN + 1];
+ char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ cygsid usersid, pgrpsid;
+ HANDLE ptok, sav_token;
+ BOOL sav_impersonated, sav_token_is_internal_token;
+ BOOL process_ok, explicitly_created_token = FALSE;
+ struct passwd * pw_new, * pw_cur;
+ cygheap_user user;
+ PSID origpsid, psid2 = NO_SID;
+
+ debug_printf ("uid: %d myself->gid: %d", uid, myself->gid);
+
+ pw_new = getpwuid32 (uid);
+ if (!usersid.getfrompw (pw_new) ||
+ (!pgrpsid.getfromgr (getgrgid32 (myself->gid))))
{
- char orig_username[UNLEN + 1];
- char orig_domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
- char username[UNLEN + 1];
- DWORD ulen = UNLEN + 1;
- char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
- DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;
- SID_NAME_USE use;
+ set_errno (EINVAL);
+ return -1;
+ }
+ /* Save current information */
+ sav_token = cygheap->user.token;
+ sav_impersonated = cygheap->user.impersonated;
+ char *env;
+ orig_username[0] = orig_domain[0] = '\0';
+ if ((env = getenv ("USERNAME")))
+ strlcpy (orig_username, env, sizeof(orig_username));
+ if ((env = getenv ("USERDOMAIN")))
+ strlcpy (orig_domain, env, sizeof(orig_domain));
- if (uid == ILLEGAL_UID || uid == myself->uid)
- {
- debug_printf ("new euid == current euid, nothing happens");
- return 0;
- }
- struct passwd *pw_new = getpwuid (uid);
- if (!pw_new)
+ RevertToSelf();
+ if (!OpenProcessToken (GetCurrentProcess (),
+ TOKEN_QUERY | TOKEN_ADJUST_DEFAULT, &ptok))
+ {
+ __seterrno ();
+ goto failed;
+ }
+ /* Verify if the process token is suitable.
+ Currently we do not try to differentiate between
+ internal tokens and others */
+ process_ok = verify_token(ptok, usersid, pgrpsid);
+ debug_printf("Process token %sverified", process_ok?"":"not ");
+ if (process_ok)
+ {
+ if (cygheap->user.token == INVALID_HANDLE_VALUE ||
+ !cygheap->user.impersonated)
{
- set_errno (EINVAL);
- return -1;
+ CloseHandle (ptok);
+ return 0; /* No change */
}
+ else cygheap->user.impersonated = FALSE;
+ }
- cygsid tok_usersid;
- DWORD siz;
-
- char *env;
- orig_username[0] = orig_domain[0] = '\0';
- if ((env = getenv ("USERNAME")))
- strncat (orig_username, env, UNLEN + 1);
- if ((env = getenv ("USERDOMAIN")))
- strncat (orig_domain, env, INTERNET_MAX_HOST_NAME_LENGTH + 1);
- if (uid == cygheap->user.orig_uid)
+ if (!process_ok && cygheap->user.token != INVALID_HANDLE_VALUE)
+ {
+ /* Verify if the current tokem is suitable */
+ BOOL token_ok = verify_token (cygheap->user.token, usersid, pgrpsid,
+ & sav_token_is_internal_token);
+ debug_printf("Thread token %d %sverified",
+ cygheap->user.token, token_ok?"":"not ");
+ if (token_ok)
{
-
- debug_printf ("RevertToSelf () (uid == orig_uid, token=%d)",
- cygheap->user.token);
- RevertToSelf ();
- if (cygheap->user.token != INVALID_HANDLE_VALUE)
- cygheap->user.impersonated = FALSE;
-
- HANDLE ptok = INVALID_HANDLE_VALUE;
- if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok))
- debug_printf ("OpenProcessToken(): %E\n");
- else if (!GetTokenInformation (ptok, TokenUser, &tok_usersid,
- sizeof tok_usersid, &siz))
- debug_printf ("GetTokenInformation(): %E");
- else if (!LookupAccountSid (NULL, tok_usersid, username, &ulen,
- domain, &dlen, &use))
- debug_printf ("LookupAccountSid(): %E");
- else
+ /* Return if current token is valid */
+ if (cygheap->user.impersonated)
{
- setenv ("USERNAME", username, 1);
- setenv ("USERDOMAIN", domain, 1);
+ CloseHandle (ptok);
+ if (!ImpersonateLoggedOnUser (cygheap->user.token))
+ system_printf ("Impersonating in seteuid failed: %E");
+ return 0; /* No change */
}
- if (ptok != INVALID_HANDLE_VALUE)
- CloseHandle (ptok);
}
- else
- {
- cygsid usersid, pgrpsid, tok_pgrpsid;
- HANDLE sav_token = INVALID_HANDLE_VALUE;
- BOOL sav_impersonation;
- BOOL current_token_is_internal_token = FALSE;
- BOOL explicitely_created_token = FALSE;
-
- struct __group16 *gr = getgrgid (myself->gid);
- debug_printf ("myself->gid: %d, gr: %d", myself->gid, gr);
-
- usersid.getfrompw (pw_new);
- pgrpsid.getfromgr (gr);
-
- /* Only when ntsec is ON! */
- /* Check if new user == user of impersonation token and
- - if reasonable - new pgrp == pgrp of impersonation token. */
- if (allow_ntsec && cygheap->user.token != INVALID_HANDLE_VALUE)
- {
- if (!GetTokenInformation (cygheap->user.token, TokenUser,
- &tok_usersid, sizeof tok_usersid, &siz))
- {
- debug_printf ("GetTokenInformation(): %E");
- tok_usersid = NO_SID;
- }
- if (!GetTokenInformation (cygheap->user.token, TokenPrimaryGroup,
- &tok_pgrpsid, sizeof tok_pgrpsid, &siz))
- {
- debug_printf ("GetTokenInformation(): %E");
- tok_pgrpsid = NO_SID;
- }
- /* Check if the current user token was internally created. */
- TOKEN_SOURCE ts;
- if (!GetTokenInformation (cygheap->user.token, TokenSource,
- &ts, sizeof ts, &siz))
- debug_printf ("GetTokenInformation(): %E");
- else if (!memcmp (ts.SourceName, "Cygwin.1", 8))
- current_token_is_internal_token = TRUE;
- if ((usersid && tok_usersid && usersid != tok_usersid) ||
- /* Check for pgrp only if current token is an internal
- token. Otherwise the external provided token is
- very likely overwritten here. */
- (current_token_is_internal_token &&
- pgrpsid && tok_pgrpsid && pgrpsid != tok_pgrpsid))
- {
- /* If not, RevertToSelf and close old token. */
- debug_printf ("tsid != usersid");
- RevertToSelf ();
- sav_token = cygheap->user.token;
- sav_impersonation = cygheap->user.impersonated;
- cygheap->user.token = INVALID_HANDLE_VALUE;
- cygheap->user.impersonated = FALSE;
- }
- }
+ else cygheap->user.token = INVALID_HANDLE_VALUE;
+ }
- /* Only when ntsec is ON! */
- /* If no impersonation token is available, try to
- authenticate using NtCreateToken() or subauthentication. */
- if (allow_ntsec && cygheap->user.token == INVALID_HANDLE_VALUE)
- {
- HANDLE ptok = INVALID_HANDLE_VALUE;
+ /* Set process def dacl to allow access to impersonated token */
+ char dacl_buf[MAX_DACL_LEN(5)];
+ if (usersid != (origpsid = cygheap->user.orig_sid())) psid2 = usersid;
+ if (sec_acl ((PACL) dacl_buf, FALSE, origpsid, psid2))
+ {
+ TOKEN_DEFAULT_DACL tdacl;
+ tdacl.DefaultDacl = (PACL) dacl_buf;
+ if (!SetTokenInformation (ptok, TokenDefaultDacl,
+ &tdacl, sizeof dacl_buf))
+ debug_printf ("SetTokenInformation"
+ "(TokenDefaultDacl): %E");
+ }
+ CloseHandle (ptok);
- ptok = create_token (usersid, pgrpsid);
- if (ptok != INVALID_HANDLE_VALUE)
- explicitely_created_token = TRUE;
- else
- {
- /* create_token failed. Try subauthentication. */
- debug_printf ("create token failed, try subauthentication.");
- ptok = subauth (pw_new);
- }
- if (ptok != INVALID_HANDLE_VALUE)
- {
- cygwin_set_impersonation_token (ptok);
- /* If sav_token was internally created, destroy it. */
- if (sav_token != INVALID_HANDLE_VALUE &&
- current_token_is_internal_token)
- CloseHandle (sav_token);
- }
- else if (sav_token != INVALID_HANDLE_VALUE)
- cygheap->user.token = sav_token;
- }
- /* If no impersonation is active but an impersonation
- token is available, try to impersonate. */
- if (cygheap->user.token != INVALID_HANDLE_VALUE &&
- !cygheap->user.impersonated)
- {
- debug_printf ("Impersonate (uid == %d)", uid);
- RevertToSelf ();
-
- /* If the token was explicitely created, all information has
- already been set correctly. */
- if (!explicitely_created_token)
- {
- /* Try setting owner to same value as user. */
- if (usersid &&
- !SetTokenInformation (cygheap->user.token, TokenOwner,
- &usersid, sizeof usersid))
- debug_printf ("SetTokenInformation(user.token, "
- "TokenOwner): %E");
- /* Try setting primary group in token to current group
- if token not explicitely created. */
- if (pgrpsid &&
- !SetTokenInformation (cygheap->user.token,
- TokenPrimaryGroup,
- &pgrpsid, sizeof pgrpsid))
- debug_printf ("SetTokenInformation(user.token, "
- "TokenPrimaryGroup): %E");
-
- }
-
- /* Now try to impersonate. */
- if (!LookupAccountSid (NULL, usersid, username, &ulen,
- domain, &dlen, &use))
- debug_printf ("LookupAccountSid (): %E");
- else if (!ImpersonateLoggedOnUser (cygheap->user.token))
- system_printf ("Impersonating (%d) in set(e)uid failed: %E",
- cygheap->user.token);
- else
- {
- cygheap->user.impersonated = TRUE;
- setenv ("USERNAME", username, 1);
- setenv ("USERDOMAIN", domain, 1);
- }
- }
+ if (!process_ok && cygheap->user.token == INVALID_HANDLE_VALUE)
+ {
+ /* If no impersonation token is available, try to
+ authenticate using NtCreateToken() or subauthentication. */
+ cygheap->user.token = create_token (usersid, pgrpsid);
+ if (cygheap->user.token != INVALID_HANDLE_VALUE)
+ explicitly_created_token = TRUE;
+ else
+ {
+ /* create_token failed. Try subauthentication. */
+ debug_printf ("create token failed, try subauthentication.");
+ cygheap->user.token = subauth (pw_new);
+ if (cygheap->user.token == INVALID_HANDLE_VALUE) goto failed;
}
+ }
- cygheap_user user;
- /* user.token is used in internal_getlogin () to determine if
- impersonation is active. If so, the token is used for
- retrieving user's SID. */
- user.token = cygheap->user.impersonated ? cygheap->user.token
- : INVALID_HANDLE_VALUE;
- /* Unsetting these both env vars is necessary to get NetUserGetInfo()
- called in internal_getlogin (). Otherwise the wrong path is used
- after a user switch, probably. */
- unsetenv ("HOMEDRIVE");
- unsetenv ("HOMEPATH");
- struct passwd *pw_cur = internal_getlogin (user);
- if (pw_cur != pw_new)
+ /* Lookup username and domain before impersonating,
+ LookupAccountSid() returns a different answer afterwards. */
+ SID_NAME_USE use;
+ if (!LookupAccountSid (NULL, usersid, username, &ulen,
+ domain, &dlen, &use))
+ {
+ debug_printf ("LookupAccountSid (): %E");
+ __seterrno ();
+ goto failed;
+ }
+ /* If using the token, set info and impersonate */
+ if (!process_ok)
+ {
+ /* If the token was explicitly created, all information has
+ already been set correctly. */
+ if (!explicitly_created_token)
{
- debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d",
- cygheap->user.token, pw_cur->pw_uid,
- pw_new->pw_uid, cygheap->user.orig_uid);
- setenv ("USERNAME", orig_username, 1);
- setenv ("USERDOMAIN", orig_domain, 1);
- set_errno (EPERM);
- return -1;
+ /* Try setting owner to same value as user. */
+ if (!SetTokenInformation (cygheap->user.token, TokenOwner,
+ &usersid, sizeof usersid))
+ debug_printf ("SetTokenInformation(user.token, "
+ "TokenOwner): %E");
+ /* Try setting primary group in token to current group */
+ if (!SetTokenInformation (cygheap->user.token,
+ TokenPrimaryGroup,
+ &pgrpsid, sizeof pgrpsid))
+ debug_printf ("SetTokenInformation(user.token, "
+ "TokenPrimaryGroup): %E");
+ }
+ /* Now try to impersonate. */
+ if (!ImpersonateLoggedOnUser (cygheap->user.token))
+ {
+ debug_printf ("ImpersonateLoggedOnUser %E");
+ __seterrno ();
+ goto failed;
}
+ cygheap->user.impersonated = TRUE;
+ }
+
+ /* user.token is used in internal_getlogin () to determine if
+ impersonation is active. If so, the token is used for
+ retrieving user's SID. */
+ user.token = cygheap->user.impersonated ? cygheap->user.token
+ : INVALID_HANDLE_VALUE;
+ /* Unsetting these two env vars is necessary to get NetUserGetInfo()
+ called in internal_getlogin (). Otherwise the wrong path is used
+ after a user switch, probably. */
+ unsetenv ("HOMEDRIVE");
+ unsetenv ("HOMEPATH");
+ setenv ("USERDOMAIN", domain, 1);
+ setenv ("USERNAME", username, 1);
+ pw_cur = internal_getlogin (user);
+ if (pw_cur == pw_new)
+ {
+ /* If sav_token was internally created and is replaced, destroy it. */
+ if (sav_token != INVALID_HANDLE_VALUE &&
+ sav_token != cygheap->user.token &&
+ sav_token_is_internal_token)
+ CloseHandle (sav_token);
myself->uid = uid;
cygheap->user = user;
+ return 0;
}
- else
- set_errno (ENOSYS);
+ debug_printf ("Diffs!!! token: %d, cur: %d, new: %d, orig: %d",
+ cygheap->user.token, pw_cur->pw_uid,
+ pw_new->pw_uid, cygheap->user.orig_uid);
+ set_errno (EPERM);
+
+ failed:
+ setenv ("USERNAME", orig_username, 1);
+ setenv ("USERDOMAIN", orig_domain, 1);
+ cygheap->user.token = sav_token;
+ cygheap->user.impersonated = sav_impersonated;
+ if ( cygheap->user.token != INVALID_HANDLE_VALUE &&
+ cygheap->user.impersonated &&
+ !ImpersonateLoggedOnUser (cygheap->user.token))
+ system_printf ("Impersonating in seteuid failed: %E");
+ return -1;
+}
+
+extern "C" int
+seteuid (__uid16_t uid)
+{
+ return seteuid32 (uid16touid32 (uid));
+}
+
+/* setuid: POSIX 4.2.2.1 */
+extern "C" int
+setuid32 (__uid32_t uid)
+{
+ int ret = seteuid32 (uid);
+ if (!ret)
+ cygheap->user.real_uid = myself->uid;
debug_printf ("real: %d, effective: %d", cygheap->user.real_uid, myself->uid);
- return 0;
+ return ret;
+}
+
+extern "C" int
+setuid (__uid16_t uid)
+{
+ return setuid32 (uid16touid32 (uid));
}
/* setegid: from System V. */
extern "C" int
-setegid (__gid16_t gid)
+setegid32 (__gid32_t gid)
{
+ if ((!wincap.has_security ()) ||
+ (gid == ILLEGAL_GID))
+ return 0;
+
sigframe thisframe (mainthread);
- if (wincap.has_security ())
+ cygsid gsid;
+ HANDLE ptok;
+
+ struct __group32 * gr = getgrgid32 (gid);
+ if (!gr || gr->gr_gid != gid || !gsid.getfromgr (gr))
{
- if (gid != ILLEGAL_GID)
- {
- struct __group16 *gr;
+ set_errno (EINVAL);
+ return -1;
+ }
+ myself->gid = gid;
- if (!(gr = getgrgid (gid)))
- {
- set_errno (EINVAL);
- return -1;
- }
- myself->gid = gid;
-#if 0 // Setting the primary group in token here isn't foolproof enough.
- if (allow_ntsec)
- {
- cygsid gsid;
- HANDLE ptok;
-
- if (gsid.getfromgr (gr))
- {
- if (!OpenProcessToken (GetCurrentProcess (),
- TOKEN_ADJUST_DEFAULT,
- &ptok))
- debug_printf ("OpenProcessToken(): %E\n");
- else
- {
- if (!SetTokenInformation (ptok, TokenPrimaryGroup,
- &gsid, sizeof gsid))
- debug_printf ("SetTokenInformation(myself, "
- "TokenPrimaryGroup): %E");
- CloseHandle (ptok);
- }
- }
- }
-#endif
- }
+ /* If impersonated, update primary group and revert */
+ if (cygheap->user.token != INVALID_HANDLE_VALUE
+ && cygheap->user.impersonated)
+ {
+ if (!SetTokenInformation (cygheap->user.token,
+ TokenPrimaryGroup,
+ &gsid, sizeof gsid))
+ debug_printf ("SetTokenInformation(thread, "
+ "TokenPrimaryGroup): %E");
+ RevertToSelf ();
}
+ if (!OpenProcessToken (GetCurrentProcess (),
+ TOKEN_ADJUST_DEFAULT,
+ &ptok))
+ debug_printf ("OpenProcessToken(): %E\n");
else
- set_errno (ENOSYS);
+ {
+ if (!SetTokenInformation (ptok, TokenPrimaryGroup,
+ &gsid, sizeof gsid))
+ debug_printf ("SetTokenInformation(process, "
+ "TokenPrimaryGroup): %E");
+ CloseHandle (ptok);
+ }
+ if (cygheap->user.token != INVALID_HANDLE_VALUE
+ && cygheap->user.impersonated
+ && !ImpersonateLoggedOnUser (cygheap->user.token))
+ system_printf ("Impersonating in setegid failed: %E");
return 0;
}
+extern "C" int
+setegid (__gid16_t gid)
+{
+ return setegid32 (gid16togid32 (gid));
+}
+
+/* setgid: POSIX 4.2.2.1 */
+extern "C" int
+setgid32 (__gid32_t gid)
+{
+ int ret = setegid32 (gid);
+ if (!ret)
+ cygheap->user.real_gid = myself->gid;
+ return ret;
+}
+
+extern "C" int
+setgid (__gid16_t gid)
+{
+ int ret = setegid32 (gid16togid32 (gid));
+ if (!ret)
+ cygheap->user.real_gid = myself->gid;
+ return ret;
+}
+
/* chroot: privileged Unix system call. */
/* FIXME: Not privileged here. How should this be done? */
extern "C" int
chroot (const char *newroot)
{
sigframe thisframe (mainthread);
- path_conv path (newroot, PC_SYM_FOLLOW | PC_FULL);
+ path_conv path (newroot, PC_SYM_FOLLOW | PC_FULL | PC_POSIX);
int ret;
if (path.error)
@@ -2224,9 +2266,7 @@ chroot (const char *newroot)
}
else
{
- char buf[MAX_PATH];
- normalize_posix_path (newroot, buf);
- cygheap->root.set (buf, path);
+ cygheap->root.set (path.normalized_path, path);
ret = 0;
}
diff --git a/winsup/cygwin/sysconf.cc b/winsup/cygwin/sysconf.cc
index efc3e5dc1..67099c282 100644
--- a/winsup/cygwin/sysconf.cc
+++ b/winsup/cygwin/sysconf.cc
@@ -1,6 +1,6 @@
/* sysconf.cc
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -62,7 +62,7 @@ sysconf (int in)
/*FALLTHRU*/
case _SC_PHYS_PAGES:
case _SC_AVPHYS_PAGES:
- if (!wincap.supports_smp ())
+ if (wincap.supports_smp ())
{
NTSTATUS ret;
SYSTEM_BASIC_INFORMATION sbi;
diff --git a/winsup/cygwin/termios.cc b/winsup/cygwin/termios.cc
index 499072f51..c44ccbdc3 100644
--- a/winsup/cygwin/termios.cc
+++ b/winsup/cygwin/termios.cc
@@ -1,6 +1,6 @@
/* termios.cc: termios for WIN32.
- Copyright 1996, 1997, 1998, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 2000, 2001, 2002 Red Hat, Inc.
Written by Doug Evans and Steve Chamberlain of Cygnus Support
dje@cygnus.com, sac@cygnus.com
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 5c44ca90a..cc24fdca6 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -1,6 +1,6 @@
/* thread.cc: Locking and threading module functions
- Copyright 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
Originally written by Marco Fuykschot <marco@ddi.nl>
Substantialy enhanced by Robert Collins <rbtcollins@hotmail.com>
@@ -37,8 +37,6 @@ details. */
#include <assert.h>
#include <stdlib.h>
#include <syslog.h>
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "perprocess.h"
#include "security.h"
@@ -345,8 +343,19 @@ MTinterface::fixup_after_fork (void)
}
}
+/* pthread calls */
+
+/* static methods */
+
+pthread *
+pthread::self ()
+{
+ return (pthread *) TlsGetValue (MT_INTERFACE->thread_self_dwTlsIndex);
+}
+
+/* member methods */
pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0),
-cancelstate (0), canceltype (0)
+cancelstate (0), canceltype (0), joiner (NULL), cleanup_handlers(NULL)
{
}
@@ -375,6 +384,14 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
function = func;
arg = threadarg;
+ if (verifyable_object_isvalid (&mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
+ {
+ thread_printf ("New thread object access mutex is not valid. this %p",
+ this);
+ magic = 0;
+ return;
+ }
+
win32_obj_id = ::CreateThread (&sec_none_nih, attr.stacksize,
(LPTHREAD_START_ROUTINE) thread_init_wrapper,
this, CREATE_SUSPENDED, &thread_id);
@@ -383,6 +400,7 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
magic = 0;
else
{
+ InterlockedIncrement (&MT_INTERFACE->threadcount);
/*FIXME: set the priority appropriately for system contention scope */
if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED)
{
@@ -393,6 +411,43 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
}
}
+void
+pthread::push_cleanup_handler (__pthread_cleanup_handler *handler)
+{
+ if (this != self ())
+ // TODO: do it?
+ api_fatal ("Attempt to push a cleanup handler across threads");
+ mutex.Lock();
+ handler->next = cleanup_handlers;
+ cleanup_handlers = handler;
+ mutex.UnLock();
+}
+
+void
+pthread::pop_cleanup_handler (int const execute)
+{
+ if (this != self ())
+ // TODO: send a signal or something to the thread ?
+ api_fatal ("Attempt to execute a cleanup handler across threads");
+
+ if (cleanup_handlers != NULL )
+ {
+ __pthread_cleanup_handler *handler = cleanup_handlers;
+
+ if (execute)
+ (*handler->function) (handler->arg);
+
+ cleanup_handlers = handler->next;
+ }
+}
+
+void
+pthread::pop_all_cleanup_handlers ()
+{
+ while (cleanup_handlers != NULL)
+ pop_cleanup_handler (1);
+}
+
pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC),
joinable (PTHREAD_CREATE_JOINABLE), contentionscope (PTHREAD_SCOPE_PROCESS),
inheritsched (PTHREAD_INHERIT_SCHED), stacksize (0)
@@ -878,7 +933,7 @@ verifyable_object_isvalid (void const * objectptr, long magic)
/* Pthreads */
void *
-thread_init_wrapper (void *_arg)
+pthread::thread_init_wrapper (void *_arg)
{
// Setup the local/global storage of this thread
@@ -910,6 +965,12 @@ thread_init_wrapper (void *_arg)
/*the OS doesn't check this for <= 64 Tls entries (pre win2k) */
TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, thread);
+ thread->mutex.Lock();
+ // if thread is detached force cleanup on exit
+ if (thread->attr.joinable == PTHREAD_CREATE_DETACHED && thread->joiner == NULL)
+ thread->joiner = pthread::self ();
+ thread->mutex.UnLock();
+
#ifdef _CYG_THREAD_FAILSAFE
if (_REENT == _impure_ptr)
system_printf ("local storage for thread isn't setup correctly");
@@ -947,7 +1008,6 @@ __pthread_create (pthread_t *thread, const pthread_attr_t *attr,
*thread = NULL;
return EAGAIN;
}
- InterlockedIncrement (&MT_INTERFACE->threadcount);
return 0;
}
@@ -1189,7 +1249,7 @@ opengroup specs.
int
__pthread_setcancelstate (int state, int *oldstate)
{
- class pthread *thread = __pthread_self ();
+ class pthread *thread = pthread::self ();
if (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE)
return EINVAL;
*oldstate = thread->cancelstate;
@@ -1200,7 +1260,7 @@ __pthread_setcancelstate (int state, int *oldstate)
int
__pthread_setcanceltype (int type, int *oldtype)
{
- class pthread *thread = __pthread_self ();
+ class pthread *thread = pthread::self ();
if (type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS)
return EINVAL;
*oldtype = thread->canceltype;
@@ -1212,7 +1272,7 @@ __pthread_setcanceltype (int type, int *oldtype)
void
__pthread_testcancel (void)
{
- class pthread *thread = __pthread_self ();
+ class pthread *thread = pthread::self ();
if (thread->cancelstate == PTHREAD_CANCEL_DISABLE)
return;
/*check the cancellation event object here - not neededuntil pthread_cancel actually
@@ -1493,11 +1553,23 @@ __pthread_attr_destroy (pthread_attr_t *attr)
void
__pthread_exit (void *value_ptr)
{
- class pthread *thread = __pthread_self ();
+ pthread * thread = pthread::self ();
+
+ // run cleanup handlers
+ thread->pop_all_cleanup_handlers();
MT_INTERFACE->destructors.IterateNull ();
+
+ thread->mutex.Lock();
+ // cleanup if thread is in detached state and not joined
+ if( __pthread_equal(&thread->joiner, &thread ) )
+ delete thread;
+ else
+ {
+ thread->return_ptr = value_ptr;
+ thread->mutex.UnLock();
+ }
- thread->return_ptr = value_ptr;
if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0)
exit (0);
else
@@ -1507,22 +1579,38 @@ __pthread_exit (void *value_ptr)
int
__pthread_join (pthread_t *thread, void **return_val)
{
+ pthread_t joiner = pthread::self ();
+
/*FIXME: wait on the thread cancellation event as well - we are a cancellation point*/
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
return ESRCH;
- if ((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED)
+ if ( joiner == *thread)
+ {
+ if (return_val)
+ *return_val = NULL;
+ return EDEADLK;
+ }
+
+ (*thread)->mutex.Lock ();
+
+ if((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED)
{
if (return_val)
- *return_val = NULL;
+ *return_val = NULL;
+ (*thread)->mutex.UnLock ();
return EINVAL;
}
else
{
+ (*thread)->joiner = joiner;
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
+ (*thread)->mutex.UnLock ();
WaitForSingleObject ((*thread)->win32_obj_id, INFINITE);
if (return_val)
- *return_val = (*thread)->return_ptr;
+ *return_val = (*thread)->return_ptr;
+ // cleanup
+ delete (*thread);
} /*End if */
pthread_testcancel ();
@@ -1536,13 +1624,25 @@ __pthread_detach (pthread_t *thread)
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
return ESRCH;
+ (*thread)->mutex.Lock ();
if ((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED)
{
- (*thread)->return_ptr = NULL;
+ (*thread)->mutex.UnLock ();
return EINVAL;
}
- (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
+ // check if thread is still alive
+ if (WAIT_TIMEOUT == WaitForSingleObject ((*thread)->win32_obj_id, 0) )
+ {
+ // force cleanup on exit
+ (*thread)->joiner = *thread;
+ (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
+ (*thread)->mutex.UnLock ();
+ }
+ else
+ // thread has already terminated.
+ delete (*thread);
+
return 0;
}
@@ -1791,20 +1891,22 @@ __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex,
InterlockedIncrement (&((*themutex)->condwaits));
if (pthread_mutex_unlock (&(*cond)->cond_access))
system_printf ("Failed to unlock condition variable access mutex, this %p", *cond);
+ /* At this point calls to Signal will progress evebn if we aren' yet waiting
+ * However, the loop there should allow us to get scheduled and call wait,
+ * and have them call PulseEvent again if we dont' respond.
+ */
rv = (*cond)->TimedWait (waitlength);
/* this may allow a race on the mutex acquisition and waits..
* But doing this within the cond access mutex creates a different race
*/
- bool last = false;
- if (InterlockedDecrement (&((*cond)->waiting)) == 0)
- last = true;
+ InterlockedDecrement (&((*cond)->waiting));
/* Tell Signal that we have been released */
InterlockedDecrement (&((*cond)->ExitingWait));
(*themutex)->Lock ();
- if (last == true)
- (*cond)->mutex = NULL;
if (pthread_mutex_lock (&(*cond)->cond_access))
system_printf ("Failed to lock condition variable access mutex, this %p", *cond);
+ if ((*cond)->waiting == 0)
+ (*cond)->mutex = NULL;
InterlockedDecrement (&((*themutex)->condwaits));
if (pthread_mutex_unlock (&(*cond)->cond_access))
system_printf ("Failed to unlock condition variable access mutex, this %p", *cond);
@@ -1901,7 +2003,7 @@ __pthread_kill (pthread_t thread, int sig)
int
__pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
{
- pthread *thread = __pthread_self ();
+ pthread *thread = pthread::self ();
// lock this myself, for the use of thread2signal
// two differt kills might clash: FIXME
@@ -1917,11 +2019,6 @@ __pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
}
/* ID */
-pthread_t
-__pthread_self ()
-{
- return (pthread *) TlsGetValue (MT_INTERFACE->thread_self_dwTlsIndex);
-}
int
__pthread_equal (pthread_t *t1, pthread_t *t2)
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index 5004c950e..0d31e02fd 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -229,6 +229,34 @@ public:
~pthread_attr ();
};
+class pthread_mutexattr:public verifyable_object
+{
+public:
+ int pshared;
+ int mutextype;
+ pthread_mutexattr ();
+ ~pthread_mutexattr ();
+};
+
+class pthread_mutex:public verifyable_object
+{
+public:
+ CRITICAL_SECTION criticalsection;
+ HANDLE win32_obj_id;
+ LONG condwaits;
+ int pshared;
+ class pthread_mutex * next;
+
+ int Lock ();
+ int TryLock ();
+ int UnLock ();
+ void fixup_after_fork ();
+
+ pthread_mutex (pthread_mutexattr * = NULL);
+ pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
+ ~pthread_mutex ();
+};
+
class pthread:public verifyable_object
{
public:
@@ -239,6 +267,7 @@ public:
void *return_ptr;
bool suspended;
int cancelstate, canceltype;
+ pthread_t joiner;
// int joinable;
DWORD GetThreadId ()
@@ -259,37 +288,22 @@ public:
pthread ();
~pthread ();
-private:
- DWORD thread_id;
-};
+ void push_cleanup_handler (__pthread_cleanup_handler *handler);
+ void pop_cleanup_handler (int const execute);
-class pthread_mutexattr:public verifyable_object
-{
-public:
- int pshared;
- int mutextype;
- pthread_mutexattr ();
- ~pthread_mutexattr ();
-};
+ static pthread* self ();
+ static void *thread_init_wrapper (void *);
-class pthread_mutex:public verifyable_object
-{
-public:
- CRITICAL_SECTION criticalsection;
- HANDLE win32_obj_id;
- LONG condwaits;
- int pshared;
- class pthread_mutex * next;
+private:
+ DWORD thread_id;
+ __pthread_cleanup_handler *cleanup_handlers;
+ pthread_mutex mutex;
- int Lock ();
- int TryLock ();
- int UnLock ();
- void fixup_after_fork ();
+ friend void __pthread_exit (void *value_ptr);
+ friend int __pthread_join (pthread_t * thread, void **return_val);
+ friend int __pthread_detach (pthread_t * thread);
- pthread_mutex (unsigned short);
- pthread_mutex (pthread_mutexattr *);
- pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
- ~pthread_mutex ();
+ void pop_all_cleanup_handlers (void);
};
class pthread_condattr:public verifyable_object
@@ -381,22 +395,25 @@ public:
void Init (int);
void fixup_after_fork (void);
- MTinterface ():reent_index (0), indexallocated (0), threadcount (1)
- {
- pthread_prepare = NULL;
- pthread_child = NULL;
- pthread_parent = NULL;
- }
+ MTinterface ():reent_index (0), indexallocated (0), threadcount (1)
+ {
+ pthread_prepare = NULL;
+ pthread_child = NULL;
+ pthread_parent = NULL;
+ }
};
void __pthread_atforkprepare(void);
void __pthread_atforkparent(void);
void __pthread_atforkchild(void);
+/* Thread Exit */
+void __pthread_exit (void *value_ptr);
+int __pthread_join (pthread_t * thread, void **return_val);
+int __pthread_detach (pthread_t * thread);
+
extern "C"
{
-void *thread_init_wrapper (void *);
-
/* ThreadCreation */
int __pthread_create (pthread_t * thread, const pthread_attr_t * attr,
void *(*start_routine) (void *), void *arg);
@@ -423,15 +440,7 @@ int __pthread_attr_setschedpolicy (pthread_attr_t *, int);
int __pthread_attr_setscope (pthread_attr_t *, int);
int __pthread_attr_setstackaddr (pthread_attr_t *, void *);
-
-
-/* Thread Exit */
-void __pthread_exit (void *value_ptr);
-int __pthread_join (pthread_t * thread, void **return_val);
-int __pthread_detach (pthread_t * thread);
-
/* Thread suspend */
-
int __pthread_suspend (pthread_t * thread);
int __pthread_continue (pthread_t * thread);
@@ -461,10 +470,8 @@ int __pthread_sigmask (int operation, const sigset_t * set,
sigset_t * old_set);
/* ID */
-pthread_t __pthread_self ();
int __pthread_equal (pthread_t * t1, pthread_t * t2);
-
/* Mutexes */
int __pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
int __pthread_mutex_lock (pthread_mutex_t *);
@@ -503,7 +510,6 @@ int __pthread_setcancelstate (int state, int *oldstate);
int __pthread_setcanceltype (int type, int *oldtype);
void __pthread_testcancel (void);
-
/* Semaphores */
int __sem_init (sem_t * sem, int pshared, unsigned int value);
int __sem_destroy (sem_t * sem);
diff --git a/winsup/cygwin/threaded_queue.cc b/winsup/cygwin/threaded_queue.cc
index 5fb22b191..321fa1612 100755
--- a/winsup/cygwin/threaded_queue.cc
+++ b/winsup/cygwin/threaded_queue.cc
@@ -1,6 +1,6 @@
/* threaded_queue.cc
- Copyright 2001 Red Hat Inc.
+ Copyright 2001, 2002 Red Hat Inc.
Written by Robert Collins <rbtcollins@hotmail.com>
@@ -15,6 +15,7 @@
#include <unistd.h>
#include <windows.h>
#include <sys/types.h>
+#include <stdlib.h>
#include "wincap.h"
#include "threaded_queue.h"
#define DEBUG 1
diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc
index b7308bf02..7a9a3eb33 100644
--- a/winsup/cygwin/times.cc
+++ b/winsup/cygwin/times.cc
@@ -17,12 +17,9 @@ details. */
#include <stdlib.h>
#include <errno.h>
#include "cygerrno.h"
-#include "perprocess.h"
#include "security.h"
#include "fhandler.h"
#include "path.h"
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "hires.h"
@@ -49,7 +46,7 @@ __to_clock_t (FILETIME * src, int flag)
/* times: POSIX 4.5.2.1 */
extern "C" clock_t
-times (struct tms * buf)
+_times (struct tms * buf)
{
FILETIME creation_time, exit_time, kernel_time, user_time;
@@ -89,12 +86,6 @@ times (struct tms * buf)
return tc;
}
-extern "C" clock_t
-_times (struct tms * buf)
-{
- return times (buf);
-}
-
/* settimeofday: BSD */
extern "C" int
settimeofday (const struct timeval *tv, const struct timezone *tz)
@@ -152,15 +143,28 @@ totimeval (struct timeval *dst, FILETIME *src, int sub, int flag)
/* FIXME: Make thread safe */
extern "C" int
-gettimeofday(struct timeval *tv, struct timezone *tz)
+gettimeofday (struct timeval *tv, struct timezone *tz)
{
- static hires gtod;
+ static hires_ms gtod;
+ static bool tzflag;
LONGLONG now = gtod.usecs (false);
if (now == (LONGLONG) -1)
return -1;
tv->tv_sec = now / 1000000;
tv->tv_usec = now % 1000000;
+
+ if (tz != NULL)
+ {
+ if (!tzflag)
+ {
+ tzset();
+ tzflag = true;
+ }
+ tz->tz_minuteswest = _timezone / 60;
+ tz->tz_dsttime = _daylight;
+ }
+
return 0;
}
@@ -223,6 +227,47 @@ to_time_t (FILETIME *ptr)
return x;
}
+/* Cygwin internal */
+/* Convert a Win32 time to "UNIX" timestruc_t format. */
+void __stdcall
+to_timestruc_t (FILETIME *ptr, timestruc_t *out)
+{
+ /* A file time is the number of 100ns since jan 1 1601
+ stuffed into two long words.
+ A timestruc_t is the number of seconds and microseconds since jan 1 1970
+ stuffed into a time_t and a long. */
+
+ long rem;
+ long long x = ((long long) ptr->dwHighDateTime << 32) + ((unsigned)ptr->dwLowDateTime);
+
+ /* pass "no time" as epoch */
+ if (x == 0)
+ {
+ out->tv_sec = 0;
+ out->tv_nsec = 0;
+ return;
+ }
+
+ x -= FACTOR; /* number of 100ns between 1601 and 1970 */
+ rem = x % ((long long)NSPERSEC);
+ x /= (long long) NSPERSEC; /* number of 100ns in a second */
+ out->tv_nsec = rem * 100; /* as tv_nsec is in nanoseconds */
+ out->tv_sec = x;
+}
+
+/* Cygwin internal */
+/* Get the current time as a "UNIX" timestruc_t format. */
+void __stdcall
+time_as_timestruc_t (timestruc_t * out)
+{
+ SYSTEMTIME systemtime;
+ FILETIME filetime;
+
+ GetSystemTime (&systemtime);
+ SystemTimeToFileTime (&systemtime, &filetime);
+ to_timestruc_t (&filetime, out);
+}
+
/* time: POSIX 4.5.1.1, C 4.12.2.4 */
/* Return number of seconds since 00:00 UTC on jan 1, 1970 */
extern "C"
@@ -427,12 +472,11 @@ utimes (const char *path, struct timeval *tvp)
}
/* MSDN suggests using FILE_FLAG_BACKUP_SEMANTICS for accessing
- the times of directories. FIXME: what about Win95??? */
+ the times of directories. */
/* Note: It's not documented in MSDN that FILE_WRITE_ATTRIBUTES is
sufficient to change the timestamps... */
HANDLE h = CreateFileA (win32.get_win32 (),
- wincap.has_specific_access_rights () ?
- FILE_WRITE_ATTRIBUTES : GENERIC_WRITE,
+ FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE,
&sec_none_nih,
OPEN_EXISTING,
@@ -536,7 +580,7 @@ cygwin_tzset ()
}
void
-hires::prime ()
+hires_us::prime ()
{
LARGE_INTEGER ifreq;
if (!QueryPerformanceFrequency (&ifreq))
@@ -568,7 +612,7 @@ hires::prime ()
}
LONGLONG
-hires::usecs (bool justdelta)
+hires_us::usecs (bool justdelta)
{
if (!inited)
prime ();
@@ -589,3 +633,46 @@ hires::usecs (bool justdelta)
now.QuadPart = (LONGLONG) (freq * (double) (now.QuadPart - primed_pc.QuadPart));
return justdelta ? now.QuadPart : primed_ft.QuadPart + now.QuadPart;
}
+
+void
+hires_ms::prime ()
+{
+ TIMECAPS tc;
+ FILETIME f;
+ int priority = GetThreadPriority (GetCurrentThread ());
+ SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL);
+
+ if (timeGetDevCaps (&tc, sizeof (tc)) != TIMERR_NOERROR)
+ minperiod = 0;
+ else
+ {
+ minperiod = min (max (tc.wPeriodMin, 1), tc.wPeriodMax);
+ timeBeginPeriod (minperiod);
+ }
+
+ initime_ms = timeGetTime ();
+ GetSystemTimeAsFileTime (&f);
+ SetThreadPriority (GetCurrentThread (), priority);
+
+ inited = 1;
+ initime_us.HighPart = f.dwHighDateTime;
+ initime_us.LowPart = f.dwLowDateTime;
+ initime_us.QuadPart -= FACTOR;
+ initime_us.QuadPart /= 10;
+}
+
+LONGLONG
+hires_ms::usecs (bool justdelta)
+{
+ if (!inited)
+ prime ();
+ DWORD now = timeGetTime ();
+ // FIXME: Not sure how this will handle the 49.71 day wrap around
+ LONGLONG res = initime_us.QuadPart + ((LONGLONG) (now - initime_ms) * 1000);
+ return res;
+}
+
+hires_ms::~hires_ms ()
+{
+ timeEndPeriod (minperiod);
+}
diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc
index 52ef8e43a..418b816f3 100644
--- a/winsup/cygwin/tty.cc
+++ b/winsup/cygwin/tty.cc
@@ -1,6 +1,6 @@
/* tty.cc
- Copyright 1997, 1998, 2000, 2001 Red Hat, Inc.
+ Copyright 1997, 1998, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -21,8 +21,6 @@ details. */
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "cygwin/cygserver_transport.h"
#include "cygwin/cygserver.h"
diff --git a/winsup/cygwin/tty.h b/winsup/cygwin/tty.h
index 34050d769..30d8bb03b 100644
--- a/winsup/cygwin/tty.h
+++ b/winsup/cygwin/tty.h
@@ -1,6 +1,6 @@
/* tty.h: shared tty info for cygwin
- Copyright 2000, 2001 Red Hat, Inc.
+ Copyright 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index 3e3513a16..1f28e92e4 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -19,8 +19,6 @@ details. */
#include <lm.h>
#include <errno.h>
#include <sys/cygwin.h>
-#include "sync.h"
-#include "sigproc.h"
#include "pinfo.h"
#include "security.h"
#include "fhandler.h"
@@ -39,7 +37,7 @@ internal_getlogin (cygheap_user &user)
struct passwd *pw = NULL;
if (!GetUserName (username, &username_len))
- user.set_name ("unknown");
+ user.set_name (NULL);
else
user.set_name (username);
debug_printf ("GetUserName() = %s", user.name ());
@@ -52,7 +50,7 @@ internal_getlogin (cygheap_user &user)
user.set_logsrv (NULL);
/* First trying to get logon info from environment */
- if ((env = getenv ("USERNAME")) != NULL)
+ if (!*user.name () && (env = getenv ("USERNAME")) != NULL)
user.set_name (env);
if ((env = getenv ("USERDOMAIN")) != NULL)
user.set_domain (env);
@@ -73,59 +71,12 @@ internal_getlogin (cygheap_user &user)
user.set_domain (buf);
NetApiBufferFree (wui);
}
- if (!user.logsrv () && get_logon_server_and_user_domain (buf, NULL))
- {
- user.set_logsrv (buf + 2);
- setenv ("LOGONSERVER", buf, 1);
- }
+ if (!user.logsrv () && user.domain () &&
+ get_logon_server (user.domain (), buf, NULL))
+ user.set_logsrv (buf + 2);
debug_printf ("Domain: %s, Logon Server: %s, Windows Username: %s",
user.domain (), user.logsrv (), user.name ());
- /* NetUserGetInfo() can be slow in NT domain environment, thus we
- * only obtain HOMEDRIVE and HOMEPATH if they are not already set
- * in the environment. */
- if (!getenv ("HOMEPATH") || !getenv ("HOMEDRIVE"))
- {
- LPUSER_INFO_3 ui = NULL;
- WCHAR wuser[UNLEN + 1];
-
- sys_mbstowcs (wuser, user.name (), sizeof (wuser) / sizeof (*wuser));
- if ((ret = NetUserGetInfo (NULL, wuser, 3, (LPBYTE *)&ui)))
- {
- if (user.logsrv ())
- {
- WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
- strcat (strcpy (buf, "\\\\"), user.logsrv ());
-
- sys_mbstowcs (wlogsrv, buf,
- sizeof (wlogsrv) / sizeof(*wlogsrv));
- ret = NetUserGetInfo (wlogsrv, wuser, 3,(LPBYTE *)&ui);
- }
- }
- if (!ret)
- {
- sys_wcstombs (buf, ui->usri3_home_dir, MAX_PATH);
- if (!buf[0])
- {
- sys_wcstombs (buf, ui->usri3_home_dir_drive, MAX_PATH);
- if (buf[0])
- strcat (buf, "\\");
- else
- {
- env = getenv ("SYSTEMDRIVE");
- if (env && *env)
- strcat (strcpy (buf, env), "\\");
- else
- GetSystemDirectoryA (buf, MAX_PATH);
- }
- }
- setenv ("HOMEPATH", buf + 2, 1);
- buf[2] = '\0';
- setenv ("HOMEDRIVE", buf, 1);
- }
- if (ui)
- NetApiBufferFree (ui);
- }
HANDLE ptok = user.token; /* Which is INVALID_HANDLE_VALUE if no
impersonation took place. */
@@ -151,17 +102,19 @@ internal_getlogin (cygheap_user &user)
and a domain user may have the same name. */
if (!ret && user.domain ())
{
+ char domain[DNLEN + 1];
+ DWORD dlen = sizeof (domain);
+ siz = sizeof (tu);
+ SID_NAME_USE use = SidTypeInvalid;
/* Concat DOMAIN\USERNAME for the next lookup */
strcat (strcat (strcpy (buf, user.domain ()), "\\"), user.name ());
- if (!(ret = lookup_name (buf, NULL, user.sid ())))
- debug_printf ("Couldn't retrieve SID locally!");
- }
+ if (!LookupAccountName (NULL, buf, tu, &siz,
+ domain, &dlen, &use) ||
+ !legal_sid_type (use))
+ debug_printf ("Couldn't retrieve SID locally!");
+ else user.set_sid (tu);
- /* If that fails, too, as a last resort try to get the SID from
- the logon server. */
- if (!ret && !(ret = lookup_name (user.name (), user.logsrv (),
- user.sid ())))
- debug_printf ("Couldn't retrieve SID from '%s'!", user.logsrv ());
+ }
/* If we have a SID, try to get the corresponding Cygwin user name
which can be different from the Windows user name. */
@@ -174,27 +127,19 @@ internal_getlogin (cygheap_user &user)
if (psid.getfrompw (pw) && EqualSid (user.sid (), psid))
{
user.set_name (pw->pw_name);
- struct __group16 *gr = getgrgid (pw->pw_gid);
+ struct __group32 *gr = getgrgid32 (pw->pw_gid);
if (gr)
if (!gsid.getfromgr (gr))
gsid = NO_SID;
break;
}
- if (!strcasematch (user.name (), "SYSTEM")
- && user.domain () && user.logsrv ())
- {
- if (get_registry_hive_path (user.sid (), buf))
- setenv ("USERPROFILE", buf, 1);
- else
- unsetenv ("USERPROFILE");
- }
}
/* If this process is started from a non Cygwin process,
set token owner to the same value as token user and
primary group to the group which is set as primary group
in /etc/passwd. */
- if (ptok != INVALID_HANDLE_VALUE && myself->ppid == 1)
+ if (ptok != INVALID_HANDLE_VALUE && !myself->ppid_handle)
{
if (!SetTokenInformation (ptok, TokenOwner, &tu, sizeof tu))
debug_printf ("SetTokenInformation(TokenOwner): %E");
@@ -212,26 +157,11 @@ internal_getlogin (cygheap_user &user)
debug_printf ("Cygwins Username: %s", user.name ());
if (!pw)
- pw = getpwnam(user.name ());
- if (!getenv ("HOME"))
- {
- const char *homedrive, *homepath;
- if (pw && pw->pw_dir && *pw->pw_dir)
- {
- setenv ("HOME", pw->pw_dir, 1);
- debug_printf ("Set HOME (from /etc/passwd) to %s", pw->pw_dir);
- }
- else if ((homedrive = getenv ("HOMEDRIVE"))
- && (homepath = getenv ("HOMEPATH")))
- {
- char home[MAX_PATH];
- strcpy (buf, homedrive);
- strcat (buf, homepath);
- cygwin_conv_to_full_posix_path (buf, home);
- setenv ("HOME", home, 1);
- debug_printf ("Set HOME (from HOMEDRIVE/HOMEPATH) to %s", home);
- }
- }
+ pw = getpwnam (user.name ());
+
+ if (!myself->ppid_handle)
+ (void) cygheap->user.ontherange (CH_HOME, pw);
+
return pw;
}
@@ -283,24 +213,48 @@ getlogin (void)
return strcpy (this_username, cygheap->user.name ());
}
+extern "C" __uid32_t
+getuid32 (void)
+{
+ return cygheap->user.real_uid;
+}
+
extern "C" __uid16_t
getuid (void)
{
return cygheap->user.real_uid;
}
+extern "C" __gid32_t
+getgid32 (void)
+{
+ return cygheap->user.real_gid;
+}
+
extern "C" __gid16_t
getgid (void)
{
return cygheap->user.real_gid;
}
+extern "C" __uid32_t
+geteuid32 (void)
+{
+ return myself->uid;
+}
+
extern "C" __uid16_t
geteuid (void)
{
return myself->uid;
}
+extern "C" __gid32_t
+getegid32 (void)
+{
+ return myself->gid;
+}
+
extern "C" __gid16_t
getegid (void)
{
@@ -311,13 +265,151 @@ getegid (void)
extern "C" char *
cuserid (char *src)
{
- if (src)
+ if (!src)
+ return getlogin ();
+
+ strcpy (src, getlogin ());
+ return src;
+}
+
+const char *
+cygheap_user::ontherange (homebodies what, struct passwd *pw)
+{
+ static char buf[MAX_PATH + 1];
+ static char homedrive_buf[3];
+ LPUSER_INFO_3 ui = NULL;
+ WCHAR wuser[UNLEN + 1];
+ NET_API_STATUS ret;
+
+ if (what == CH_HOME)
{
- strcpy (src, getlogin ());
- return src;
+ char *p;
+ if ((p = getenv ("HOMEDRIVE")))
+ {
+ memcpy (homedrive_buf, p, 2);
+ homedrive = homedrive_buf;
+ }
+ if ((p = getenv ("HOMEPATH")))
+ {
+ strcpy (buf, p);
+ homepath = buf;
+ }
+ if ((p = getenv ("HOME")))
+ debug_printf ("HOME is already in the environment %s", p);
+ else
+ {
+ if (!pw)
+ pw = getpwnam (name ());
+ if (pw && pw->pw_dir && *pw->pw_dir)
+ {
+ setenv ("HOME", pw->pw_dir, 1);
+ debug_printf ("Set HOME (from /etc/passwd) to %s", pw->pw_dir);
+ }
+ else if (homedrive && homepath)
+ {
+ char home[MAX_PATH];
+ strcpy (buf, homedrive);
+ strcat (buf, homepath);
+ cygwin_conv_to_full_posix_path (buf, home);
+ setenv ("HOME", home, 1);
+ debug_printf ("Set HOME (from HOMEDRIVE/HOMEPATH) to %s", home);
+ }
+ }
}
- else
+
+ if (homedrive == NULL)
+ {
+ if (!pw)
+ pw = getpwnam (name ());
+ if (pw && pw->pw_dir && *pw->pw_dir)
+ cygwin_conv_to_full_win32_path (pw->pw_dir, buf);
+ else
+ {
+ sys_mbstowcs (wuser, name (), sizeof (wuser) / sizeof (*wuser));
+ if ((ret = NetUserGetInfo (NULL, wuser, 3, (LPBYTE *)&ui)))
+ {
+ if (logsrv ())
+ {
+ WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
+ strcat (strcpy (buf, "\\\\"), logsrv ());
+ sys_mbstowcs (wlogsrv, buf, sizeof (wlogsrv) / sizeof(*wlogsrv));
+ ret = NetUserGetInfo (wlogsrv, wuser, 3,(LPBYTE *)&ui);
+ }
+ }
+ if (!ret)
+ {
+ char *p;
+ sys_wcstombs (buf, ui->usri3_home_dir, MAX_PATH);
+ if (!buf[0])
+ {
+ sys_wcstombs (buf, ui->usri3_home_dir_drive, MAX_PATH);
+ if (buf[0])
+ strcat (buf, "\\");
+ else if (!GetSystemDirectory (buf, MAX_PATH))
+ strcpy (buf, "c:\\");
+ else if ((p = strchr (buf, '\\')))
+ p[1] = '\0';
+ }
+ }
+ if (ui)
+ NetApiBufferFree (ui);
+ }
+
+ if (buf[1] != ':')
+ {
+ homedrive_buf[0] = homedrive_buf[1] = '\0';
+ homepath = buf;
+ }
+ else
+ {
+ homedrive_buf[0] = buf[0];
+ homedrive_buf[1] = buf[1];
+ homepath = buf + 2;
+ }
+ homedrive = homedrive_buf;
+ }
+
+ switch (what)
{
- return getlogin ();
+ case CH_HOMEDRIVE:
+ return homedrive;
+ case CH_HOMEPATH:
+ return homepath;
+ default:
+ return homepath;
}
}
+
+const char *
+cygheap_user::env_logsrv ()
+{
+ char *p = plogsrv - 2;
+
+ *p = p[1] = '\\';
+ return p;
+}
+
+const char *
+cygheap_user::env_userprofile ()
+{
+ static char buf[512]; /* FIXME: This shouldn't be static. */
+ if (strcasematch (name (), "SYSTEM") || !domain () || !logsrv ())
+ return NULL;
+
+ if (get_registry_hive_path (sid (), buf))
+ return buf;
+ else
+ return NULL;
+}
+
+const char *
+cygheap_user::env_homepath ()
+{
+ return ontherange (CH_HOMEPATH);
+}
+
+const char *
+cygheap_user::env_homedrive ()
+{
+ return ontherange (CH_HOMEDRIVE);
+}
diff --git a/winsup/cygwin/uname.cc b/winsup/cygwin/uname.cc
index aff158340..de7b9000c 100644
--- a/winsup/cygwin/uname.cc
+++ b/winsup/cygwin/uname.cc
@@ -1,6 +1,6 @@
/* uname.cc
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
Rewritten by Geoffrey Noer of Cygnus Solutions, noer@cygnus.com
@@ -69,7 +69,7 @@ uname (struct utsname *name)
else
{
if (sysinfo.dwProcessorType == PROCESSOR_INTEL_386 ||
- sysinfo.dwProcessorType == PROCESSOR_INTEL_486)
+ sysinfo.dwProcessorType == PROCESSOR_INTEL_486)
ptype = sysinfo.dwProcessorType / 100;
else
ptype = PROCESSOR_INTEL_PENTIUM / 100;
diff --git a/winsup/cygwin/wait.cc b/winsup/cygwin/wait.cc
index 0fa3005cf..d9588e87a 100644
--- a/winsup/cygwin/wait.cc
+++ b/winsup/cygwin/wait.cc
@@ -1,6 +1,6 @@
/* wait.cc: Posix wait routines.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -13,7 +13,6 @@ details. */
#include <stdlib.h>
#include <errno.h>
#include "cygerrno.h"
-#include "sync.h"
#include "sigproc.h"
#include "perthread.h"
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index 09e95fba0..29e33b626 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -1,7 +1,7 @@
/* wincap.cc -- figure out on which OS we're running. Set the
capability class to the appropriate values.
- Copyright 2001 Red Hat, Inc.
+ Copyright 2001, 2002 Red Hat, Inc.
This file is part of Cygwin.
@@ -22,7 +22,6 @@ static NO_COPY wincaps wincap_unknown = {
has_security:false,
has_security_descriptor_control:false,
has_get_process_times:false,
- has_specific_access_rights:false,
has_lseek_bug:false,
has_lock_file_ex:false,
has_signal_object_and_wait:false,
@@ -46,6 +45,7 @@ static NO_COPY wincaps wincap_unknown = {
has_raw_devices:false,
has_valid_processorlevel:false,
has_64bit_file_access:false,
+ has_process_io_counters:false,
};
static NO_COPY wincaps wincap_95 = {
@@ -59,7 +59,6 @@ static NO_COPY wincaps wincap_95 = {
has_security:false,
has_security_descriptor_control:false,
has_get_process_times:false,
- has_specific_access_rights:false,
has_lseek_bug:true,
has_lock_file_ex:false,
has_signal_object_and_wait:false,
@@ -83,6 +82,7 @@ static NO_COPY wincaps wincap_95 = {
has_raw_devices:false,
has_valid_processorlevel:false,
has_64bit_file_access:false,
+ has_process_io_counters:false,
};
static NO_COPY wincaps wincap_95osr2 = {
@@ -96,7 +96,6 @@ static NO_COPY wincaps wincap_95osr2 = {
has_security:false,
has_security_descriptor_control:false,
has_get_process_times:false,
- has_specific_access_rights:false,
has_lseek_bug:true,
has_lock_file_ex:false,
has_signal_object_and_wait:false,
@@ -120,6 +119,7 @@ static NO_COPY wincaps wincap_95osr2 = {
has_raw_devices:false,
has_valid_processorlevel:false,
has_64bit_file_access:false,
+ has_process_io_counters:false,
};
static NO_COPY wincaps wincap_98 = {
@@ -133,7 +133,6 @@ static NO_COPY wincaps wincap_98 = {
has_security:false,
has_security_descriptor_control:false,
has_get_process_times:false,
- has_specific_access_rights:false,
has_lseek_bug:true,
has_lock_file_ex:false,
has_signal_object_and_wait:false,
@@ -157,6 +156,7 @@ static NO_COPY wincaps wincap_98 = {
has_raw_devices:false,
has_valid_processorlevel:true,
has_64bit_file_access:false,
+ has_process_io_counters:false,
};
static NO_COPY wincaps wincap_98se = {
@@ -170,7 +170,6 @@ static NO_COPY wincaps wincap_98se = {
has_security:false,
has_security_descriptor_control:false,
has_get_process_times:false,
- has_specific_access_rights:false,
has_lseek_bug:true,
has_lock_file_ex:false,
has_signal_object_and_wait:false,
@@ -194,6 +193,7 @@ static NO_COPY wincaps wincap_98se = {
has_raw_devices:false,
has_valid_processorlevel:true,
has_64bit_file_access:false,
+ has_process_io_counters:false,
};
static NO_COPY wincaps wincap_me = {
@@ -207,7 +207,6 @@ static NO_COPY wincaps wincap_me = {
has_security:false,
has_security_descriptor_control:false,
has_get_process_times:false,
- has_specific_access_rights:false,
has_lseek_bug:true,
has_lock_file_ex:false,
has_signal_object_and_wait:false,
@@ -231,6 +230,7 @@ static NO_COPY wincaps wincap_me = {
has_raw_devices:false,
has_valid_processorlevel:true,
has_64bit_file_access:false,
+ has_process_io_counters:false,
};
static NO_COPY wincaps wincap_nt3 = {
@@ -244,7 +244,6 @@ static NO_COPY wincaps wincap_nt3 = {
has_security:true,
has_security_descriptor_control:false,
has_get_process_times:true,
- has_specific_access_rights:true,
has_lseek_bug:false,
has_lock_file_ex:true,
has_signal_object_and_wait:false,
@@ -268,6 +267,7 @@ static NO_COPY wincaps wincap_nt3 = {
has_raw_devices:true,
has_valid_processorlevel:true,
has_64bit_file_access:true,
+ has_process_io_counters:false,
};
static NO_COPY wincaps wincap_nt4 = {
@@ -281,7 +281,6 @@ static NO_COPY wincaps wincap_nt4 = {
has_security:true,
has_security_descriptor_control:false,
has_get_process_times:true,
- has_specific_access_rights:true,
has_lseek_bug:false,
has_lock_file_ex:true,
has_signal_object_and_wait:true,
@@ -305,6 +304,7 @@ static NO_COPY wincaps wincap_nt4 = {
has_raw_devices:true,
has_valid_processorlevel:true,
has_64bit_file_access:true,
+ has_process_io_counters:false,
};
static NO_COPY wincaps wincap_nt4sp4 = {
@@ -318,7 +318,6 @@ static NO_COPY wincaps wincap_nt4sp4 = {
has_security:true,
has_security_descriptor_control:false,
has_get_process_times:true,
- has_specific_access_rights:true,
has_lseek_bug:false,
has_lock_file_ex:true,
has_signal_object_and_wait:true,
@@ -342,6 +341,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
has_raw_devices:true,
has_valid_processorlevel:true,
has_64bit_file_access:true,
+ has_process_io_counters:false,
};
static NO_COPY wincaps wincap_2000 = {
@@ -355,7 +355,6 @@ static NO_COPY wincaps wincap_2000 = {
has_security:true,
has_security_descriptor_control:true,
has_get_process_times:true,
- has_specific_access_rights:true,
has_lseek_bug:false,
has_lock_file_ex:true,
has_signal_object_and_wait:true,
@@ -379,6 +378,7 @@ static NO_COPY wincaps wincap_2000 = {
has_raw_devices:true,
has_valid_processorlevel:true,
has_64bit_file_access:true,
+ has_process_io_counters:true,
};
static NO_COPY wincaps wincap_xp = {
@@ -392,7 +392,6 @@ static NO_COPY wincaps wincap_xp = {
has_security:true,
has_security_descriptor_control:true,
has_get_process_times:true,
- has_specific_access_rights:true,
has_lseek_bug:false,
has_lock_file_ex:true,
has_signal_object_and_wait:true,
@@ -416,9 +415,10 @@ static NO_COPY wincaps wincap_xp = {
has_raw_devices:true,
has_valid_processorlevel:true,
has_64bit_file_access:true,
+ has_process_io_counters:true,
};
-wincapc NO_COPY wincap;
+wincapc wincap;
void
wincapc::init ()
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index 088907ad2..fbf36a5b9 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -23,7 +23,6 @@ struct wincaps
unsigned has_security : 1;
unsigned has_security_descriptor_control : 1;
unsigned has_get_process_times : 1;
- unsigned has_specific_access_rights : 1;
unsigned has_lseek_bug : 1;
unsigned has_lock_file_ex : 1;
unsigned has_signal_object_and_wait : 1;
@@ -47,6 +46,7 @@ struct wincaps
unsigned has_raw_devices : 1;
unsigned has_valid_processorlevel : 1;
unsigned has_64bit_file_access : 1;
+ unsigned has_process_io_counters : 1;
};
class wincapc
@@ -56,7 +56,6 @@ class wincapc
void *caps;
public:
- wincapc (): caps (NULL) {}
void init ();
void set_chunksize (DWORD nchunksize);
@@ -75,7 +74,6 @@ public:
bool IMPLEMENT (has_security)
bool IMPLEMENT (has_security_descriptor_control)
bool IMPLEMENT (has_get_process_times)
- bool IMPLEMENT (has_specific_access_rights)
bool IMPLEMENT (has_lseek_bug)
bool IMPLEMENT (has_lock_file_ex)
bool IMPLEMENT (has_signal_object_and_wait)
@@ -99,6 +97,7 @@ public:
bool IMPLEMENT (has_raw_devices)
bool IMPLEMENT (has_valid_processorlevel)
bool IMPLEMENT (has_64bit_file_access)
+ bool IMPLEMENT (has_process_io_counters)
#undef IMPLEMENT
};
diff --git a/winsup/cygwin/window.cc b/winsup/cygwin/window.cc
index 2a1dafb62..38b19c418 100644
--- a/winsup/cygwin/window.cc
+++ b/winsup/cygwin/window.cc
@@ -1,6 +1,6 @@
/* window.cc: hidden windows for signals/itimer support
- Copyright 1997, 1998, 2000, 2001 Red Hat, Inc.
+ Copyright 1997, 1998, 2000, 2001, 2002 Red Hat, Inc.
Written by Sergey Okhapkin <sos@prospect.com.ru>
@@ -64,7 +64,7 @@ WndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return 0;
case WM_ASYNCIO:
if (WSAGETSELECTEVENT(lParam) == FD_OOB)
- raise (SIGURG);
+ raise (SIGURG);
else
raise (SIGIO);
return 0;
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index ea9251aaf..2758569a5 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -147,10 +147,19 @@ extern "C" void __stdcall do_exit (int) __attribute__ ((noreturn));
/* UID/GID */
void uinfo_init (void);
-#define ILLEGAL_UID ((__uid16_t)-1)
-#define ILLEGAL_GID ((__gid16_t)-1)
+#define ILLEGAL_UID16 ((__uid16_t)-1)
+#define ILLEGAL_UID ((__uid32_t)-1)
+#define ILLEGAL_GID16 ((__gid16_t)-1)
+#define ILLEGAL_GID ((__gid32_t)-1)
#define ILLEGAL_SEEK ((__off64_t)-1)
+#define uid16touid32(u16) ((u16)==ILLEGAL_UID16?ILLEGAL_UID:(__uid32_t)(u16))
+#define gid16togid32(g16) ((g16)==ILLEGAL_GID16?ILLEGAL_GID:(__gid32_t)(g16))
+
+extern "C" __uid32_t getuid32 (void);
+extern "C" __uid32_t geteuid32 (void);
+extern "C" struct passwd *getpwuid32 (__uid32_t);
+
/* various events */
void events_init (void);
void events_terminate (void);
@@ -197,6 +206,8 @@ extern "C" char *__stdcall strcasestr (const char *searchee, const char *lookfor
/* Time related */
void __stdcall totimeval (struct timeval *dst, FILETIME * src, int sub, int flag);
long __stdcall to_time_t (FILETIME * ptr);
+void __stdcall to_timestruc_t (FILETIME * ptr, timestruc_t * out);
+void __stdcall time_as_timestruc_t (timestruc_t * out);
void __stdcall set_console_title (char *);
void early_stuff_init ();
@@ -228,9 +239,6 @@ extern void multiple_cygwin_problem (const char *, unsigned, unsigned);
extern "C" void __malloc_lock (struct _reent *);
extern "C" void __malloc_unlock (struct _reent *);
-extern "C" void __malloc_lock (struct _reent *);
-extern "C" void __malloc_unlock (struct _reent *);
-
class path_conv;
int __stdcall stat_worker (const char *name, struct __stat64 *buf, int nofollow,
path_conv *pc = NULL) __attribute__ ((regparm (3)));
@@ -269,6 +277,9 @@ extern SYSTEM_INFO system_info;
#define STD_RBITS (S_IRUSR | S_IRGRP | S_IROTH)
#define STD_WBITS (S_IWUSR)
#define STD_XBITS (S_IXUSR | S_IXGRP | S_IXOTH)
+#define NO_W ~(S_IWUSR | S_IWGRP | S_IWOTH)
+#define NO_R ~(S_IRUSR | S_IRGRP | S_IROTH)
+#define NO_X ~(S_IXUSR | S_IXGRP | S_IXOTH)
/* The title on program start. */
extern char *old_title;