diff options
author | Christopher Faylor <me@cgf.cx> | 2003-07-06 05:10:44 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2003-07-06 05:10:44 +0000 |
commit | 3b2ea48e0b0f06644e5374cdb27f85b999631a1d (patch) | |
tree | a3273e53e0e8428503e2ca72fde4397efc58fa43 | |
parent | 139af9b586ae0e68fb504710d899d935f702787f (diff) | |
download | newlib-3b2ea48e0b0f06644e5374cdb27f85b999631a1d.zip newlib-3b2ea48e0b0f06644e5374cdb27f85b999631a1d.tar.gz newlib-3b2ea48e0b0f06644e5374cdb27f85b999631a1d.tar.bz2 |
merge from trunk
92 files changed, 704 insertions, 514 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a418231..352df7b 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,18 +1,32 @@ +2003-07-04 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc (fhandler_disk_file::mmap): Fix address test. + +2003-07-03 Christopher Faylor <cgf@redhat.com> + + * path.cc (fillout_mntent): Change "posix" to "managed". + 2003-07-02 Christopher Faylor <cgf@redhat.com> * fhandler.h (FH_ENC): New enum. (fhandler_base::get_encoded): New function. (fhandler_base::set_encoded): Ditto. - * fhandler_disk_file.cc (fhandler_disk_file::readdir): Unmunge filename - as appropriate based on new encoding flag. - * path.cc (normalize_posix_path): Change drive check short-circuit. + * fhandler_disk_file.cc (fhandler_disk_file::opendir): Set encoded flag + in fhandler, as appropriate. + (fhandler_disk_file::readdir): Unmunge filename as appropriate based on + new encoding flag. + * path.cc (normalize_posix_path): Don't punt on files with colons. (special_char): New function. (mount_item::fnmunge): Ditto. (fnunmunge): Ditto. (special_name): Ditto. + (mount_item::build_win32): Avoid drive considerations when file is + encoded. (mount_info::conv_to_win32_path): Handle encoded filenames. + (mount_info::conv_to_posix_path): Ditto. (fillout_mntent): Add posix string when directory is encoded. * path.h (fnunmunge): Declare. + (path_conv::is_encoded): Declare. 2003-07-03 Christopher Faylor <cgf@redhat.com> @@ -386,7 +400,7 @@ 2003-05-27 Bill C. Riemers <cygwin@docbill.net> * fhandler_disk_file.cc (fhandler_disk_file::fstat_helper): Filter - permissions throug umask on FAT or if ntsec is off. + permissions through umask on FAT or if ntsec is off. 2003-05-26 Pierre Humblet <pierre.humblet@ieee.org> diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index b892b37..53422ac 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -146,9 +146,7 @@ DLL_IMPORTS:=$(w32api_lib)/libkernel32.a MT_SAFE_OBJECTS:= # Please maintain this list in sorted order, with maximum files per 80 col line -DLL_OFILES:=assert.o autoload.o cxx.o cygheap.o cygserver_client.o \ - cygserver_transport.o cygserver_transport_pipes.o \ - cygserver_transport_sockets.o cygthread.o dcrt0.o debug.o \ +DLL_OFILES:=assert.o autoload.o cxx.o cygheap.o cygthread.o dcrt0.o debug.o \ delqueue.o devices.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 \ @@ -252,7 +250,7 @@ install_host=@install_host@ all: all_target $(all_host) -all_target: $(TARGET_LIBS) cygserver.exe +all_target: $(TARGET_LIBS) all_host: $(TEST_LIB_NAME) @@ -264,7 +262,7 @@ install: install-libs install-headers install-man install_target \ uninstall: uninstall-libs uninstall-headers uninstall-man install-libs: $(TARGET_LIBS) - $(INSTALL_DATA) $(TEST_DLL_NAME) $(bindir)/$(DLL_NAME); \ + $(INSTALL_PROGRAM) $(TEST_DLL_NAME) $(bindir)/$(DLL_NAME); \ for i in $^; do \ $(INSTALL_DATA) $$i $(tooldir)/lib/`basename $$i` ; \ done @@ -293,8 +291,7 @@ install-man: $(INSTALL_DATA) $$i $(tooldir)/man/man7/`basename $$i` ; \ done -install_target: cygserver.exe - $(INSTALL_PROGRAM) cygserver.exe $(bindir)/cygserver.exe +install_target: install_host: @@ -399,32 +396,6 @@ winver_stamp: mkvers.sh include/cygwin/version.h winver.rc $(DLL_OFILES) $(COMPILE_CXX) -o version.o version.cc && \ touch $@ -cygserver_transport_outside.o: cygserver_transport.cc - $(COMPILE_CXX) -D__OUTSIDE_CYGWIN__ -o $@ $< - -cygserver_transport_pipes_outside.o: cygserver_transport_pipes.cc - $(COMPILE_CXX) -D__OUTSIDE_CYGWIN__ -o $@ $< - -cygserver_transport_sockets_outside.o: cygserver_transport_sockets.cc - $(COMPILE_CXX) -D__OUTSIDE_CYGWIN__ -o $@ $< - -cygserver_client_outside.o: cygserver_client.cc - $(COMPILE_CXX) -D__OUTSIDE_CYGWIN__ -o $@ $< - -# gperf -c --key-positions='1-126' -r -t -C -E -L 'ANSI-C' -Hdevhash -N'device::lookup' -Z devstring -7 $? |\ - -$(srcdir)/devices.cc: cygwin-gperf devices.gperf devices.h - perl $^ > $@ - -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 $@ $^ -lstdc++ -#ifdef VERBOSE -# $(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,3,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS) -#else -# @echo $(CXX) -o $@ ${wordlist 1,3,$^} ${filter-out -B%, $(MINGW_CXXFLAGS) $(MINGW_LDFLAGS)};\ -# $(CXX) $(MINGW_CXXFLAGS) -o $@ ${wordlist 1,3,$^} -B$(mingw_build)/ $(MINGW_LDFLAGS) -#endif - -lgcc: : diff --git a/winsup/cygwin/acconfig.h b/winsup/cygwin/acconfig.h index c187c0b..79e2651 100644 --- a/winsup/cygwin/acconfig.h +++ b/winsup/cygwin/acconfig.h @@ -7,8 +7,14 @@ /* Define if GCC supports builtin memset. */ #undef HAVE_BUILTIN_MEMSET +/* Define if MALLOC_DEBUGGING support is requested. */ +#undef MALLOC_DEBUG + /* Define if building thread-safe Cygwin DLL. */ #undef _MT_SAFE /* Define if using new vfork functionality. */ #undef NEWVFORK + +/* Define if using cygserver */ +#undef USE_CYGSERVER diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index 71e7f9e..f5cc250 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -492,6 +492,7 @@ LoadDLLfuncEx (WSAEnumNetworkEvents, 12, ws2_32, 1) LoadDLLfuncEx (GetIfTable, 12, iphlpapi, 1) LoadDLLfuncEx (GetIfEntry, 4, iphlpapi, 1) LoadDLLfuncEx (GetIpAddrTable, 12, iphlpapi, 1) +LoadDLLfuncEx (GetNetworkParams, 8, iphlpapi, 1) LoadDLLfunc (CoInitialize, 4, ole32) LoadDLLfunc (CoUninitialize, 0, ole32) diff --git a/winsup/cygwin/config.h.in b/winsup/cygwin/config.h.in index 8a961b3..d4f6269 100644 --- a/winsup/cygwin/config.h.in +++ b/winsup/cygwin/config.h.in @@ -25,17 +25,17 @@ /* Define if DEBUGGING support is requested. */ #undef DEBUGGING -/* Define if MALLOC_DEBUGGING support is requested. */ -#undef MALLOC_DEBUG - /* Define if building "extra" thread-safe Cygwin DLL. */ #undef _CYG_THREAD_FAILSAFE /* Define if GCC supports builtin memset. */ #undef HAVE_BUILTIN_MEMSET -/* Define if building thread-safe Cygwin DLL. */ -#undef _MT_SAFE +/* Define if MALLOC_DEBUGGING support is requested. */ +#undef MALLOC_DEBUG /* Define if using new vfork functionality. */ #undef NEWVFORK + +/* Define if using cygserver */ +#undef USE_CYGSERVER diff --git a/winsup/cygwin/configure b/winsup/cygwin/configure index f5c8a7d..af5f3ca 100755 --- a/winsup/cygwin/configure +++ b/winsup/cygwin/configure @@ -12,12 +12,12 @@ ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help - --enable-threadsafe=[runtime] Build a cygwin DLL which is thread safe" -ac_help="$ac_help --enable-extra-threadsafe-checking Build a cygwin DLL which is thread safe with extra consistency checking" ac_help="$ac_help --enable-debugging Build a cygwin DLL which has more consistency checking for debugging" ac_help="$ac_help + --enable-server Build a cygwin DLL which can communicate with cygserver" +ac_help="$ac_help --enable-malloc-debugging Build a cygwin DLL with heap sanity checking (this is very slow, use only if you have heap corruption problems)" ac_help="$ac_help --enable-vfork Build a cygwin DLL which uses experimental vfork code" @@ -1865,28 +1865,6 @@ ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$a cross_compiling=$ac_cv_prog_cc_cross -mt_safe_val=1 -MT_SAFE=yes - -# Check whether --enable-threadsafe or --disable-threadsafe was given. -if test "${enable_threadsafe+set}" = set; then - enableval="$enable_threadsafe" - case "${enableval}" in -yes) - ;; -runtime) - mt_safe_val=2 - MT_SAFE=yes - ;; -no) - mt_safe_val=0 - MT_SAFE=no - ;; -esac - -fi - - # Check whether --enable-extra-threadsafe-checking or --disable-extra-threadsafe-checking was given. if test "${enable_extra_threadsafe_checking+set}" = set; then enableval="$enable_extra_threadsafe_checking" @@ -1906,21 +1884,26 @@ esac fi -if test "$MT_SAFE" = "yes"; then - cat >> confdefs.h <<EOF -#define _MT_SAFE $mt_safe_val +# Check whether --enable-debugging or --disable-debugging was given. +if test "${enable_debugging+set}" = set; then + enableval="$enable_debugging" + case "${enableval}" in +yes) cat >> confdefs.h <<\EOF +#define DEBUGGING 1 EOF + ;; +no) ;; +esac fi - -# Check whether --enable-debugging or --disable-debugging was given. -if test "${enable_debugging+set}" = set; then - enableval="$enable_debugging" +# Check whether --enable-server or --disable-server was given. +if test "${enable_server+set}" = set; then + enableval="$enable_server" case "${enableval}" in yes) cat >> confdefs.h <<\EOF -#define DEBUGGING 1 +#define USE_CYGSERVER 1 EOF ;; no) ;; @@ -2146,7 +2129,6 @@ s%@WINDRES@%$WINDRES%g s%@CPP@%$CPP%g s%@ALLOCA@%$ALLOCA%g s%@SET_MAKE@%$SET_MAKE%g -s%@MT_SAFE@%$MT_SAFE%g s%@MALLOC_OFILES@%$MALLOC_OFILES%g s%@DLL_ENTRY@%$DLL_ENTRY%g s%@DEF_DLL_ENTRY@%$DEF_DLL_ENTRY%g diff --git a/winsup/cygwin/configure.in b/winsup/cygwin/configure.in index 48ffe7d..c192221 100644 --- a/winsup/cygwin/configure.in +++ b/winsup/cygwin/configure.in @@ -1,5 +1,5 @@ dnl Autoconf configure script for Cygwin. -dnl Copyright 1996, 1997, 1998, 2000, 2001 Red Hat, Inc. +dnl Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003 Red Hat, Inc. dnl dnl This file is part of Cygwin. dnl @@ -111,27 +111,6 @@ if test $use_builtin_memset = "yes"; then fi AC_LANG_RESTORE -dnl set default mt safeness and then process the options. -mt_safe_val=1 -MT_SAFE=yes - -AC_ARG_ENABLE(threadsafe, -[ --enable-threadsafe=[runtime] Build a cygwin DLL which is thread safe], -[case "${enableval}" in -yes) - dnl default. - ;; -runtime) - mt_safe_val=2 - MT_SAFE=yes - ;; -no) - mt_safe_val=0 - MT_SAFE=no - ;; -esac -]) - AC_ARG_ENABLE(extra-threadsafe-checking, [ --enable-extra-threadsafe-checking Build a cygwin DLL which is thread safe with extra consistency checking], [case "${enableval}" in @@ -146,13 +125,6 @@ no) esac ]) -if test "$MT_SAFE" = "yes"; then - AC_DEFINE_UNQUOTED(_MT_SAFE,$mt_safe_val) -fi - -dnl Makefile uses MT_SAFE, so we subst as well as defining it. -AC_SUBST(MT_SAFE) - AC_ARG_ENABLE(debugging, [ --enable-debugging Build a cygwin DLL which has more consistency checking for debugging], [case "${enableval}" in @@ -161,6 +133,14 @@ no) ;; esac ]) +AC_ARG_ENABLE(server, +[ --enable-server Build a cygwin DLL which can communicate with cygserver], +[case "${enableval}" in +yes) AC_DEFINE(USE_CYGSERVER) ;; +no) ;; +esac +]) + MALLOC_OFILES= AC_ARG_ENABLE(malloc-debugging, [ --enable-malloc-debugging Build a cygwin DLL with heap sanity checking (this is very slow, use only if you have heap corruption problems)], diff --git a/winsup/cygwin/cygerrno.h b/winsup/cygwin/cygerrno.h index 0c1513f..fb00f3f 100644 --- a/winsup/cygwin/cygerrno.h +++ b/winsup/cygwin/cygerrno.h @@ -1,6 +1,6 @@ /* cygerrno.h: main Cygwin header file. - Copyright 2000 Red Hat, Inc. + Copyright 2000, 2001, 2002, 2003 Red Hat, Inc. This file is part of Cygwin. @@ -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. */ +#include <errno.h> + void __stdcall seterrno_from_win_error (const char *file, int line, DWORD code) __attribute__ ((regparm(3))); void __stdcall seterrno (const char *, int line) __attribute__ ((regparm(2))); int __stdcall geterrno_from_win_error (DWORD code, int deferrno) __attribute__ ((regparm(2))); @@ -16,12 +18,12 @@ int __stdcall geterrno_from_win_error (DWORD code, int deferrno) __attribute__ ( #define __seterrno_from_win_error(val) seterrno_from_win_error (__FILE__, __LINE__, val) #ifndef DEBUGGING -#define set_errno(val) (_impure_ptr->_errno = (val)) +#define set_errno(val) (errno = (val)) #else int __stdcall __set_errno (const char *ln, int ln, int val) __attribute ((regparm(3))); #define set_errno(val) __set_errno (__PRETTY_FUNCTION__, __LINE__, (val)) #endif -#define get_errno() (_impure_ptr->_errno) +#define get_errno() (errno) extern "C" void __stdcall set_sig_errno (int e); class save_errno diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc index 1d3e4fb..1ee1f2d 100644 --- a/winsup/cygwin/cygheap.cc +++ b/winsup/cygwin/cygheap.cc @@ -10,7 +10,6 @@ #include "winsup.h" #include <string.h> -#include <errno.h> #include <assert.h> #include <stdlib.h> #include "security.h" diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h index 281f9b4..215d202 100644 --- a/winsup/cygwin/cygheap.h +++ b/winsup/cygwin/cygheap.h @@ -92,7 +92,13 @@ enum homebodies CH_HOME }; -struct passwd; +enum impersonation +{ + IMP_BAD = -1, + IMP_NONE = 0, + IMP_EXTERNAL, + IMP_INTERNAL +}; class cygheap_user { @@ -117,8 +123,9 @@ public: /* token is needed if set(e)uid should be called. It can be set by a call to `set_impersonation_token()'. */ - HANDLE token; - BOOL impersonated; + HANDLE external_token; + HANDLE internal_token; + enum impersonation impersonation_state; /* CGF 2002-06-27. I removed the initializaton from this constructor since this class is always allocated statically. That means that everything @@ -165,7 +172,40 @@ public: const char *ontherange (homebodies what, struct passwd * = NULL); bool issetuid () const { - return impersonated && token != INVALID_HANDLE_VALUE; + return impersonation_state > IMP_NONE; + } + HANDLE token () + { + if (impersonation_state == IMP_EXTERNAL) + return external_token; + if (impersonation_state == IMP_INTERNAL) + return internal_token; + return INVALID_HANDLE_VALUE; + } + void deimpersonate () + { + if (impersonation_state > IMP_NONE) + RevertToSelf (); + } + void reimpersonate () + { + if (impersonation_state > IMP_NONE + && !ImpersonateLoggedOnUser (token ())) + system_printf ("ImpersonateLoggedOnUser: %E"); + } + bool has_impersonation_tokens () { return external_token || internal_token; } + void close_impersonation_tokens () + { + if (external_token) + { + CloseHandle (external_token); + external_token = 0; + } + if (internal_token) + { + CloseHandle (internal_token); + internal_token = 0; + } } const char *cygheap_user::test_uid (char *&, const char *, size_t) __attribute__ ((regparm (3))); diff --git a/winsup/cygwin/cygserver.cc b/winsup/cygwin/cygserver.cc index 0c07403..137730f 100755 --- a/winsup/cygwin/cygserver.cc +++ b/winsup/cygwin/cygserver.cc @@ -16,7 +16,6 @@ details. */ #include <assert.h> #include <ctype.h> -#include <errno.h> #include <getopt.h> #include <signal.h> #include <stdio.h> diff --git a/winsup/cygwin/cygserver_client.cc b/winsup/cygwin/cygserver_client.cc index 138c9dd..f668318 100755 --- a/winsup/cygwin/cygserver_client.cc +++ b/winsup/cygwin/cygserver_client.cc @@ -18,7 +18,6 @@ details. */ #endif #include <assert.h> -#include <errno.h> #include <stdio.h> #include <unistd.h> diff --git a/winsup/cygwin/cygserver_process.cc b/winsup/cygwin/cygserver_process.cc index 7118bbc..2cc7be1 100755 --- a/winsup/cygwin/cygserver_process.cc +++ b/winsup/cygwin/cygserver_process.cc @@ -15,7 +15,6 @@ details. */ #include <sys/types.h> #include <assert.h> -#include <errno.h> #include <stdlib.h> #include "cygerrno.h" diff --git a/winsup/cygwin/cygserver_transport_pipes.cc b/winsup/cygwin/cygserver_transport_pipes.cc index 495d804..6d80def 100755 --- a/winsup/cygwin/cygserver_transport_pipes.cc +++ b/winsup/cygwin/cygserver_transport_pipes.cc @@ -20,7 +20,6 @@ details. */ #include <sys/types.h> #include <assert.h> -#include <errno.h> #include <netdb.h> #include <pthread.h> #include <unistd.h> diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index 2d45f29..c4c871c 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -9,7 +9,6 @@ details. */ #include "winsup.h" #include <windows.h> #include <stdlib.h> -#include <errno.h> #include "exceptions.h" #include "security.h" #include "cygthread.h" diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din index 5dda7ea..107dc00 100644 --- a/winsup/cygwin/cygwin.din +++ b/winsup/cygwin/cygwin.din @@ -26,6 +26,7 @@ __eprintf __errno __fpclassifyd __fpclassifyf +__getreent __infinity __main __signbitd @@ -1299,6 +1300,7 @@ sysconf _sysconf = sysconf syslog _syslog = syslog +vsyslog system _system = system tan diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 09fbf58..04449b2 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -17,7 +17,6 @@ details. */ #include <limits.h> #include <wingdi.h> #include <winuser.h> -#include <errno.h> #include "sigproc.h" #include "pinfo.h" #include "cygerrno.h" @@ -54,9 +53,9 @@ per_thread NO_COPY *threadstuff[] = {&waitq_storage, &signal_dispatch_storage, NULL}; -BOOL display_title; -BOOL strip_title_path; -BOOL allow_glob = TRUE; +bool display_title; +bool strip_title_path; +bool allow_glob = TRUE; codepage_type current_codepage = ansi_cp; int cygwin_finished_initializing; diff --git a/winsup/cygwin/debug.cc b/winsup/cygwin/debug.cc index e85717b..2f0471a 100644 --- a/winsup/cygwin/debug.cc +++ b/winsup/cygwin/debug.cc @@ -15,7 +15,6 @@ details. */ #include "security.h" #include "cygerrno.h" #ifdef DEBUGGING -#include <errno.h> #include "path.h" #include "fhandler.h" #include "dtable.h" @@ -222,6 +221,6 @@ int __stdcall __set_errno (const char *func, int ln, int val) { debug_printf ("%s:%d val %d", func, ln, val); - return _impure_ptr->_errno = val; + return errno = val; } #endif /*DEBUGGING*/ diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc index 4ed076e..88a1689 100644 --- a/winsup/cygwin/dir.cc +++ b/winsup/cygwin/dir.cc @@ -12,7 +12,6 @@ details. */ #include <unistd.h> #include <stdlib.h> #include <sys/stat.h> -#include <errno.h> #define _COMPILING_NEWLIB #include <dirent.h> diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 4e54919..38af9aa 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -8,7 +8,6 @@ details. */ #include "winsup.h" #include <stdlib.h> -#include <errno.h> #include "cygerrno.h" #include "perprocess.h" #include "dll_init.h" diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 40c37ca..6ff8121 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -11,7 +11,6 @@ details. */ #define __INSIDE_CYGWIN_NET__ #include "winsup.h" -#include <errno.h> #include <sys/socket.h> #include <stdlib.h> #include <stdio.h> @@ -676,8 +675,7 @@ dtable::vfork_child_dup () int res = 1; /* Remove impersonation */ - if (cygheap->user.issetuid ()) - RevertToSelf (); + cygheap->user.deimpersonate (); for (size_t i = 0; i < size; i++) if (not_open (i)) @@ -696,8 +694,7 @@ dtable::vfork_child_dup () out: /* Restore impersonation */ - if (cygheap->user.issetuid ()) - ImpersonateLoggedOnUser (cygheap->user.token); + cygheap->user.reimpersonate (); ReleaseResourceLock (LOCK_FD_LIST, WRITE_LOCK | READ_LOCK, "dup"); return 1; diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc index 6a11251..6c75f98 100644 --- a/winsup/cygwin/environ.cc +++ b/winsup/cygwin/environ.cc @@ -1,14 +1,13 @@ /* environ.cc: Cygwin-adopted functions from newlib to manipulate process's environment. - Copyright 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. 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 <errno.h> #include <stdlib.h> #include <stddef.h> #include <ctype.h> @@ -27,17 +26,17 @@ details. */ #include "environ.h" #include "child_info.h" -extern BOOL allow_daemon; -extern BOOL allow_glob; +extern bool allow_glob; extern bool ignore_case_with_glob; -extern BOOL allow_ntea; -extern BOOL allow_smbntsec; -extern BOOL allow_winsymlinks; -extern BOOL strip_title_path; +extern bool allow_ntea; +extern bool allow_smbntsec; +extern bool allow_winsymlinks; +extern bool strip_title_path; extern int pcheck_case; extern int subauth_id; -BOOL reset_com = FALSE; -static BOOL envcache = TRUE; +bool reset_com = false; +bool allow_daemon = false; +static bool envcache = true; static char **lastenviron; @@ -366,7 +365,7 @@ ucenv (char *p, char *eq) /* Parse CYGWIN options */ -static NO_COPY BOOL export_settings = false; +static NO_COPY bool export_settings = false; enum settings { @@ -385,18 +384,18 @@ glob_init (const char *buf) { if (!buf || !*buf) { - allow_glob = FALSE; - ignore_case_with_glob = FALSE; + allow_glob = false; + ignore_case_with_glob = false; } else if (strncasematch (buf, "ignorecase", 10)) { - allow_glob = TRUE; - ignore_case_with_glob = TRUE; + allow_glob = true; + ignore_case_with_glob = true; } else { - allow_glob = TRUE; - ignore_case_with_glob = FALSE; + allow_glob = true; + ignore_case_with_glob = false; } } @@ -489,7 +488,7 @@ static struct parse_thing const char *name; union parse_setting { - BOOL *b; + bool *b; DWORD *x; int *i; void (*func)(const char *); @@ -507,21 +506,21 @@ static struct parse_thing {"binmode", {x: &binmode}, justset, NULL, {{O_TEXT}, {O_BINARY}}}, {"check_case", {func: &check_case_init}, isfunc, NULL, {{0}, {0}}}, {"codepage", {func: &codepage_init}, isfunc, NULL, {{0}, {0}}}, - {"daemon", {&allow_daemon}, justset, NULL, {{FALSE}, {TRUE}}}, - {"envcache", {&envcache}, justset, NULL, {{TRUE}, {FALSE}}}, + {"daemon", {&allow_daemon}, justset, NULL, {{false}, {true}}}, + {"envcache", {&envcache}, justset, NULL, {{true}, {false}}}, {"error_start", {func: &error_start_init}, isfunc, NULL, {{0}, {0}}}, - {"export", {&export_settings}, justset, NULL, {{FALSE}, {TRUE}}}, + {"export", {&export_settings}, justset, NULL, {{false}, {true}}}, {"forkchunk", {func: set_chunksize}, isfunc, NULL, {{0}, {0}}}, {"glob", {func: &glob_init}, isfunc, NULL, {{0}, {s: "normal"}}}, - {"ntea", {&allow_ntea}, justset, NULL, {{FALSE}, {TRUE}}}, - {"ntsec", {&allow_ntsec}, justset, NULL, {{FALSE}, {TRUE}}}, - {"smbntsec", {&allow_smbntsec}, justset, NULL, {{FALSE}, {TRUE}}}, - {"reset_com", {&reset_com}, justset, NULL, {{FALSE}, {TRUE}}}, - {"strip_title", {&strip_title_path}, justset, NULL, {{FALSE}, {TRUE}}}, + {"ntea", {&allow_ntea}, justset, NULL, {{false}, {true}}}, + {"ntsec", {&allow_ntsec}, justset, NULL, {{false}, {true}}}, + {"smbntsec", {&allow_smbntsec}, justset, NULL, {{false}, {true}}}, + {"reset_com", {&reset_com}, justset, NULL, {{false}, {true}}}, + {"strip_title", {&strip_title_path}, justset, NULL, {{false}, {true}}}, {"subauth_id", {func: &subauth_id_init}, isfunc, NULL, {{0}, {0}}}, - {"title", {&display_title}, justset, NULL, {{FALSE}, {TRUE}}}, + {"title", {&display_title}, justset, NULL, {{false}, {true}}}, {"tty", {NULL}, set_process_state, NULL, {{0}, {PID_USETTY}}}, - {"winsymlinks", {&allow_winsymlinks}, justset, NULL, {{FALSE}, {TRUE}}}, + {"winsymlinks", {&allow_winsymlinks}, justset, NULL, {{false}, {true}}}, {NULL, {0}, justset, 0, {{0}, {0}}} }; @@ -677,7 +676,7 @@ environ_init (char **envp, int envc) /* Set ntsec explicit as default, if NT is running */ if (wincap.has_security ()) - allow_ntsec = TRUE; + allow_ntsec = true; if (!envp) envp_passed_in = 0; diff --git a/winsup/cygwin/errno.cc b/winsup/cygwin/errno.cc index a922d52..127eff9 100644 --- a/winsup/cygwin/errno.cc +++ b/winsup/cygwin/errno.cc @@ -10,14 +10,14 @@ details. */ #define _sys_nerr FOO_sys_nerr #define sys_nerr FOOsys_nerr +#define _sys_errlist FOO_sys_errlist #include "winsup.h" -#define _REENT_ONLY #include <stdio.h> -#include <errno.h> #include "cygerrno.h" #include "thread.h" #undef _sys_nerr #undef sys_nerr +#undef _sys_errlist /* Table to map Windows error codes to Errno values. */ /* FIXME: Doing things this way is a little slow. It's trivial to change @@ -25,13 +25,12 @@ details. */ #define X(w, e) {ERROR_##w, #w, e} -static const NO_COPY struct - { - DWORD w; /* windows version of error */ - const char *s; /* text of windows version */ - int e; /* errno version of error */ - } -errmap[] = +static NO_COPY struct +{ + DWORD w; /* windows version of error */ + const char *s; /* text of windows version */ + int e; /* errno version of error */ +} errmap[] = { /* FIXME: Some of these choices are arbitrary! */ X (INVALID_FUNCTION, EBADRQC), @@ -116,42 +115,8 @@ errmap[] = { 0, NULL, 0} }; -int __stdcall -geterrno_from_win_error (DWORD code, int deferrno) -{ - for (int i = 0; errmap[i].w != 0; ++i) - if (code == errmap[i].w) - { - syscall_printf ("windows error %u == errno %d", code, errmap[i].e); - return errmap[i].e; - } - - syscall_printf ("unknown windows error %u, setting errno to %d", code, - deferrno); - return deferrno; /* FIXME: what's so special about EACCESS? */ -} - -/* seterrno_from_win_error: Given a Windows error code, set errno - as appropriate. */ -void __stdcall -seterrno_from_win_error (const char *file, int line, DWORD code) -{ - syscall_printf ("%s:%d windows error %d", file, line, code); - set_errno (geterrno_from_win_error (code, EACCES)); - return; -} - -/* seterrno: Set `errno' based on GetLastError (). */ -void __stdcall -seterrno (const char *file, int line) -{ - seterrno_from_win_error (file, line, GetLastError ()); -} - -extern char *_user_strerror _PARAMS ((int)); - extern "C" { -const NO_COPY char __declspec(dllexport) * const _sys_errlist[]= +const char __declspec(dllexport) * _sys_errlist[] NO_COPY_INIT = { /* NOERROR 0 */ "No error", /* EPERM 1 */ "Operation not permitted", @@ -295,9 +260,43 @@ const NO_COPY char __declspec(dllexport) * const _sys_errlist[]= /* EOVERFLOW 139 */ "Value too large for defined data type" }; -extern const int NO_COPY __declspec(dllexport) _sys_nerr = sizeof (_sys_errlist) / sizeof (_sys_errlist[0]); +int NO_COPY_INIT _sys_nerr = sizeof (_sys_errlist) / sizeof (_sys_errlist[0]); }; +int __stdcall +geterrno_from_win_error (DWORD code, int deferrno) +{ + for (int i = 0; errmap[i].w != 0; ++i) + if (code == errmap[i].w) + { + syscall_printf ("windows error %u == errno %d", code, errmap[i].e); + return errmap[i].e; + } + + syscall_printf ("unknown windows error %u, setting errno to %d", code, + deferrno); + return deferrno; /* FIXME: what's so special about EACCESS? */ +} + +/* seterrno_from_win_error: Given a Windows error code, set errno + as appropriate. */ +void __stdcall +seterrno_from_win_error (const char *file, int line, DWORD code) +{ + syscall_printf ("%s:%d windows error %d", file, line, code); + set_errno (geterrno_from_win_error (code, EACCES)); + return; +} + +/* seterrno: Set `errno' based on GetLastError (). */ +void __stdcall +seterrno (const char *file, int line) +{ + seterrno_from_win_error (file, line, GetLastError ()); +} + +extern char *_user_strerror _PARAMS ((int)); + /* FIXME: Why is strerror() a long switch and not just: return sys_errlist[errnum]; (or moral equivalent). @@ -681,7 +680,11 @@ strerror (int errnum) error = "Value too large for defined data type"; break; default: +#ifdef _MT_SAFE char *buf= _reent_winsup ()->_strerror_buf; +#else + static NO_COPY char buf[20]; +#endif __small_sprintf (buf, "error %d", errnum); error = buf; break; diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index 4a38a8e..3c8bf39 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -10,7 +10,6 @@ details. */ #include "winsup.h" #include <imagehlp.h> -#include <errno.h> #include <stdlib.h> #include "exceptions.h" @@ -154,7 +153,7 @@ error_start_init (const char *buf) for (char *p = strchr (pgm, '\\'); p; p = strchr (p, '\\')) *p = '/'; - __small_sprintf (debugger_command, "%s %s", buf, pgm); + __small_sprintf (debugger_command, "%s \"%s\"", buf, pgm); } static void @@ -932,7 +931,13 @@ ctrl_c_handler (DWORD type) is shut down or console window is closed. */ if (type == CTRL_SHUTDOWN_EVENT) { +#if 0 + /* Don't send a signal. Only NT service applications and their child + processes will receive this event and the services typically already + handle the shutdown action when getting the SERVICE_CONTROL_SHUTDOWN + control message. */ sig_send (NULL, SIGTERM); +#endif return FALSE; } if (type == CTRL_CLOSE_EVENT) diff --git a/winsup/cygwin/exec.cc b/winsup/cygwin/exec.cc index af345be..d7c2ee1 100644 --- a/winsup/cygwin/exec.cc +++ b/winsup/cygwin/exec.cc @@ -12,7 +12,6 @@ details. */ #include "winsup.h" #include <unistd.h> #include <stdlib.h> -#include <errno.h> #include <process.h> #include "perprocess.h" #include "security.h" diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc index c1a829a..49e4305 100644 --- a/winsup/cygwin/external.cc +++ b/winsup/cygwin/external.cc @@ -11,7 +11,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include <errno.h> #include "security.h" #include "sigproc.h" #include "pinfo.h" diff --git a/winsup/cygwin/fcntl.cc b/winsup/cygwin/fcntl.cc index f99dd2d..b1afb57 100644 --- a/winsup/cygwin/fcntl.cc +++ b/winsup/cygwin/fcntl.cc @@ -10,7 +10,6 @@ details. */ #include "winsup.h" #include <stdarg.h> -#include <errno.h> #include <unistd.h> #include "security.h" #include "path.h" diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index ab5e4b8..253fca6 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 <errno.h> #include <unistd.h> #include <stdlib.h> #include <sys/cygwin.h> @@ -600,7 +599,7 @@ fhandler_base::write (const void *ptr, size_t len) if (current_position > actual_length) { if ((get_fs_flags (FILE_SUPPORTS_SPARSE_FILES)) - && current_position >= actual_length + (64 * 1024)) + && current_position >= actual_length + (128 * 1024)) { /* If the file systemn supports sparse files and the application is writing after a long seek beyond EOF, convert the file to diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index d3b0f5d..2ee82fc 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -20,8 +20,7 @@ enum FH_WBINSET = 0x00010000, /* binary write mode has been explicitly set */ FH_APPEND = 0x00020000, /* always append */ FH_ASYNC = 0x00040000, /* async I/O */ - FH_SIGCLOSE = 0x00080000, /* signal handler should close fd on interrupt */ - + FH_ENC = 0x00080000, /* native path is encoded */ FH_SYMLINK = 0x00100000, /* is a symlink */ FH_EXECABL = 0x00200000, /* file looked like it would run: * ends in .exe or .bat or begins with #! */ @@ -200,6 +199,9 @@ class fhandler_base bool get_need_fork_fixup () { return FHISSETF (FFIXUP); } void set_need_fork_fixup () { FHSETF (FFIXUP); } + bool get_encoded () { return FHISSETF (ENC);} + void set_encoded () { FHSETF (ENC);} + virtual void set_close_on_exec (int val); virtual void fixup_before_fork_exec (DWORD) {} @@ -387,6 +389,7 @@ class fhandler_socket: public fhandler_base bool is_connect_pending () const {return had_connect_or_listen == CONNECT_PENDING;} bool is_connected () const {return had_connect_or_listen == CONNECTED;} void set_connect_state (int newstate) { had_connect_or_listen = newstate; } + int get_connect_state () const { return had_connect_or_listen; } int bind (const struct sockaddr *name, int namelen); int connect (const struct sockaddr *name, int namelen); diff --git a/winsup/cygwin/fhandler_clipboard.cc b/winsup/cygwin/fhandler_clipboard.cc index 3f72703..3f24094 100644 --- a/winsup/cygwin/fhandler_clipboard.cc +++ b/winsup/cygwin/fhandler_clipboard.cc @@ -13,7 +13,6 @@ details. */ #include "winsup.h" #include <stdio.h> #include <stdlib.h> -#include <errno.h> #include <unistd.h> #include <windows.h> #include <wingdi.h> diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc index a76cfb0..9409cdd 100644 --- a/winsup/cygwin/fhandler_console.cc +++ b/winsup/cygwin/fhandler_console.cc @@ -12,7 +12,6 @@ details. */ #include <sys/termios.h> #include <stdio.h> #include <stdlib.h> -#include <errno.h> #include <unistd.h> #include <wingdi.h> #include <winuser.h> diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index 7e6d033..d97b5dc 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 <errno.h> #include <unistd.h> #include <stdlib.h> #include <sys/cygwin.h> @@ -627,6 +626,8 @@ fhandler_disk_file::opendir () res = dir; } + if (real_name.isencoded ()) + set_encoded (); } syscall_printf ("%p = opendir (%s)", res, get_name ()); @@ -653,9 +654,7 @@ fhandler_disk_file::readdir (DIR *dir) } } else if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE) - { - return res; - } + return res; else if (!FindNextFileA (dir->__d_u.__d_data.__handle, &buf)) { DWORD lasterr = GetLastError (); @@ -670,7 +669,10 @@ fhandler_disk_file::readdir (DIR *dir) } /* We get here if `buf' contains valid data. */ - strcpy (dir->__d_dirent->d_name, buf.cFileName); + if (get_encoded ()) + (void) fnunmunge (dir->__d_dirent->d_name, buf.cFileName); + else + strcpy (dir->__d_dirent->d_name, buf.cFileName); /* Check for Windows shortcut. If it's a Cygwin or U/WIN symlink, drop the .lnk suffix. */ diff --git a/winsup/cygwin/fhandler_dsp.cc b/winsup/cygwin/fhandler_dsp.cc index f961ec9..3c577a8 100644 --- a/winsup/cygwin/fhandler_dsp.cc +++ b/winsup/cygwin/fhandler_dsp.cc @@ -12,7 +12,6 @@ details. */ #include "winsup.h" #include <stdio.h> -#include <errno.h> #include <windows.h> #include <sys/soundcard.h> #include <mmsystem.h> diff --git a/winsup/cygwin/fhandler_floppy.cc b/winsup/cygwin/fhandler_floppy.cc index dbf603c..1b8cccf 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 <errno.h> #include <unistd.h> #include <winioctl.h> #include <asm/socket.h> diff --git a/winsup/cygwin/fhandler_mem.cc b/winsup/cygwin/fhandler_mem.cc index 243986e..883412f 100644 --- a/winsup/cygwin/fhandler_mem.cc +++ b/winsup/cygwin/fhandler_mem.cc @@ -9,7 +9,6 @@ details. */ #include "winsup.h" -#include <errno.h> #include <unistd.h> #include <sys/mman.h> #include <ntdef.h> diff --git a/winsup/cygwin/fhandler_proc.cc b/winsup/cygwin/fhandler_proc.cc index 2ab9fad..081fcf5 100644 --- a/winsup/cygwin/fhandler_proc.cc +++ b/winsup/cygwin/fhandler_proc.cc @@ -11,7 +11,6 @@ details. */ #define _WIN32_WINNT 0x0501 #include "winsup.h" -#include <errno.h> #include <unistd.h> #include <stdlib.h> #include <sys/cygwin.h> diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index 1c46f6f..ca48352 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -9,7 +9,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include <errno.h> #include <unistd.h> #include <stdlib.h> #include <sys/cygwin.h> diff --git a/winsup/cygwin/fhandler_random.cc b/winsup/cygwin/fhandler_random.cc index 257228a..5595334 100644 --- a/winsup/cygwin/fhandler_random.cc +++ b/winsup/cygwin/fhandler_random.cc @@ -11,7 +11,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include <errno.h> #include <limits.h> #include "cygerrno.h" #include "security.h" diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc index 302af88..9266290 100644 --- a/winsup/cygwin/fhandler_raw.cc +++ b/winsup/cygwin/fhandler_raw.cc @@ -10,7 +10,6 @@ #include "winsup.h" #include <sys/termios.h> -#include <errno.h> #include <unistd.h> #include <cygwin/rdevio.h> diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc index ea193b8..9137014 100644 --- a/winsup/cygwin/fhandler_registry.cc +++ b/winsup/cygwin/fhandler_registry.cc @@ -11,7 +11,6 @@ details. */ /* FIXME: Access permissions are ignored at the moment. */ #include "winsup.h" -#include <errno.h> #include <unistd.h> #include <stdlib.h> #include <sys/cygwin.h> diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc index eec4735..45c3cc1 100644 --- a/winsup/cygwin/fhandler_serial.cc +++ b/winsup/cygwin/fhandler_serial.cc @@ -9,7 +9,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include <errno.h> #include <unistd.h> #include <stdlib.h> #include "cygerrno.h" diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 6a163b6..3dc1690 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -13,7 +13,6 @@ #define __INSIDE_CYGWIN_NET__ #include "winsup.h" -#include <errno.h> #include <sys/socket.h> #include <sys/un.h> #include <sys/uio.h> @@ -328,6 +327,7 @@ fhandler_socket::dup (fhandler_base *child) if (get_addr_family () == AF_LOCAL) fhs->set_sun_path (get_sun_path ()); fhs->set_socket_type (get_socket_type ()); + fhs->set_connect_state (get_connect_state ()); if (winsock2_active) { @@ -338,12 +338,10 @@ fhandler_socket::dup (fhandler_base *child) If WSADuplicateSocket() still fails for some reason, we fall back to DuplicateHandle(). */ WSASetLastError (0); - if (cygheap->user.issetuid ()) - RevertToSelf (); + cygheap->user.deimpersonate (); fhs->set_io_handle (get_io_handle ()); fhs->fixup_before_fork_exec (GetCurrentProcessId ()); - if (cygheap->user.issetuid ()) - ImpersonateLoggedOnUser (cygheap->user.token); + cygheap->user.reimpersonate (); if (!WSAGetLastError ()) { fhs->fixup_after_fork (hMainProc); @@ -492,6 +490,7 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) BOOL in_progress = FALSE; sockaddr_in sin; int secret [4]; + DWORD err; if (!get_inet_addr (name, namelen, &sin, &namelen, secret)) return -1; @@ -504,12 +503,12 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) when called on a non-blocking socket. */ if (is_nonblocking () || is_connect_pending ()) { - DWORD err = WSAGetLastError (); + err = WSAGetLastError (); if (err == WSAEWOULDBLOCK || err == WSAEALREADY) - { - WSASetLastError (WSAEINPROGRESS); - in_progress = TRUE; - } + in_progress = TRUE; + + if (err == WSAEWOULDBLOCK) + WSASetLastError (WSAEINPROGRESS); else if (err == WSAEINVAL) WSASetLastError (WSAEISCONN); } @@ -546,7 +545,8 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen) } } - if (WSAGetLastError () == WSAEINPROGRESS) + err = WSAGetLastError (); + if (err == WSAEINPROGRESS || err == WSAEALREADY) set_connect_state (CONNECT_PENDING); else set_connect_state (CONNECTED); diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc index 4cbf868..e3efcd1 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 <errno.h> #include <unistd.h> #include <sys/mtio.h> #include "cygerrno.h" diff --git a/winsup/cygwin/fhandler_termios.cc b/winsup/cygwin/fhandler_termios.cc index cd4faff..89d883c 100644 --- a/winsup/cygwin/fhandler_termios.cc +++ b/winsup/cygwin/fhandler_termios.cc @@ -12,7 +12,6 @@ details. */ #include <sys/termios.h> #include <stdlib.h> #include <unistd.h> -#include <errno.h> #include <ctype.h> #include "cygerrno.h" #include "security.h" diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 322b80a..3c88fcc 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -14,7 +14,6 @@ details. */ #include <stdio.h> #include <unistd.h> #include <stdlib.h> -#include <errno.h> #include <ctype.h> #include <limits.h> #include "cygerrno.h" @@ -508,9 +507,11 @@ fhandler_tty_slave::open (int flags, mode_t) HANDLE from_master_local, to_master_local; - if (!wincap.has_security () || - cygserver_running == CYGSERVER_UNAVAIL || - !cygserver_attach_tty (&from_master_local, &to_master_local)) +#ifdef USE_CYGSERVER + if (!wincap.has_security () + || cygserver_running == CYGSERVER_UNAVAIL + || !cygserver_attach_tty (&from_master_local, &to_master_local)) +#endif { termios_printf ("cannot dup handles via server. using old method."); @@ -583,7 +584,8 @@ fhandler_tty_slave::close () { if (!output_done_event) { - fhandler_console::open_fhs--; + if (!--fhandler_console::open_fhs && myself->ctty == -1) + FreeConsole (); termios_printf ("decremented open_fhs %d", fhandler_console::open_fhs); } return fhandler_tty_common::close (); @@ -593,6 +595,9 @@ int fhandler_tty_slave::cygserver_attach_tty (LPHANDLE from_master_ptr, LPHANDLE to_master_ptr) { +#ifndef USE_CYGSERVER + return 0; +#else if (!from_master_ptr || !to_master_ptr) return 0; @@ -605,7 +610,9 @@ fhandler_tty_slave::cygserver_attach_tty (LPHANDLE from_master_ptr, *from_master_ptr = req.from_master (); *to_master_ptr = req.to_master (); + return 1; +#endif } void diff --git a/winsup/cygwin/fhandler_virtual.cc b/winsup/cygwin/fhandler_virtual.cc index baf8e79..aedaf01 100644 --- a/winsup/cygwin/fhandler_virtual.cc +++ b/winsup/cygwin/fhandler_virtual.cc @@ -9,7 +9,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include <errno.h> #include <unistd.h> #include <stdlib.h> #include <sys/cygwin.h> diff --git a/winsup/cygwin/fhandler_windows.cc b/winsup/cygwin/fhandler_windows.cc index 81972bf..4affbc6 100644 --- a/winsup/cygwin/fhandler_windows.cc +++ b/winsup/cygwin/fhandler_windows.cc @@ -12,7 +12,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include <errno.h> #include <wingdi.h> #include <winuser.h> #include "cygerrno.h" diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc index ac1708a..859bb64 100644 --- a/winsup/cygwin/fork.cc +++ b/winsup/cygwin/fork.cc @@ -13,7 +13,6 @@ details. */ #include <unistd.h> #include <stdlib.h> #include <stdarg.h> -#include <errno.h> #include "security.h" #include "path.h" #include "fhandler.h" @@ -237,14 +236,7 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls) /* Restore the inheritance state as in parent Don't call setuid here! The flags are already set. */ - if (cygheap->user.impersonated) - { - debug_printf ("Impersonation of child, token: %d", cygheap->user.token); - if (cygheap->user.token == INVALID_HANDLE_VALUE) - RevertToSelf (); // probably not needed - else if (!ImpersonateLoggedOnUser (cygheap->user.token)) - system_printf ("Impersonate for forked child failed: %E"); - } + cygheap->user.reimpersonate (); sync_with_parent ("after longjmp.", TRUE); sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d", hParent, @@ -306,8 +298,10 @@ fork_child (HANDLE& hParent, dll *&first_dll, bool& load_dlls) (void) ForceCloseHandle1 (fork_info->subproc_ready, subproc_ready); (void) ForceCloseHandle1 (fork_info->forker_finished, forker_finished); +#ifdef USE_CYGSERVER if (fixup_shms_after_fork ()) api_fatal ("recreate_shm areas after fork failed"); +#endif pinfo_fixup_after_fork (); signal_fixup_after_fork (); @@ -437,8 +431,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, si.cbReserved2 = sizeof (ch); /* Remove impersonation */ - if (cygheap->user.issetuid ()) - RevertToSelf (); + cygheap->user.deimpersonate (); ch.parent = hParent; #ifdef DEBUGGING @@ -486,8 +479,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, ForceCloseHandle (subproc_ready); ForceCloseHandle (forker_finished); /* Restore impersonation */ - if (cygheap->user.issetuid ()) - ImpersonateLoggedOnUser (cygheap->user.token); + cygheap->user.reimpersonate (); cygheap_setup_for_child_cleanup (newheap, &ch, 0); return -1; } @@ -514,8 +506,7 @@ fork_parent (HANDLE& hParent, dll *&first_dll, strcpy (forked->progname, myself->progname); /* Restore impersonation */ - if (cygheap->user.issetuid ()) - ImpersonateLoggedOnUser (cygheap->user.token); + cygheap->user.reimpersonate (); ProtectHandle (pi.hThread); /* Protect the handle but name it similarly to the way it will diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index f4df758..6e34a3a 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -16,7 +16,6 @@ details. */ #include <wininet.h> #include <stdio.h> #include <stdlib.h> -#include <errno.h> #include "pinfo.h" #include "security.h" #include "path.h" @@ -262,7 +261,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) { /* If impersonated, use impersonation token. */ if (cygheap->user.issetuid ()) - hToken = cygheap->user.token; + hToken = cygheap->user.token (); else if (!OpenProcessToken (hMainProc, TOKEN_QUERY, &hToken)) hToken = NULL; } @@ -296,7 +295,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) ++cnt; if (gidsetsize && cnt > gidsetsize) { - if (hToken != cygheap->user.token) + if (!cygheap->user.issetuid ()) CloseHandle (hToken); goto error; } @@ -306,7 +305,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid) } else debug_printf ("%d = GetTokenInformation(NULL) %E", size); - if (hToken != cygheap->user.token) + if (!cygheap->user.issetuid ()) CloseHandle (hToken); return cnt; } diff --git a/winsup/cygwin/heap.cc b/winsup/cygwin/heap.cc index ae8a9d0..d6f0452 100644 --- a/winsup/cygwin/heap.cc +++ b/winsup/cygwin/heap.cc @@ -9,7 +9,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include <errno.h> #include "cygerrno.h" #include "sigproc.h" #include "pinfo.h" diff --git a/winsup/cygwin/include/cygwin/config.h b/winsup/cygwin/include/cygwin/config.h index 77815a0..e3e09f0 100644 --- a/winsup/cygwin/include/cygwin/config.h +++ b/winsup/cygwin/include/cygwin/config.h @@ -19,6 +19,7 @@ extern "C" { #endif #define _CYGWIN_CONFIG_H +#define __DYNAMIC_REENT__ #define __FILENAME_MAX__ (260 - 1 /* NUL */) #define _READ_WRITE_RETURN_TYPE _ssize_t #define __LARGE64_FILES 1 diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index cd49fa5..13657a0 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -205,12 +205,15 @@ details. */ underscore. No problems with backward compatibility since no official release has been made so far. This change removes exported symbols like fopen64, which might confuse configure. + 86: Export ftok + 87: Export vsyslog + 88: Export _getreent */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 85 +#define CYGWIN_VERSION_API_MINOR 88 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible diff --git a/winsup/cygwin/include/sys/syslog.h b/winsup/cygwin/include/sys/syslog.h index f319517..a37b042 100644 --- a/winsup/cygwin/include/sys/syslog.h +++ b/winsup/cygwin/include/sys/syslog.h @@ -12,6 +12,8 @@ details. */ #define _SYS_LOG_H #include <sys/cdefs.h> +#include <stdarg.h> + #define LOG_EMERG 0 #define LOG_ALERT 1 #define LOG_CRIT 2 @@ -76,6 +78,7 @@ void closelog (void); void openlog (const char *, int, int); int setlogmask (int); void syslog (int, const char *, ...); +void vsyslog (int, const char *, va_list ap); __END_DECLS diff --git a/winsup/cygwin/ioctl.cc b/winsup/cygwin/ioctl.cc index 5d9ec87..3991790 100644 --- a/winsup/cygwin/ioctl.cc +++ b/winsup/cygwin/ioctl.cc @@ -13,7 +13,6 @@ details. */ #include "winsup.h" #include <sys/ioctl.h> -#include <errno.h> #include "cygerrno.h" #include "security.h" #include "path.h" diff --git a/winsup/cygwin/malloc_wrapper.cc b/winsup/cygwin/malloc_wrapper.cc index 9841cd5..5798cf4 100644 --- a/winsup/cygwin/malloc_wrapper.cc +++ b/winsup/cygwin/malloc_wrapper.cc @@ -18,7 +18,6 @@ details. */ #include "path.h" #include "fhandler.h" #include "dtable.h" -#include <errno.h> #include "cygerrno.h" #include "cygheap.h" #include "heap.h" diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index 6cf8cc7..08f89c8 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -13,7 +13,6 @@ details. */ #include <stdlib.h> #include <stddef.h> #include <sys/mman.h> -#include <errno.h> #include "security.h" #include "path.h" #include "fhandler.h" @@ -272,7 +271,8 @@ public: void erase (int i); void erase (); mmap_record *match (_off64_t off, DWORD len); - long match (caddr_t addr, DWORD len, long start); + long match (caddr_t addr, DWORD len, caddr_t &m_addr, DWORD &m_len, + long start); }; list::list () @@ -325,13 +325,24 @@ list::match (_off64_t off, DWORD len) /* Used in munmap() */ long -list::match (caddr_t addr, DWORD len, _off_t start) +list::match (caddr_t addr, DWORD len, caddr_t &m_addr, DWORD &m_len, + _off_t start) { + caddr_t low, high; + for (int i = start + 1; i < nrecs; ++i) - if (addr >= recs[i].get_address () - && addr + len <= recs[i].get_address () - + (PAGE_CNT (recs[i].get_size ()) * getpagesize ())) - return i; + { + low = (addr >= recs[i].get_address ()) ? addr : recs[i].get_address (); + high = recs[i].get_address () + + (PAGE_CNT (recs[i].get_size ()) * getpagesize ()); + high = (addr + len < high) ? addr + len : high; + if (low < high) + { + m_addr = low; + m_len = high - low; + return i; + } + } return -1; } @@ -440,7 +451,7 @@ mmap64 (caddr_t addr, size_t len, int prot, int flags, int fd, _off64_t off) if (off % getpagesize () || (!(flags & MAP_SHARED) && !(flags & MAP_PRIVATE)) || ((flags & MAP_SHARED) && (flags & MAP_PRIVATE)) - || ((flags & MAP_FIXED) && ((DWORD)addr % granularity)) + || ((flags & MAP_FIXED) && ((DWORD)addr % getpagesize ())) || !len) { set_errno (EINVAL); @@ -471,8 +482,6 @@ mmap64 (caddr_t addr, size_t len, int prot, int flags, int fd, _off64_t off) DWORD gran_len = howmany (off + len, granularity) * granularity - gran_off; fhandler_base *fh; - caddr_t base = addr; - HANDLE h; if (fd != -1) { @@ -490,6 +499,16 @@ mmap64 (caddr_t addr, size_t len, int prot, int flags, int fd, _off64_t off) DWORD high; DWORD low = GetFileSize (fh->get_handle (), &high); _off64_t fsiz = ((_off64_t)high << 32) + low; + /* Don't allow mappings beginning beyond EOF since Windows can't + handle that POSIX like. FIXME: Still looking for a good idea + to allow that nevertheless. */ + if (gran_off >= fsiz) + { + set_errno (ENXIO); + ReleaseResourceLock (LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK, + "mmap"); + return MAP_FAILED; + } fsiz -= gran_off; if (gran_len > fsiz) gran_len = fsiz; @@ -542,7 +561,13 @@ mmap64 (caddr_t addr, size_t len, int prot, int flags, int fd, _off64_t off) && (wincap.has_working_copy_on_write () || fd != -1)) access = FILE_MAP_COPY; - h = fh->mmap (&base, gran_len, access, flags, gran_off); + caddr_t base = addr; + /* This shifts the base address to the next lower 64K boundary. + The offset is re-added when evaluating the return value. */ + if (base) + base -= off - gran_off; + + HANDLE h = fh->mmap (&base, gran_len, access, flags, gran_off); if (h == INVALID_HANDLE_VALUE) { @@ -589,16 +614,16 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, _off_t off) return mmap64 (addr, len, prot, flags, fd, (_off64_t)off); } -/* munmap () removes an mmapped area. It insists that base area - requested is the same as that mmapped, error if not. */ +/* munmap () removes all mmapped pages between addr and addr+len. */ extern "C" int munmap (caddr_t addr, size_t len) { syscall_printf ("munmap (addr %x, len %d)", addr, len); - /* Error conditions according to SUSv2 */ - if (((DWORD)addr % getpagesize ()) || !len) + /* Error conditions according to SUSv3 */ + if (!addr || ((DWORD)addr % getpagesize ()) || !len + || IsBadReadPtr (addr, len)) { set_errno (EINVAL); syscall_printf ("-1 = munmap(): Invalid parameters"); @@ -606,17 +631,15 @@ munmap (caddr_t addr, size_t len) } SetResourceLock (LOCK_MMAP_LIST, WRITE_LOCK | READ_LOCK, "munmap"); - /* Check if a mmap'ed area was ever created */ if (mmapped_areas == NULL) { syscall_printf ("-1 = munmap(): mmapped_areas == NULL"); - set_errno (EINVAL); ReleaseResourceLock (LOCK_MMAP_LIST, WRITE_LOCK | READ_LOCK, "munmap"); - return -1; + return 0; } - /* Iterate through the map, looking for the mmapped area. - Error if not found. */ + /* Iterate through the map, unmap pages between addr and addr+len + in all maps. */ for (int it = 0; it < mmapped_areas->nlists; ++it) { @@ -624,10 +647,13 @@ munmap (caddr_t addr, size_t len) if (map_list) { long li = -1; - if ((li = map_list->match(addr, len, li)) >= 0) + caddr_t u_addr; + DWORD u_len; + + while ((li = map_list->match(addr, len, u_addr, u_len, li)) >= 0) { mmap_record *rec = map_list->recs + li; - if (rec->unmap_map (addr, len)) + if (rec->unmap_map (u_addr, u_len)) { fhandler_base *fh = rec->alloc_fh (); fh->munmap (rec->get_handle (), addr, len); @@ -636,18 +662,13 @@ munmap (caddr_t addr, size_t len) /* Delete the entry. */ map_list->erase (li); } - syscall_printf ("0 = munmap(): %x", addr); - ReleaseResourceLock (LOCK_MMAP_LIST, WRITE_LOCK | READ_LOCK, "munmap"); - return 0; } } } - set_errno (EINVAL); - syscall_printf ("-1 = munmap(): EINVAL"); - ReleaseResourceLock (LOCK_MMAP_LIST, WRITE_LOCK | READ_LOCK, "munmap"); - return -1; + syscall_printf ("0 = munmap(): %x", addr); + return 0; } /* Sync file with memory. Ignore flags for now. */ @@ -815,9 +836,15 @@ fhandler_disk_file::mmap (caddr_t *addr, size_t len, DWORD access, } DWORD high = off >> 32, low = off & 0xffffffff; - void *base = MapViewOfFileEx (h, access, high, low, len, - (flags & MAP_FIXED) ? *addr : NULL); - debug_printf ("%x = MapViewOfFileEx (h:%x, access:%x, 0, off:%D, len:%d, addr:%x)", base, h, access, off, len, (flags & MAP_FIXED) ? *addr : NULL); + void *base = NULL; + /* If a non-zero address is given, try mapping using the given address first. + If it fails and flags is not MAP_FIXED, try again with NULL address. */ + if (*addr) + base = MapViewOfFileEx (h, access, high, low, len, *addr); + if (!base && !(flags & MAP_FIXED)) + base = MapViewOfFileEx (h, access, high, low, len, NULL); + debug_printf ("%x = MapViewOfFileEx (h:%x, access:%x, 0, off:%D, " + "len:%d, addr:%x)", base, h, access, off, len, *addr); if (!base || ((flags & MAP_FIXED) && base != *addr)) { if (!base) diff --git a/winsup/cygwin/msg.cc b/winsup/cygwin/msg.cc index c76fd8e..fecaa06 100644 --- a/winsup/cygwin/msg.cc +++ b/winsup/cygwin/msg.cc @@ -15,7 +15,6 @@ details. */ #include <sys/types.h> #include <cygwin/msg.h> -#include <errno.h> #include "cygerrno.h" diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index fc4f548..1d1abab 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -13,7 +13,6 @@ details. */ #define __INSIDE_CYGWIN_NET__ #include "winsup.h" -#include <errno.h> #include <ctype.h> #include <sys/socket.h> #include <sys/un.h> @@ -1288,20 +1287,39 @@ getdomainname (char *domain, size_t len) if (__check_null_invalid_struct_errno (domain, len)) return -1; + PFIXED_INFO info = NULL; + ULONG size = 0; + + if (GetNetworkParams(info, &size) == ERROR_BUFFER_OVERFLOW + && (info = (PFIXED_INFO) alloca(size)) + && GetNetworkParams(info, &size) == ERROR_SUCCESS) + { + strncpy(domain, info->DomainName, len); + return 0; + } + + /* This is only used by Win95 and NT <= 4.0. + The registry names are language independent. + FIXME: Handle DHCP on Win95. The DhcpDomain(s) may be available + in ..VxD\DHCP\DhcpInfoXX\OptionInfo, RFC 1533 format */ + reg_key r (HKEY_LOCAL_MACHINE, KEY_READ, (!wincap.is_winnt ()) ? "System" : "SYSTEM", "CurrentControlSet", "Services", (!wincap.is_winnt ()) ? "VxD" : "Tcpip", (!wincap.is_winnt ()) ? "MSTCP" : "Parameters", NULL); - /* FIXME: Are registry keys case sensitive? */ - if (r.error () || r.get_string ("Domain", domain, len, "") != ERROR_SUCCESS) + if (!r.error ()) { - __seterrno (); - return -1; + int res1, res2 = 0; /* Suppress compiler warning */ + res1 = r.get_string ("Domain", domain, len, ""); + if (res1 != ERROR_SUCCESS || !domain[0]) + res2 = r.get_string ("DhcpDomain", domain, len, ""); + if (res1 == ERROR_SUCCESS || res2 == ERROR_SUCCESS) + return 0; } - - return 0; + __seterrno (); + return -1; } /* Fill out an ifconf struct. */ @@ -1972,7 +1990,10 @@ cygwin_rcmd (char **ahost, unsigned short inport, char *locuser, cygheap_fdnew res_fd; if (res_fd >= 0 && fdsock (res_fd, tcp_dev, res)) - res = res_fd; + { + ((fhandler_socket *) res_fd)->set_connect_state (CONNECTED); + res = res_fd; + } else { closesocket (res); @@ -1985,7 +2006,10 @@ cygwin_rcmd (char **ahost, unsigned short inport, char *locuser, cygheap_fdget fd (*fd2p); if (newfd >= 0 && fdsock (newfd, tcp_dev, fd2s)) - *fd2p = newfd; + { + *fd2p = newfd; + ((fhandler_socket *) fd2p)->set_connect_state (CONNECTED); + } else { closesocket (res); @@ -2048,7 +2072,10 @@ cygwin_rexec (char **ahost, unsigned short inport, char *locuser, cygheap_fdnew res_fd; if (res_fd >= 0 && fdsock (res_fd, tcp_dev, res)) - res = res_fd; + { + ((fhandler_socket *) res_fd)->set_connect_state (CONNECTED); + res = res_fd; + } else { closesocket (res); @@ -2061,7 +2088,10 @@ cygwin_rexec (char **ahost, unsigned short inport, char *locuser, cygheap_fdget fd (*fd2p); if (newfd >= 0 && fdsock (newfd, tcp_dev, fd2s)) - *fd2p = newfd; + { + ((fhandler_socket *) fd2p)->set_connect_state (CONNECTED); + *fd2p = newfd; + } else { closesocket (res); @@ -2234,6 +2264,7 @@ socketpair (int family, int type, int protocol, int *sb) ((fhandler_socket *) sb0)->set_sun_path (""); ((fhandler_socket *) sb0)->set_addr_family (family); ((fhandler_socket *) sb0)->set_socket_type (type); + ((fhandler_socket *) sb0)->set_connect_state (CONNECTED); cygheap_fdnew sb1 (sb0, false); @@ -2242,6 +2273,7 @@ socketpair (int family, int type, int protocol, int *sb) ((fhandler_socket *) sb1)->set_sun_path (""); ((fhandler_socket *) sb1)->set_addr_family (family); ((fhandler_socket *) sb1)->set_socket_type (type); + ((fhandler_socket *) sb1)->set_connect_state (CONNECTED); sb[0] = sb0; sb[1] = sb1; diff --git a/winsup/cygwin/ntea.cc b/winsup/cygwin/ntea.cc index 7ddff77..4841a4c 100644 --- a/winsup/cygwin/ntea.cc +++ b/winsup/cygwin/ntea.cc @@ -16,7 +16,7 @@ details. */ #include "security.h" /* Default to not using NTEA information */ -BOOL allow_ntea; +bool allow_ntea; /* From Windows NT DDK: diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc index 38876d2..01e9a6b 100644 --- a/winsup/cygwin/passwd.cc +++ b/winsup/cygwin/passwd.cc @@ -12,7 +12,6 @@ details. */ #include <stdlib.h> #include <pwd.h> #include <stdio.h> -#include <errno.h> #include "cygerrno.h" #include "security.h" #include "path.h" diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 60856f2..8947be7 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -53,7 +53,6 @@ details. */ #include <sys/mount.h> #include <mntent.h> #include <unistd.h> -#include <errno.h> #include <ctype.h> #include <winioctl.h> #include <wingdi.h> @@ -208,7 +207,7 @@ normalize_posix_path (const char *src, char *dst) syscall_printf ("src %s", src); - if (isdrive (src) || strpbrk (src, "\\:")) + if (isdrive (src)) { int err = normalize_win32_path (src, dst); if (!err && isdrive (dst)) @@ -513,7 +512,7 @@ path_conv::check (const char *src, unsigned opt, /* Scan path_copy from right to left looking either for a symlink or an actual existing file. If an existing file is found, just - return. If a symlink is found exit the for loop. + return. If a symlink is found, exit the for loop. Also: be careful to preserve the errno returned from symlink.check as the caller may need it. */ /* FIXME: Do we have to worry about multiple \'s here? */ @@ -1151,10 +1150,99 @@ set_flags (unsigned *flags, unsigned val) } } +char special_chars[] = + "\001" "\002" "\003" "\004" "\005" "\006" "\007" "\010" + "\011" "\012" "\013" "\014" "\015" "\016" "\017" "\020" + "\021" "\022" "\023" "\024" "\025" "\026" "\027" "\030" + "\031" "\032" "\033" "\034" "\035" "\036" "\037" + ":" "\\" "*" "?" "%" + "A" "B" "C" "D" "E" "F" "G" "H" + "I" "J" "K" "L" "M" "N" "O" "P" + "Q" "R" "S" "T" "U" "V" "W" "X" + "Y" "Z"; + +static inline char +special_char (const char *s) +{ + char *p = strechr (special_chars, *s); + if (*p == '%' && strlen (p) >= 3) + { + char hex[] = {s[1], s[2], '\0'}; + unsigned char c = strtoul (hex, &p, 16); + p = strechr (special_chars, c); + } + return *p; +} + +bool +fnunmunge (char *dst, const char *src) +{ + bool converted = false; + char c; + + while (*src) + if (*src != '%' || !(c = special_char (src))) + *dst++ = *src++; + else + { + converted = true; + *dst++ = c; + src += 3; + } + + *dst = *src; + return converted; +} + +/* Determines if name is "special". Assumes that name is empty or "absolute" */ +static int +special_name (const char *s) +{ + if (!*s) + return false; + + if (strpbrk (++s, special_chars)) + return !strncasematch (s, "%2f", 3); + + if (strcasematch (s, "nul") + || strcasematch (s, "aux") + || strcasematch (s, "prn")) + return -1; + if (!strncasematch (s, "com", 3) + && !strncasematch (s, "lpt", 3)) + return false; + char *p; + (void) strtol (s, &p, 10); + return -(*p == '\0'); +} + void mount_item::fnmunge (char *dst, const char *src) { - strcpy (dst, src); + int name_type; + if (!(flags & MOUNT_ENC) || !(name_type = special_name (src))) + strcpy (dst, src); + else + { + char *d = dst; + *d++ = *src++; + if (name_type < 0) + { + __small_sprintf (d, "%%%02x", (unsigned char) *src++); + d += 3; + } + + while (*src) + if (!special_char (src)) + *d++ = *src++; + else + { + __small_sprintf (d, "%%%02x", (unsigned char) *src++); + d += 3; + } + *d = *src; + } + backslashify (dst, dst, 0); } @@ -1181,7 +1269,7 @@ mount_item::build_win32 (char *dst, const char *src, unsigned *outflags, unsigne const char *p = src + real_posix_pathlen; if (*p == '/') /* nothing */; - else if ((isdrive (dst) && !dst[2]) || *p) + else if ((!(flags & MOUNT_ENC) && isdrive (dst) && !dst[2]) || *p) dst[n++] = '\\'; fnmunge (dst + n, p); } @@ -1234,22 +1322,6 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, if (dst == NULL) goto out; /* Sanity check. */ - /* An MS-DOS spec has either a : or a \. If this is found, short - circuit most of the rest of this function. */ - if (strpbrk (src_path, ":\\") != NULL || slash_unc_prefix_p (src_path)) - { - debug_printf ("%s already win32", src_path); - rc = normalize_win32_path (src_path, dst); - if (rc) - { - debug_printf ("normalize_win32_path failed, rc %d", rc); - return rc; - } - - set_flags (flags, (unsigned) set_flags_from_win32_path (dst)); - goto out; - } - /* Normalize the path, taking out ../../ stuff, we need to do this so that we can move from one mounted directory to another with relative stuff. @@ -1349,16 +1421,21 @@ mount_info::conv_to_win32_path (const char *src_path, char *dst, device& dev, break; } - if (i >= nmounts) + if (i < nmounts) { - backslashify (pathbuf, dst, 0); /* just convert */ - set_flags (flags, PATH_BINARY); - chroot_ok = !cygheap->root.exists (); + mi->build_win32 (dst, pathbuf, flags, chroot_pathlen); + chroot_ok = true; } else { - mi->build_win32 (dst, pathbuf, flags, chroot_pathlen); - chroot_ok = true; + if (strpbrk (src_path, ":\\") != NULL || slash_unc_prefix_p (src_path)) + rc = normalize_win32_path (src_path, dst); + else + { + backslashify (pathbuf, dst, 0); /* just convert */ + set_flags (flags, PATH_BINARY); + } + chroot_ok = !cygheap->root.exists (); } if (!isvirtual_dev (dev.devn)) @@ -1522,6 +1599,12 @@ mount_info::conv_to_posix_path (const char *src_path, char *posix_path, const char *p = cygheap->root.unchroot (posix_path); memmove (posix_path, p, strlen (p) + 1); } + if (mi.flags & MOUNT_ENC) + { + char tmpbuf[MAX_PATH + 1]; + if (fnunmunge (tmpbuf, posix_path)) + strcpy (posix_path, tmpbuf); + } goto out; } @@ -1656,10 +1739,16 @@ mount_info::from_registry () /* FIXME: Need a mutex to avoid collisions with other tasks. */ int -mount_info::add_reg_mount (const char * native_path, const char * posix_path, unsigned mountflags) +mount_info::add_reg_mount (const char *native_path, const char *posix_path, unsigned mountflags) { int res = 0; + if (strchr (posix_path, '\\')) + { + set_errno (EINVAL); + goto err1; + } + /* Add the mount to the right registry location, depending on whether MOUNT_SYSTEM is set in the mount flags. */ if (!(mountflags & MOUNT_SYSTEM)) /* current_user mount */ @@ -1710,6 +1799,7 @@ mount_info::add_reg_mount (const char * native_path, const char * posix_path, un return 0; /* Success */ err: __seterrno_from_win_error (res); + err1: return -1; } @@ -2175,6 +2265,8 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags) strcat (_reent_winsup ()->mnt_opts, (char *) ",exec"); else if (flags & MOUNT_NOTEXEC) strcat (_reent_winsup ()->mnt_opts, (char *) ",noexec"); + if (flags & MOUNT_ENC) + strcat (_reent_winsup ()->mnt_opts, ",managed"); if ((flags & MOUNT_CYGDRIVE)) /* cygdrive */ strcat (_reent_winsup ()->mnt_opts, (char *) ",noumount"); @@ -2259,7 +2351,9 @@ mount (const char *win32_path, const char *posix_path, unsigned flags) { int res = -1; - if (flags & MOUNT_CYGDRIVE) /* normal mount */ + if (strpbrk (posix_path, "\\:")) + set_errno (EINVAL); + else if (flags & MOUNT_CYGDRIVE) /* normal mount */ { /* When flags include MOUNT_CYGDRIVE, take this to mean that we actually want to change the cygdrive prefix and flags @@ -3162,7 +3256,7 @@ chdir (const char *in_dir) return -1; } - const char *native_dir = path.get_win32 (); + const char *native_dir = path; /* Check to see if path translates to something like C:. If it does, append a \ to the native directory specification to diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 9275bef..3f4fe34 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -59,6 +59,7 @@ enum path_types PATH_EXEC = MOUNT_EXEC, PATH_NOTEXEC = MOUNT_NOTEXEC, PATH_CYGWIN_EXEC = MOUNT_CYGWIN_EXEC, + PATH_ENC = MOUNT_ENC, PATH_ALL_EXEC = (PATH_CYGWIN_EXEC | PATH_EXEC), PATH_LNK = 0x01000000, PATH_TEXT = 0x02000000, @@ -108,6 +109,7 @@ class path_conv 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;} + bool isencoded () {return path_flags & PATH_ENC;} int binmode () const { if (path_flags & PATH_BINARY) @@ -242,6 +244,8 @@ 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))); +bool fnunmunge (char *, const char *) __attribute__ ((regparm (2))); + int path_prefix_p (const char *path1, const char *path2, int len1) __attribute__ ((regparm (3))); /* FIXME: Move to own include file eventually */ diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index bd07e48..e7eeb43 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -11,7 +11,6 @@ details. */ #include "winsup.h" #include <stdlib.h> #include <time.h> -#include <errno.h> #include <limits.h> #include <stdarg.h> #include "security.h" @@ -361,7 +360,7 @@ _pinfo::commune_send (DWORD code, ...) res.s = NULL; res.n = 0; - if (!pid || !this) + if (!pid || !this || (dwProcessId != (DWORD) pid && !pinfo (myself->dwProcessId))) { set_errno (ESRCH); goto err; diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index 50f5a4d..a1e99b2 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -12,7 +12,6 @@ details. */ #include "winsup.h" #include <unistd.h> -#include <errno.h> #include <sys/socket.h> #include "cygerrno.h" #include "security.h" diff --git a/winsup/cygwin/poll.cc b/winsup/cygwin/poll.cc index 35d02a8..da650ff 100644 --- a/winsup/cygwin/poll.cc +++ b/winsup/cygwin/poll.cc @@ -10,11 +10,11 @@ #define __INSIDE_CYGWIN_NET__ +#define FD_SETSIZE 16384 // lots of fds #include "winsup.h" #include <sys/time.h> #include <sys/poll.h> #include <sys/socket.h> -#include <errno.h> #include <stdlib.h> #define USE_SYS_TYPES_FD_SET #include <winsock2.h> diff --git a/winsup/cygwin/resource.cc b/winsup/cygwin/resource.cc index 01e065b..e87702b 100644 --- a/winsup/cygwin/resource.cc +++ b/winsup/cygwin/resource.cc @@ -13,7 +13,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include <errno.h> #include <unistd.h> #include <limits.h> #include "cygerrno.h" diff --git a/winsup/cygwin/scandir.cc b/winsup/cygwin/scandir.cc index 52a36ea..a2f682a 100644 --- a/winsup/cygwin/scandir.cc +++ b/winsup/cygwin/scandir.cc @@ -13,7 +13,6 @@ #include "winsup.h" #include <dirent.h> #include <stdlib.h> -#include <errno.h> #include "cygerrno.h" extern "C" int diff --git a/winsup/cygwin/sched.cc b/winsup/cygwin/sched.cc index 99c7391..b29d7a4 100644 --- a/winsup/cygwin/sched.cc +++ b/winsup/cygwin/sched.cc @@ -16,7 +16,6 @@ #include "winsup.h" #include <limits.h> -#include <errno.h> #include "cygerrno.h" #include <assert.h> #include <stdlib.h> diff --git a/winsup/cygwin/sec_acl.cc b/winsup/cygwin/sec_acl.cc index f712361..c358910 100644 --- a/winsup/cygwin/sec_acl.cc +++ b/winsup/cygwin/sec_acl.cc @@ -15,7 +15,6 @@ details. */ #include <pwd.h> #include <unistd.h> #include <stdlib.h> -#include <errno.h> #include <limits.h> #include <sys/types.h> #include <sys/stat.h> diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc index b50a4c8..3869a60 100644 --- a/winsup/cygwin/sec_helper.cc +++ b/winsup/cygwin/sec_helper.cc @@ -15,7 +15,6 @@ details. */ #include <pwd.h> #include <unistd.h> #include <stdlib.h> -#include <errno.h> #include <limits.h> #include <sys/types.h> #include <sys/stat.h> diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 98cb376..47f7c33 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -16,7 +16,6 @@ details. */ #include <pwd.h> #include <unistd.h> #include <stdlib.h> -#include <errno.h> #include <limits.h> #include <sys/types.h> #include <sys/stat.h> @@ -41,12 +40,11 @@ details. */ #include "lm.h" #include "pwdgrp.h" -extern BOOL allow_ntea; -BOOL allow_ntsec; +bool allow_ntsec; /* allow_smbntsec is handled exclusively in path.cc (path_conv::check). It's defined here because of it's strong relationship to allow_ntsec. The default is TRUE to reflect the old behaviour. */ -BOOL allow_smbntsec; +bool allow_smbntsec; cygsid * cygsidlist::alloc_sids (int n) @@ -71,10 +69,16 @@ extern "C" void cygwin_set_impersonation_token (const HANDLE hToken) { debug_printf ("set_impersonation_token (%d)", hToken); - if (cygheap->user.token != hToken) + if (cygheap->user.impersonation_state == IMP_EXTERNAL + && cygheap->user.external_token != hToken) { - cygheap->user.token = hToken; - cygheap->user.impersonated = FALSE; + set_errno (EPERM); + return; + } + else + { + cygheap->user.external_token = hToken; + return; } } @@ -718,7 +722,7 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, BOOL *pintern) if (pintern) { TOKEN_SOURCE ts; - if (!GetTokenInformation (cygheap->user.token, TokenSource, + if (!GetTokenInformation (token, TokenSource, &ts, sizeof ts, &size)) debug_printf ("GetTokenInformation(): %E"); else @@ -1907,7 +1911,7 @@ check_file_access (const char *fn, int flags) goto done; if (cygheap->user.issetuid ()) - hToken = cygheap->user.token; + hToken = cygheap->user.token (); else if (!OpenProcessToken (hMainProc, TOKEN_DUPLICATE, &hToken)) { __seterrno (); @@ -1915,7 +1919,7 @@ check_file_access (const char *fn, int flags) } if (!(status = DuplicateToken (hToken, SecurityIdentification, &hIToken))) __seterrno (); - if (hToken != cygheap->user.token) + if (!cygheap->user.issetuid ()) CloseHandle (hToken); if (!status) goto done; diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 2965b1d..71ffe4c 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -209,9 +209,9 @@ legal_sid_type (SID_NAME_USE type) || type == SidTypeAlias || type == SidTypeWellKnownGroup; } -extern BOOL allow_ntea; -extern BOOL allow_ntsec; -extern BOOL allow_smbntsec; +extern bool allow_ntea; +extern bool allow_ntsec; +extern bool allow_smbntsec; /* File manipulation */ int __stdcall set_process_privileges (); diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index 6c8a5b4..48cb56c 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -20,7 +20,6 @@ details. */ #define __INSIDE_CYGWIN_NET__ #include "winsup.h" -#include <errno.h> #include <sys/socket.h> #include <stdlib.h> #include <sys/time.h> diff --git a/winsup/cygwin/sem.cc b/winsup/cygwin/sem.cc index 63aba8e..97d91a3 100644 --- a/winsup/cygwin/sem.cc +++ b/winsup/cygwin/sem.cc @@ -15,7 +15,6 @@ details. */ #include <sys/types.h> #include <cygwin/sem.h> -#include <errno.h> #include "cygerrno.h" diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc index c91e380..1f11458 100644 --- a/winsup/cygwin/shared.cc +++ b/winsup/cygwin/shared.cc @@ -14,7 +14,6 @@ details. */ #include <stdlib.h> #include <grp.h> #include <pwd.h> -#include <errno.h> #include "pinfo.h" #include "security.h" #include "path.h" diff --git a/winsup/cygwin/shm.cc b/winsup/cygwin/shm.cc index 618cac1..1221298 100644 --- a/winsup/cygwin/shm.cc +++ b/winsup/cygwin/shm.cc @@ -12,11 +12,10 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" - +#ifdef USE_CYGSERVER #include <sys/types.h> #include <assert.h> -#include <errno.h> #include <stdio.h> #include <unistd.h> @@ -691,3 +690,4 @@ client_request_shm::client_request_shm (const key_t key, msglen (sizeof (_parameters.in)); } +#endif /* USE_CYGSERVER */ diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 547a128..0530fcf 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -12,7 +12,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include <errno.h> #include <stdlib.h> #include "cygerrno.h" #include <sys/cygwin.h> @@ -297,8 +296,8 @@ abort (void) be flushed. However this is the way FreeBSD does it, and it is much easier to do things this way, so... */ - if (_reent_clib ()->__cleanup) - _reent_clib ()->__cleanup (_reent_clib ()); + if (_REENT->__cleanup) + _REENT->__cleanup (_REENT); /* Ensure that SIGABRT can be caught regardless of blockage. */ sigset_t sig_mask; diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index dafaad8..3237acc 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -14,7 +14,6 @@ details. */ #include <stdlib.h> #include <time.h> #include <sys/wait.h> -#include <errno.h> #include <stdlib.h> #include <sys/cygwin.h> #include <assert.h> diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 850536c..fe4efba 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -14,7 +14,6 @@ details. */ #include <unistd.h> #include <process.h> #include <sys/wait.h> -#include <errno.h> #include <limits.h> #include <wingdi.h> #include <winuser.h> @@ -622,7 +621,16 @@ spawn_guts (const char * prog_arg, const char *const *argv, cygbench ("spawn-guts"); cygheap->fdtab.set_file_pointers_for_exec (); - if (!cygheap->user.issetuid ()) + cygheap->user.deimpersonate (); + /* When ruid != euid we create the new process under the current original + account and impersonate in child, this way maintaining the different + effective vs. real ids. + FIXME: If ruid != euid and ruid != orig_uid we currently give + up on ruid. The new process will have ruid == euid. */ + if (!cygheap->user.issetuid () + || (cygheap->user.orig_uid == cygheap->user.real_uid + && cygheap->user.orig_gid == cygheap->user.real_gid + && !cygheap->user.groups.issetgroups ())) { PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf); ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc, @@ -646,8 +654,6 @@ spawn_guts (const char * prog_arg, const char *const *argv, /* Set security attributes with sid */ PSECURITY_ATTRIBUTES sec_attribs = sec_user_nih (sa_buf, sid); - RevertToSelf (); - /* Load users registry hive. */ load_registry_hive (sid); @@ -671,7 +677,7 @@ spawn_guts (const char * prog_arg, const char *const *argv, ciresrv.moreinfo->envp = build_env (envp, envblock, ciresrv.moreinfo->envc, real_path.iscygexec ()); newheap = cygheap_setup_for_child (&ciresrv, cygheap->fdtab.need_fixup_before ()); - rc = CreateProcessAsUser (cygheap->user.token, + rc = CreateProcessAsUser (cygheap->user.token (), runpath, /* image name - with full path */ one_line.buf, /* what was passed to exec */ sec_attribs, /* process security attrs */ @@ -682,11 +688,11 @@ spawn_guts (const char * prog_arg, const char *const *argv, 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) - ImpersonateLoggedOnUser (cygheap->user.token); } + /* Restore impersonation. In case of _P_OVERLAY this isn't + allowed since it would overwrite child data. */ + if (mode != _P_OVERLAY) + cygheap->user.reimpersonate (); MALLOC_CHECK; if (envblock) diff --git a/winsup/cygwin/strace.cc b/winsup/cygwin/strace.cc index 283f019..57ad3ba 100644 --- a/winsup/cygwin/strace.cc +++ b/winsup/cygwin/strace.cc @@ -14,7 +14,6 @@ details. */ #include <wingdi.h> #include <winuser.h> #include <ctype.h> -#include <errno.h> #include "pinfo.h" #include "perprocess.h" #include "cygwin_version.h" diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 5625f1a..91b533f 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -29,7 +29,6 @@ details. */ #include <process.h> #include <utmp.h> #include <sys/uio.h> -#include <errno.h> #include <limits.h> #include <unistd.h> #include <setjmp.h> @@ -1539,8 +1538,6 @@ getpagesize () static int check_posix_perm (const char *fname, int v) { - extern int allow_ntea, allow_ntsec, allow_smbntsec; - /* Windows 95/98/ME don't support file system security at all. */ if (!wincap.has_security ()) return 0; @@ -2123,66 +2120,52 @@ seteuid32 (__uid32_t uid) sigframe thisframe (mainthread); cygsid usersid; user_groups &groups = cygheap->user.groups; - HANDLE ptok, sav_token; - BOOL sav_impersonated, sav_token_is_internal_token; - BOOL process_ok, explicitly_created_token = FALSE; + HANDLE ptok, new_token = INVALID_HANDLE_VALUE; struct passwd * pw_new; PSID origpsid, psid2 = NO_SID; + enum impersonation new_state = IMP_BAD; + BOOL token_is_internal; pw_new = internal_getpwuid (uid); if (!wincap.has_security () && pw_new) - goto success; + goto success_9x; if (!usersid.getfrompw (pw_new)) { set_errno (EINVAL); return -1; } - /* Save current information */ - sav_token = cygheap->user.token; - sav_impersonated = cygheap->user.impersonated; RevertToSelf (); if (!OpenProcessToken (hMainProc, TOKEN_QUERY | TOKEN_ADJUST_DEFAULT, &ptok)) { __seterrno (); - goto failed; + goto failed_ptok;; } - /* 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, groups); - debug_printf ("Process token %sverified", process_ok ? "" : "not "); - if (process_ok) + + /* Verify if the process token is suitable. */ + if (verify_token (ptok, usersid, groups)) + new_state = IMP_NONE; + /* Verify if a current token is suitable */ + else if (cygheap->user.external_token + && verify_token (cygheap->user.external_token, usersid, groups)) { - if (cygheap->user.issetuid ()) - cygheap->user.impersonated = FALSE; - else - { - CloseHandle (ptok); - goto success; /* No change */ - } + new_token = cygheap->user.external_token; + new_state = IMP_EXTERNAL; + } + else if (cygheap->user.internal_token + && verify_token (cygheap->user.internal_token, usersid, groups, + &token_is_internal)) + { + new_token = cygheap->user.internal_token; + new_state = IMP_INTERNAL; } - if (!process_ok && cygheap->user.token != INVALID_HANDLE_VALUE) + debug_printf ("New token %d, state %d", new_token, new_state); + /* Return if current token is valid */ + if (cygheap->user.impersonation_state == new_state) { - /* Verify if the current tokem is suitable */ - BOOL token_ok = verify_token (cygheap->user.token, usersid, groups, - &sav_token_is_internal_token); - debug_printf ("Thread token %d %sverified", - cygheap->user.token, token_ok?"":"not "); - if (!token_ok) - cygheap->user.token = INVALID_HANDLE_VALUE; - else - { - /* Return if current token is valid */ - if (cygheap->user.impersonated) - { - CloseHandle (ptok); - if (!ImpersonateLoggedOnUser (cygheap->user.token)) - system_printf ("Impersonating in seteuid failed: %E"); - goto success; /* No change */ - } - } + cygheap->user.reimpersonate (); + goto success; /* No change */ } /* Set process def dacl to allow access to impersonated token */ @@ -2198,72 +2181,72 @@ seteuid32 (__uid32_t uid) debug_printf ("SetTokenInformation" "(TokenDefaultDacl): %E"); } - CloseHandle (ptok); - if (!process_ok && cygheap->user.token == INVALID_HANDLE_VALUE) + if (new_state == IMP_BAD) { /* If no impersonation token is available, try to authenticate using NtCreateToken () or subauthentication. */ - cygheap->user.token = create_token (usersid, groups, pw_new); - if (cygheap->user.token != INVALID_HANDLE_VALUE) - explicitly_created_token = TRUE; - else + new_token = create_token (usersid, groups, pw_new); + if (new_token == INVALID_HANDLE_VALUE) { /* 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) + new_token = subauth (pw_new); + if (new_token == INVALID_HANDLE_VALUE) goto failed; } + new_state = IMP_INTERNAL; } /* If using the token, set info and impersonate */ - if (!process_ok) + if (new_state != IMP_NONE) { /* If the token was explicitly created, all information has already been set correctly. */ - if (!explicitly_created_token) + if (new_state == IMP_EXTERNAL) { /* Try setting owner to same value as user. */ - if (!SetTokenInformation (cygheap->user.token, TokenOwner, + if (!SetTokenInformation (new_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, + if (!SetTokenInformation (new_token, TokenPrimaryGroup, &groups.pgsid, sizeof (cygsid))) debug_printf ("SetTokenInformation(user.token, " "TokenPrimaryGroup): %E"); } - /* Now try to impersonate. */ - if (!ImpersonateLoggedOnUser (cygheap->user.token)) + /* Try to impersonate. */ + if (!ImpersonateLoggedOnUser (new_token)) { debug_printf ("ImpersonateLoggedOnUser %E"); __seterrno (); goto failed; } - cygheap->user.impersonated = TRUE; + /* Keep at most one internal token */ + if (new_state == IMP_INTERNAL) + { + if (cygheap->user.internal_token) + CloseHandle (cygheap->user.internal_token); + cygheap->user.internal_token = new_token; + } } - - /* 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); cygheap->user.set_sid (usersid); + success: + CloseHandle (ptok); + cygheap->user.impersonation_state = new_state; +success_9x: cygheap->user.set_name (pw_new->pw_name); myself->uid = uid; groups.ischanged = FALSE; return 0; failed: - cygheap->user.token = sav_token; - cygheap->user.impersonated = sav_impersonated; - if (cygheap->user.issetuid () - && !ImpersonateLoggedOnUser (cygheap->user.token)) - system_printf ("Impersonating in seteuid failed: %E"); + CloseHandle (ptok); +failed_ptok: + cygheap->user.reimpersonate (); return -1; } @@ -2344,7 +2327,7 @@ setegid32 (__gid32_t gid) /* If impersonated, update primary group and revert */ if (cygheap->user.issetuid ()) { - if (!SetTokenInformation (cygheap->user.token, + if (!SetTokenInformation (cygheap->user.token (), TokenPrimaryGroup, &gsid, sizeof gsid)) debug_printf ("SetTokenInformation(thread, " @@ -2362,7 +2345,7 @@ setegid32 (__gid32_t gid) CloseHandle (ptok); } if (cygheap->user.issetuid () - && !ImpersonateLoggedOnUser (cygheap->user.token)) + && !ImpersonateLoggedOnUser (cygheap->user.token ())) system_printf ("Impersonating in setegid failed: %E"); return 0; } diff --git a/winsup/cygwin/sysconf.cc b/winsup/cygwin/sysconf.cc index 608f187..55eaa8c 100644 --- a/winsup/cygwin/sysconf.cc +++ b/winsup/cygwin/sysconf.cc @@ -10,7 +10,6 @@ details. */ #include "winsup.h" #include <unistd.h> -#include <errno.h> #include <time.h> #include <limits.h> #include <ntdef.h> diff --git a/winsup/cygwin/syslog.cc b/winsup/cygwin/syslog.cc index cf3931f..f8b1714 100644 --- a/winsup/cygwin/syslog.cc +++ b/winsup/cygwin/syslog.cc @@ -14,7 +14,6 @@ details. */ #include <syslog.h> #include <stdarg.h> #include <unistd.h> -#include <errno.h> #include "security.h" #include "path.h" #include "fhandler.h" @@ -208,7 +207,7 @@ pass_handler::print_va (const char *fmt, va_list list) */ extern "C" void -syslog (int priority, const char *message, ...) +vsyslog (int priority, const char *message, va_list ap) { debug_printf ("%x %s", priority, message); /* If the priority fails the current mask, reject */ @@ -281,8 +280,6 @@ syslog (int priority, const char *message, ...) output, then do it again to a malloc'ed string. This is ugly, slow, but prevents core dumps :-). */ - va_list ap; - pass_handler pass; for (int pass_number = 0; pass_number < 2; ++pass_number) { @@ -341,10 +338,8 @@ syslog (int priority, const char *message, ...) } /* Print out the variable part */ - va_start (ap, message); if (pass.print_va (message, ap) == -1) return; - va_end (ap); } const char *msg_strings[1]; @@ -409,6 +404,15 @@ syslog (int priority, const char *message, ...) } extern "C" void +syslog (int priority, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + vsyslog (priority, message, ap); + va_end (ap); +} + +extern "C" void closelog (void) { ; diff --git a/winsup/cygwin/termios.cc b/winsup/cygwin/termios.cc index 99019b8..ebc0657 100644 --- a/winsup/cygwin/termios.cc +++ b/winsup/cygwin/termios.cc @@ -12,7 +12,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include <errno.h> #include <signal.h> #include <stdlib.h> #include "cygerrno.h" diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 0321ea4..b42bb14 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -29,7 +29,6 @@ details. */ # include "config.h" #endif -#ifdef _MT_SAFE #include "winsup.h" #include <limits.h> #include "cygerrno.h" @@ -45,16 +44,21 @@ details. */ extern int threadsafe; -struct _reent * -_reent_clib () +extern "C" struct _reent * +__getreent () { struct __reent_t *_r = (struct __reent_t *) MT_INTERFACE->reent_key.get (); -#ifdef _CYG_THREAD_FAILSAFE if (_r == 0) - system_printf ("local thread storage not inited"); + { +#ifdef _CYG_THREAD_FAILSAFE + system_printf ("local thread storage not inited"); #endif + /* Return _impure_ptr as long as MTinterface is not initialized */ + return _impure_ptr; + } + return _r->_clib; } @@ -64,10 +68,14 @@ _reent_winsup () struct __reent_t *_r = (struct __reent_t *) MT_INTERFACE->reent_key.get (); -#ifdef _CYG_THREAD_FAILSAFE if (_r == 0) - system_printf ("local thread storage not inited"); + { +#ifdef _CYG_THREAD_FAILSAFE + system_printf ("local thread storage not inited"); #endif + return NULL; + } + return _r->_winsup; } @@ -212,9 +220,24 @@ MTinterface::fixup_after_fork (void) { pthread_key::fixup_after_fork (); +#ifndef __SIGNALS_ARE_MULTITHREADED__ + /* As long as the signal handling not multithreaded + switch reents storage back to _impure_ptr for the mainthread + to support fork from threads other than the mainthread */ + struct _reent *reent_old = __getreent (); + + if (reent_old && _impure_ptr != reent_old) + *_impure_ptr = *reent_old; + reents._clib = _impure_ptr; + reents._winsup = &winsup_reent; + winsup_reent._process_logmask = LOG_UPTO (LOG_DEBUG); + reent_key.set (&reents); +#endif + threadcount = 1; pthread::init_mainthread (); + pthread::fixup_after_fork (); pthread_mutex::fixup_after_fork (); pthread_cond::fixup_after_fork (); pthread_rwlock::fixup_after_fork (); @@ -261,11 +284,16 @@ pthread::get_tls_self_pointer () +List<pthread> pthread::threads; + /* member methods */ pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0), + running (false), suspended (false), cancelstate (0), canceltype (0), cancel_event (0), - joiner (NULL), cleanup_stack (NULL) + joiner (NULL), next (NULL), cleanup_stack (NULL) { + if (this != pthread_null::get_null_pthread ()) + threads.insert (this); } pthread::~pthread () @@ -274,6 +302,9 @@ pthread::~pthread () CloseHandle (win32_obj_id); if (cancel_event) CloseHandle (cancel_event); + + if (this != pthread_null::get_null_pthread ()) + threads.remove (this); } void @@ -347,13 +378,15 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr, void pthread::postcreate () { - InterlockedIncrement (&MT_INTERFACE->threadcount); - /* FIXME: set the priority appropriately for system contention scope */ - if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED) - { - /* FIXME: set the scheduling settings for the new thread */ - /* sched_thread_setparam (win32_obj_id, attr.schedparam); */ - } + running = true; + + InterlockedIncrement (&MT_INTERFACE->threadcount); + /* FIXME: set the priority appropriately for system contention scope */ + if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED) + { + /* FIXME: set the scheduling settings for the new thread */ + /* sched_thread_setparam (win32_obj_id, attr.schedparam); */ + } } void @@ -372,6 +405,7 @@ pthread::exit (void *value_ptr) delete this; else { + running = false; return_ptr = value_ptr; mutex.unlock (); } @@ -390,6 +424,12 @@ pthread::cancel (void) mutex.lock (); + if (!running) + { + mutex.unlock (); + return 0; + } + if (canceltype == PTHREAD_CANCEL_DEFERRED || cancelstate == PTHREAD_CANCEL_DISABLE) { @@ -739,6 +779,19 @@ pthread::init_current_thread () set_tls_self_pointer (this); } +void +pthread::_fixup_after_fork () +{ + /* set thread to not running if it is not the forking thread */ + if (this != pthread::self ()) + { + magic = 0; + running = false; + win32_obj_id = NULL; + cancel_event = NULL; + } +} + /* static members */ bool pthread_attr::is_good_object (pthread_attr_t const *attr) @@ -1964,14 +2017,15 @@ pthread::atfork (void (*prepare)(void), void (*parent)(void), void (*child)(void extern "C" int pthread_attr_init (pthread_attr_t *attr) { - if (check_valid_pointer (attr)) - return EINVAL; + if (pthread_attr::is_good_object (attr)) + return EBUSY; + *attr = new pthread_attr; if (!pthread_attr::is_good_object (attr)) { delete (*attr); *attr = NULL; - return EAGAIN; + return ENOMEM; } return 0; } @@ -2187,7 +2241,7 @@ pthread::detach (pthread_t *thread) } // check if thread is still alive - if (WaitForSingleObject ((*thread)->win32_obj_id, 0) == WAIT_TIMEOUT) + if ((*thread)->running && WaitForSingleObject ((*thread)->win32_obj_id, 0) == WAIT_TIMEOUT) { // force cleanup on exit (*thread)->joiner = *thread; @@ -2488,14 +2542,15 @@ pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) extern "C" int pthread_condattr_init (pthread_condattr_t *condattr) { - if (check_valid_pointer (condattr)) - return EINVAL; + if (pthread_condattr::is_good_object (condattr)) + return EBUSY; + *condattr = new pthread_condattr; if (!pthread_condattr::is_good_object (condattr)) { delete (*condattr); *condattr = NULL; - return EAGAIN; + return ENOMEM; } return 0; } @@ -2673,14 +2728,15 @@ pthread_rwlock_unlock (pthread_rwlock_t *rwlock) extern "C" int pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr) { - if (check_valid_pointer (rwlockattr)) - return EINVAL; + if (pthread_rwlockattr::is_good_object (rwlockattr)) + return EBUSY; + *rwlockattr = new pthread_rwlockattr; if (!pthread_rwlockattr::is_good_object (rwlockattr)) { delete (*rwlockattr); *rwlockattr = NULL; - return EAGAIN; + return ENOMEM; } return 0; } @@ -3172,5 +3228,3 @@ pthread_null::getsequence_np () } pthread_null pthread_null::_instance; - -#endif // MT_SAFE diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index 55d9415..ea1f13f 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -110,7 +110,6 @@ struct __reent_t struct _winsup_t *_winsup; }; -_reent *_reent_clib (); _winsup_t *_reent_winsup (); void SetResourceLock (int, int, const char *) __attribute__ ((regparm (3))); void ReleaseResourceLock (int, int, const char *) @@ -386,11 +385,11 @@ public: void *(*function) (void *); void *arg; void *return_ptr; + bool running; bool suspended; int cancelstate, canceltype; HANDLE cancel_event; pthread_t joiner; - // int joinable; /* signal handling */ struct sigaction *sigs; @@ -443,11 +442,21 @@ public: return t1 == t2; } + /* List support calls */ + class pthread *next; + static void fixup_after_fork () + { + threads.for_each (&pthread::_fixup_after_fork); + } + private: + static List<pthread> threads; DWORD thread_id; __pthread_cleanup_handler *cleanup_stack; pthread_mutex mutex; + void _fixup_after_fork (); + void pop_all_cleanup_handlers (void); void precreate (pthread_attr *); void postcreate (); diff --git a/winsup/cygwin/times.cc b/winsup/cygwin/times.cc index 87b8c85..44a0883 100644 --- a/winsup/cygwin/times.cc +++ b/winsup/cygwin/times.cc @@ -15,7 +15,6 @@ details. */ #include <utime.h> #include <stdio.h> #include <stdlib.h> -#include <errno.h> #include "cygerrno.h" #include "security.h" #include "path.h" diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index 01d3f52..f13a96f 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -9,7 +9,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ #include "winsup.h" -#include <errno.h> #include <unistd.h> #include <utmp.h> #include <wingdi.h> @@ -409,11 +408,16 @@ tty::common_init (fhandler_pty_master *ptym) */ if (wincap.has_security ()) { +#ifdef USE_CYGSERVER if (cygserver_running == CYGSERVER_UNKNOWN) cygserver_init (); +#endif - if (cygserver_running != CYGSERVER_OK - && !SetKernelObjectSecurity (hMainProc, + if ( +#ifdef USE_CYGSERVER + cygserver_running != CYGSERVER_OK && +#endif + !SetKernelObjectSecurity (hMainProc, DACL_SECURITY_INFORMATION, get_null_sd ())) system_printf ("Can't set process security, %E"); diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc index b74cd16..8c16ac6 100644 --- a/winsup/cygwin/uinfo.cc +++ b/winsup/cygwin/uinfo.cc @@ -17,7 +17,6 @@ details. */ #include <limits.h> #include <stdlib.h> #include <lm.h> -#include <errno.h> #include <sys/cygwin.h> #include "pinfo.h" #include "security.h" @@ -103,18 +102,28 @@ internal_getlogin (cygheap_user &user) void uinfo_init () { - if (!child_proc_info || cygheap->user.token != INVALID_HANDLE_VALUE) + if (child_proc_info && !cygheap->user.has_impersonation_tokens ()) + return; + + if (!child_proc_info) + internal_getlogin (cygheap->user); /* Set the cygheap->user. */ + /* Conditions must match those in spawn to allow starting child + processes with ruid != euid and rgid != egid. */ + else if (cygheap->user.issetuid () + && cygheap->user.orig_uid == cygheap->user.real_uid + && cygheap->user.orig_gid == cygheap->user.real_gid + && !cygheap->user.groups.issetgroups ()) { - if (!child_proc_info) - internal_getlogin (cygheap->user); /* Set the cygheap->user. */ - else - CloseHandle (cygheap->user.token); - cygheap->user.set_orig_sid (); /* Update the original sid */ - cygheap->user.token = INVALID_HANDLE_VALUE; /* No token present */ + cygheap->user.reimpersonate (); + return; } - /* Real and effective uid/gid are identical on process start up. */ + else + cygheap->user.close_impersonation_tokens (); + cygheap->user.orig_uid = cygheap->user.real_uid = myself->uid; cygheap->user.orig_gid = cygheap->user.real_gid = myself->gid; + cygheap->user.impersonation_state = IMP_NONE; + cygheap->user.set_orig_sid (); /* Update the original sid */ } extern "C" char * diff --git a/winsup/cygwin/wait.cc b/winsup/cygwin/wait.cc index 3b6427a..fd78278 100644 --- a/winsup/cygwin/wait.cc +++ b/winsup/cygwin/wait.cc @@ -11,7 +11,6 @@ details. */ #include "winsup.h" #include <sys/wait.h> #include <stdlib.h> -#include <errno.h> #include "cygerrno.h" #include "sigproc.h" #include "perthread.h" diff --git a/winsup/cygwin/window.cc b/winsup/cygwin/window.cc index bdcb450..ea9ed6e 100644 --- a/winsup/cygwin/window.cc +++ b/winsup/cygwin/window.cc @@ -13,7 +13,6 @@ details. */ #include "winsup.h" #include <sys/time.h> #include <stdlib.h> -#include <errno.h> #include <signal.h> #include <limits.h> #include <wingdi.h> diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index 092f502..fc9de77 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -98,6 +98,8 @@ extern int dynamically_loaded; extern int cygserver_running; +#define _MT_SAFE // DELTEME someday + #define TITLESIZE 1024 /* status bit manipulation */ @@ -197,7 +199,6 @@ extern int cygwin_finished_initializing; void __stdcall set_std_handle (int); int __stdcall writable_directory (const char *file); int __stdcall stat_dev (DWORD, int, unsigned long, struct __stat64 *); -extern BOOL allow_ntsec; __ino64_t __stdcall hash_path_name (__ino64_t hash, const char *name) __attribute__ ((regparm(2))); void __stdcall nofinalslash (const char *src, char *dst) __attribute__ ((regparm(2))); @@ -292,7 +293,7 @@ extern SYSTEM_INFO system_info; /* The title on program start. */ extern char *old_title; -extern BOOL display_title; +extern bool display_title; extern HANDLE hMainThread; extern HANDLE hMainProc; |