2014-11-07 Corinna Vinschen <corinna@vinschen.de>
* dcrt0.cc (cygwin__cxa_atexit): Fetch correct DSO handle value by searching dll list. Explain why. 2014-11-06 Corinna Vinschen <corinna@vinschen.de> * dcrt0.cc (cygwin_atexit): Change preceeding comment to reflect API version numbers. * external.cc (cygwin_internal): disable setting cxx_malloc on 64 bit. Add CW_FIXED_ATEXIT case. * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump. * include/sys/cygwin.h (cygwin_getinfo_types): Add CW_FIXED_ATEXIT. * lib/atexit.c (atexit): Test running Cygwin version by checking return value of cygwin_internal (CW_FIXED_ATEXIT). 2014-11-05 Corinna Vinschen <corinna@vinschen.de> * lib/atexit.c (atexit): Check for being linked into the executable. If so, call __cxa_atexit with NULL DSO handle. Explain why. * lib/dso_handle.c: New file providing fallback __dso_handle. 2014-11-05 Corinna Vinschen <corinna@vinschen.de> * Makefile.in (NEW_FUNCTIONS): Add atexit to be not exported. * lib/atexit.c (atexit): New, statically linkable version of atexit. * dcrt0.cc (cygwin_atexit): Add comment to mark this function as old entry point. Indiscriminately check for DSO of function pointer for all functions, if checking for DSO of return address fails on x86_64. Change comment accordingly. 2014-11-05 Corinna Vinschen <corinna@vinschen.de> * Makefile.in (NEW_FUNCTIONS): Define target-independent. Add target dependent stuff afterwards. Globally define timezone and all xdr symbols as non-exported from libcygwin.a. 2014-11-03 Corinna Vinschen <corinna@vinschen.de> * cygheap.cc: Fix formatting. 2014-10-29 Corinna Vinschen <corinna@vinschen.de> * cygheap.cc (init_cygheap::init_installation_root): Create content of installation_dir as non-prefixed path, if possible. 2014-10-29 Corinna Vinschen <corinna@vinschen.de> * common.din (__cxa_atexit): Define as cygwin__cxa_atexit. * dcrt0.cc (cygwin__cxa_atexit): New function. Explain what we do. 2014-10-28 Corinna Vinschen <corinna@vinschen.de> * globals.cc (dos_file_warning): Set to false by default. * path.cc (warn_msdos): Make static. Drop test for dos_file_warning. (path_conv::check): Check for dos_file_warning here to avoid a function call in the default case. 2014-10-27 Corinna Vinschen <corinna@vinschen.de> * dcrt0.cc (cygwin_atexit): Add workaround for broken atexit calls in __gcc_register_frame of DLLs built with gcc-4.8.3-3. 2014-10-27 Corinna Vinschen <corinna@vinschen.de> * cygheap.cc (init_cygheap::init_installation_root): Set installation_dir_len. * cygheap.h (struct init_cygheap): Add installation_dir_len member. * environ.cc (win_env::add_cache): Use stpcpy for speed. (posify_maybe): Use tmp_pathbuf buffer instead of stack. (raise_envblock): New function to resize Windows environment block. (build_env): Fix indentation. Call raise_envblock function. Check if $PATH exists and is non-empty. If not, add PATH variable with Cygwin installation directory as content to Windows environment. Explain why. 2014-10-24 Corinna Vinschen <corinna@vinschen.de> * fhandler_proc.cc (format_proc_cygdrive): Fix symlink path if cygdrive is "/". 2014-10-24 Corinna Vinschen <corinna@vinschen.de> * gendef (sigdelayed): 64 bit only: Fix seh_pushreg statements in prologue. 2014-10-22 Yaakov Selkowitz <yselkowi@redhat.com> * common.din (stime): Export. * times.cc (stime): New function. * include/cygwin/time.h (stime): Declare. * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump. 2014-10-20 Corinna Vinschen <corinna@vinschen.de> * fhandler_serial.cc: Revert debug code accidentally checked in on 2014-08-18. 2014-10-20 Corinna Vinschen <corinna@vinschen.de> * path.cc (symlink_info::check): Set error from status code if opening the parent directory failed, but keep special case for root dirs. 2014-10-17 Corinna Vinschen <corinna@vinschen.de> * cygheap.cc (init_cygheap::init_installation_root): Just memmove contents of installation_root instead of calling GetModuleFileNameW again. Copy installation_root to installation_dir before stripping of "bin" dir. Explain what we do. * cygheap.h (struct init_cygheap): Add installation_dir member. 2014-10-17 Corinna Vinschen <corinna@vinschen.de> * cygtls.h (__try): Define __l_endtry as block-local label in 32 bit case as well. 2014-10-17 Corinna Vinschen <corinna@vinschen.de> * Makefile.in (DLL_OFILES): Add quotactl.o. * common.din (quotactl): Export. * ntdll.h: Define FILE_FS_CONTROL_INFORMATION::FileSystemControlFlags flag values. (struct _FILE_FS_CONTROL_INFORMATION): Define. (struct _FILE_GET_QUOTA_INFORMATION): Define. (typedef struct _FILE_QUOTA_INFORMATION): Define. (NtQueryObject): Use PVOID rather than VOID*. (NtQueryVolumeInformationFile): Ditto. (NtQueryQuotaInformationFile): Declare. (NtSetQuotaInformationFile): Declare. (NtSetVolumeInformationFile): Declare. * quotactl.cc: New file implementing quotactl(). * include/sys/mount.h (BLOCK_SIZE): Define. (BLOCK_SIZE_BITS): Define. * include/sys/quota.h: New header. * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump. 2014-10-16 Corinna Vinschen <corinna@vinschen.de> * Makefile.in (DLL_OFILES): Rearrange with one file per line. 2014-10-16 Corinna Vinschen <corinna@vinschen.de> * fhandler_proc.cc (format_proc_partitions): Extend output to print the windows mount points the device is mounted on. 2014-10-13 Corinna Vinschen <corinna@vinschen.de> * net.cc (cygwin_setsockopt): Drop redundant test for AF_LOCAL and SOCK_STREAM in SO_PEERCRED case, as in the original patch. 2014-10-12 Corinna Vinschen <corinna@vinschen.de> * dlfcn.cc (gfpod_helper): Only check for POSIX dir separator, same as in get_full_path_of_dll. 2014-10-12 Corinna Vinschen <corinna@vinschen.de> * dlfcn.cc (set_dl_error): Drop useless __stdcall. (check_path_access): Ditto. Drop FE_CWD from call to find_exec. (gfpod_helper): Call path_conv::check for all paths containing a dir separator to more closely follow the Linux search algorithm. (get_full_path_of_dll): Drop useless __stdcall. (dlopen): Simplify RTLD_NOLOAD case by calling GetModuleHandleEx instead of GetModuleHandle/LoadLibrary. 2014-10-11 Christian Franke <franke@computer.org> Add setsockopt(sd, SOL_SOCKET, SO_PEERCRED, NULL, 0) to disable initial handshake on AF_LOCAL sockets. * fhandler.h (class fhandler_socket): Add no_getpeereid status flag. (fhandler_socket::af_local_set_no_getpeereid): New prototype. * fhandler_socket.cc (fhandler_socket::af_local_connect): Skip handshake if no_getpeereid is set. Add debug output. (fhandler_socket::af_local_accept): Likewise. (fhandler_socket::af_local_set_no_getpeereid): New function. (fhandler_socket::af_local_copy): Copy no_getpeereid. (fhandler_socket::getpeereid): Fail if no_getpeereid is set. * net.cc (cygwin_setsockopt): Add SO_PEERCRED for AF_LOCAL/SOCK_STREAM sockets. Add comment to explain why we need it. * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump. 2014-10-10 Corinna Vinschen <corinna@vinschen.de> * dlfcn.cc (dlopen): Disable old 32 bit code on 64 bit. * dcrt0.cc (check_sanity_and_sync): Ditto. * dll_init.cc (dll_dllcrt0_1): Fix typo in comment. 2014-10-08 Corinna Vinschen <corinna@vinschen.de> * common.din (ffsl): Export. (ffsll): Export. * syscalls.cc (ffs): Implement using GCC intrinsic. (ffsl): Ditto. (ffsll): Ditto. * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump. 2014-10-08 Christian Franke <franke@computer.org> * syscalls.cc (ffs): Fix crash of ffs (0x80000000) on 64 bit. 2014-10-08 Corinna Vinschen <corinna@vinschen.de> * fhandler_process.cc (format_process_statm): Fix output of dirty pages. Add linefeed. 2014-09-05 Corinna Vinschen <corinna@vinschen.de> * fhandler_proc.cc (proc_tab): Add entry for cygdrive symlink. (format_proc_cygdrive): New function to implement /proc/cygdrive. 2014-09-05 Corinna Vinschen <corinna@vinschen.de> * exception.h (class exception): Remove unnecessary #ifdef. 2014-09-05 Corinna Vinschen <corinna@vinschen.de> * winlean.h (DNLEN): Raise to 31. Explain why. 2014-08-28 Corinna Vinschen <corinna@vinschen.de> * fhandler_disk_file.cc (fhandler_disk_file::fstatvfs): Try the FileFsSizeInformation information class on filesystems choking on FileFsFullSizeInformation (I see you Netapp!) 2014-08-27 Corinna Vinschen <corinna@vinschen.de> * fhandler.h (fhandler_pty_slave::fch_open_handles): Add bool parameter to declaration. * fhandler_tty.cc (fhandler_pty_slave::fch_open_handles): Add bool parameter "chown". Only request WRITE_OWNER access when opening pty synchronization objects if "chown" is set. (fhandler_pty_slave::fchmod): Call fch_open_handles with new bool parameter set to false. (fhandler_pty_slave::fchown): Call fch_open_handles with new bool parameter set to true. * kernel32.cc (CreateFileMappingW): Fix default standard rights for file mappings from READ_CONTROL to STANDARD_RIGHTS_REQUIRED to allow changing the DACL (fixes "access denied" error in pinfo::set_acl). * fhandler_disk_file.cc (fhandler_base::fstat_helper): Change debug output to print mode bits in octal. * security.cc (alloc_sd): Ditto. (set_file_attribute): Ditto. 2014-08-27 Corinna Vinschen <corinna@vinschen.de> * ntea.cc (read_ea): Change left-over return to __leave. Fix condition to close handle. Call NtClose rather than CloseHandle. (write_ea): Fix condition to close handle. Call NtClose rather than CloseHandle. * security.cc (get_file_sd): Call pc.init_reopen_attr if a valid incoming handle was given, pc.get_object_attr otherwise. (set_file_sd): Ditto. 2014-08-26 Corinna Vinschen <corinna@vinschen.de> * path.h (path_conv::init_reopen_attr): Change from void to returning POBJECT_ATTRIBUTES. Take OBJECT_ATTRIBUTES reference as argument, not pointer. * fhandler_disk_file.cc: Throughout accommodate above change. * syscalls.cc: Ditto. * ntea.cc (read_ea): Don't set hdl to NULL if it's already NULL. Set attr with pc.init_reopen_attr before trying to reopen file. (write_ea): Ditto. * security.cc (get_file_sd): Use pc.init_reopen_attr rather than pc.get_object_attr when trying to reopen file. (set_file_sd): Ditto. 2014-08-25 Corinna Vinschen <corinna@vinschen.de> * cygtls.cc (san::leave/x86_64): Implement. * cygtls.h (class tls_pathbuf): Move counter variables into a union. Add 64 bit element _counters covering both counter variables to optimize save and restore operations. (class san/x86_64): Only store single 64 bit value. (san::san/x86_64): Implement. (san::leave/x86_64): Only declare here, as returns_twice function. Explain why. (class san/i686): Change type of _c_cnt and _w_cnt to uint32_t. (__try/x86_64): Move definition of __sebastian after the first memory barrier. Drop __sebastian.setup call. 2014-08-25 Corinna Vinschen <corinna@vinschen.de> * cygtls.cc (_cygtls::remove): Revert previous patch. * cygtls.h (struct _local_storage): Move pathbufs back here. (class san/x86_64): Revert class. Save and restore pathbufs counters only. (class san/i686): Revert saving and restoring pathbufs counters. (__try/x86_64): Add a san variable and call it's setup method. (__except/x86_64): Call san::leave to restore pathbufs counters. * gendef (_sigbe): Revert previous change. * thread.cc (verifyable_object_state): Remove gcc 4.7 workaround in forward declaration as well. * tls_pbuf.cc (tls_pbuf): Revert previous change. * tls_pbuf.h (class tmp_pathbuf): Accommodate reverting pathbufs to locals structure. * tlsoffsets.h: Regenerate. * tlsoffsets64.h: Regenerate. 2014-08-21 Corinna Vinschen <corinna@vinschen.de> * Throughout, use __try/__except/__endtry blocks, rather than myfault handler. * cygtls.cc (_cygtls::remove): Accommodate the fact that pathbufs has been moved from _local_storage to _cygtls. * cygtls.h (class tls_pathbuf): Add comment to hint to gendef usage of counters. Change type of counters to uint32_t for clarity. Remove _cygtls as friend class. (struct _local_storage): Move pathbufs from here... (struct _cygtls): ...to here, allowing to access it from _sigbe. (class san): Only define on 32 bit. Remove errno, _c_cnt and _w_cnt members. (san::setup): Drop parameter. Don't initialize removed members. (san::leave): Don't set removed members. (class myfault): Only define on 32 bit. (myfault::faulted): Only keep implementation not taking any parameter. Drop argument in call to sebastian.setup. (__try/__leave/__except/__endtry): Implement to support real SEH. For now stick to SJLJ on 32 bit. * dcrt0.cc (dll_crt0_0): Drop 64 bit call to exception::install_myfault_handler. * exception.h (exception_handler): Define with EXCEPTION_DISPOSITION as return type. (PDISPATCHER_CONTEXT): Define as void * on 32 bit. Define as pointer to _DISPATCHER_CONTEXT on 64 bit. (class exception): Define separately for 32 and 64 bit. (exception::myfault): Add handler for myfault SEH handling on 64 bit. (exception::exception): Fix mangled method name to account for change in type of last parameter. (exception::install_myfault_handler): Remove. * exceptions.cc (exception::myfault_handle): Remove. (exception::myfault): New SEH handler for 64 bit. * gendef (_sigbe): Set tls_pathbuf counters to 0 explicitely when returning to the caller. * ntdll.h: Move a comment to a better place. (struct _SCOPE_TABLE): Define on 64 bit. * thread.cc (verifyable_object_isvalid): Remove gcc 4.7 workaround. * tls_pbuf.cc (tls_pbuf): Fix to accommodate new place of pathbufs. (tls_pathbuf::destroy): Change type of loop variables to uint32_t. * tls_pbuf.h (class tmp_pathbuf): Change type of buffer counters to uint32_t. Accommodate new place of pathbufs. * tlsoffsets.h: Regenerate. * tlsoffsets64.h: Regenerate. 2014-08-21 Corinna Vinschen <corinna@vinschen.de> * miscfuncs.cc (__import_address): Cover the first dereference to imp under the fault handler. 2014-08-21 Corinna Vinschen <corinna@vinschen.de> * net.cc (if_freenameindex): Don't catch a SEGV from free to fail loudly on double free. 2014-08-21 Corinna Vinschen <corinna@vinschen.de> * dir.cc (rmdir): Don't skip deleting fh in the ENOTEMPTY case. 2014-08-20 Corinna Vinschen <corinna@vinschen.de> * tls_pbuf.h (tmp_pathbuf::tmp_pathbuf): Convert to inline method. (tmp_pathbuf::~tmp_pathbuf): Ditto. * tls_pbuf.cc (tmp_pathbuf::tmp_pathbuf): Remove here. (tmp_pathbuf::~tmp_pathbuf): Ditto. 2014-08-19 Corinna Vinschen <corinna@vinschen.de> * dir.cc (dirfd): Per POSIX, return EINVAL on invalid directory stream. (telldir): Per POSIX, return -1 and set errno to EBADF, rather than just returning 0, on invalid directory stream. * signal.cc (sigwaitinfo): Return -1, not EFAULT, when SEGV was catched. 2014-08-19 Corinna Vinschen <corinna@vinschen.de> * autoload.cc: Replace WNet[...]A with WNet[...]W imports. * dcrt0.cc (initial_env): Drop strlwr calls. Call strcasestr instead. * fhandler_netdrive.cc: Throughout, convert to calling WNet UNICODE functions. Use tmp_pathbuf rather than alloca. Replace call to strlwr with call to RtlDowncaseUnicodeString. 2014-08-19 Corinna Vinschen <corinna@vinschen.de> * fhandler.h (fhandler_serial::is_tty): Reinstantiate. 2014-08-18 Corinna Vinschen <corinna@vinschen.de> * miscfuncs.cc (strlwr): Rename from cygwin_strlwr. Drop __stdcall decoration. (strupr): Rename from cygwin_strupr. Drop __stdcall decoration. * string.h (strlwr): Remove override macro. Simply declare. (strupr): Ditto. 2014-08-18 Corinna Vinschen <corinna@vinschen.de> * dtable.cc (dtable::init_std_file_from_handle): Mention that console handles are kernel objects since Windows 8. * fhandler.h (enum conn_state): Add "listener" state. (class fhandler_socket): Drop listener status flag. (fhandler_socket::lseek): Return -1 and errno ESPIPE. (fhandler_serial::lseek): Ditto. (fhandler_serial::is_tty): Remove. * fhandler_socket.cc (fhandler_socket::listen): Set connect_state to listener. Add comment. (fhandler_socket::accept4): Explicitely check if the socket is listening and fail with EINVAL, if not. Explain why we have to do that. (fhandler_socket::getpeereid): Drop now redundant test. 2014-08-15 Corinna Vinschen <corinna@vinschen.de> * winsup.h (_GNU_SOURCE): Define. Explain why. 2014-08-14 Corinna Vinschen <corinna@vinschen.de> * dlmalloc.c: Remove unused file. * dlmalloc.h: Ditto. * malloc.cc: Update to Doug Lea's malloc version 2.8.6. 2014-08-13 Corinna Vinschen <corinna@vinschen.de> * include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 33. (CYGWIN_VERSION_API_MINOR): Bump to reflect intermediate 1.7.32 release. 2014-07-21 Corinna Vinschen <corinna@vinschen.de> * include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 32. 2014-05-06 Corinna Vinschen <corinna@vinschen.de> * winlean.h (PIPE_REJECT_REMOTE_CLIENTS): Drop temporary definition since Mingw64 catched up. (DNLEN): Redefine as 16. Explain why. 2014-03-06 Corinna Vinschen <corinna@vinschen.de> * setlsapwd.cc (setlsapwd): Use RtlSecureZeroMemory to delete password from memory. 2014-11-05 Corinna Vinschen <corinna@vinschen.de> * new-features.xml (ov-new1.7.33): Document atexit. 2014-10-28 Corinna Vinschen <corinna@vinschen.de> * cygwinenv.xml: Change default setting of dosfilewarning. * new-features.xml (ov-new1.7.33): Document aforementioned change. 2014-10-27 Corinna Vinschen <corinna@vinschen.de> * new-features.xml (ov-new1.7.33): Document empty $PATH handling. 2014-10-22 Corinna Vinschen <corinna@vinschen.de> * posix.xml (std-gnu): Add ffsl, ffsll, quotactl. (std-notes): Add restrictions of quotactl. 2014-10-22 Yaakov Selkowitz <yselkowi@redhat.com> * new-features.xml (ov-new1.7.33): Document stime. * posix.xml (std-deprec): Add stime. 2014-10-22 Corinna Vinschen <corinna@vinschen.de> * new-features.xml (ov-new1.7.33): s/Linux/glibc. 2014-10-22 Corinna Vinschen <corinna@vinschen.de> * new-features.xml (ov-new1.7.33): Update to current state. 2014-08-13 Corinna Vinschen <corinna@vinschen.de> * new-features.xml (ov-new1.7.33): Add new section. (ov-new1.7.32): Reflect intermediate 1.7.32 release. 2014-10-21 Corinna Vinschen <corinna@vinschen.de> * cygcheck.cc (CYGLSA64_DLL): Remove unused macro. (dump_sysinfo): If COMSPEC isn't set in the MSVCRT environment, set it. Explain why.
This commit is contained in:
parent
a6aa222d5c
commit
b4dc8397e9
|
@ -1,3 +1,425 @@
|
|||
2014-11-07 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* dcrt0.cc (cygwin__cxa_atexit): Fetch correct DSO handle value
|
||||
by searching dll list. Explain why.
|
||||
|
||||
2014-11-06 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* dcrt0.cc (cygwin_atexit): Change preceeding comment to reflect
|
||||
API version numbers.
|
||||
* external.cc (cygwin_internal): disable setting cxx_malloc on 64 bit.
|
||||
Add CW_FIXED_ATEXIT case.
|
||||
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
|
||||
* include/sys/cygwin.h (cygwin_getinfo_types): Add CW_FIXED_ATEXIT.
|
||||
* lib/atexit.c (atexit): Test running Cygwin version by checking
|
||||
return value of cygwin_internal (CW_FIXED_ATEXIT).
|
||||
|
||||
2014-11-05 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* lib/atexit.c (atexit): Check for being linked into the executable.
|
||||
If so, call __cxa_atexit with NULL DSO handle. Explain why.
|
||||
* lib/dso_handle.c: New file providing fallback __dso_handle.
|
||||
|
||||
2014-11-05 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* Makefile.in (NEW_FUNCTIONS): Add atexit to be not exported.
|
||||
* lib/atexit.c (atexit): New, statically linkable version of atexit.
|
||||
* dcrt0.cc (cygwin_atexit): Add comment to mark this function as old
|
||||
entry point. Indiscriminately check for DSO of function pointer for
|
||||
all functions, if checking for DSO of return address fails on x86_64.
|
||||
Change comment accordingly.
|
||||
|
||||
2014-11-05 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* Makefile.in (NEW_FUNCTIONS): Define target-independent. Add target
|
||||
dependent stuff afterwards. Globally define timezone and all xdr
|
||||
symbols as non-exported from libcygwin.a.
|
||||
|
||||
2014-11-03 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygheap.cc: Fix formatting.
|
||||
|
||||
2014-10-29 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygheap.cc (init_cygheap::init_installation_root): Create content of
|
||||
installation_dir as non-prefixed path, if possible.
|
||||
|
||||
2014-10-29 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* common.din (__cxa_atexit): Define as cygwin__cxa_atexit.
|
||||
* dcrt0.cc (cygwin__cxa_atexit): New function. Explain what we do.
|
||||
|
||||
2014-10-28 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* globals.cc (dos_file_warning): Set to false by default.
|
||||
* path.cc (warn_msdos): Make static. Drop test for dos_file_warning.
|
||||
(path_conv::check): Check for dos_file_warning here to avoid a function
|
||||
call in the default case.
|
||||
|
||||
2014-10-27 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* dcrt0.cc (cygwin_atexit): Add workaround for broken atexit calls
|
||||
in __gcc_register_frame of DLLs built with gcc-4.8.3-3.
|
||||
|
||||
2014-10-27 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygheap.cc (init_cygheap::init_installation_root): Set
|
||||
installation_dir_len.
|
||||
* cygheap.h (struct init_cygheap): Add installation_dir_len member.
|
||||
* environ.cc (win_env::add_cache): Use stpcpy for speed.
|
||||
(posify_maybe): Use tmp_pathbuf buffer instead of stack.
|
||||
(raise_envblock): New function to resize Windows environment block.
|
||||
(build_env): Fix indentation. Call raise_envblock function. Check if
|
||||
$PATH exists and is non-empty. If not, add PATH variable with Cygwin
|
||||
installation directory as content to Windows environment. Explain why.
|
||||
|
||||
2014-10-24 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler_proc.cc (format_proc_cygdrive): Fix symlink path if cygdrive
|
||||
is "/".
|
||||
|
||||
2014-10-24 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* gendef (sigdelayed): 64 bit only: Fix seh_pushreg statements in
|
||||
prologue.
|
||||
|
||||
2014-10-22 Yaakov Selkowitz <yselkowi@redhat.com>
|
||||
|
||||
* common.din (stime): Export.
|
||||
* times.cc (stime): New function.
|
||||
* include/cygwin/time.h (stime): Declare.
|
||||
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
|
||||
|
||||
2014-10-20 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler_serial.cc: Revert debug code accidentally checked in on
|
||||
2014-08-18.
|
||||
|
||||
2014-10-20 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* path.cc (symlink_info::check): Set error from status code if opening
|
||||
the parent directory failed, but keep special case for root dirs.
|
||||
|
||||
2014-10-17 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygheap.cc (init_cygheap::init_installation_root): Just memmove
|
||||
contents of installation_root instead of calling GetModuleFileNameW
|
||||
again. Copy installation_root to installation_dir before stripping of
|
||||
"bin" dir. Explain what we do.
|
||||
* cygheap.h (struct init_cygheap): Add installation_dir member.
|
||||
|
||||
2014-10-17 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygtls.h (__try): Define __l_endtry as block-local label in 32 bit
|
||||
case as well.
|
||||
|
||||
2014-10-17 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* Makefile.in (DLL_OFILES): Add quotactl.o.
|
||||
* common.din (quotactl): Export.
|
||||
* ntdll.h: Define FILE_FS_CONTROL_INFORMATION::FileSystemControlFlags
|
||||
flag values.
|
||||
(struct _FILE_FS_CONTROL_INFORMATION): Define.
|
||||
(struct _FILE_GET_QUOTA_INFORMATION): Define.
|
||||
(typedef struct _FILE_QUOTA_INFORMATION): Define.
|
||||
(NtQueryObject): Use PVOID rather than VOID*.
|
||||
(NtQueryVolumeInformationFile): Ditto.
|
||||
(NtQueryQuotaInformationFile): Declare.
|
||||
(NtSetQuotaInformationFile): Declare.
|
||||
(NtSetVolumeInformationFile): Declare.
|
||||
* quotactl.cc: New file implementing quotactl().
|
||||
* include/sys/mount.h (BLOCK_SIZE): Define.
|
||||
(BLOCK_SIZE_BITS): Define.
|
||||
* include/sys/quota.h: New header.
|
||||
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
|
||||
|
||||
2014-10-16 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* Makefile.in (DLL_OFILES): Rearrange with one file per line.
|
||||
|
||||
2014-10-16 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler_proc.cc (format_proc_partitions): Extend output to print
|
||||
the windows mount points the device is mounted on.
|
||||
|
||||
2014-10-13 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* net.cc (cygwin_setsockopt): Drop redundant test for AF_LOCAL and
|
||||
SOCK_STREAM in SO_PEERCRED case, as in the original patch.
|
||||
|
||||
2014-10-12 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* dlfcn.cc (gfpod_helper): Only check for POSIX dir separator, same as
|
||||
in get_full_path_of_dll.
|
||||
|
||||
2014-10-12 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* dlfcn.cc (set_dl_error): Drop useless __stdcall.
|
||||
(check_path_access): Ditto. Drop FE_CWD from call to find_exec.
|
||||
(gfpod_helper): Call path_conv::check for all paths containing a dir
|
||||
separator to more closely follow the Linux search algorithm.
|
||||
(get_full_path_of_dll): Drop useless __stdcall.
|
||||
(dlopen): Simplify RTLD_NOLOAD case by calling GetModuleHandleEx
|
||||
instead of GetModuleHandle/LoadLibrary.
|
||||
|
||||
2014-10-11 Christian Franke <franke@computer.org>
|
||||
|
||||
Add setsockopt(sd, SOL_SOCKET, SO_PEERCRED, NULL, 0) to disable
|
||||
initial handshake on AF_LOCAL sockets.
|
||||
* fhandler.h (class fhandler_socket): Add no_getpeereid status flag.
|
||||
(fhandler_socket::af_local_set_no_getpeereid): New prototype.
|
||||
* fhandler_socket.cc (fhandler_socket::af_local_connect): Skip handshake
|
||||
if no_getpeereid is set. Add debug output.
|
||||
(fhandler_socket::af_local_accept): Likewise.
|
||||
(fhandler_socket::af_local_set_no_getpeereid): New function.
|
||||
(fhandler_socket::af_local_copy): Copy no_getpeereid.
|
||||
(fhandler_socket::getpeereid): Fail if no_getpeereid is set.
|
||||
* net.cc (cygwin_setsockopt): Add SO_PEERCRED for AF_LOCAL/SOCK_STREAM
|
||||
sockets. Add comment to explain why we need it.
|
||||
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
|
||||
|
||||
2014-10-10 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* dlfcn.cc (dlopen): Disable old 32 bit code on 64 bit.
|
||||
* dcrt0.cc (check_sanity_and_sync): Ditto.
|
||||
* dll_init.cc (dll_dllcrt0_1): Fix typo in comment.
|
||||
|
||||
2014-10-08 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* common.din (ffsl): Export.
|
||||
(ffsll): Export.
|
||||
* syscalls.cc (ffs): Implement using GCC intrinsic.
|
||||
(ffsl): Ditto.
|
||||
(ffsll): Ditto.
|
||||
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
|
||||
|
||||
2014-10-08 Christian Franke <franke@computer.org>
|
||||
|
||||
* syscalls.cc (ffs): Fix crash of ffs (0x80000000) on 64 bit.
|
||||
|
||||
2014-10-08 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler_process.cc (format_process_statm): Fix output of dirty
|
||||
pages. Add linefeed.
|
||||
|
||||
2014-09-05 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler_proc.cc (proc_tab): Add entry for cygdrive symlink.
|
||||
(format_proc_cygdrive): New function to implement /proc/cygdrive.
|
||||
|
||||
2014-09-05 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* exception.h (class exception): Remove unnecessary #ifdef.
|
||||
|
||||
2014-09-05 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* winlean.h (DNLEN): Raise to 31. Explain why.
|
||||
|
||||
2014-08-28 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler_disk_file.cc (fhandler_disk_file::fstatvfs): Try the
|
||||
FileFsSizeInformation information class on filesystems choking on
|
||||
FileFsFullSizeInformation (I see you Netapp!)
|
||||
|
||||
2014-08-27 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler.h (fhandler_pty_slave::fch_open_handles): Add bool parameter
|
||||
to declaration.
|
||||
* fhandler_tty.cc (fhandler_pty_slave::fch_open_handles): Add bool
|
||||
parameter "chown". Only request WRITE_OWNER access when opening pty
|
||||
synchronization objects if "chown" is set.
|
||||
(fhandler_pty_slave::fchmod): Call fch_open_handles with new bool
|
||||
parameter set to false.
|
||||
(fhandler_pty_slave::fchown): Call fch_open_handles with new bool
|
||||
parameter set to true.
|
||||
* kernel32.cc (CreateFileMappingW): Fix default standard rights for
|
||||
file mappings from READ_CONTROL to STANDARD_RIGHTS_REQUIRED to allow
|
||||
changing the DACL (fixes "access denied" error in pinfo::set_acl).
|
||||
|
||||
* fhandler_disk_file.cc (fhandler_base::fstat_helper): Change debug
|
||||
output to print mode bits in octal.
|
||||
* security.cc (alloc_sd): Ditto.
|
||||
(set_file_attribute): Ditto.
|
||||
|
||||
2014-08-27 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* ntea.cc (read_ea): Change left-over return to __leave. Fix
|
||||
condition to close handle. Call NtClose rather than CloseHandle.
|
||||
(write_ea): Fix condition to close handle. Call NtClose rather than
|
||||
CloseHandle.
|
||||
* security.cc (get_file_sd): Call pc.init_reopen_attr if a valid
|
||||
incoming handle was given, pc.get_object_attr otherwise.
|
||||
(set_file_sd): Ditto.
|
||||
|
||||
2014-08-26 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* path.h (path_conv::init_reopen_attr): Change from void to returning
|
||||
POBJECT_ATTRIBUTES. Take OBJECT_ATTRIBUTES reference as argument, not
|
||||
pointer.
|
||||
* fhandler_disk_file.cc: Throughout accommodate above change.
|
||||
* syscalls.cc: Ditto.
|
||||
* ntea.cc (read_ea): Don't set hdl to NULL if it's already NULL. Set
|
||||
attr with pc.init_reopen_attr before trying to reopen file.
|
||||
(write_ea): Ditto.
|
||||
* security.cc (get_file_sd): Use pc.init_reopen_attr rather than
|
||||
pc.get_object_attr when trying to reopen file.
|
||||
(set_file_sd): Ditto.
|
||||
|
||||
2014-08-25 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygtls.cc (san::leave/x86_64): Implement.
|
||||
* cygtls.h (class tls_pathbuf): Move counter variables into a union.
|
||||
Add 64 bit element _counters covering both counter variables to
|
||||
optimize save and restore operations.
|
||||
(class san/x86_64): Only store single 64 bit value.
|
||||
(san::san/x86_64): Implement.
|
||||
(san::leave/x86_64): Only declare here, as returns_twice function.
|
||||
Explain why.
|
||||
(class san/i686): Change type of _c_cnt and _w_cnt to uint32_t.
|
||||
(__try/x86_64): Move definition of __sebastian after the first memory
|
||||
barrier. Drop __sebastian.setup call.
|
||||
|
||||
2014-08-25 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygtls.cc (_cygtls::remove): Revert previous patch.
|
||||
* cygtls.h (struct _local_storage): Move pathbufs back here.
|
||||
(class san/x86_64): Revert class. Save and restore pathbufs counters
|
||||
only.
|
||||
(class san/i686): Revert saving and restoring pathbufs counters.
|
||||
(__try/x86_64): Add a san variable and call it's setup method.
|
||||
(__except/x86_64): Call san::leave to restore pathbufs counters.
|
||||
* gendef (_sigbe): Revert previous change.
|
||||
* thread.cc (verifyable_object_state): Remove gcc 4.7 workaround in
|
||||
forward declaration as well.
|
||||
* tls_pbuf.cc (tls_pbuf): Revert previous change.
|
||||
* tls_pbuf.h (class tmp_pathbuf): Accommodate reverting pathbufs to
|
||||
locals structure.
|
||||
* tlsoffsets.h: Regenerate.
|
||||
* tlsoffsets64.h: Regenerate.
|
||||
|
||||
2014-08-21 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* Throughout, use __try/__except/__endtry blocks, rather than myfault
|
||||
handler.
|
||||
* cygtls.cc (_cygtls::remove): Accommodate the fact that pathbufs
|
||||
has been moved from _local_storage to _cygtls.
|
||||
* cygtls.h (class tls_pathbuf): Add comment to hint to gendef usage
|
||||
of counters. Change type of counters to uint32_t for clarity.
|
||||
Remove _cygtls as friend class.
|
||||
(struct _local_storage): Move pathbufs from here...
|
||||
(struct _cygtls): ...to here, allowing to access it from _sigbe.
|
||||
(class san): Only define on 32 bit. Remove errno, _c_cnt and _w_cnt
|
||||
members.
|
||||
(san::setup): Drop parameter. Don't initialize removed members.
|
||||
(san::leave): Don't set removed members.
|
||||
(class myfault): Only define on 32 bit.
|
||||
(myfault::faulted): Only keep implementation not taking any parameter.
|
||||
Drop argument in call to sebastian.setup.
|
||||
(__try/__leave/__except/__endtry): Implement to support real SEH. For
|
||||
now stick to SJLJ on 32 bit.
|
||||
* dcrt0.cc (dll_crt0_0): Drop 64 bit call to
|
||||
exception::install_myfault_handler.
|
||||
* exception.h (exception_handler): Define with EXCEPTION_DISPOSITION
|
||||
as return type.
|
||||
(PDISPATCHER_CONTEXT): Define as void * on 32 bit. Define as pointer
|
||||
to _DISPATCHER_CONTEXT on 64 bit.
|
||||
(class exception): Define separately for 32 and 64 bit.
|
||||
(exception::myfault): Add handler for myfault SEH handling on 64 bit.
|
||||
(exception::exception): Fix mangled method name to account for change
|
||||
in type of last parameter.
|
||||
(exception::install_myfault_handler): Remove.
|
||||
* exceptions.cc (exception::myfault_handle): Remove.
|
||||
(exception::myfault): New SEH handler for 64 bit.
|
||||
* gendef (_sigbe): Set tls_pathbuf counters to 0 explicitely when
|
||||
returning to the caller.
|
||||
* ntdll.h: Move a comment to a better place.
|
||||
(struct _SCOPE_TABLE): Define on 64 bit.
|
||||
* thread.cc (verifyable_object_isvalid): Remove gcc 4.7 workaround.
|
||||
* tls_pbuf.cc (tls_pbuf): Fix to accommodate new place of pathbufs.
|
||||
(tls_pathbuf::destroy): Change type of loop variables to uint32_t.
|
||||
* tls_pbuf.h (class tmp_pathbuf): Change type of buffer counters to
|
||||
uint32_t. Accommodate new place of pathbufs.
|
||||
* tlsoffsets.h: Regenerate.
|
||||
* tlsoffsets64.h: Regenerate.
|
||||
|
||||
2014-08-21 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* miscfuncs.cc (__import_address): Cover the first dereference to imp
|
||||
under the fault handler.
|
||||
|
||||
2014-08-21 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* net.cc (if_freenameindex): Don't catch a SEGV from free to fail
|
||||
loudly on double free.
|
||||
|
||||
2014-08-21 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* dir.cc (rmdir): Don't skip deleting fh in the ENOTEMPTY case.
|
||||
|
||||
2014-08-20 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* tls_pbuf.h (tmp_pathbuf::tmp_pathbuf): Convert to inline method.
|
||||
(tmp_pathbuf::~tmp_pathbuf): Ditto.
|
||||
* tls_pbuf.cc (tmp_pathbuf::tmp_pathbuf): Remove here.
|
||||
(tmp_pathbuf::~tmp_pathbuf): Ditto.
|
||||
|
||||
2014-08-19 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* dir.cc (dirfd): Per POSIX, return EINVAL on invalid directory stream.
|
||||
(telldir): Per POSIX, return -1 and set errno to EBADF, rather than
|
||||
just returning 0, on invalid directory stream.
|
||||
* signal.cc (sigwaitinfo): Return -1, not EFAULT, when SEGV was catched.
|
||||
|
||||
2014-08-19 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* autoload.cc: Replace WNet[...]A with WNet[...]W imports.
|
||||
* dcrt0.cc (initial_env): Drop strlwr calls. Call strcasestr instead.
|
||||
* fhandler_netdrive.cc: Throughout, convert to calling WNet UNICODE
|
||||
functions. Use tmp_pathbuf rather than alloca. Replace call to
|
||||
strlwr with call to RtlDowncaseUnicodeString.
|
||||
|
||||
2014-08-19 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler.h (fhandler_serial::is_tty): Reinstantiate.
|
||||
|
||||
2014-08-18 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* miscfuncs.cc (strlwr): Rename from cygwin_strlwr. Drop __stdcall
|
||||
decoration.
|
||||
(strupr): Rename from cygwin_strupr. Drop __stdcall decoration.
|
||||
* string.h (strlwr): Remove override macro. Simply declare.
|
||||
(strupr): Ditto.
|
||||
|
||||
2014-08-18 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* dtable.cc (dtable::init_std_file_from_handle): Mention that console
|
||||
handles are kernel objects since Windows 8.
|
||||
* fhandler.h (enum conn_state): Add "listener" state.
|
||||
(class fhandler_socket): Drop listener status flag.
|
||||
(fhandler_socket::lseek): Return -1 and errno ESPIPE.
|
||||
(fhandler_serial::lseek): Ditto.
|
||||
(fhandler_serial::is_tty): Remove.
|
||||
* fhandler_socket.cc (fhandler_socket::listen): Set connect_state to
|
||||
listener. Add comment.
|
||||
(fhandler_socket::accept4): Explicitely check if the socket is listening
|
||||
and fail with EINVAL, if not. Explain why we have to do that.
|
||||
(fhandler_socket::getpeereid): Drop now redundant test.
|
||||
|
||||
2014-08-15 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* winsup.h (_GNU_SOURCE): Define. Explain why.
|
||||
|
||||
2014-08-14 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* dlmalloc.c: Remove unused file.
|
||||
* dlmalloc.h: Ditto.
|
||||
* malloc.cc: Update to Doug Lea's malloc version 2.8.6.
|
||||
|
||||
2014-08-13 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 33.
|
||||
(CYGWIN_VERSION_API_MINOR): Bump to reflect intermediate 1.7.32 release.
|
||||
|
||||
2014-08-11 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cpuid.h: Add missing copyright header. Fix formatting. Use uint32_t
|
||||
|
@ -49,6 +471,10 @@
|
|||
* thread.cc (pthread::init_mainthread): Initialize thread mutex to
|
||||
type PTHREAD_MUTEX_RECURSIVE, just as for any other thread.
|
||||
|
||||
2014-07-21 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 32.
|
||||
|
||||
2014-07-16 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* thread.cc (pthread::create): Handle stackaddr as upper bound address.
|
||||
|
@ -127,7 +553,8 @@
|
|||
writing small buffers. Rename variables and add comments to help
|
||||
understanding the code in years to come.
|
||||
|
||||
2014-07-07 Corinna Vinschen <corinna@vinschen.de>
|
||||
2014-07-07 Pierre Humblet <Pierre.Humblet@ieee.org>
|
||||
Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* libc/minires.c (minires_dprintf): Change "Minires" to "Resolv" to
|
||||
differ from external minres lib.
|
||||
|
@ -257,7 +684,7 @@
|
|||
2014-05-20 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler_floppy.cc (fhandler_dev_floppy::get_drive_info): Fix floppy
|
||||
drive handling broken with 1.7.19.
|
||||
drive handling broken with 1.7.19.
|
||||
|
||||
2014-05-20 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
|
@ -318,6 +745,12 @@
|
|||
* fhandler_console.cc (dev_console::save_restore): Only save current
|
||||
dwEnd line rather than the one after that.
|
||||
|
||||
2014-05-06 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* winlean.h (PIPE_REJECT_REMOTE_CLIENTS): Drop temporary definition
|
||||
since Mingw64 catched up.
|
||||
(DNLEN): Redefine as 16. Explain why.
|
||||
|
||||
2014-05-05 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* net.cc (cygwin_getsockopt): Rearrange code slightly and handle
|
||||
|
@ -381,7 +814,7 @@
|
|||
(tmp_pathbuf::w_get): Ditto.
|
||||
* tls_pbuf.h (class tmp_pathbuf): Change type of c_buf_old and w_buf_old
|
||||
to unsigned.
|
||||
(tmp_pathbuf::check_usage): New inline method to check if we have
|
||||
(tmp_pathbuf::check_usage): New inline method to check if we have
|
||||
enough tmp_pathbuf buffers left to call a function using tmp_pathbuf
|
||||
buffers.
|
||||
* tlsoffsets.h: Regenerate.
|
||||
|
@ -395,21 +828,21 @@
|
|||
|
||||
* include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 30.
|
||||
|
||||
2014-04-09 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* exceptions.cc (exception::myfault_handle): Only handle the minimum
|
||||
amount of exceptions the myfault handler was designed for.
|
||||
|
||||
2014-04-08 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygwin.sc.in: (Temporarily?) workaround serious ld bug which
|
||||
truncates symbols in certain computations to 32 bit. See
|
||||
https://sourceware.org/bugzilla/show_bug.cgi?id=16821
|
||||
|
||||
2014-04-09 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* exceptions.cc (exception::myfault_handle): Only handle the minimum
|
||||
amount of exceptions the myfault handler was designed for.
|
||||
|
||||
2014-04-07 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygserver_ipc.h (ipc_set_proc_info): Add bool parameter to specify
|
||||
whether or not to send signal_arrived.
|
||||
whether or not to send signal_arrived.
|
||||
* shm.cc (client_request_shm::client_request_shm): Call
|
||||
ipc_set_proc_info with bool parameter set to true to not send
|
||||
signal_arrived.
|
||||
|
@ -606,6 +1039,11 @@
|
|||
|
||||
* dir.cc (opendir): Propagate any errno from build_fh_name.
|
||||
|
||||
2014-03-06 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* setlsapwd.cc (setlsapwd): Use RtlSecureZeroMemory to delete password
|
||||
from memory.
|
||||
|
||||
2014-03-05 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* include/cygwin/config.h (__TM_GMTOFF): Define.
|
||||
|
@ -641,13 +1079,6 @@
|
|||
(fhandler_console::char_command): Use scroll_buffer_screen as appropriate.
|
||||
(dev_console::scroll_buffer): Remove if 0'ed block.
|
||||
|
||||
2014-02-22 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* external.cc (cygwin_internal): Add cases for CW_GETPWSID and
|
||||
CW_GETGRSID.
|
||||
* include/sys/cygwin.h (cygwin_getinfo_types): Add CW_SETENT, CW_GETENT,
|
||||
CW_ENDENT, CW_GETNSSSEP, CW_GETPWSID and CW_GETGRSID.
|
||||
|
||||
2014-02-22 Christopher Faylor <me.cygwin2014@cgf.cx>
|
||||
|
||||
* dev_console::scroll_buffer): Reinstate clipping region.
|
||||
|
@ -677,6 +1108,13 @@
|
|||
(fhandler_console::cursor_get): Ditto.
|
||||
(fhandler_console::write): Fix "reverse index".
|
||||
|
||||
2014-02-22 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* external.cc (cygwin_internal): Add cases for CW_GETPWSID and
|
||||
CW_GETGRSID.
|
||||
* include/sys/cygwin.h (cygwin_getinfo_types): Add CW_SETENT, CW_GETENT,
|
||||
CW_ENDENT, CW_GETNSSSEP, CW_GETPWSID and CW_GETGRSID.
|
||||
|
||||
2014-02-20 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* grp.cc (getgrouplist): Fix previous fix so ret is only set to ngroups
|
||||
|
@ -687,6 +1125,16 @@
|
|||
* grp.cc (get_groups): Don't add gid to list if it's ILLEGAL_GID.
|
||||
(getgrouplist): Return number of groups, just like glibc.
|
||||
|
||||
2014-02-18 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* setlsapwd.cc (setlsapwd): Fix conditional expression after breaking
|
||||
it on 2014-01-23.
|
||||
|
||||
2014-02-16 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* dcrt0.cc (dll_crt0_1): Call initial_setlocale before fetching
|
||||
current user information.
|
||||
|
||||
2014-02-15 Christopher Faylor <me.cygwin2014@cgf.cx>
|
||||
|
||||
* DevNotes: Add entry cgf-000024.
|
||||
|
@ -765,6 +1213,9 @@
|
|||
* net.cc (cygwin_gethostname): Call GetComputerNameExA rather than
|
||||
GetComputerNameA if gethostname failed.
|
||||
* shared.cc (user_info::initialize): Fix formatting.
|
||||
|
||||
2014-02-06 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* include/sys/file.h: Define flock and accompanying macros if not
|
||||
already defined in sys/_default_fcntl.h.
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Makefile.in for Cygwin.
|
||||
# Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
# 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
# 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
#
|
||||
# This file is part of Cygwin.
|
||||
#
|
||||
|
@ -153,31 +153,157 @@ DLL_IMPORTS:=${shell $(CC) -print-file-name=w32api/libkernel32.a} ${shell $(CC)
|
|||
|
||||
MT_SAFE_OBJECTS:=
|
||||
#
|
||||
DLL_OFILES:=advapi32.o arc4random.o assert.o autoload.o base64.o bsdlib.o ctype.o \
|
||||
cxx.o cygheap.o cygthread.o cygtls.o cygwait.o cygxdr.o dcrt0.o debug.o \
|
||||
devices.o dir.o dlfcn.o dll_init.o dtable.o environ.o errno.o exceptions.o \
|
||||
exec.o external.o fcntl.o fenv.o fhandler.o fhandler_clipboard.o \
|
||||
fhandler_console.o fhandler_dev.o fhandler_disk_file.o fhandler_dsp.o \
|
||||
fhandler_fifo.o fhandler_floppy.o fhandler_mailslot.o \
|
||||
fhandler_netdrive.o fhandler_nodevice.o fhandler_proc.o \
|
||||
fhandler_process.o fhandler_procnet.o fhandler_procsys.o \
|
||||
fhandler_procsysvipc.o fhandler_random.o fhandler_raw.o \
|
||||
fhandler_registry.o fhandler_serial.o fhandler_socket.o fhandler_tape.o \
|
||||
fhandler_termios.o fhandler_tty.o fhandler_virtual.o fhandler_windows.o \
|
||||
fhandler_zero.o flock.o fnmatch.o fork.o fts.o ftw.o getopt.o glob.o \
|
||||
glob_pattern_p.o globals.o grp.o heap.o hookapi.o inet_addr.o \
|
||||
inet_network.o init.o ioctl.o ipc.o kernel32.o libstdcxx_wrapper.o \
|
||||
localtime.o lsearch.o malloc_wrapper.o minires-os-if.o minires.o \
|
||||
miscfuncs.o mktemp.o mmap.o msg.o mount.o net.o netdb.o nfs.o nftw.o \
|
||||
nlsfuncs.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o posix_ipc.o \
|
||||
pseudo-reloc.o pthread.o random.o regcomp.o regerror.o regexec.o regfree.o \
|
||||
registry.o resource.o rexec.o rcmd.o scandir.o sched.o sec_acl.o \
|
||||
sec_auth.o sec_helper.o security.o select.o sem.o setlsapwd.o shared.o \
|
||||
shm.o sigfe.o signal.o sigproc.o smallprint.o spawn.o strace.o strfmon.o \
|
||||
strfuncs.o strptime.o strsep.o strsig.o sync.o syscalls.o sysconf.o \
|
||||
syslog.o termios.o thread.o timer.o times.o tls_pbuf.o tty.o uinfo.o \
|
||||
uname.o wait.o wincap.o window.o winf.o wow64.o xsique.o \
|
||||
$(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS)
|
||||
DLL_OFILES:= \
|
||||
advapi32.o \
|
||||
arc4random.o \
|
||||
assert.o \
|
||||
autoload.o \
|
||||
base64.o \
|
||||
bsdlib.o \
|
||||
ctype.o \
|
||||
cxx.o \
|
||||
cygheap.o \
|
||||
cygthread.o \
|
||||
cygtls.o \
|
||||
cygwait.o \
|
||||
cygxdr.o \
|
||||
dcrt0.o \
|
||||
debug.o \
|
||||
devices.o \
|
||||
dir.o \
|
||||
dlfcn.o \
|
||||
dll_init.o \
|
||||
dtable.o \
|
||||
environ.o \
|
||||
errno.o \
|
||||
exceptions.o \
|
||||
exec.o \
|
||||
external.o \
|
||||
fcntl.o \
|
||||
fenv.o \
|
||||
fhandler.o \
|
||||
fhandler_clipboard.o \
|
||||
fhandler_console.o \
|
||||
fhandler_dev.o \
|
||||
fhandler_disk_file.o \
|
||||
fhandler_dsp.o \
|
||||
fhandler_fifo.o \
|
||||
fhandler_floppy.o \
|
||||
fhandler_mailslot.o \
|
||||
fhandler_netdrive.o \
|
||||
fhandler_nodevice.o \
|
||||
fhandler_proc.o \
|
||||
fhandler_process.o \
|
||||
fhandler_procnet.o \
|
||||
fhandler_procsys.o \
|
||||
fhandler_procsysvipc.o \
|
||||
fhandler_random.o \
|
||||
fhandler_raw.o \
|
||||
fhandler_registry.o \
|
||||
fhandler_serial.o \
|
||||
fhandler_socket.o \
|
||||
fhandler_tape.o \
|
||||
fhandler_termios.o \
|
||||
fhandler_tty.o \
|
||||
fhandler_virtual.o \
|
||||
fhandler_windows.o \
|
||||
fhandler_zero.o \
|
||||
flock.o \
|
||||
fnmatch.o \
|
||||
fork.o \
|
||||
fts.o \
|
||||
ftw.o \
|
||||
getopt.o \
|
||||
glob.o \
|
||||
glob_pattern_p.o \
|
||||
globals.o \
|
||||
grp.o \
|
||||
heap.o \
|
||||
hookapi.o \
|
||||
inet_addr.o \
|
||||
inet_network.o \
|
||||
init.o \
|
||||
ioctl.o \
|
||||
ipc.o \
|
||||
kernel32.o \
|
||||
libstdcxx_wrapper.o \
|
||||
localtime.o \
|
||||
lsearch.o \
|
||||
malloc_wrapper.o \
|
||||
minires-os-if.o \
|
||||
minires.o \
|
||||
miscfuncs.o \
|
||||
mktemp.o \
|
||||
mmap.o \
|
||||
msg.o \
|
||||
mount.o \
|
||||
net.o \
|
||||
netdb.o \
|
||||
nfs.o \
|
||||
nftw.o \
|
||||
nlsfuncs.o \
|
||||
ntea.o \
|
||||
passwd.o \
|
||||
path.o \
|
||||
pinfo.o \
|
||||
pipe.o \
|
||||
poll.o \
|
||||
posix_ipc.o \
|
||||
pseudo-reloc.o \
|
||||
pthread.o \
|
||||
quotactl.o \
|
||||
random.o \
|
||||
regcomp.o \
|
||||
regerror.o \
|
||||
regexec.o \
|
||||
regfree.o \
|
||||
registry.o \
|
||||
resource.o \
|
||||
rexec.o \
|
||||
rcmd.o \
|
||||
scandir.o \
|
||||
sched.o \
|
||||
sec_acl.o \
|
||||
sec_auth.o \
|
||||
sec_helper.o \
|
||||
security.o \
|
||||
select.o \
|
||||
sem.o \
|
||||
setlsapwd.o \
|
||||
shared.o \
|
||||
shm.o \
|
||||
sigfe.o \
|
||||
signal.o \
|
||||
sigproc.o \
|
||||
smallprint.o \
|
||||
spawn.o \
|
||||
strace.o \
|
||||
strfmon.o \
|
||||
strfuncs.o \
|
||||
strptime.o \
|
||||
strsep.o \
|
||||
strsig.o \
|
||||
sync.o \
|
||||
syscalls.o \
|
||||
sysconf.o \
|
||||
syslog.o \
|
||||
termios.o \
|
||||
thread.o \
|
||||
timer.o \
|
||||
times.o \
|
||||
tls_pbuf.o \
|
||||
tty.o \
|
||||
uinfo.o \
|
||||
uname.o \
|
||||
wait.o \
|
||||
wincap.o \
|
||||
window.o \
|
||||
winf.o \
|
||||
wow64.o \
|
||||
xsique.o \
|
||||
$(EXTRA_OFILES) \
|
||||
$(MALLOC_OFILES) \
|
||||
$(MT_SAFE_OBJECTS)
|
||||
|
||||
EXCLUDE_STATIC_OFILES:=$(addprefix --exclude=,\
|
||||
cygtls.o \
|
||||
|
@ -202,10 +328,63 @@ endif
|
|||
|
||||
GMON_OFILES:=gmon.o mcount.o profil.o mcountFunc.o
|
||||
|
||||
ifeq ($(target_cpu),x86_64)
|
||||
NEW_FUNCTIONS:=
|
||||
else
|
||||
NEW_FUNCTIONS:=$(addprefix --replace=,\
|
||||
atexit= \
|
||||
timezone= \
|
||||
__xdrrec_getrec= \
|
||||
__xdrrec_setnonblock= \
|
||||
xdr_array= \
|
||||
xdr_bool= \
|
||||
xdr_bytes= \
|
||||
xdr_char= \
|
||||
xdr_double= \
|
||||
xdr_enum= \
|
||||
xdr_float= \
|
||||
xdr_free= \
|
||||
xdr_hyper= \
|
||||
xdr_int= \
|
||||
xdr_int16_t= \
|
||||
xdr_int32_t= \
|
||||
xdr_int64_t= \
|
||||
xdr_int8_t= \
|
||||
xdr_long= \
|
||||
xdr_longlong_t= \
|
||||
xdr_netobj= \
|
||||
xdr_opaque= \
|
||||
xdr_pointer= \
|
||||
xdr_reference= \
|
||||
xdr_short= \
|
||||
xdr_sizeof= \
|
||||
xdr_string= \
|
||||
xdr_u_char= \
|
||||
xdr_u_hyper= \
|
||||
xdr_u_int= \
|
||||
xdr_u_int16_t= \
|
||||
xdr_u_int32_t= \
|
||||
xdr_u_int64_t= \
|
||||
xdr_u_int8_t= \
|
||||
xdr_u_long= \
|
||||
xdr_u_longlong_t= \
|
||||
xdr_u_short= \
|
||||
xdr_uint16_t= \
|
||||
xdr_uint32_t= \
|
||||
xdr_uint64_t= \
|
||||
xdr_uint8_t= \
|
||||
xdr_union= \
|
||||
xdr_vector= \
|
||||
xdr_void= \
|
||||
xdr_wrapstring= \
|
||||
xdrmem_create= \
|
||||
xdrrec_create= \
|
||||
xdrrec_endofrecord= \
|
||||
xdrrec_eof= \
|
||||
xdrrec_skiprecord= \
|
||||
xdrstdio_create= \
|
||||
)
|
||||
ifeq ($(target_cpu),x86_64)
|
||||
NEW_FUNCTIONS+=
|
||||
else
|
||||
NEW_FUNCTIONS+=$(addprefix --replace=,\
|
||||
acl=_acl32 \
|
||||
aclcheck=_aclcheck32 \
|
||||
aclfrommode=_aclfrommode32 \
|
||||
|
@ -253,7 +432,6 @@ NEW_FUNCTIONS:=$(addprefix --replace=,\
|
|||
setreuid=_setreuid32 \
|
||||
setuid=_setuid32 \
|
||||
stat=_stat64 \
|
||||
timezone= \
|
||||
tmpfile=_tmpfile64 \
|
||||
truncate=_truncate64 \
|
||||
)
|
||||
|
|
|
@ -581,10 +581,10 @@ LoadDLLfuncEx2 (IdnToUnicode, 20, kernel32, 1, 0)
|
|||
LoadDLLfunc (LocaleNameToLCID, 8, kernel32)
|
||||
|
||||
LoadDLLfunc (WNetCloseEnum, 4, mpr)
|
||||
LoadDLLfunc (WNetEnumResourceA, 16, mpr)
|
||||
LoadDLLfunc (WNetGetProviderNameA, 12, mpr)
|
||||
LoadDLLfunc (WNetGetResourceInformationA, 16, mpr)
|
||||
LoadDLLfunc (WNetOpenEnumA, 20, mpr)
|
||||
LoadDLLfunc (WNetEnumResourceW, 16, mpr)
|
||||
LoadDLLfunc (WNetGetProviderNameW, 12, mpr)
|
||||
LoadDLLfunc (WNetGetResourceInformationW, 16, mpr)
|
||||
LoadDLLfunc (WNetOpenEnumW, 20, mpr)
|
||||
|
||||
LoadDLLfunc (DsGetDcNameW, 24, netapi32)
|
||||
LoadDLLfunc (NetApiBufferFree, 4, netapi32)
|
||||
|
|
|
@ -41,7 +41,7 @@ __assert_func NOSIGFE
|
|||
__assertfail NOSIGFE
|
||||
__b64_ntop NOSIGFE
|
||||
__b64_pton NOSIGFE
|
||||
__cxa_atexit SIGFE
|
||||
__cxa_atexit = cygwin__cxa_atexit SIGFE
|
||||
__cxa_finalize SIGFE
|
||||
__dn_comp SIGFE
|
||||
__dn_expand SIGFE
|
||||
|
@ -374,6 +374,8 @@ feupdateenv SIGFE
|
|||
fexecve SIGFE
|
||||
fflush SIGFE
|
||||
ffs NOSIGFE
|
||||
ffsl NOSIGFE
|
||||
ffsll NOSIGFE
|
||||
fgetc SIGFE
|
||||
fgetpos SIGFE
|
||||
fgets SIGFE
|
||||
|
@ -918,6 +920,7 @@ putwc SIGFE
|
|||
putwchar SIGFE
|
||||
pwrite SIGFE
|
||||
qsort NOSIGFE
|
||||
quotactl SIGFE
|
||||
raise SIGFE
|
||||
rand NOSIGFE
|
||||
rand_r NOSIGFE
|
||||
|
@ -1106,6 +1109,7 @@ sscanf SIGFE
|
|||
stat SIGFE
|
||||
statfs SIGFE
|
||||
statvfs SIGFE
|
||||
stime SIGFE
|
||||
stpcpy NOSIGFE
|
||||
stpncpy NOSIGFE
|
||||
strcasecmp NOSIGFE
|
||||
|
|
|
@ -140,6 +140,8 @@ init_cygheap::close_ctty ()
|
|||
void
|
||||
init_cygheap::init_installation_root ()
|
||||
{
|
||||
ptrdiff_t len = 0;
|
||||
|
||||
if (!GetModuleFileNameW (cygwin_hmodule, installation_root, PATH_MAX))
|
||||
api_fatal ("Can't initialize Cygwin installation root dir.\n"
|
||||
"GetModuleFileNameW(%p, %p, %u), %E",
|
||||
|
@ -147,16 +149,18 @@ init_cygheap::init_installation_root ()
|
|||
PWCHAR p = installation_root;
|
||||
if (wcsncasecmp (p, L"\\\\", 2)) /* Normal drive letter path */
|
||||
{
|
||||
p = wcpcpy (p, L"\\??\\");
|
||||
GetModuleFileNameW (cygwin_hmodule, p, PATH_MAX - 4);
|
||||
len = 4;
|
||||
memmove (p + 4, p, PATH_MAX - 4);
|
||||
p = wcpncpy (p, L"\\\\?\\", 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool unc = false;
|
||||
if (wcsncmp (p + 2, L"?\\", 2)) /* No long path prefix, so UNC path. */
|
||||
{
|
||||
p = wcpcpy (p, L"\\??\\UN");
|
||||
GetModuleFileNameW (cygwin_hmodule, p, PATH_MAX - 6);
|
||||
len = 6;
|
||||
memmove (p + 6, p, PATH_MAX - 6);
|
||||
p = wcpncpy (p, L"\\??\\UN", 6);
|
||||
*p = L'C';
|
||||
unc = true;
|
||||
}
|
||||
|
@ -170,12 +174,12 @@ init_cygheap::init_installation_root ()
|
|||
}
|
||||
}
|
||||
installation_root[1] = L'?';
|
||||
|
||||
RtlInitEmptyUnicodeString (&installation_key, installation_key_buf,
|
||||
sizeof installation_key_buf);
|
||||
RtlInt64ToHexUnicodeString (hash_path_name (0, installation_root),
|
||||
&installation_key, FALSE);
|
||||
|
||||
/* Strip off last path component ("\\cygwin1.dll") */
|
||||
PWCHAR w = wcsrchr (installation_root, L'\\');
|
||||
if (w)
|
||||
{
|
||||
|
@ -185,6 +189,20 @@ init_cygheap::init_installation_root ()
|
|||
if (!w)
|
||||
api_fatal ("Can't initialize Cygwin installation root dir.\n"
|
||||
"Invalid DLL path");
|
||||
|
||||
/* Copy result into installation_dir before stripping off "bin" dir and
|
||||
revert to Win32 path. This path is added to the Windows environment
|
||||
in buildenv. See there for a description. */
|
||||
installation_dir_len = wcpncpy (installation_dir, installation_root + len,
|
||||
PATH_MAX)
|
||||
- installation_dir;
|
||||
if (len == 4) /* Local path */
|
||||
;
|
||||
else if (len == 6) /* UNC path */
|
||||
installation_dir[0] = L'\\';
|
||||
else /* Long, prefixed path */
|
||||
installation_dir[1] = L'\\';
|
||||
|
||||
/* If w < p, the Cygwin DLL resides in the root dir of a drive or network
|
||||
path. In that case, if we strip off yet another backslash, the path
|
||||
becomes invalid. We avoid that here so that the DLL also works in this
|
||||
|
@ -638,10 +656,7 @@ init_cygheap::find_tls (int sig, bool& issig_wait)
|
|||
_cygtls *t = NULL;
|
||||
issig_wait = false;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
threadlist[ix]->remove (INFINITE);
|
||||
else
|
||||
__try
|
||||
{
|
||||
ix = -1;
|
||||
/* Scan thread list looking for valid signal-delivery candidates */
|
||||
|
@ -652,11 +667,15 @@ init_cygheap::find_tls (int sig, bool& issig_wait)
|
|||
{
|
||||
t = cygheap->threadlist[ix];
|
||||
issig_wait = true;
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
else if (!t && !sigismember (&(threadlist[ix]->sigmask), sig))
|
||||
t = cygheap->threadlist[ix];
|
||||
}
|
||||
out:
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
threadlist[ix]->remove (INFINITE);
|
||||
}
|
||||
__endtry
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* cygheap.h: Cygwin heap manager.
|
||||
|
||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
2011, 2012, 2013 Red Hat, Inc.
|
||||
2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -375,6 +375,8 @@ struct init_cygheap: public mini_cygheap
|
|||
unsigned bucket_val[NBUCKETS];
|
||||
char *buckets[NBUCKETS];
|
||||
WCHAR installation_root[PATH_MAX];
|
||||
WCHAR installation_dir[PATH_MAX];
|
||||
size_t installation_dir_len;
|
||||
UNICODE_STRING installation_key;
|
||||
WCHAR installation_key_buf[18];
|
||||
cygheap_root root;
|
||||
|
|
|
@ -200,3 +200,11 @@ _cygtls::remove (DWORD wait)
|
|||
cygheap->remove_tls (this, wait);
|
||||
remove_wq (wait);
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
void san::leave ()
|
||||
{
|
||||
/* Restore tls_pathbuf counters in case of error. */
|
||||
_my_tls.locals.pathbufs._counters = _cnt;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -44,18 +44,28 @@ details. */
|
|||
#else
|
||||
#pragma pack(push,4)
|
||||
#endif
|
||||
|
||||
/* Defined here to support auto rebuild of tlsoffsets.h. */
|
||||
class tls_pathbuf
|
||||
{
|
||||
int c_cnt;
|
||||
int w_cnt;
|
||||
/* Make sure that c_cnt and w_cnt are always the first two members of this
|
||||
class, and never change the size (32 bit), unless you also change the
|
||||
mov statements in sigbe! */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t c_cnt;
|
||||
uint32_t w_cnt;
|
||||
};
|
||||
uint64_t _counters;
|
||||
};
|
||||
char *c_buf[TP_NUM_C_BUFS];
|
||||
WCHAR *w_buf[TP_NUM_W_BUFS];
|
||||
|
||||
public:
|
||||
void destroy ();
|
||||
friend class tmp_pathbuf;
|
||||
friend class _cygtls;
|
||||
friend class san;
|
||||
};
|
||||
|
||||
|
@ -136,7 +146,6 @@ struct _local_storage
|
|||
/* thread.cc */
|
||||
HANDLE cw_timer;
|
||||
|
||||
/* All functions requiring temporary path buffers. */
|
||||
tls_pathbuf pathbufs;
|
||||
char ttybuf[32];
|
||||
};
|
||||
|
@ -288,31 +297,43 @@ const int CYGTLS_PADSIZE = 12700;
|
|||
extern PVOID _tlsbase __asm__ ("%fs:4");
|
||||
extern PVOID _tlstop __asm__ ("%fs:8");
|
||||
#endif
|
||||
|
||||
#define _my_tls (*((_cygtls *) ((char *)_tlsbase - CYGTLS_PADSIZE)))
|
||||
extern _cygtls *_main_tls;
|
||||
extern _cygtls *_sig_tls;
|
||||
|
||||
#ifdef __x86_64__
|
||||
class san
|
||||
{
|
||||
uint64_t _cnt;
|
||||
public:
|
||||
san () __attribute__ ((always_inline))
|
||||
{
|
||||
_cnt = _my_tls.locals.pathbufs._counters;
|
||||
}
|
||||
/* This is the first thing called in the __except handler. The attribute
|
||||
"returns_twice" makes sure that GCC disregards any register value set
|
||||
earlier in the function, so this call serves as a register barrier. */
|
||||
void leave () __attribute__ ((returns_twice));
|
||||
};
|
||||
#else
|
||||
class san
|
||||
{
|
||||
san *_clemente;
|
||||
jmp_buf _context;
|
||||
int _errno;
|
||||
unsigned _c_cnt;
|
||||
unsigned _w_cnt;
|
||||
uint32_t _c_cnt;
|
||||
uint32_t _w_cnt;
|
||||
public:
|
||||
int setup (int myerrno = 0) __attribute__ ((always_inline))
|
||||
int setup () __attribute__ ((always_inline))
|
||||
{
|
||||
_clemente = _my_tls.andreas;
|
||||
_my_tls.andreas = this;
|
||||
_errno = myerrno;
|
||||
_c_cnt = _my_tls.locals.pathbufs.c_cnt;
|
||||
_w_cnt = _my_tls.locals.pathbufs.w_cnt;
|
||||
return __sjfault (_context);
|
||||
}
|
||||
void leave () __attribute__ ((always_inline))
|
||||
{
|
||||
if (_errno)
|
||||
set_errno (_errno);
|
||||
/* Restore tls_pathbuf counters in case of error. */
|
||||
_my_tls.locals.pathbufs.c_cnt = _c_cnt;
|
||||
_my_tls.locals.pathbufs.w_cnt = _w_cnt;
|
||||
|
@ -331,17 +352,76 @@ public:
|
|||
~myfault () __attribute__ ((always_inline)) { sebastian.reset (); }
|
||||
inline int faulted () __attribute__ ((always_inline))
|
||||
{
|
||||
return sebastian.setup (0);
|
||||
}
|
||||
inline int faulted (void const *obj, int myerrno = 0) __attribute__ ((always_inline))
|
||||
{
|
||||
return !obj || !(*(const char **) obj) || sebastian.setup (myerrno);
|
||||
}
|
||||
inline int faulted (int myerrno) __attribute__ ((always_inline))
|
||||
{
|
||||
return sebastian.setup (myerrno);
|
||||
return sebastian.setup ();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Exception handling macros. These are required because SEH differs a lot
|
||||
between 32 and 64 bit. Essentially, on 64 bit, we have to create compile
|
||||
time SEH tables which define the handler and try/except labels, while on
|
||||
32 bit we can simply set up an SJLJ handler within the myfault class. */
|
||||
#define __mem_barrier __asm__ __volatile__ ("" ::: "memory")
|
||||
#ifdef __x86_64__
|
||||
#define __try \
|
||||
{ \
|
||||
__label__ __l_try, __l_except, __l_endtry; \
|
||||
__mem_barrier; \
|
||||
san __sebastian; \
|
||||
__asm__ goto ("\n" \
|
||||
" .seh_handler _ZN9exception7myfaultEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT, @except \n" \
|
||||
" .seh_handlerdata \n" \
|
||||
" .long 1 \n" \
|
||||
" .rva %l[__l_try],%l[__l_endtry],%l[__l_except],%l[__l_except] \n" \
|
||||
" .seh_code \n" \
|
||||
: : : : __l_try, __l_endtry, __l_except); \
|
||||
{ \
|
||||
__l_try: \
|
||||
__mem_barrier;
|
||||
|
||||
#define __leave \
|
||||
goto __l_endtry
|
||||
|
||||
#define __except(__errno) \
|
||||
goto __l_endtry; \
|
||||
} \
|
||||
{ \
|
||||
__l_except: \
|
||||
__mem_barrier; \
|
||||
__sebastian.leave (); \
|
||||
if (__errno) \
|
||||
set_errno (__errno);
|
||||
|
||||
#define __endtry \
|
||||
} \
|
||||
__l_endtry: \
|
||||
__mem_barrier; \
|
||||
}
|
||||
|
||||
#else /* !__x86_64__ */
|
||||
#define __try \
|
||||
{ \
|
||||
__label__ __l_endtry; \
|
||||
myfault efault; \
|
||||
if (!efault.faulted ()) \
|
||||
{
|
||||
|
||||
#define __leave \
|
||||
goto __l_endtry
|
||||
|
||||
#define __except(__errno) \
|
||||
goto __l_endtry; \
|
||||
} \
|
||||
{ \
|
||||
if (__errno) \
|
||||
set_errno (__errno);
|
||||
|
||||
#define __endtry \
|
||||
} \
|
||||
__l_endtry: \
|
||||
__mem_barrier; \
|
||||
}
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
class set_signal_arrived
|
||||
{
|
||||
|
|
|
@ -393,11 +393,13 @@ check_sanity_and_sync (per_process *p)
|
|||
api_fatal ("cygwin DLL and APP are out of sync -- API version mismatch %u > %u",
|
||||
p->api_major, cygwin_version.api_major);
|
||||
|
||||
#ifndef __x86_64__
|
||||
/* This is a kludge to work around a version of _cygwin_common_crt0
|
||||
which overwrote the cxx_malloc field with the local DLL copy.
|
||||
Hilarity ensues if the DLL is not loaded while the process
|
||||
is forking. */
|
||||
__cygwin_user_data.cxx_malloc = &default_cygwin_cxx_malloc;
|
||||
#endif
|
||||
}
|
||||
|
||||
child_info NO_COPY *child_proc_info;
|
||||
|
@ -517,14 +519,12 @@ initial_env ()
|
|||
{
|
||||
char buf1[NT_MAX_PATH];
|
||||
GetModuleFileName (NULL, buf1, NT_MAX_PATH);
|
||||
strlwr (buf1);
|
||||
strlwr (buf);
|
||||
char *p = strpbrk (buf, ":=");
|
||||
if (!p)
|
||||
p = (char *) "gdb.exe -nw";
|
||||
else
|
||||
*p++ = '\0';
|
||||
if (strstr (buf1, buf))
|
||||
if (strcasestr (buf1, buf))
|
||||
{
|
||||
error_start_init (p);
|
||||
jit_debug = true;
|
||||
|
@ -798,10 +798,6 @@ dll_crt0_0 ()
|
|||
|
||||
_main_tls = &_my_tls;
|
||||
|
||||
#ifdef __x86_64__
|
||||
exception::install_myfault_handler ();
|
||||
#endif
|
||||
|
||||
/* Initialize signal processing here, early, in the hopes that the creation
|
||||
of a thread early in the process will cause more predictability in memory
|
||||
layout for the main thread. */
|
||||
|
@ -936,14 +932,14 @@ dll_crt0_1 (void *)
|
|||
/* Allocate cygheap->fdtab */
|
||||
dtable_init ();
|
||||
|
||||
/* Set internal locale to the environment settings. */
|
||||
initial_setlocale ();
|
||||
|
||||
uinfo_init (); /* initialize user info */
|
||||
|
||||
/* Connect to tty. */
|
||||
tty::init_session ();
|
||||
|
||||
/* Set internal locale to the environment settings. */
|
||||
initial_setlocale ();
|
||||
|
||||
if (!__argc)
|
||||
{
|
||||
PWCHAR wline = GetCommandLineW ();
|
||||
|
@ -1235,11 +1231,62 @@ do_exit (int status)
|
|||
myself.exit (n);
|
||||
}
|
||||
|
||||
/* When introducing support for -fuse-cxa-atexit with Cygwin 1.7.32 and
|
||||
GCC 4.8.3-3, we defined __dso_value as &ImageBase. This supposedly allowed
|
||||
a reproducible value which could also be easily evaluated in cygwin_atexit.
|
||||
However, when building C++ applications with -fuse-cxa-atexit, G++ creates
|
||||
calls to __cxa_atexit using the *address* of __dso_handle as DSO handle.
|
||||
|
||||
So what we do here is this: A call to __cxa_atexit from the application
|
||||
actually calls cygwin__cxa_atexit. From dso_handle (which is either
|
||||
&__dso_handle, or __dso_handle == ImageBase or NULL) we fetch the dll
|
||||
structure of the DLL. Then use dll::handle == ImageBase as the actual DSO
|
||||
handle value in calls to __cxa_atexit and __cxa_finalize.
|
||||
Thus, __cxa_atexit becomes entirely independent of the incoming value of
|
||||
dso_handle, as long as it's *some* pointer into the DSO's address space. */
|
||||
extern "C" int
|
||||
cygwin__cxa_atexit (void (*fn)(void *), void *obj, void *dso_handle)
|
||||
{
|
||||
dll *d = dso_handle ? dlls.find (dso_handle) : NULL;
|
||||
return __cxa_atexit (fn, obj, d ? d->handle : NULL);
|
||||
}
|
||||
|
||||
/* This function is only called for applications built with Cygwin versions
|
||||
up to API 0.279. Starting with API 0.280 (Cygwin 1.7.33/1.8.6-2), atexit
|
||||
is a statically linked function inside of libcygwin.a. The reason is that
|
||||
the old method to fetch the caller return address is unreliable given GCCs
|
||||
ability to perform tail call elimination. For the details, see the below
|
||||
comment. The atexit replacement is defined in libcygwin.a to allow reliable
|
||||
access to the correct DSO handle. */
|
||||
extern "C" int
|
||||
cygwin_atexit (void (*fn) (void))
|
||||
{
|
||||
int res;
|
||||
|
||||
dll *d = dlls.find ((void *) _my_tls.retaddr ());
|
||||
#ifdef __x86_64__
|
||||
/* x86_64 DLLs created with GCC 4.8.3-3 register __gcc_deregister_frame
|
||||
as atexit function using a call to atexit, rather than __cxa_atexit.
|
||||
Due to GCC's tail call optimizing, cygwin_atexit doesn't get the correct
|
||||
return address on the stack. As a result it fails to get the HMODULE of
|
||||
the caller and thus calls atexit rather than __cxa_atexit. Then, if the
|
||||
module gets dlclosed, __cxa_finalize (called from dll_list::detach) can't
|
||||
remove __gcc_deregister_frame from the atexit function chain. So at
|
||||
process exit, __call_exitprocs calls __gcc_deregister_frame while the
|
||||
module is already unloaded and the __gcc_deregister_frame function not
|
||||
available ==> SEGV.
|
||||
|
||||
This also occurs for other functions.
|
||||
|
||||
Workaround: If dlls.find fails, try to find the dll entry of the DLL
|
||||
containing fn. If that works, proceed by calling __cxa_atexit, otherwise
|
||||
call atexit.
|
||||
|
||||
This *should* be sufficiently safe. Ultimately, new applications will
|
||||
use the statically linked atexit function though, as outlined above. */
|
||||
if (!d)
|
||||
d = dlls.find ((void *) fn);
|
||||
#endif
|
||||
res = d ? __cxa_atexit ((void (*) (void *)) fn, NULL, d->handle) : atexit (fn);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -28,16 +28,16 @@ details. */
|
|||
extern "C" int
|
||||
dirfd (DIR *dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
__try
|
||||
{
|
||||
set_errno (EBADF);
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
return dir->__d_fd;
|
||||
syscall_printf ("-1 = dirfd (%p)", dir);
|
||||
return -1;
|
||||
set_errno (EINVAL);
|
||||
}
|
||||
return dir->__d_fd;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Symbol kept for backward compatibility. Don't remove. Don't declare
|
||||
|
@ -93,79 +93,86 @@ fdopendir (int fd)
|
|||
static int
|
||||
readdir_worker (DIR *dir, dirent *de)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return EFAULT;
|
||||
int res = 0;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
__try
|
||||
{
|
||||
syscall_printf ("%p = readdir (%p)", NULL, dir);
|
||||
return EBADF;
|
||||
}
|
||||
|
||||
de->d_ino = 0;
|
||||
de->d_type = DT_UNKNOWN;
|
||||
memset (&de->__d_unused1, 0, sizeof (de->__d_unused1));
|
||||
|
||||
int res = ((fhandler_base *) dir->__fh)->readdir (dir, de);
|
||||
|
||||
if (res == ENMFILE)
|
||||
{
|
||||
if (!(dir->__flags & dirent_saw_dot))
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
{
|
||||
strcpy (de->d_name, ".");
|
||||
dir->__flags |= dirent_saw_dot;
|
||||
dir->__d_position++;
|
||||
res = 0;
|
||||
}
|
||||
else if (!(dir->__flags & dirent_saw_dot_dot))
|
||||
{
|
||||
strcpy (de->d_name, "..");
|
||||
dir->__flags |= dirent_saw_dot_dot;
|
||||
dir->__d_position++;
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!res && !de->d_ino)
|
||||
{
|
||||
bool is_dot = false;
|
||||
bool is_dot_dot = false;
|
||||
|
||||
if (de->d_name[0] == '.')
|
||||
{
|
||||
if (de->d_name[1] == '\0')
|
||||
is_dot = true;
|
||||
else if (de->d_name[1] == '.' && de->d_name[2] == '\0')
|
||||
is_dot_dot = true;
|
||||
syscall_printf ("%p = readdir (%p)", NULL, dir);
|
||||
res = EBADF;
|
||||
__leave;
|
||||
}
|
||||
|
||||
if (is_dot_dot && !(dir->__flags & dirent_isroot))
|
||||
de->d_ino = readdir_get_ino (((fhandler_base *) dir->__fh)->get_name (),
|
||||
true);
|
||||
else
|
||||
de->d_ino = 0;
|
||||
de->d_type = DT_UNKNOWN;
|
||||
memset (&de->__d_unused1, 0, sizeof (de->__d_unused1));
|
||||
|
||||
res = ((fhandler_base *) dir->__fh)->readdir (dir, de);
|
||||
|
||||
if (res == ENMFILE)
|
||||
{
|
||||
/* Compute d_ino by combining filename hash with directory hash. */
|
||||
de->d_ino = ((fhandler_base *) dir->__fh)->get_ino ();
|
||||
if (!is_dot && !is_dot_dot)
|
||||
if (!(dir->__flags & dirent_saw_dot))
|
||||
{
|
||||
PUNICODE_STRING w32name =
|
||||
((fhandler_base *) dir->__fh)->pc.get_nt_native_path ();
|
||||
DWORD devn = ((fhandler_base *) dir->__fh)->get_device ();
|
||||
/* Paths below /proc don't have a Win32 pendant. */
|
||||
if (isproc_dev (devn))
|
||||
de->d_ino = hash_path_name (de->d_ino, L"/");
|
||||
else if (w32name->Buffer[w32name->Length / sizeof (WCHAR) - 1]
|
||||
!= L'\\')
|
||||
de->d_ino = hash_path_name (de->d_ino, L"\\");
|
||||
de->d_ino = hash_path_name (de->d_ino, de->d_name);
|
||||
strcpy (de->d_name, ".");
|
||||
dir->__flags |= dirent_saw_dot;
|
||||
dir->__d_position++;
|
||||
res = 0;
|
||||
}
|
||||
else if (!(dir->__flags & dirent_saw_dot_dot))
|
||||
{
|
||||
strcpy (de->d_name, "..");
|
||||
dir->__flags |= dirent_saw_dot_dot;
|
||||
dir->__d_position++;
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* This fills out the old 32 bit d_ino field for old applications,
|
||||
build under Cygwin before 1.5.x. */
|
||||
de->__d_internal1 = de->d_ino;
|
||||
|
||||
if (!res && !de->d_ino)
|
||||
{
|
||||
bool is_dot = false;
|
||||
bool is_dot_dot = false;
|
||||
|
||||
if (de->d_name[0] == '.')
|
||||
{
|
||||
if (de->d_name[1] == '\0')
|
||||
is_dot = true;
|
||||
else if (de->d_name[1] == '.' && de->d_name[2] == '\0')
|
||||
is_dot_dot = true;
|
||||
}
|
||||
|
||||
if (is_dot_dot && !(dir->__flags & dirent_isroot))
|
||||
de->d_ino = readdir_get_ino (((fhandler_base *)
|
||||
dir->__fh)->get_name (),
|
||||
true);
|
||||
else
|
||||
{
|
||||
/* Compute d_ino by combining filename hash with directory hash. */
|
||||
de->d_ino = ((fhandler_base *) dir->__fh)->get_ino ();
|
||||
if (!is_dot && !is_dot_dot)
|
||||
{
|
||||
PUNICODE_STRING w32name =
|
||||
((fhandler_base *) dir->__fh)->pc.get_nt_native_path ();
|
||||
DWORD devn = ((fhandler_base *) dir->__fh)->get_device ();
|
||||
/* Paths below /proc don't have a Win32 pendant. */
|
||||
if (isproc_dev (devn))
|
||||
de->d_ino = hash_path_name (de->d_ino, L"/");
|
||||
else if (w32name->Buffer[w32name->Length / sizeof (WCHAR) - 1]
|
||||
!= L'\\')
|
||||
de->d_ino = hash_path_name (de->d_ino, L"\\");
|
||||
de->d_ino = hash_path_name (de->d_ino, de->d_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* This fills out the old 32 bit d_ino field for old applications,
|
||||
build under Cygwin before 1.5.x. */
|
||||
de->__d_internal1 = de->d_ino;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
res = EFAULT;
|
||||
}
|
||||
__endtry
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -200,13 +207,15 @@ readdir_r (DIR *__restrict dir, dirent *__restrict de, dirent **__restrict ode)
|
|||
extern "C" long
|
||||
telldir (DIR *dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
return 0;
|
||||
return ((fhandler_base *) dir->__fh)->telldir (dir);
|
||||
__try
|
||||
{
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
return ((fhandler_base *) dir->__fh)->telldir (dir);
|
||||
set_errno (EBADF);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* telldir was never defined using off_t in POSIX, only in early versions
|
||||
|
@ -222,14 +231,17 @@ telldir64 (DIR *dir)
|
|||
extern "C" void
|
||||
seekdir (DIR *dir, long loc)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
return;
|
||||
dir->__flags &= dirent_info_mask;
|
||||
return ((fhandler_base *) dir->__fh)->seekdir (dir, loc);
|
||||
__try
|
||||
{
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
{
|
||||
dir->__flags &= dirent_info_mask;
|
||||
((fhandler_base *) dir->__fh)->seekdir (dir, loc);
|
||||
}
|
||||
set_errno (EINVAL); /* Diagnosis */
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
}
|
||||
|
||||
/* seekdir was never defined using off_t in POSIX, only in early versions
|
||||
|
@ -245,42 +257,45 @@ seekdir64 (DIR *dir, off_t loc)
|
|||
extern "C" void
|
||||
rewinddir (DIR *dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
return;
|
||||
dir->__flags &= dirent_info_mask;
|
||||
return ((fhandler_base *) dir->__fh)->rewinddir (dir);
|
||||
__try
|
||||
{
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
{
|
||||
dir->__flags &= dirent_info_mask;
|
||||
((fhandler_base *) dir->__fh)->rewinddir (dir);
|
||||
}
|
||||
set_errno (EINVAL); /* Diagnosis */
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
}
|
||||
|
||||
/* closedir: POSIX 5.1.2.1 */
|
||||
extern "C" int
|
||||
closedir (DIR *dir)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
if (dir->__d_cookie != __DIRENT_COOKIE)
|
||||
__try
|
||||
{
|
||||
if (dir->__d_cookie == __DIRENT_COOKIE)
|
||||
{
|
||||
/* Reset the marker in case the caller tries to use `dir' again. */
|
||||
dir->__d_cookie = 0;
|
||||
|
||||
int res = ((fhandler_base *) dir->__fh)->closedir (dir);
|
||||
|
||||
close (dir->__d_fd);
|
||||
free (dir->__d_dirname);
|
||||
free (dir->__d_dirent);
|
||||
free (dir);
|
||||
syscall_printf ("%R = closedir(%p)", res, dir);
|
||||
return res;
|
||||
}
|
||||
set_errno (EBADF);
|
||||
syscall_printf ("%R = closedir(%p)", -1, dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Reset the marker in case the caller tries to use `dir' again. */
|
||||
dir->__d_cookie = 0;
|
||||
|
||||
int res = ((fhandler_base *) dir->__fh)->closedir (dir);
|
||||
|
||||
close (dir->__d_fd);
|
||||
free (dir->__d_dirname);
|
||||
free (dir->__d_dirent);
|
||||
free (dir);
|
||||
syscall_printf ("%R = closedir(%p)", res, dir);
|
||||
return res;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = closedir(%p)", -1, dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* mkdir: POSIX 5.4.1.1 */
|
||||
|
@ -291,43 +306,42 @@ mkdir (const char *dir, mode_t mode)
|
|||
fhandler_base *fh = NULL;
|
||||
tmp_pathbuf tp;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
/* POSIX says mkdir("symlink-to-missing/") should create the
|
||||
directory "missing", but Linux rejects it with EEXIST. Copy
|
||||
Linux behavior for now. */
|
||||
|
||||
if (!*dir)
|
||||
__try
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
goto done;
|
||||
}
|
||||
if (isdirsep (dir[strlen (dir) - 1]))
|
||||
{
|
||||
/* This converts // to /, but since both give EEXIST, we're okay. */
|
||||
char *buf;
|
||||
char *p = stpcpy (buf = tp.c_get (), dir) - 1;
|
||||
dir = buf;
|
||||
while (p > dir && isdirsep (*p))
|
||||
*p-- = '\0';
|
||||
}
|
||||
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
||||
goto done; /* errno already set */;
|
||||
/* POSIX says mkdir("symlink-to-missing/") should create the
|
||||
directory "missing", but Linux rejects it with EEXIST. Copy
|
||||
Linux behavior for now. */
|
||||
|
||||
if (fh->error ())
|
||||
{
|
||||
debug_printf ("got %d error from build_fh_name", fh->error ());
|
||||
set_errno (fh->error ());
|
||||
}
|
||||
else if (has_dot_last_component (dir, true))
|
||||
set_errno (fh->exists () ? EEXIST : ENOENT);
|
||||
else if (!fh->mkdir (mode))
|
||||
res = 0;
|
||||
delete fh;
|
||||
if (!*dir)
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
__leave;
|
||||
}
|
||||
if (isdirsep (dir[strlen (dir) - 1]))
|
||||
{
|
||||
/* This converts // to /, but since both give EEXIST, we're okay. */
|
||||
char *buf;
|
||||
char *p = stpcpy (buf = tp.c_get (), dir) - 1;
|
||||
dir = buf;
|
||||
while (p > dir && isdirsep (*p))
|
||||
*p-- = '\0';
|
||||
}
|
||||
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
||||
__leave; /* errno already set */;
|
||||
|
||||
done:
|
||||
if (fh->error ())
|
||||
{
|
||||
debug_printf ("got %d error from build_fh_name", fh->error ());
|
||||
set_errno (fh->error ());
|
||||
}
|
||||
else if (has_dot_last_component (dir, true))
|
||||
set_errno (fh->exists () ? EEXIST : ENOENT);
|
||||
else if (!fh->mkdir (mode))
|
||||
res = 0;
|
||||
delete fh;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = mkdir(%s, %d)", res, dir, mode);
|
||||
return res;
|
||||
}
|
||||
|
@ -339,33 +353,28 @@ rmdir (const char *dir)
|
|||
int res = -1;
|
||||
fhandler_base *fh = NULL;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
||||
goto done; /* errno already set */;
|
||||
|
||||
if (fh->error ())
|
||||
__try
|
||||
{
|
||||
debug_printf ("got %d error from build_fh_name", fh->error ());
|
||||
set_errno (fh->error ());
|
||||
}
|
||||
else if (!fh->exists ())
|
||||
set_errno (ENOENT);
|
||||
else if (has_dot_last_component (dir, false))
|
||||
set_errno (EINVAL);
|
||||
else if (isdev_dev (fh->dev ()))
|
||||
{
|
||||
set_errno (ENOTEMPTY);
|
||||
goto done;
|
||||
}
|
||||
else if (!fh->rmdir ())
|
||||
res = 0;
|
||||
if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
|
||||
__leave; /* errno already set */;
|
||||
|
||||
delete fh;
|
||||
|
||||
done:
|
||||
if (fh->error ())
|
||||
{
|
||||
debug_printf ("got %d error from build_fh_name", fh->error ());
|
||||
set_errno (fh->error ());
|
||||
}
|
||||
else if (!fh->exists ())
|
||||
set_errno (ENOENT);
|
||||
else if (has_dot_last_component (dir, false))
|
||||
set_errno (EINVAL);
|
||||
else if (isdev_dev (fh->dev ()))
|
||||
set_errno (ENOTEMPTY);
|
||||
else if (!fh->rmdir ())
|
||||
res = 0;
|
||||
delete fh;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = rmdir(%s)", res, dir);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* dlfcn.cc
|
||||
|
||||
Copyright 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||
2010, 2011, 2013 Red Hat, Inc.
|
||||
2010, 2011, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -20,7 +20,7 @@ details. */
|
|||
#include "tls_pbuf.h"
|
||||
#include "ntdll.h"
|
||||
|
||||
static void __stdcall
|
||||
static void
|
||||
set_dl_error (const char *str)
|
||||
{
|
||||
strcpy (_my_tls.locals.dl_buffer, strerror (get_errno ()));
|
||||
|
@ -30,10 +30,10 @@ set_dl_error (const char *str)
|
|||
/* Look for an executable file given the name and the environment
|
||||
variable to use for searching (eg., PATH); returns the full
|
||||
pathname (static buffer) if found or NULL if not. */
|
||||
inline const char * __stdcall
|
||||
inline const char *
|
||||
check_path_access (const char *mywinenv, const char *name, path_conv& buf)
|
||||
{
|
||||
return find_exec (name, buf, mywinenv, FE_NNF | FE_NATIVE | FE_CWD | FE_DLL);
|
||||
return find_exec (name, buf, mywinenv, FE_NNF | FE_NATIVE | FE_DLL);
|
||||
}
|
||||
|
||||
/* Search LD_LIBRARY_PATH for dll, if it exists. Search /usr/bin and /usr/lib
|
||||
|
@ -41,7 +41,7 @@ check_path_access (const char *mywinenv, const char *name, path_conv& buf)
|
|||
static inline bool
|
||||
gfpod_helper (const char *name, path_conv &real_filename)
|
||||
{
|
||||
if (isabspath (name))
|
||||
if (strchr (name, '/'))
|
||||
real_filename.check (name, PC_SYM_FOLLOW | PC_NULLEMPTY);
|
||||
else if (!check_path_access ("LD_LIBRARY_PATH=", name, real_filename))
|
||||
check_path_access ("/usr/bin:/usr/lib", name, real_filename);
|
||||
|
@ -50,7 +50,7 @@ gfpod_helper (const char *name, path_conv &real_filename)
|
|||
return !real_filename.error;
|
||||
}
|
||||
|
||||
static bool __stdcall
|
||||
static bool
|
||||
get_full_path_of_dll (const char* str, path_conv &real_filename)
|
||||
{
|
||||
int len = strlen (str);
|
||||
|
@ -135,6 +135,7 @@ dlopen (const char *name, int flags)
|
|||
if (last_bs && !wcschr (last_bs, L'.'))
|
||||
wcscat (last_bs, L".");
|
||||
|
||||
#ifndef __x86_64__
|
||||
/* Workaround for broken DLLs built against Cygwin versions 1.7.0-49
|
||||
up to 1.7.0-57. They override the cxx_malloc pointer in their
|
||||
DLL initialization code even if loaded dynamically. This is a
|
||||
|
@ -150,18 +151,20 @@ dlopen (const char *name, int flags)
|
|||
/* Store original cxx_malloc pointer. */
|
||||
struct per_process_cxx_malloc *tmp_malloc;
|
||||
tmp_malloc = __cygwin_user_data.cxx_malloc;
|
||||
#endif
|
||||
|
||||
if (!(flags & RTLD_NOLOAD)
|
||||
|| (ret = GetModuleHandleW (path)) != NULL)
|
||||
{
|
||||
ret = (void *) LoadLibraryW (path);
|
||||
if (ret && (flags & RTLD_NODELETE))
|
||||
GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_PIN, path,
|
||||
(HMODULE *) &ret);
|
||||
}
|
||||
if (flags & RTLD_NOLOAD)
|
||||
GetModuleHandleExW (0, path, (HMODULE *) &ret);
|
||||
else
|
||||
ret = (void *) LoadLibraryW (path);
|
||||
if (ret && (flags & RTLD_NODELETE))
|
||||
GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_PIN, path,
|
||||
(HMODULE *) &ret);
|
||||
|
||||
#ifndef __x86_64__
|
||||
/* Restore original cxx_malloc pointer. */
|
||||
__cygwin_user_data.cxx_malloc = tmp_malloc;
|
||||
#endif
|
||||
|
||||
if (!ret)
|
||||
__seterrno ();
|
||||
|
|
|
@ -640,7 +640,7 @@ dll_dllcrt0_1 (VOID *x)
|
|||
when loaded either statically or dynamically. Because this leaves
|
||||
a stale pointer into demapped memory space if the DLL is unloaded
|
||||
by a call to dlclose, we prevent this happening for dynamically
|
||||
loaded DLLS in dlopen by saving and restoring cxx_malloc around
|
||||
loaded DLLs in dlopen by saving and restoring cxx_malloc around
|
||||
the call to LoadLibrary, which invokes the DLL's startup sequence.
|
||||
Modern DLLs won't even attempt to override the pointer when loaded
|
||||
statically, but will write their overrides directly into the
|
||||
|
|
|
@ -371,9 +371,10 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
|
|||
FILE_ACCESS_INFORMATION fai;
|
||||
int openflags = O_BINARY;
|
||||
|
||||
/* Console windows are not kernel objects, so the access mask returned
|
||||
by NtQueryInformationFile is meaningless. CMD always hands down
|
||||
stdin handles as R/O handles, but our tty slave sides are R/W. */
|
||||
/* Console windows are no kernel objects up to Windows 7/2008R2, so the
|
||||
access mask returned by NtQueryInformationFile is meaningless. CMD
|
||||
always hands down stdin handles as R/O handles, but our tty slave
|
||||
sides are R/W. */
|
||||
if (fh->is_tty ())
|
||||
{
|
||||
openflags |= O_RDWR;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
process's environment.
|
||||
|
||||
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
|
||||
2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
|
@ -396,18 +396,15 @@ win_env::add_cache (const char *in_posix, const char *in_native)
|
|||
if (in_native)
|
||||
{
|
||||
native = (char *) realloc (native, namelen + 1 + strlen (in_native));
|
||||
strcpy (native, name);
|
||||
strcpy (native + namelen, in_native);
|
||||
stpcpy (stpcpy (native, name), in_native);
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_pathbuf tp;
|
||||
char *buf = tp.c_get ();
|
||||
strcpy (buf, name + namelen);
|
||||
towin32 (in_posix, buf, NT_MAX_PATH);
|
||||
native = (char *) realloc (native, namelen + 1 + strlen (buf));
|
||||
strcpy (native, name);
|
||||
strcpy (native + namelen, buf);
|
||||
stpcpy (stpcpy (native, name), buf);
|
||||
}
|
||||
MALLOC_CHECK;
|
||||
if (immediate && cygwin_finished_initializing)
|
||||
|
@ -480,8 +477,9 @@ posify_maybe (char **here, const char *value, char *outenv)
|
|||
{
|
||||
/* The conversion routine removed elements from a path list so we have
|
||||
to recalculate the windows path to remove elements there, too. */
|
||||
char cleanvalue[strlen (value) + 1];
|
||||
conv->towin32 (newvalue, cleanvalue, sizeof cleanvalue);
|
||||
tmp_pathbuf tp;
|
||||
char *cleanvalue = tp.c_get ();
|
||||
conv->towin32 (newvalue, cleanvalue, NT_MAX_PATH);
|
||||
conv->add_cache (newvalue, cleanvalue);
|
||||
}
|
||||
|
||||
|
@ -664,19 +662,22 @@ _addenv (const char *name, const char *value, int overwrite)
|
|||
extern "C" int
|
||||
putenv (char *str)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (*str)
|
||||
__try
|
||||
{
|
||||
char *eq = strchr (str, '=');
|
||||
if (eq)
|
||||
return _addenv (str, eq + 1, -1);
|
||||
if (*str)
|
||||
{
|
||||
char *eq = strchr (str, '=');
|
||||
if (eq)
|
||||
return _addenv (str, eq + 1, -1);
|
||||
|
||||
/* Remove str from the environment. */
|
||||
unsetenv (str);
|
||||
/* Remove str from the environment. */
|
||||
unsetenv (str);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the value of the environment variable "name" to be
|
||||
|
@ -684,15 +685,18 @@ putenv (char *str)
|
|||
extern "C" int
|
||||
setenv (const char *name, const char *value, int overwrite)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (!name || !*name || strchr (name, '='))
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (!name || !*name || strchr (name, '='))
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
return _addenv (name, value, !!overwrite);
|
||||
}
|
||||
return _addenv (name, value, !!overwrite);
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Delete environment variable "name". */
|
||||
|
@ -701,22 +705,26 @@ unsetenv (const char *name)
|
|||
{
|
||||
register char **e;
|
||||
int offset;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (!name || *name == '\0' || strchr (name, '='))
|
||||
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (!name || *name == '\0' || strchr (name, '='))
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
|
||||
while (my_findenv (name, &offset)) /* if set multiple times */
|
||||
/* Move up the rest of the array */
|
||||
for (e = cur_environ () + offset; ; e++)
|
||||
if (!(*e = *(e + 1)))
|
||||
break;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (my_findenv (name, &offset)) /* if set multiple times */
|
||||
/* Move up the rest of the array */
|
||||
for (e = cur_environ () + offset; ; e++)
|
||||
if (!(*e = *(e + 1)))
|
||||
break;
|
||||
|
||||
return 0;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Minimal list of Windows vars which must be converted to uppercase.
|
||||
|
@ -822,96 +830,101 @@ environ_init (char **envp, int envc)
|
|||
bool envp_passed_in;
|
||||
bool got_something_from_registry;
|
||||
static char NO_COPY cygterm[] = "TERM=cygwin";
|
||||
myfault efault;
|
||||
tmp_pathbuf tp;
|
||||
|
||||
if (efault.faulted ())
|
||||
api_fatal ("internal error reading the windows environment - too many environment variables?");
|
||||
|
||||
char *tmpbuf = tp.t_get ();
|
||||
got_something_from_registry = regopt (L"default", tmpbuf);
|
||||
if (myself->progname[0])
|
||||
got_something_from_registry = regopt (myself->progname, tmpbuf)
|
||||
|| got_something_from_registry;
|
||||
|
||||
if (!envp)
|
||||
envp_passed_in = 0;
|
||||
else
|
||||
__try
|
||||
{
|
||||
envc++;
|
||||
envc *= sizeof (char *);
|
||||
char **newenv = (char **) malloc (envc);
|
||||
memcpy (newenv, envp, envc);
|
||||
cfree (envp);
|
||||
char *tmpbuf = tp.t_get ();
|
||||
got_something_from_registry = regopt (L"default", tmpbuf);
|
||||
if (myself->progname[0])
|
||||
got_something_from_registry = regopt (myself->progname, tmpbuf)
|
||||
|| got_something_from_registry;
|
||||
|
||||
/* Older applications relied on the fact that cygwin malloced elements of the
|
||||
environment list. */
|
||||
envp = newenv;
|
||||
if (ENVMALLOC)
|
||||
for (char **e = newenv; *e; e++)
|
||||
{
|
||||
char *p = *e;
|
||||
*e = strdup (p);
|
||||
cfree (p);
|
||||
}
|
||||
envp_passed_in = 1;
|
||||
goto out;
|
||||
if (!envp)
|
||||
envp_passed_in = 0;
|
||||
else
|
||||
{
|
||||
envc++;
|
||||
envc *= sizeof (char *);
|
||||
char **newenv = (char **) malloc (envc);
|
||||
memcpy (newenv, envp, envc);
|
||||
cfree (envp);
|
||||
|
||||
/* Older applications relied on the fact that cygwin malloced elements of the
|
||||
environment list. */
|
||||
envp = newenv;
|
||||
if (ENVMALLOC)
|
||||
for (char **e = newenv; *e; e++)
|
||||
{
|
||||
char *p = *e;
|
||||
*e = strdup (p);
|
||||
cfree (p);
|
||||
}
|
||||
envp_passed_in = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Allocate space for environment + trailing NULL + CYGWIN env. */
|
||||
lastenviron = envp = (char **) malloc ((4 + (envc = 100)) * sizeof (char *));
|
||||
|
||||
rawenv = GetEnvironmentStringsW ();
|
||||
if (!rawenv)
|
||||
{
|
||||
system_printf ("GetEnvironmentStrings returned NULL, %E");
|
||||
return;
|
||||
}
|
||||
debug_printf ("GetEnvironmentStrings returned %p", rawenv);
|
||||
|
||||
/* Current directory information is recorded as variables of the
|
||||
form "=X:=X:\foo\bar; these must be changed into something legal
|
||||
(we could just ignore them but maybe an application will
|
||||
eventually want to use them). */
|
||||
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
|
||||
{
|
||||
sys_wcstombs_alloc (&newp, HEAP_NOTHEAP, w);
|
||||
if (i >= envc)
|
||||
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
|
||||
envp[i] = newp;
|
||||
if (*newp == '=')
|
||||
*newp = '!';
|
||||
char *eq = strchrnul (newp, '=');
|
||||
ucenv (newp, eq); /* uppercase env vars which need it */
|
||||
if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
|
||||
sawTERM = 1;
|
||||
else if (*newp == 'C' && strncmp (newp, "CYGWIN=", 7) == 0)
|
||||
parse_options (newp + 7);
|
||||
if (*eq)
|
||||
posify_maybe (envp + i, *++eq ? eq : --eq, tmpbuf);
|
||||
debug_printf ("%p: %s", envp[i], envp[i]);
|
||||
}
|
||||
|
||||
if (!sawTERM)
|
||||
envp[i++] = strdup (cygterm);
|
||||
envp[i] = NULL;
|
||||
FreeEnvironmentStringsW (rawenv);
|
||||
|
||||
out:
|
||||
findenv_func = (char * (*)(const char*, int*)) my_findenv;
|
||||
__cygwin_environ = envp;
|
||||
update_envptrs ();
|
||||
if (envp_passed_in)
|
||||
{
|
||||
p = getenv ("CYGWIN");
|
||||
if (p)
|
||||
parse_options (p);
|
||||
}
|
||||
|
||||
if (got_something_from_registry)
|
||||
parse_options (NULL); /* possibly export registry settings to
|
||||
environment */
|
||||
MALLOC_CHECK;
|
||||
}
|
||||
|
||||
/* Allocate space for environment + trailing NULL + CYGWIN env. */
|
||||
lastenviron = envp = (char **) malloc ((4 + (envc = 100)) * sizeof (char *));
|
||||
|
||||
rawenv = GetEnvironmentStringsW ();
|
||||
if (!rawenv)
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
system_printf ("GetEnvironmentStrings returned NULL, %E");
|
||||
return;
|
||||
api_fatal ("internal error reading the windows environment "
|
||||
"- too many environment variables?");
|
||||
}
|
||||
debug_printf ("GetEnvironmentStrings returned %p", rawenv);
|
||||
|
||||
/* Current directory information is recorded as variables of the
|
||||
form "=X:=X:\foo\bar; these must be changed into something legal
|
||||
(we could just ignore them but maybe an application will
|
||||
eventually want to use them). */
|
||||
for (i = 0, w = rawenv; *w != L'\0'; w = wcschr (w, L'\0') + 1, i++)
|
||||
{
|
||||
sys_wcstombs_alloc (&newp, HEAP_NOTHEAP, w);
|
||||
if (i >= envc)
|
||||
envp = (char **) realloc (envp, (4 + (envc += 100)) * sizeof (char *));
|
||||
envp[i] = newp;
|
||||
if (*newp == '=')
|
||||
*newp = '!';
|
||||
char *eq = strchrnul (newp, '=');
|
||||
ucenv (newp, eq); /* uppercase env vars which need it */
|
||||
if (*newp == 'T' && strncmp (newp, "TERM=", 5) == 0)
|
||||
sawTERM = 1;
|
||||
else if (*newp == 'C' && strncmp (newp, "CYGWIN=", 7) == 0)
|
||||
parse_options (newp + 7);
|
||||
if (*eq)
|
||||
posify_maybe (envp + i, *++eq ? eq : --eq, tmpbuf);
|
||||
debug_printf ("%p: %s", envp[i], envp[i]);
|
||||
}
|
||||
|
||||
if (!sawTERM)
|
||||
envp[i++] = strdup (cygterm);
|
||||
envp[i] = NULL;
|
||||
FreeEnvironmentStringsW (rawenv);
|
||||
|
||||
out:
|
||||
findenv_func = (char * (*)(const char*, int*)) my_findenv;
|
||||
__cygwin_environ = envp;
|
||||
update_envptrs ();
|
||||
if (envp_passed_in)
|
||||
{
|
||||
p = getenv ("CYGWIN");
|
||||
if (p)
|
||||
parse_options (p);
|
||||
}
|
||||
|
||||
if (got_something_from_registry)
|
||||
parse_options (NULL); /* possibly export registry settings to
|
||||
environment */
|
||||
MALLOC_CHECK;
|
||||
__endtry
|
||||
}
|
||||
|
||||
/* Function called by qsort to sort environment strings. */
|
||||
|
@ -1017,6 +1030,21 @@ spenv::retrieve (bool no_envblock, const char *const env)
|
|||
return getwinenveq (name, namelen, HEAP_1_STR);
|
||||
}
|
||||
|
||||
static inline int
|
||||
raise_envblock (int new_tl, PWCHAR &envblock, PWCHAR &s)
|
||||
{
|
||||
int tl = new_tl + 100;
|
||||
PWCHAR new_envblock =
|
||||
(PWCHAR) realloc (envblock, (2 + tl) * sizeof (WCHAR));
|
||||
/* If realloc moves the block, move `s' with it. */
|
||||
if (new_envblock != envblock)
|
||||
{
|
||||
s += new_envblock - envblock;
|
||||
envblock = new_envblock;
|
||||
}
|
||||
return tl;
|
||||
}
|
||||
|
||||
#define SPENVS_SIZE (sizeof (spenvs) / sizeof (spenvs[0]))
|
||||
|
||||
/* Create a Windows-style environment block, i.e. a typical character buffer
|
||||
|
@ -1081,14 +1109,14 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
|
|||
for (unsigned i = 0; i < SPENVS_SIZE; i++)
|
||||
if (!saw_spenv[i] && (spenvs[i].force_into_environment || cygheap->user.issetuid ()))
|
||||
{
|
||||
*dstp = spenvs[i].retrieve (false);
|
||||
if (*dstp && *dstp != env_dontadd)
|
||||
{
|
||||
*pass_dstp++ = *dstp;
|
||||
tl += strlen (*dstp) + 1;
|
||||
dstp++;
|
||||
}
|
||||
}
|
||||
*dstp = spenvs[i].retrieve (false);
|
||||
if (*dstp && *dstp != env_dontadd)
|
||||
{
|
||||
*pass_dstp++ = *dstp;
|
||||
tl += strlen (*dstp) + 1;
|
||||
dstp++;
|
||||
}
|
||||
}
|
||||
|
||||
envc = dstp - newenv; /* Number of entries in newenv */
|
||||
assert ((size_t) envc <= (n + SPENVS_SIZE));
|
||||
|
@ -1111,6 +1139,7 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
|
|||
PWCHAR s;
|
||||
envblock = (PWCHAR) malloc ((2 + tl) * sizeof (WCHAR));
|
||||
int new_tl = 0;
|
||||
bool saw_PATH = false;
|
||||
for (srcp = pass_env, s = envblock; *srcp; srcp++)
|
||||
{
|
||||
const char *p;
|
||||
|
@ -1129,7 +1158,17 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
|
|||
/* See if this entry requires posix->win32 conversion. */
|
||||
conv = getwinenv (*srcp, rest, &temp);
|
||||
if (conv)
|
||||
p = conv->native; /* Use win32 path */
|
||||
{
|
||||
p = conv->native; /* Use win32 path */
|
||||
/* Does PATH exist in the environment? */
|
||||
if (**srcp == 'P')
|
||||
{
|
||||
/* And is it non-empty? */
|
||||
if (!conv->native || !conv->native[0])
|
||||
continue;
|
||||
saw_PATH = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
p = *srcp; /* Don't worry about it */
|
||||
|
||||
|
@ -1138,19 +1177,9 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
|
|||
|
||||
/* See if we need to increase the size of the block. */
|
||||
if (new_tl > tl)
|
||||
{
|
||||
tl = new_tl + 100;
|
||||
PWCHAR new_envblock =
|
||||
(PWCHAR) realloc (envblock, (2 + tl) * sizeof (WCHAR));
|
||||
/* If realloc moves the block, move `s' with it. */
|
||||
if (new_envblock != envblock)
|
||||
{
|
||||
s += new_envblock - envblock;
|
||||
envblock = new_envblock;
|
||||
}
|
||||
}
|
||||
tl = raise_envblock (new_tl, envblock, s);
|
||||
|
||||
int slen = sys_mbstowcs (s, len, p);
|
||||
len = sys_mbstowcs (s, len, p);
|
||||
|
||||
/* See if environment variable is "special" in a Windows sense.
|
||||
Under NT, the current directories for visited drives are stored
|
||||
|
@ -1159,7 +1188,17 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
|
|||
if (s[0] == L'!' && (iswdrive (s + 1) || (s[1] == L':' && s[2] == L':'))
|
||||
&& s[3] == L'=')
|
||||
*s = L'=';
|
||||
s += slen + 1;
|
||||
s += len + 1;
|
||||
}
|
||||
/* If PATH doesn't exist in the environment, add a PATH with just
|
||||
Cygwin's bin dir to the Windows env to allow loading system DLLs
|
||||
during execve. */
|
||||
if (!saw_PATH)
|
||||
{
|
||||
new_tl += cygheap->installation_dir_len + 5;
|
||||
if (new_tl > tl)
|
||||
tl = raise_envblock (new_tl, envblock, s);
|
||||
s = wcpcpy (wcpcpy (s, L"PATH="), cygheap->installation_dir) + 1;
|
||||
}
|
||||
*s = L'\0'; /* Two null bytes at the end */
|
||||
assert ((s - envblock) <= tl); /* Detect if we somehow ran over end
|
||||
|
|
|
@ -94,8 +94,10 @@ to install your own exception filter. This one is documented.
|
|||
a teensy bit of detail of the innards of exception handling (i.e. what we
|
||||
have to do). */
|
||||
|
||||
typedef int (exception_handler) (EXCEPTION_RECORD *, struct _exception_list *,
|
||||
CONTEXT *, void *);
|
||||
typedef EXCEPTION_DISPOSITION (exception_handler) (EXCEPTION_RECORD *,
|
||||
struct _exception_list *,
|
||||
CONTEXT *,
|
||||
void *);
|
||||
|
||||
typedef struct _exception_list
|
||||
{
|
||||
|
@ -104,70 +106,51 @@ typedef struct _exception_list
|
|||
} exception_list;
|
||||
|
||||
extern exception_list *_except_list asm ("%fs:0");
|
||||
#else
|
||||
typedef void exception_list;
|
||||
#endif /* !__x86_64 */
|
||||
typedef void *PDISPATCHER_CONTEXT;
|
||||
|
||||
class exception
|
||||
{
|
||||
#ifdef __x86_64__
|
||||
static LONG myfault_handle (LPEXCEPTION_POINTERS ep);
|
||||
#else
|
||||
exception_list el;
|
||||
exception_list *save;
|
||||
#endif /* __x86_64__ */
|
||||
static int handle (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
|
||||
static EXCEPTION_DISPOSITION handle (EXCEPTION_RECORD *, exception_list *,
|
||||
CONTEXT *, PDISPATCHER_CONTEXT);
|
||||
public:
|
||||
exception () __attribute__ ((always_inline))
|
||||
{
|
||||
/* Install SEH handler. */
|
||||
save = _except_list;
|
||||
el.handler = handle;
|
||||
el.prev = _except_list;
|
||||
_except_list = ⪙
|
||||
};
|
||||
~exception () __attribute__ ((always_inline)) { _except_list = save; }
|
||||
};
|
||||
|
||||
#else /* __x86_64__ */
|
||||
|
||||
#define exception_list void
|
||||
typedef struct _DISPATCHER_CONTEXT *PDISPATCHER_CONTEXT;
|
||||
|
||||
class exception
|
||||
{
|
||||
static EXCEPTION_DISPOSITION myfault (EXCEPTION_RECORD *, exception_list *,
|
||||
CONTEXT *, PDISPATCHER_CONTEXT);
|
||||
static EXCEPTION_DISPOSITION handle (EXCEPTION_RECORD *, exception_list *,
|
||||
CONTEXT *, PDISPATCHER_CONTEXT);
|
||||
public:
|
||||
exception () __attribute__ ((always_inline))
|
||||
{
|
||||
/* Install SEH handler. */
|
||||
#ifdef __x86_64__
|
||||
asm volatile ("\n\
|
||||
1: \n\
|
||||
.seh_handler \
|
||||
_ZN9exception6handleEP17_EXCEPTION_RECORDPvP8_CONTEXTS2_, \
|
||||
_ZN9exception6handleEP17_EXCEPTION_RECORDPvP8_CONTEXTP19_DISPATCHER_CONTEXT, \
|
||||
@except \n\
|
||||
.seh_handlerdata \n\
|
||||
.long 1 \n\
|
||||
.rva 1b, 2f, 2f, 2f \n\
|
||||
.seh_code \n");
|
||||
#else
|
||||
save = _except_list;
|
||||
el.handler = handle;
|
||||
el.prev = _except_list;
|
||||
_except_list = ⪙
|
||||
#endif /* __x86_64__ */
|
||||
};
|
||||
#ifdef __x86_64__
|
||||
static void install_myfault_handler () __attribute__ ((always_inline))
|
||||
{
|
||||
/* Install myfault exception handler as VEH. Here's what happens:
|
||||
Some Windows DLLs (advapi32, for instance) are using SEH to catch
|
||||
exceptions inside its own functions. If we install a VEH handler
|
||||
to catch all exceptions, our Cygwin VEH handler would illegitimatly
|
||||
handle exceptions inside of Windows DLLs which are usually handled
|
||||
by its own SEH handler. So, for standard exceptions we use an SEH
|
||||
handler as installed in the constructor above so as not to override
|
||||
the SEH handlers in Windows DLLs.
|
||||
But we have a special case, myfault handling. The myfault handling
|
||||
catches exceptions inside of the Cygwin DLL, some of them entirely
|
||||
expected as in verifyable_object_isvalid. The ultimately right thing
|
||||
to do would be to install SEH handlers for each of these cases.
|
||||
But there are two problems with that:
|
||||
|
||||
1. It would be a massive and, partially unreliable change in the
|
||||
calling functions due to the incomplete SEH support in GCC.
|
||||
|
||||
2. It doesn't always work. Certain DLLs appear to call Cygwin
|
||||
functions during DLL initialization while the SEH handler is
|
||||
not installed in the active call frame. For these cases we
|
||||
need a more generic approach.
|
||||
|
||||
So, what we do here is to install a myfault VEH handler. This
|
||||
function is called from dll_crt0_0, so the myfault handler is
|
||||
available very early. */
|
||||
AddVectoredExceptionHandler (1, myfault_handle);
|
||||
}
|
||||
~exception () __attribute__ ((always_inline))
|
||||
{
|
||||
asm volatile ("\n\
|
||||
|
@ -175,11 +158,10 @@ public:
|
|||
2: \n\
|
||||
nop \n");
|
||||
}
|
||||
#else
|
||||
~exception () __attribute__ ((always_inline)) { _except_list = save; }
|
||||
#endif /* !__x86_64__ */
|
||||
};
|
||||
|
||||
#endif /* !__x86_64__ */
|
||||
|
||||
class cygwin_exception
|
||||
{
|
||||
PUINT_PTR framep;
|
||||
|
|
|
@ -341,38 +341,41 @@ void
|
|||
cygwin_exception::dumpstack ()
|
||||
{
|
||||
static bool already_dumped;
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return;
|
||||
|
||||
if (already_dumped || cygheap->rlim_core == 0Ul)
|
||||
return;
|
||||
already_dumped = true;
|
||||
open_stackdumpfile ();
|
||||
|
||||
if (e)
|
||||
dump_exception ();
|
||||
|
||||
int i;
|
||||
|
||||
thestack.init (framep, 1, ctx); /* Initialize from the input CONTEXT */
|
||||
#ifdef __x86_64__
|
||||
small_printf ("Stack trace:\r\nFrame Function Args\r\n");
|
||||
#else
|
||||
small_printf ("Stack trace:\r\nFrame Function Args\r\n");
|
||||
#endif
|
||||
for (i = 0; i < 16 && thestack++; i++)
|
||||
__try
|
||||
{
|
||||
small_printf (_AFMT " " _AFMT, thestack.sf.AddrFrame.Offset,
|
||||
thestack.sf.AddrPC.Offset);
|
||||
for (unsigned j = 0; j < NPARAMS; j++)
|
||||
small_printf ("%s" _AFMT, j == 0 ? " (" : ", ", thestack.sf.Params[j]);
|
||||
small_printf (")\r\n");
|
||||
if (already_dumped || cygheap->rlim_core == 0Ul)
|
||||
return;
|
||||
already_dumped = true;
|
||||
open_stackdumpfile ();
|
||||
|
||||
if (e)
|
||||
dump_exception ();
|
||||
|
||||
int i;
|
||||
|
||||
thestack.init (framep, 1, ctx); /* Initialize from the input CONTEXT */
|
||||
#ifdef __x86_64__
|
||||
small_printf ("Stack trace:\r\nFrame Function Args\r\n");
|
||||
#else
|
||||
small_printf ("Stack trace:\r\nFrame Function Args\r\n");
|
||||
#endif
|
||||
for (i = 0; i < 16 && thestack++; i++)
|
||||
{
|
||||
small_printf (_AFMT " " _AFMT, thestack.sf.AddrFrame.Offset,
|
||||
thestack.sf.AddrPC.Offset);
|
||||
for (unsigned j = 0; j < NPARAMS; j++)
|
||||
small_printf ("%s" _AFMT, j == 0 ? " (" : ", ",
|
||||
thestack.sf.Params[j]);
|
||||
small_printf (")\r\n");
|
||||
}
|
||||
small_printf ("End of stack trace%s\n",
|
||||
i == 16 ? " (more stack frames may be present)" : "");
|
||||
if (h)
|
||||
NtClose (h);
|
||||
}
|
||||
small_printf ("End of stack trace%s\n",
|
||||
i == 16 ? " (more stack frames may be present)" : "");
|
||||
if (h)
|
||||
NtClose (h);
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -549,40 +552,24 @@ rtl_unwind (exception_list *frame, PEXCEPTION_RECORD e)
|
|||
#endif /* __x86_64 */
|
||||
|
||||
#ifdef __x86_64__
|
||||
/* myfault vectored exception handler */
|
||||
LONG
|
||||
exception::myfault_handle (LPEXCEPTION_POINTERS ep)
|
||||
/* myfault exception handler. */
|
||||
EXCEPTION_DISPOSITION
|
||||
exception::myfault (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
|
||||
PDISPATCHER_CONTEXT dispatch)
|
||||
{
|
||||
_cygtls& me = _my_tls;
|
||||
|
||||
if (me.andreas)
|
||||
{
|
||||
/* Only handle the minimum amount of exceptions the myfault handler
|
||||
was designed for. */
|
||||
switch (ep->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
case STATUS_ACCESS_VIOLATION:
|
||||
case STATUS_DATATYPE_MISALIGNMENT:
|
||||
#if 0
|
||||
/* PAGE_GUARD-based stack commits are based on structured exception
|
||||
handling. Short-circuiting STATUS_STACK_OVERFLOW in a vectored
|
||||
exception handler disables that, which can ultimately result in
|
||||
a spurious SEGV. */
|
||||
case STATUS_STACK_OVERFLOW:
|
||||
#endif
|
||||
case STATUS_ARRAY_BOUNDS_EXCEEDED:
|
||||
me.andreas->leave (); /* Return from a "san" caught fault */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
PSCOPE_TABLE table = (PSCOPE_TABLE) dispatch->HandlerData;
|
||||
RtlUnwindEx (frame,
|
||||
(char *) dispatch->ImageBase + table->ScopeRecord[0].JumpTarget,
|
||||
e, 0, in, dispatch->HistoryTable);
|
||||
/* NOTREACHED, make gcc happy. */
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
#endif /* __x86_64 */
|
||||
#endif
|
||||
|
||||
/* Main exception handler. */
|
||||
int
|
||||
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in, void *)
|
||||
EXCEPTION_DISPOSITION
|
||||
exception::handle (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *in,
|
||||
PDISPATCHER_CONTEXT dispatch)
|
||||
{
|
||||
static bool NO_COPY debugging;
|
||||
_cygtls& me = _my_tls;
|
||||
|
|
|
@ -243,11 +243,13 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||
break;
|
||||
|
||||
case CW_USER_DATA:
|
||||
#ifndef __x86_64__
|
||||
/* This is a kludge to work around a version of _cygwin_common_crt0
|
||||
which overwrote the cxx_malloc field with the local DLL copy.
|
||||
Hilarity ensues if the DLL is not loaded like while the process
|
||||
is forking. */
|
||||
__cygwin_user_data.cxx_malloc = &default_cygwin_cxx_malloc;
|
||||
#endif
|
||||
res = (uintptr_t) &__cygwin_user_data;
|
||||
break;
|
||||
|
||||
|
@ -572,6 +574,10 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
|||
}
|
||||
break;
|
||||
|
||||
case CW_FIXED_ATEXIT:
|
||||
res = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
set_errno (ENOSYS);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* fcntl.cc: fcntl syscall
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2008, 2009,
|
||||
2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -28,53 +28,54 @@ fcntl64 (int fd, int cmd, ...)
|
|||
|
||||
pthread_testcancel ();
|
||||
|
||||
debug_printf ("fcntl(%d, %d, ...)", fd, cmd);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
cygheap_fdget cfd (fd, true);
|
||||
if (cfd < 0)
|
||||
goto done;
|
||||
|
||||
/* FIXME? All numerical args to fcntl are defined as long on Linux.
|
||||
This relies on a really dirty trick on x86_64: A 32 bit mov to
|
||||
a register (e.g. mov $1, %edx) always sets the high 32 bit to 0.
|
||||
We're following the Linux lead here since the third arg to any
|
||||
function is in a register anyway (%r8 in MS ABI). That's the easy
|
||||
case which is covered here by always reading the arg with
|
||||
sizeof (intptr_t) == sizeof (long) == sizeof (void*) which matches
|
||||
all targets.
|
||||
|
||||
However, the POSIX standard defines all numerical args as type int.
|
||||
If we take that literally, we had a (small) problem on 64 bit, since
|
||||
sizeof (void*) != sizeof (int). If we would like to follow POSIX
|
||||
more closely than Linux, we'd have to call va_arg on a per cmd basis. */
|
||||
|
||||
va_start (args, cmd);
|
||||
arg = va_arg (args, intptr_t);
|
||||
va_end (args);
|
||||
|
||||
switch (cmd)
|
||||
__try
|
||||
{
|
||||
case F_DUPFD:
|
||||
case F_DUPFD_CLOEXEC:
|
||||
if (arg >= 0 && arg < OPEN_MAX_MAX)
|
||||
|
||||
debug_printf ("fcntl(%d, %d, ...)", fd, cmd);
|
||||
cygheap_fdget cfd (fd, true);
|
||||
if (cfd < 0)
|
||||
__leave;
|
||||
|
||||
/* FIXME? All numerical args to fcntl are defined as long on Linux.
|
||||
This relies on a really dirty trick on x86_64: A 32 bit mov to
|
||||
a register (e.g. mov $1, %edx) always sets the high 32 bit to 0.
|
||||
We're following the Linux lead here since the third arg to any
|
||||
function is in a register anyway (%r8 in MS ABI). That's the easy
|
||||
case which is covered here by always reading the arg with
|
||||
sizeof (intptr_t) == sizeof (long) == sizeof (void*) which matches
|
||||
all targets.
|
||||
|
||||
However, the POSIX standard defines all numerical args as type int.
|
||||
If we take that literally, we had a (small) problem on 64 bit, since
|
||||
sizeof (void*) != sizeof (int). If we would like to follow POSIX more
|
||||
closely than Linux, we'd have to call va_arg on a per cmd basis. */
|
||||
|
||||
va_start (args, cmd);
|
||||
arg = va_arg (args, intptr_t);
|
||||
va_end (args);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
int flags = cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0;
|
||||
res = cygheap->fdtab.dup3 (fd, cygheap_fdnew ((arg) - 1), flags);
|
||||
case F_DUPFD:
|
||||
case F_DUPFD_CLOEXEC:
|
||||
if (arg >= 0 && arg < OPEN_MAX_MAX)
|
||||
{
|
||||
int flags = cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0;
|
||||
res = cygheap->fdtab.dup3 (fd, cygheap_fdnew ((arg) - 1), flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
res = -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
res = cfd->fcntl (cmd, arg);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
res = -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
res = cfd->fcntl (cmd, arg);
|
||||
break;
|
||||
}
|
||||
done:
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = fcntl(%d, %d, %ly)", res, fd, cmd, arg);
|
||||
return res;
|
||||
}
|
||||
|
@ -91,32 +92,34 @@ _fcntl (int fd, int cmd, ...)
|
|||
struct __flock32 *src = NULL;
|
||||
struct flock dst;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
va_start (args, cmd);
|
||||
arg = va_arg (args, intptr_t);
|
||||
va_end (args);
|
||||
if (cmd == F_GETLK || cmd == F_SETLK || cmd == F_SETLKW)
|
||||
__try
|
||||
{
|
||||
src = (struct __flock32 *) arg;
|
||||
dst.l_type = src->l_type;
|
||||
dst.l_whence = src->l_whence;
|
||||
dst.l_start = src->l_start;
|
||||
dst.l_len = src->l_len;
|
||||
dst.l_pid = src->l_pid;
|
||||
arg = (intptr_t) &dst;
|
||||
va_start (args, cmd);
|
||||
arg = va_arg (args, intptr_t);
|
||||
va_end (args);
|
||||
if (cmd == F_GETLK || cmd == F_SETLK || cmd == F_SETLKW)
|
||||
{
|
||||
src = (struct __flock32 *) arg;
|
||||
dst.l_type = src->l_type;
|
||||
dst.l_whence = src->l_whence;
|
||||
dst.l_start = src->l_start;
|
||||
dst.l_len = src->l_len;
|
||||
dst.l_pid = src->l_pid;
|
||||
arg = (intptr_t) &dst;
|
||||
}
|
||||
int res = fcntl64 (fd, cmd, arg);
|
||||
if (cmd == F_GETLK)
|
||||
{
|
||||
src->l_type = dst.l_type;
|
||||
src->l_whence = dst.l_whence;
|
||||
src->l_start = dst.l_start;
|
||||
src->l_len = dst.l_len;
|
||||
src->l_pid = (short) dst.l_pid;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
int res = fcntl64 (fd, cmd, arg);
|
||||
if (cmd == F_GETLK)
|
||||
{
|
||||
src->l_type = dst.l_type;
|
||||
src->l_whence = dst.l_whence;
|
||||
src->l_start = dst.l_start;
|
||||
src->l_len = dst.l_len;
|
||||
src->l_pid = (short) dst.l_pid;
|
||||
}
|
||||
return res;
|
||||
__except (EFAULT)
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -77,7 +77,8 @@ enum conn_state
|
|||
unconnected = 0,
|
||||
connect_pending = 1,
|
||||
connected = 2,
|
||||
connect_failed = 3
|
||||
listener = 3,
|
||||
connect_failed = 4
|
||||
};
|
||||
|
||||
enum line_edit_status
|
||||
|
@ -502,6 +503,7 @@ class fhandler_socket: public fhandler_base
|
|||
int af_local_accept ();
|
||||
public:
|
||||
int af_local_connect ();
|
||||
int af_local_set_no_getpeereid ();
|
||||
void af_local_set_sockpair_cred ();
|
||||
|
||||
private:
|
||||
|
@ -528,12 +530,12 @@ class fhandler_socket: public fhandler_base
|
|||
unsigned saw_shutdown_read : 1; /* Socket saw a SHUT_RD */
|
||||
unsigned saw_shutdown_write : 1; /* Socket saw a SHUT_WR */
|
||||
unsigned saw_reuseaddr : 1; /* Socket saw SO_REUSEADDR call */
|
||||
unsigned listener : 1; /* listen called */
|
||||
unsigned connect_state : 2;
|
||||
unsigned connect_state : 3;
|
||||
unsigned no_getpeereid : 1;
|
||||
public:
|
||||
status_flags () :
|
||||
async_io (0), saw_shutdown_read (0), saw_shutdown_write (0),
|
||||
listener (0), connect_state (unconnected)
|
||||
connect_state (unconnected), no_getpeereid (0)
|
||||
{}
|
||||
} status;
|
||||
|
||||
|
@ -554,8 +556,8 @@ class fhandler_socket: public fhandler_base
|
|||
IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_read)
|
||||
IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_write)
|
||||
IMPLEMENT_STATUS_FLAG (bool, saw_reuseaddr)
|
||||
IMPLEMENT_STATUS_FLAG (bool, listener)
|
||||
IMPLEMENT_STATUS_FLAG (conn_state, connect_state)
|
||||
IMPLEMENT_STATUS_FLAG (bool, no_getpeereid)
|
||||
|
||||
int bind (const struct sockaddr *name, int namelen);
|
||||
int connect (const struct sockaddr *name, int namelen);
|
||||
|
@ -582,7 +584,11 @@ class fhandler_socket: public fhandler_base
|
|||
|
||||
int ioctl (unsigned int cmd, void *);
|
||||
int fcntl (int cmd, intptr_t);
|
||||
off_t lseek (off_t, int) { return 0; }
|
||||
off_t lseek (off_t, int)
|
||||
{
|
||||
set_errno (ESPIPE);
|
||||
return -1;
|
||||
}
|
||||
int shutdown (int how);
|
||||
int close ();
|
||||
void hclose (HANDLE) {close ();}
|
||||
|
@ -1135,7 +1141,11 @@ class fhandler_serial: public fhandler_base
|
|||
int switch_modem_lines (int set, int clr);
|
||||
int tcsetattr (int a, const struct termios *t);
|
||||
int tcgetattr (struct termios *t);
|
||||
off_t lseek (off_t, int) { return 0; }
|
||||
off_t lseek (off_t, int)
|
||||
{
|
||||
set_errno (ESPIPE);
|
||||
return -1;
|
||||
}
|
||||
int tcflush (int);
|
||||
bool is_tty () const { return true; }
|
||||
void fixup_after_fork (HANDLE parent);
|
||||
|
@ -1498,7 +1508,7 @@ class fhandler_pty_slave: public fhandler_pty_common
|
|||
HANDLE inuse; // used to indicate that a tty is in use
|
||||
|
||||
/* Helper functions for fchmod and fchown. */
|
||||
bool fch_open_handles ();
|
||||
bool fch_open_handles (bool chown);
|
||||
int fch_set_sd (security_descriptor &sd, bool chown);
|
||||
void fch_close_handles ();
|
||||
|
||||
|
|
|
@ -648,9 +648,9 @@ fhandler_base::fstat_helper (struct stat *buf,
|
|||
/* We have to re-open the file. Either the file is not opened
|
||||
for reading, or the read will change the file position of the
|
||||
original handle. */
|
||||
pc.init_reopen_attr (&attr, h);
|
||||
status = NtOpenFile (&h, SYNCHRONIZE | FILE_READ_DATA,
|
||||
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
||||
pc.init_reopen_attr (attr, h), &io,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT
|
||||
| FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
if (!NT_SUCCESS (status))
|
||||
|
@ -690,7 +690,7 @@ fhandler_base::fstat_helper (struct stat *buf,
|
|||
}
|
||||
|
||||
done:
|
||||
syscall_printf ("0 = fstat (%S, %p) st_size=%D, st_mode=%y, st_ino=%D"
|
||||
syscall_printf ("0 = fstat (%S, %p) st_size=%D, st_mode=0%o, st_ino=%D"
|
||||
"st_atim=%lx.%lx st_ctim=%lx.%lx "
|
||||
"st_mtim=%lx.%lx st_birthtim=%lx.%lx",
|
||||
pc.get_nt_native_path (), buf,
|
||||
|
@ -776,6 +776,26 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
|
|||
}
|
||||
ret = 0;
|
||||
}
|
||||
else if (status == STATUS_INVALID_PARAMETER /* Netapp */
|
||||
|| status == STATUS_INVALID_INFO_CLASS)
|
||||
{
|
||||
FILE_FS_SIZE_INFORMATION fsi;
|
||||
status = NtQueryVolumeInformationFile (fh, &io, &fsi, sizeof fsi,
|
||||
FileFsSizeInformation);
|
||||
if (NT_SUCCESS (status))
|
||||
{
|
||||
sfs->f_bsize = fsi.BytesPerSector * fsi.SectorsPerAllocationUnit;
|
||||
sfs->f_frsize = sfs->f_bsize;
|
||||
sfs->f_blocks = (fsblkcnt_t) fsi.TotalAllocationUnits.QuadPart;
|
||||
sfs->f_bfree = sfs->f_bavail =
|
||||
(fsblkcnt_t) fsi.AvailableAllocationUnits.QuadPart;
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
debug_printf ("%y = NtQueryVolumeInformationFile"
|
||||
"(%S, FileFsSizeInformation)",
|
||||
status, pc.get_nt_native_path ());
|
||||
}
|
||||
else
|
||||
debug_printf ("%y = NtQueryVolumeInformationFile"
|
||||
"(%S, FileFsFullSizeInformation)",
|
||||
|
@ -870,9 +890,9 @@ fhandler_disk_file::fchmod (mode_t mode)
|
|||
OBJECT_ATTRIBUTES attr;
|
||||
HANDLE fh;
|
||||
|
||||
pc.init_reopen_attr (&attr, get_handle ());
|
||||
if (NT_SUCCESS (NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
if (NT_SUCCESS (NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES,
|
||||
pc.init_reopen_attr (attr, get_handle ()),
|
||||
&io, FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT)))
|
||||
{
|
||||
NtSetAttributesFile (fh, pc.file_attributes ());
|
||||
|
@ -1360,9 +1380,9 @@ fhandler_base::utimens_fs (const struct timespec *tvp)
|
|||
OBJECT_ATTRIBUTES attr;
|
||||
HANDLE fh;
|
||||
|
||||
pc.init_reopen_attr (&attr, get_handle ());
|
||||
if (NT_SUCCESS (NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
if (NT_SUCCESS (NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES,
|
||||
pc.init_reopen_attr (attr, get_handle ()),
|
||||
&io, FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT)))
|
||||
{
|
||||
NtSetInformationFile (fh, &io, &fbi, sizeof fbi,
|
||||
|
@ -1531,8 +1551,8 @@ fhandler_disk_file::prw_open (bool write)
|
|||
|
||||
/* First try to open with the original access mask */
|
||||
ACCESS_MASK access = get_access ();
|
||||
pc.init_reopen_attr (&attr, get_handle ());
|
||||
status = NtOpenFile (&prw_handle, access, &attr, &io,
|
||||
status = NtOpenFile (&prw_handle, access,
|
||||
pc.init_reopen_attr (attr, get_handle ()), &io,
|
||||
FILE_SHARE_VALID_FLAGS, get_options ());
|
||||
if (status == STATUS_ACCESS_DENIED)
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* fhandler_netdrive.cc: fhandler for // and //MACHINE handling
|
||||
|
||||
Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014
|
||||
Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -17,6 +18,7 @@ details. */
|
|||
#include "dtable.h"
|
||||
#include "cygheap.h"
|
||||
#include "cygthread.h"
|
||||
#include "tls_pbuf.h"
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
|
@ -47,19 +49,20 @@ static DWORD WINAPI
|
|||
thread_netdrive (void *arg)
|
||||
{
|
||||
netdriveinf *ndi = (netdriveinf *) arg;
|
||||
char provider[256], *dummy = NULL;
|
||||
LPNETRESOURCE nro;
|
||||
WCHAR provider[256], *dummy = NULL;
|
||||
LPNETRESOURCEW nro;
|
||||
DWORD cnt, size;
|
||||
struct net_hdls *nh;
|
||||
tmp_pathbuf tp;
|
||||
|
||||
ReleaseSemaphore (ndi->sem, 1, NULL);
|
||||
switch (ndi->what)
|
||||
{
|
||||
case GET_RESOURCE_OPENENUMTOP:
|
||||
nro = (LPNETRESOURCE) alloca (size = 4096);
|
||||
nro = (LPNETRESOURCEW) tp.c_get ();
|
||||
nh = (struct net_hdls *) ndi->out;
|
||||
ndi->ret = WNetGetProviderName (WNNC_NET_LANMAN, provider,
|
||||
(size = 256, &size));
|
||||
ndi->ret = WNetGetProviderNameW (WNNC_NET_LANMAN, provider,
|
||||
(size = 256, &size));
|
||||
if (ndi->ret != NO_ERROR)
|
||||
break;
|
||||
memset (nro, 0, sizeof *nro);
|
||||
|
@ -69,33 +72,35 @@ thread_netdrive (void *arg)
|
|||
nro->dwUsage = RESOURCEUSAGE_RESERVED | RESOURCEUSAGE_CONTAINER;
|
||||
nro->lpRemoteName = provider;
|
||||
nro->lpProvider = provider;
|
||||
ndi->ret = WNetOpenEnum (RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
|
||||
RESOURCEUSAGE_ALL, nro, &nh->net);
|
||||
ndi->ret = WNetOpenEnumW (RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
|
||||
RESOURCEUSAGE_ALL, nro, &nh->net);
|
||||
if (ndi->ret != NO_ERROR)
|
||||
break;
|
||||
while ((ndi->ret = WNetEnumResource (nh->net, (cnt = 1, &cnt), nro,
|
||||
(size = 4096, &size))) == NO_ERROR)
|
||||
while ((ndi->ret = WNetEnumResourceW (nh->net, (cnt = 1, &cnt), nro,
|
||||
(size = NT_MAX_PATH, &size)))
|
||||
== NO_ERROR)
|
||||
{
|
||||
ndi->ret = WNetOpenEnum (RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
|
||||
RESOURCEUSAGE_ALL, nro, &nh->dom);
|
||||
ndi->ret = WNetOpenEnumW (RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
|
||||
RESOURCEUSAGE_ALL, nro, &nh->dom);
|
||||
if (ndi->ret == NO_ERROR)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GET_RESOURCE_OPENENUM:
|
||||
nro = (LPNETRESOURCE) alloca (size = 4096);
|
||||
nro = (LPNETRESOURCEW) tp.c_get ();
|
||||
nh = (struct net_hdls *) ndi->out;
|
||||
ndi->ret = WNetGetProviderName (WNNC_NET_LANMAN, provider,
|
||||
ndi->ret = WNetGetProviderNameW (WNNC_NET_LANMAN, provider,
|
||||
(size = 256, &size));
|
||||
if (ndi->ret != NO_ERROR)
|
||||
break;
|
||||
((LPNETRESOURCE) ndi->in)->lpProvider = provider;
|
||||
ndi->ret = WNetGetResourceInformation ((LPNETRESOURCE) ndi->in,
|
||||
nro, &size, &dummy);
|
||||
((LPNETRESOURCEW) ndi->in)->lpProvider = provider;
|
||||
ndi->ret = WNetGetResourceInformationW ((LPNETRESOURCEW) ndi->in, nro,
|
||||
(size = NT_MAX_PATH, &size),
|
||||
&dummy);
|
||||
if (ndi->ret != NO_ERROR)
|
||||
break;
|
||||
ndi->ret = WNetOpenEnum (RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
|
||||
RESOURCEUSAGE_ALL, nro, &nh->dom);
|
||||
ndi->ret = WNetOpenEnumW (RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
|
||||
RESOURCEUSAGE_ALL, nro, &nh->dom);
|
||||
break;
|
||||
case GET_RESOURCE_ENUM:
|
||||
nh = (struct net_hdls *) ndi->in;
|
||||
|
@ -104,19 +109,20 @@ thread_netdrive (void *arg)
|
|||
ndi->ret = ERROR_NO_MORE_ITEMS;
|
||||
break;
|
||||
}
|
||||
while ((ndi->ret = WNetEnumResource (nh->dom, (cnt = 1, &cnt),
|
||||
(LPNETRESOURCE) ndi->out,
|
||||
&ndi->outsize)) != NO_ERROR
|
||||
nro = (LPNETRESOURCEW) tp.c_get ();
|
||||
while ((ndi->ret = WNetEnumResourceW (nh->dom, (cnt = 1, &cnt),
|
||||
(LPNETRESOURCEW) ndi->out,
|
||||
&ndi->outsize)) != NO_ERROR
|
||||
&& nh->net)
|
||||
{
|
||||
WNetCloseEnum (nh->dom);
|
||||
nh->dom = NULL;
|
||||
nro = (LPNETRESOURCE) alloca (size = 4096);
|
||||
while ((ndi->ret = WNetEnumResource (nh->net, (cnt = 1, &cnt), nro,
|
||||
(size = 4096, &size))) == NO_ERROR)
|
||||
while ((ndi->ret = WNetEnumResourceW (nh->net, (cnt = 1, &cnt), nro,
|
||||
(size = NT_MAX_PATH, &size)))
|
||||
== NO_ERROR)
|
||||
{
|
||||
ndi->ret = WNetOpenEnum (RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
|
||||
RESOURCEUSAGE_ALL, nro, &nh->dom);
|
||||
ndi->ret = WNetOpenEnumW (RESOURCE_GLOBALNET, RESOURCETYPE_DISK,
|
||||
RESOURCEUSAGE_ALL, nro, &nh->dom);
|
||||
if (ndi->ret == NO_ERROR)
|
||||
break;
|
||||
}
|
||||
|
@ -152,15 +158,20 @@ fhandler_netdrive::exists ()
|
|||
size_t len = strlen (get_name ());
|
||||
if (len == 2)
|
||||
return virt_rootdir;
|
||||
|
||||
char namebuf[len + 1];
|
||||
tmp_pathbuf tp;
|
||||
PWCHAR name = tp.w_get ();
|
||||
|
||||
for (to = namebuf, from = get_name (); *from; to++, from++)
|
||||
*to = (*from == '/') ? '\\' : *from;
|
||||
*to = '\0';
|
||||
|
||||
struct net_hdls nh = { NULL, NULL };
|
||||
NETRESOURCE nr = {0};
|
||||
NETRESOURCEW nr = {0};
|
||||
nr.dwType = RESOURCETYPE_DISK;
|
||||
nr.lpRemoteName = namebuf;
|
||||
sys_mbstowcs (name, NT_MAX_PATH, namebuf);
|
||||
nr.lpRemoteName = name;
|
||||
DWORD ret = create_thread_and_wait (GET_RESOURCE_OPENENUM,
|
||||
&nr, &nh, 0, "WNetOpenEnum");
|
||||
if (nh.dom)
|
||||
|
@ -190,28 +201,30 @@ fhandler_netdrive::fstat (struct stat *buf)
|
|||
int
|
||||
fhandler_netdrive::readdir (DIR *dir, dirent *de)
|
||||
{
|
||||
NETRESOURCE *nro;
|
||||
NETRESOURCEW *nro;
|
||||
DWORD ret;
|
||||
int res;
|
||||
tmp_pathbuf tp;
|
||||
|
||||
if (!dir->__d_position)
|
||||
{
|
||||
size_t len = strlen (get_name ());
|
||||
char *namebuf = NULL;
|
||||
NETRESOURCE nr = { 0 };
|
||||
PWCHAR name = NULL;
|
||||
NETRESOURCEW nr = { 0 };
|
||||
struct net_hdls *nh;
|
||||
|
||||
if (len != 2) /* // */
|
||||
{
|
||||
const char *from;
|
||||
char *to;
|
||||
namebuf = (char *) alloca (len + 1);
|
||||
char *namebuf = (char *) alloca (len + 1);
|
||||
for (to = namebuf, from = get_name (); *from; to++, from++)
|
||||
*to = (*from == '/') ? '\\' : *from;
|
||||
*to = '\0';
|
||||
name = tp.w_get ();
|
||||
sys_mbstowcs (name, NT_MAX_PATH, namebuf);
|
||||
}
|
||||
|
||||
nr.lpRemoteName = namebuf;
|
||||
nr.lpRemoteName = name;
|
||||
nr.dwType = RESOURCETYPE_DISK;
|
||||
nh = (struct net_hdls *) ccalloc (HEAP_FHANDLER, 1, sizeof *nh);
|
||||
ret = create_thread_and_wait (len == 2 ? GET_RESOURCE_OPENENUMTOP
|
||||
|
@ -225,28 +238,37 @@ fhandler_netdrive::readdir (DIR *dir, dirent *de)
|
|||
}
|
||||
dir->__handle = (HANDLE) nh;
|
||||
}
|
||||
ret = create_thread_and_wait (GET_RESOURCE_ENUM, dir->__handle,
|
||||
nro = (LPNETRESOURCE) alloca (16384),
|
||||
16384, "WnetEnumResource");
|
||||
nro = (LPNETRESOURCEW) tp.c_get ();
|
||||
ret = create_thread_and_wait (GET_RESOURCE_ENUM, dir->__handle, nro,
|
||||
NT_MAX_PATH, "WnetEnumResource");
|
||||
if (ret != NO_ERROR)
|
||||
res = geterrno_from_win_error (ret);
|
||||
else
|
||||
{
|
||||
dir->__d_position++;
|
||||
char *bs = strrchr (nro->lpRemoteName, '\\');
|
||||
strcpy (de->d_name, bs ? bs + 1 : nro->lpRemoteName);
|
||||
PWCHAR bs = wcsrchr (nro->lpRemoteName, L'\\');
|
||||
bs = bs ? bs + 1 : nro->lpRemoteName;
|
||||
if (strlen (get_name ()) == 2)
|
||||
{
|
||||
strlwr (de->d_name);
|
||||
UNICODE_STRING ss, ds;
|
||||
|
||||
tp.u_get (&ds);
|
||||
RtlInitUnicodeString (&ss, bs);
|
||||
RtlDowncaseUnicodeString (&ds, &ss, FALSE);
|
||||
sys_wcstombs (de->d_name, sizeof de->d_name,
|
||||
ds.Buffer, ds.Length / sizeof (WCHAR));
|
||||
de->d_ino = hash_path_name (get_ino (), de->d_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
de->d_ino = readdir_get_ino (nro->lpRemoteName, false);
|
||||
sys_wcstombs (de->d_name, sizeof de->d_name, bs);
|
||||
char *rpath = tp.c_get ();
|
||||
sys_wcstombs (rpath, NT_MAX_PATH, nro->lpRemoteName);
|
||||
de->d_ino = readdir_get_ino (rpath, false);
|
||||
/* We can't trust remote inode numbers of only 32 bit. That means,
|
||||
remote NT4 NTFS, as well as shares of Samba version < 3.0. */
|
||||
if (de->d_ino <= UINT32_MAX)
|
||||
de->d_ino = hash_path_name (0, nro->lpRemoteName);
|
||||
de->d_ino = hash_path_name (0, rpath);
|
||||
}
|
||||
de->d_type = DT_DIR;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ details. */
|
|||
#include "cygerrno.h"
|
||||
#include "security.h"
|
||||
#include "path.h"
|
||||
#include "shared_info.h"
|
||||
#include "fhandler.h"
|
||||
#include "fhandler_virtual.h"
|
||||
#include "pinfo.h"
|
||||
|
@ -44,6 +45,7 @@ static off_t format_proc_uptime (void *, char *&);
|
|||
static off_t format_proc_cpuinfo (void *, char *&);
|
||||
static off_t format_proc_partitions (void *, char *&);
|
||||
static off_t format_proc_self (void *, char *&);
|
||||
static off_t format_proc_cygdrive (void *, char *&);
|
||||
static off_t format_proc_mounts (void *, char *&);
|
||||
static off_t format_proc_filesystems (void *, char *&);
|
||||
static off_t format_proc_swaps (void *, char *&);
|
||||
|
@ -55,6 +57,7 @@ static const virt_tab_t proc_tab[] = {
|
|||
{ _VN ("."), FH_PROC, virt_directory, NULL },
|
||||
{ _VN (".."), FH_PROC, virt_directory, NULL },
|
||||
{ _VN ("cpuinfo"), FH_PROC, virt_file, format_proc_cpuinfo },
|
||||
{ _VN ("cygdrive"), FH_PROC, virt_symlink, format_proc_cygdrive },
|
||||
{ _VN ("devices"), FH_PROC, virt_file, format_proc_devices },
|
||||
{ _VN ("filesystems"), FH_PROC, virt_file, format_proc_filesystems },
|
||||
{ _VN ("loadavg"), FH_PROC, virt_file, format_proc_loadavg },
|
||||
|
@ -1178,6 +1181,10 @@ format_proc_partitions (void *, char *&destbuf)
|
|||
char *buf = tp.c_get ();
|
||||
char *bufptr = buf;
|
||||
char *ioctl_buf = tp.c_get ();
|
||||
PWCHAR mp_buf = tp.w_get ();
|
||||
WCHAR fpath[MAX_PATH];
|
||||
WCHAR gpath[MAX_PATH];
|
||||
DWORD len;
|
||||
|
||||
/* Open \Device object directory. */
|
||||
wchar_t wpath[MAX_PATH] = L"\\Device";
|
||||
|
@ -1216,13 +1223,12 @@ format_proc_partitions (void *, char *&destbuf)
|
|||
continue;
|
||||
/* Got it. Now construct the path to the entire disk, which is
|
||||
"\\Device\\HarddiskX\\Partition0", and open the disk with
|
||||
minimum permssions. */
|
||||
minimum permissions. */
|
||||
unsigned long drive_num = wcstoul (dbi->ObjectName.Buffer + 8, NULL, 10);
|
||||
wcscpy (wpath, dbi->ObjectName.Buffer);
|
||||
PWCHAR wpart = wpath + dbi->ObjectName.Length / sizeof (WCHAR);
|
||||
__small_swprintf (wpart, L"\\Partition0");
|
||||
upath.Length = dbi->ObjectName.Length
|
||||
+ wcslen (wpart) * sizeof (WCHAR);
|
||||
wcpcpy (wpart, L"\\Partition0");
|
||||
upath.Length = dbi->ObjectName.Length + 22;
|
||||
upath.MaximumLength = upath.Length + sizeof (WCHAR);
|
||||
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE,
|
||||
dirhdl, NULL);
|
||||
|
@ -1236,7 +1242,7 @@ format_proc_partitions (void *, char *&destbuf)
|
|||
}
|
||||
if (!got_one)
|
||||
{
|
||||
print ("major minor #blocks name\n\n");
|
||||
print ("major minor #blocks name win-mounts\n\n");
|
||||
got_one = true;
|
||||
}
|
||||
/* Fetch partition info for the entire disk to get its size. */
|
||||
|
@ -1305,9 +1311,27 @@ format_proc_partitions (void *, char *&destbuf)
|
|||
if (part_num == 0)
|
||||
continue;
|
||||
dev.parsedisk (drive_num, part_num);
|
||||
bufptr += __small_sprintf (bufptr, "%5d %5d %9U %s\n",
|
||||
|
||||
bufptr += __small_sprintf (bufptr, "%5d %5d %9U %s",
|
||||
dev.get_major (), dev.get_minor (),
|
||||
size >> 10, dev.name + 5);
|
||||
/* Check if the partition is mounted in Windows and, if so,
|
||||
print the mount point list. */
|
||||
__small_swprintf (fpath,
|
||||
L"\\\\?\\GLOBALROOT\\Device\\%S\\Partition%u\\",
|
||||
&dbi->ObjectName, part_num);
|
||||
if (GetVolumeNameForVolumeMountPointW (fpath, gpath, MAX_PATH)
|
||||
&& GetVolumePathNamesForVolumeNameW (gpath, mp_buf,
|
||||
NT_MAX_PATH, &len))
|
||||
{
|
||||
len = strlen (dev.name + 5);
|
||||
while (len++ < 6)
|
||||
*bufptr++ = ' ';
|
||||
for (PWCHAR p = mp_buf; *p; p = wcschr (p, L'\0') + 1)
|
||||
bufptr += __small_sprintf (bufptr, " %W", p);
|
||||
}
|
||||
|
||||
*bufptr++ = '\n';
|
||||
}
|
||||
NtClose (devhdl);
|
||||
}
|
||||
|
@ -1328,6 +1352,16 @@ format_proc_self (void *, char *&destbuf)
|
|||
return __small_sprintf (destbuf, "%d", getpid ());
|
||||
}
|
||||
|
||||
static off_t
|
||||
format_proc_cygdrive (void *, char *&destbuf)
|
||||
{
|
||||
destbuf = (char *) crealloc_abort (destbuf, mount_table->cygdrive_len + 1);
|
||||
char *dend = stpcpy (destbuf, mount_table->cygdrive);
|
||||
if (dend > destbuf + 1) /* cygdrive != "/"? */
|
||||
*--dend = '\0';
|
||||
return dend - destbuf;
|
||||
}
|
||||
|
||||
static off_t
|
||||
format_proc_mounts (void *, char *&destbuf)
|
||||
{
|
||||
|
|
|
@ -1161,8 +1161,8 @@ format_process_statm (void *data, char *&destbuf)
|
|||
&vmlib, &vmshare))
|
||||
return 0;
|
||||
destbuf = (char *) crealloc_abort (destbuf, 96);
|
||||
return __small_sprintf (destbuf, "%ld %ld %ld %ld %ld %ld %ld",
|
||||
vmsize, vmrss, vmshare, vmtext, vmlib, vmdata, 0);
|
||||
return __small_sprintf (destbuf, "%ld %ld %ld %ld %ld %ld 0\n",
|
||||
vmsize, vmrss, vmshare, vmtext, vmlib, vmdata);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
|
|
@ -400,7 +400,10 @@ fhandler_socket::af_local_connect ()
|
|||
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
||||
return 0;
|
||||
|
||||
debug_printf ("af_local_connect called");
|
||||
debug_printf ("af_local_connect called, no_getpeereid=%d", no_getpeereid ());
|
||||
if (no_getpeereid ())
|
||||
return 0;
|
||||
|
||||
bool orig_async_io, orig_is_nonblocking;
|
||||
af_local_setblocking (orig_async_io, orig_is_nonblocking);
|
||||
if (!af_local_send_secret () || !af_local_recv_secret ()
|
||||
|
@ -418,7 +421,10 @@ fhandler_socket::af_local_connect ()
|
|||
int
|
||||
fhandler_socket::af_local_accept ()
|
||||
{
|
||||
debug_printf ("af_local_accept called");
|
||||
debug_printf ("af_local_accept called, no_getpeereid=%d", no_getpeereid ());
|
||||
if (no_getpeereid ())
|
||||
return 0;
|
||||
|
||||
bool orig_async_io, orig_is_nonblocking;
|
||||
af_local_setblocking (orig_async_io, orig_is_nonblocking);
|
||||
if (!af_local_recv_secret () || !af_local_send_secret ()
|
||||
|
@ -434,6 +440,25 @@ fhandler_socket::af_local_accept ()
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fhandler_socket::af_local_set_no_getpeereid ()
|
||||
{
|
||||
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
if (connect_state () != unconnected)
|
||||
{
|
||||
set_errno (EALREADY);
|
||||
return -1;
|
||||
}
|
||||
|
||||
debug_printf ("no_getpeereid set");
|
||||
no_getpeereid (true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_socket::af_local_set_cred ()
|
||||
{
|
||||
|
@ -458,6 +483,7 @@ fhandler_socket::af_local_copy (fhandler_socket *sock)
|
|||
sock->sec_peer_pid = sec_peer_pid;
|
||||
sock->sec_peer_uid = sec_peer_uid;
|
||||
sock->sec_peer_gid = sec_peer_gid;
|
||||
sock->no_getpeereid (no_getpeereid ());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1180,8 +1206,7 @@ fhandler_socket::listen (int backlog)
|
|||
{
|
||||
if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
|
||||
af_local_set_cred ();
|
||||
connect_state (connected);
|
||||
listener (true);
|
||||
connect_state (listener); /* gets set to connected on accepted socket. */
|
||||
}
|
||||
else
|
||||
set_winsock_errno ();
|
||||
|
@ -1195,7 +1220,17 @@ fhandler_socket::accept4 (struct sockaddr *peer, int *len, int flags)
|
|||
struct sockaddr_storage lpeer;
|
||||
int llen = sizeof (struct sockaddr_storage);
|
||||
|
||||
int res = 0;
|
||||
int res = (int) INVALID_SOCKET;
|
||||
|
||||
/* Windows event handling does not check for the validity of the desired
|
||||
flags so we have to do it here. */
|
||||
if (connect_state () != listener)
|
||||
{
|
||||
WSASetLastError (WSAEINVAL);
|
||||
set_winsock_errno ();
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (!(res = wait_for_events (FD_ACCEPT | FD_CLOSE, 0))
|
||||
&& (res = ::accept (get_socket (), (struct sockaddr *) &lpeer, &llen))
|
||||
== SOCKET_ERROR
|
||||
|
@ -2259,26 +2294,28 @@ fhandler_socket::getpeereid (pid_t *pid, uid_t *euid, gid_t *egid)
|
|||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
if (no_getpeereid ())
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
return -1;
|
||||
}
|
||||
if (connect_state () != connected)
|
||||
{
|
||||
set_errno (ENOTCONN);
|
||||
return -1;
|
||||
}
|
||||
if (sec_peer_pid == (pid_t) 0)
|
||||
{
|
||||
set_errno (ENOTCONN); /* Usually when calling getpeereid on
|
||||
accepting (instead of accepted) socket. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (pid)
|
||||
*pid = sec_peer_pid;
|
||||
if (euid)
|
||||
*euid = sec_peer_uid;
|
||||
if (egid)
|
||||
*egid = sec_peer_gid;
|
||||
return 0;
|
||||
__try
|
||||
{
|
||||
if (pid)
|
||||
*pid = sec_peer_pid;
|
||||
if (euid)
|
||||
*euid = sec_peer_uid;
|
||||
if (egid)
|
||||
*egid = sec_peer_gid;
|
||||
return 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
classes.
|
||||
|
||||
Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
||||
2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -977,159 +977,163 @@ mtinfo_drive::set_options (HANDLE mt, int32_t options)
|
|||
int
|
||||
mtinfo_drive::ioctl (HANDLE mt, unsigned int cmd, void *buf)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return ERROR_NOACCESS;
|
||||
if (cmd == MTIOCTOP)
|
||||
__try
|
||||
{
|
||||
struct mtop *op = (struct mtop *) buf;
|
||||
if (lasterr == ERROR_BUS_RESET)
|
||||
if (cmd == MTIOCTOP)
|
||||
{
|
||||
/* If a bus reset occurs, block further access to this device
|
||||
until the user rewinds, unloads or in any other way tries
|
||||
to maintain a well-known tape position. */
|
||||
if (op->mt_op != MTREW && op->mt_op != MTOFFL
|
||||
&& op->mt_op != MTRETEN && op->mt_op != MTERASE
|
||||
&& op->mt_op != MTSEEK && op->mt_op != MTEOM)
|
||||
return ERROR_BUS_RESET;
|
||||
/* Try to maintain last lock state after bus reset. */
|
||||
if (lock >= auto_locked && PrepareTape (mt, TAPE_LOCK, FALSE))
|
||||
struct mtop *op = (struct mtop *) buf;
|
||||
if (lasterr == ERROR_BUS_RESET)
|
||||
{
|
||||
debug_printf ("Couldn't relock drive after bus reset.");
|
||||
lock = unlocked;
|
||||
/* If a bus reset occurs, block further access to this device
|
||||
until the user rewinds, unloads or in any other way tries
|
||||
to maintain a well-known tape position. */
|
||||
if (op->mt_op != MTREW && op->mt_op != MTOFFL
|
||||
&& op->mt_op != MTRETEN && op->mt_op != MTERASE
|
||||
&& op->mt_op != MTSEEK && op->mt_op != MTEOM)
|
||||
return ERROR_BUS_RESET;
|
||||
/* Try to maintain last lock state after bus reset. */
|
||||
if (lock >= auto_locked && PrepareTape (mt, TAPE_LOCK, FALSE))
|
||||
{
|
||||
debug_printf ("Couldn't relock drive after bus reset.");
|
||||
lock = unlocked;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (op->mt_op)
|
||||
{
|
||||
case MTRESET:
|
||||
break;
|
||||
case MTFSF:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, op->mt_count, false);
|
||||
break;
|
||||
case MTBSF:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, -op->mt_count, false);
|
||||
break;
|
||||
case MTFSR:
|
||||
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS, op->mt_count, false);
|
||||
break;
|
||||
case MTBSR:
|
||||
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS, -op->mt_count, false);
|
||||
break;
|
||||
case MTWEOF:
|
||||
write_marks (mt, TAPE_FILEMARKS, op->mt_count);
|
||||
break;
|
||||
case MTREW:
|
||||
set_pos (mt, TAPE_REWIND, 0, false);
|
||||
break;
|
||||
case MTOFFL:
|
||||
case MTUNLOAD:
|
||||
prepare (mt, TAPE_UNLOAD);
|
||||
break;
|
||||
case MTNOP:
|
||||
lasterr = 0;
|
||||
break;
|
||||
case MTRETEN:
|
||||
if (!get_feature (TAPE_DRIVE_TENSION))
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
else if (!set_pos (mt, TAPE_REWIND, 0, false))
|
||||
prepare (mt, TAPE_TENSION);
|
||||
break;
|
||||
case MTBSFM:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, -op->mt_count, true);
|
||||
break;
|
||||
case MTFSFM:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, op->mt_count, true);
|
||||
break;
|
||||
case MTEOM:
|
||||
if (fast_eom () && get_feature (TAPE_DRIVE_END_OF_DATA))
|
||||
set_pos (mt, TAPE_SPACE_END_OF_DATA, 0, false);
|
||||
else
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, 32767, false);
|
||||
break;
|
||||
case MTERASE:
|
||||
erase (mt, TAPE_ERASE_LONG);
|
||||
break;
|
||||
case MTRAS1:
|
||||
case MTRAS2:
|
||||
case MTRAS3:
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
case MTSETBLK:
|
||||
if (!get_feature (TAPE_DRIVE_SET_BLOCK_SIZE))
|
||||
{
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
switch (op->mt_op)
|
||||
{
|
||||
case MTRESET:
|
||||
break;
|
||||
}
|
||||
if ((DWORD) op->mt_count == mp ()->BlockSize)
|
||||
{
|
||||
/* Nothing has changed. */
|
||||
case MTFSF:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, op->mt_count, false);
|
||||
break;
|
||||
case MTBSF:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, -op->mt_count, false);
|
||||
break;
|
||||
case MTFSR:
|
||||
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS, op->mt_count, false);
|
||||
break;
|
||||
case MTBSR:
|
||||
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS, -op->mt_count, false);
|
||||
break;
|
||||
case MTWEOF:
|
||||
write_marks (mt, TAPE_FILEMARKS, op->mt_count);
|
||||
break;
|
||||
case MTREW:
|
||||
set_pos (mt, TAPE_REWIND, 0, false);
|
||||
break;
|
||||
case MTOFFL:
|
||||
case MTUNLOAD:
|
||||
prepare (mt, TAPE_UNLOAD);
|
||||
break;
|
||||
case MTNOP:
|
||||
lasterr = 0;
|
||||
break;
|
||||
}
|
||||
if ((op->mt_count == 0 && !get_feature (TAPE_DRIVE_VARIABLE_BLOCK))
|
||||
|| (op->mt_count > 0
|
||||
&& ((DWORD) op->mt_count < dp ()->MinimumBlockSize
|
||||
|| (DWORD) op->mt_count > dp ()->MaximumBlockSize)))
|
||||
{
|
||||
case MTRETEN:
|
||||
if (!get_feature (TAPE_DRIVE_TENSION))
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
else if (!set_pos (mt, TAPE_REWIND, 0, false))
|
||||
prepare (mt, TAPE_TENSION);
|
||||
break;
|
||||
case MTBSFM:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, -op->mt_count, true);
|
||||
break;
|
||||
case MTFSFM:
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, op->mt_count, true);
|
||||
break;
|
||||
case MTEOM:
|
||||
if (fast_eom () && get_feature (TAPE_DRIVE_END_OF_DATA))
|
||||
set_pos (mt, TAPE_SPACE_END_OF_DATA, 0, false);
|
||||
else
|
||||
set_pos (mt, TAPE_SPACE_FILEMARKS, 32767, false);
|
||||
break;
|
||||
case MTERASE:
|
||||
erase (mt, TAPE_ERASE_LONG);
|
||||
break;
|
||||
case MTRAS1:
|
||||
case MTRAS2:
|
||||
case MTRAS3:
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
if (set_blocksize (mt, op->mt_count)
|
||||
&& lasterr == ERROR_INVALID_FUNCTION)
|
||||
lasterr = ERROR_INVALID_BLOCK_LENGTH;
|
||||
break;
|
||||
case MTSEEK:
|
||||
if (get_feature (TAPE_DRIVE_LOGICAL_BLK))
|
||||
set_pos (mt, TAPE_LOGICAL_BLOCK, op->mt_count, false);
|
||||
else if (!get_pos (mt))
|
||||
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS,
|
||||
op->mt_count - block, false);
|
||||
break;
|
||||
case MTTELL:
|
||||
if (!get_pos (mt))
|
||||
op->mt_count = (int) block;
|
||||
break;
|
||||
case MTFSS:
|
||||
set_pos (mt, TAPE_SPACE_SETMARKS, op->mt_count, false);
|
||||
break;
|
||||
case MTBSS:
|
||||
set_pos (mt, TAPE_SPACE_SETMARKS, -op->mt_count, false);
|
||||
break;
|
||||
case MTWSM:
|
||||
write_marks (mt, TAPE_SETMARKS, op->mt_count);
|
||||
break;
|
||||
case MTLOCK:
|
||||
prepare (mt, TAPE_LOCK);
|
||||
break;
|
||||
case MTUNLOCK:
|
||||
prepare (mt, TAPE_UNLOCK);
|
||||
break;
|
||||
case MTLOAD:
|
||||
prepare (mt, TAPE_LOAD);
|
||||
break;
|
||||
case MTCOMPRESSION:
|
||||
set_compression (mt, op->mt_count);
|
||||
break;
|
||||
case MTSETPART:
|
||||
set_partition (mt, op->mt_count);
|
||||
break;
|
||||
case MTMKPART:
|
||||
create_partitions (mt, op->mt_count);
|
||||
break;
|
||||
case MTSETDRVBUFFER:
|
||||
set_options (mt, op->mt_count);
|
||||
break;
|
||||
case MTSETDENSITY:
|
||||
default:
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
case MTSETBLK:
|
||||
if (!get_feature (TAPE_DRIVE_SET_BLOCK_SIZE))
|
||||
{
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
if ((DWORD) op->mt_count == mp ()->BlockSize)
|
||||
{
|
||||
/* Nothing has changed. */
|
||||
lasterr = 0;
|
||||
break;
|
||||
}
|
||||
if ((op->mt_count == 0 && !get_feature (TAPE_DRIVE_VARIABLE_BLOCK))
|
||||
|| (op->mt_count > 0
|
||||
&& ((DWORD) op->mt_count < dp ()->MinimumBlockSize
|
||||
|| (DWORD) op->mt_count > dp ()->MaximumBlockSize)))
|
||||
{
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
if (set_blocksize (mt, op->mt_count)
|
||||
&& lasterr == ERROR_INVALID_FUNCTION)
|
||||
lasterr = ERROR_INVALID_BLOCK_LENGTH;
|
||||
break;
|
||||
case MTSEEK:
|
||||
if (get_feature (TAPE_DRIVE_LOGICAL_BLK))
|
||||
set_pos (mt, TAPE_LOGICAL_BLOCK, op->mt_count, false);
|
||||
else if (!get_pos (mt))
|
||||
set_pos (mt, TAPE_SPACE_RELATIVE_BLOCKS,
|
||||
op->mt_count - block, false);
|
||||
break;
|
||||
case MTTELL:
|
||||
if (!get_pos (mt))
|
||||
op->mt_count = (int) block;
|
||||
break;
|
||||
case MTFSS:
|
||||
set_pos (mt, TAPE_SPACE_SETMARKS, op->mt_count, false);
|
||||
break;
|
||||
case MTBSS:
|
||||
set_pos (mt, TAPE_SPACE_SETMARKS, -op->mt_count, false);
|
||||
break;
|
||||
case MTWSM:
|
||||
write_marks (mt, TAPE_SETMARKS, op->mt_count);
|
||||
break;
|
||||
case MTLOCK:
|
||||
prepare (mt, TAPE_LOCK);
|
||||
break;
|
||||
case MTUNLOCK:
|
||||
prepare (mt, TAPE_UNLOCK);
|
||||
break;
|
||||
case MTLOAD:
|
||||
prepare (mt, TAPE_LOAD);
|
||||
break;
|
||||
case MTCOMPRESSION:
|
||||
set_compression (mt, op->mt_count);
|
||||
break;
|
||||
case MTSETPART:
|
||||
set_partition (mt, op->mt_count);
|
||||
break;
|
||||
case MTMKPART:
|
||||
create_partitions (mt, op->mt_count);
|
||||
break;
|
||||
case MTSETDRVBUFFER:
|
||||
set_options (mt, op->mt_count);
|
||||
break;
|
||||
case MTSETDENSITY:
|
||||
default:
|
||||
lasterr = ERROR_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (cmd == MTIOCGET)
|
||||
get_status (mt, (struct mtget *) buf);
|
||||
else if (cmd == MTIOCPOS && !get_pos (mt))
|
||||
((struct mtpos *) buf)->mt_blkno = (long) block;
|
||||
}
|
||||
else if (cmd == MTIOCGET)
|
||||
get_status (mt, (struct mtget *) buf);
|
||||
else if (cmd == MTIOCPOS && !get_pos (mt))
|
||||
((struct mtpos *) buf)->mt_blkno = (long) block;
|
||||
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
lasterr = ERROR_NOACCESS;
|
||||
}
|
||||
__endtry
|
||||
return lasterr;
|
||||
}
|
||||
|
||||
|
|
|
@ -1102,17 +1102,18 @@ fhandler_pty_slave::fstat (struct stat *st)
|
|||
/* Helper function for fchmod and fchown, which just opens all handles
|
||||
and signals success via bool return. */
|
||||
bool
|
||||
fhandler_pty_slave::fch_open_handles ()
|
||||
fhandler_pty_slave::fch_open_handles (bool chown)
|
||||
{
|
||||
char buf[MAX_PATH];
|
||||
DWORD write_access = WRITE_DAC | (chown ? WRITE_OWNER : 0);
|
||||
|
||||
_tc = cygwin_shared->tty[get_minor ()];
|
||||
shared_name (buf, INPUT_AVAILABLE_EVENT, get_minor ());
|
||||
input_available_event = OpenEvent (READ_CONTROL | WRITE_DAC | WRITE_OWNER,
|
||||
input_available_event = OpenEvent (READ_CONTROL | write_access,
|
||||
TRUE, buf);
|
||||
output_mutex = get_ttyp ()->open_output_mutex (WRITE_DAC | WRITE_OWNER);
|
||||
input_mutex = get_ttyp ()->open_input_mutex (WRITE_DAC | WRITE_OWNER);
|
||||
inuse = get_ttyp ()->open_inuse (WRITE_DAC | WRITE_OWNER);
|
||||
output_mutex = get_ttyp ()->open_output_mutex (write_access);
|
||||
input_mutex = get_ttyp ()->open_input_mutex (write_access);
|
||||
inuse = get_ttyp ()->open_inuse (write_access);
|
||||
if (!input_available_event || !output_mutex || !input_mutex || !inuse)
|
||||
{
|
||||
__seterrno ();
|
||||
|
@ -1166,7 +1167,7 @@ fhandler_pty_slave::fchmod (mode_t mode)
|
|||
if (!input_available_event)
|
||||
{
|
||||
to_close = true;
|
||||
if (!fch_open_handles ())
|
||||
if (!fch_open_handles (false))
|
||||
goto errout;
|
||||
}
|
||||
sd.malloc (sizeof (SECURITY_DESCRIPTOR));
|
||||
|
@ -1195,7 +1196,7 @@ fhandler_pty_slave::fchown (uid_t uid, gid_t gid)
|
|||
if (!input_available_event)
|
||||
{
|
||||
to_close = true;
|
||||
if (!fch_open_handles ())
|
||||
if (!fch_open_handles (true))
|
||||
goto errout;
|
||||
}
|
||||
sd.malloc (sizeof (SECURITY_DESCRIPTOR));
|
||||
|
|
|
@ -1761,37 +1761,37 @@ flock (int fd, int operation)
|
|||
int cmd;
|
||||
struct flock fl = { 0, SEEK_SET, 0, 0, 0 };
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
cygheap_fdget cfd (fd, true);
|
||||
if (cfd < 0)
|
||||
goto done;
|
||||
|
||||
cmd = (operation & LOCK_NB) ? F_SETLK : F_SETLKW;
|
||||
switch (operation & (~LOCK_NB))
|
||||
__try
|
||||
{
|
||||
case LOCK_EX:
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
case LOCK_SH:
|
||||
fl.l_type = F_RDLCK;
|
||||
break;
|
||||
case LOCK_UN:
|
||||
fl.l_type = F_UNLCK;
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
goto done;
|
||||
cygheap_fdget cfd (fd, true);
|
||||
if (cfd < 0)
|
||||
__leave;
|
||||
|
||||
cmd = (operation & LOCK_NB) ? F_SETLK : F_SETLKW;
|
||||
switch (operation & (~LOCK_NB))
|
||||
{
|
||||
case LOCK_EX:
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
case LOCK_SH:
|
||||
fl.l_type = F_RDLCK;
|
||||
break;
|
||||
case LOCK_UN:
|
||||
fl.l_type = F_UNLCK;
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
if (!cfd->mandatory_locking ())
|
||||
fl.l_type |= F_FLOCK;
|
||||
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
|
||||
: cfd->lock (cmd, &fl);
|
||||
if ((res == -1) && ((get_errno () == EAGAIN) || (get_errno () == EACCES)))
|
||||
set_errno (EWOULDBLOCK);
|
||||
}
|
||||
if (!cfd->mandatory_locking ())
|
||||
fl.l_type |= F_FLOCK;
|
||||
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
|
||||
: cfd->lock (cmd, &fl);
|
||||
if ((res == -1) && ((get_errno () == EAGAIN) || (get_errno () == EACCES)))
|
||||
set_errno (EWOULDBLOCK);
|
||||
done:
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = flock(%d, %d)", res, fd, operation);
|
||||
return res;
|
||||
}
|
||||
|
@ -1805,50 +1805,50 @@ lockf (int filedes, int function, off_t size)
|
|||
|
||||
pthread_testcancel ();
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
cygheap_fdget cfd (filedes, true);
|
||||
if (cfd < 0)
|
||||
goto done;
|
||||
|
||||
fl.l_start = 0;
|
||||
fl.l_len = size;
|
||||
fl.l_whence = SEEK_CUR;
|
||||
|
||||
switch (function)
|
||||
__try
|
||||
{
|
||||
case F_ULOCK:
|
||||
cmd = F_SETLK;
|
||||
fl.l_type = F_UNLCK;
|
||||
break;
|
||||
case F_LOCK:
|
||||
cmd = F_SETLKW;
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
case F_TLOCK:
|
||||
cmd = F_SETLK;
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
case F_TEST:
|
||||
fl.l_type = F_WRLCK;
|
||||
if (cfd->lock (F_GETLK, &fl) == -1)
|
||||
goto done;
|
||||
if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
|
||||
res = 0;
|
||||
else
|
||||
errno = EAGAIN;
|
||||
goto done;
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
errno = EINVAL;
|
||||
goto done;
|
||||
/* NOTREACHED */
|
||||
cygheap_fdget cfd (filedes, true);
|
||||
if (cfd < 0)
|
||||
__leave;
|
||||
|
||||
fl.l_start = 0;
|
||||
fl.l_len = size;
|
||||
fl.l_whence = SEEK_CUR;
|
||||
|
||||
switch (function)
|
||||
{
|
||||
case F_ULOCK:
|
||||
cmd = F_SETLK;
|
||||
fl.l_type = F_UNLCK;
|
||||
break;
|
||||
case F_LOCK:
|
||||
cmd = F_SETLKW;
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
case F_TLOCK:
|
||||
cmd = F_SETLK;
|
||||
fl.l_type = F_WRLCK;
|
||||
break;
|
||||
case F_TEST:
|
||||
fl.l_type = F_WRLCK;
|
||||
if (cfd->lock (F_GETLK, &fl) == -1)
|
||||
__leave;
|
||||
if (fl.l_type == F_UNLCK || fl.l_pid == getpid ())
|
||||
res = 0;
|
||||
else
|
||||
errno = EAGAIN;
|
||||
__leave;
|
||||
/* NOTREACHED */
|
||||
default:
|
||||
errno = EINVAL;
|
||||
__leave;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
|
||||
: cfd->lock (cmd, &fl);
|
||||
}
|
||||
res = cfd->mandatory_locking () ? cfd->mand_lock (cmd, &fl)
|
||||
: cfd->lock (cmd, &fl);
|
||||
done:
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
syscall_printf ("%R = lockf(%d, %d, %D)", res, filedes, function, size);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/perl
|
||||
# Copyright 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012, 2013
|
||||
# Copyright 2003, 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012, 2013, 2014
|
||||
# Red Hat, Inc.
|
||||
#
|
||||
# This file is part of Cygwin.
|
||||
|
@ -188,10 +188,12 @@ _sigbe: # return here after cygwin syscall
|
|||
.seh_proc sigdelayed
|
||||
sigdelayed:
|
||||
pushq %r10 # used for return address injection
|
||||
.seh_pushreg %rbp
|
||||
.seh_pushreg %r10
|
||||
pushq %rbp
|
||||
.seh_pushreg %rbp
|
||||
movq %rsp,%rbp
|
||||
pushf
|
||||
.seh_pushreg %rax # fake, there's no .seh_pushreg for the flags
|
||||
# stack is aligned or unaligned on entry!
|
||||
# make sure it is aligned from here on
|
||||
# We could be called from an interrupted thread which doesn't know
|
||||
|
@ -224,9 +226,8 @@ sigdelayed:
|
|||
.seh_pushreg %rbx
|
||||
pushq %rax
|
||||
.seh_pushreg %rax
|
||||
pushf
|
||||
subq \$0x130,%rsp
|
||||
.seh_stackalloc 0x130
|
||||
subq \$0x128,%rsp
|
||||
.seh_stackalloc 0x128
|
||||
fnstcw 0x120(%rsp)
|
||||
movdqa %xmm15,0x110(%rsp)
|
||||
movdqa %xmm14,0x100(%rsp)
|
||||
|
@ -288,8 +289,7 @@ sigdelayed:
|
|||
movdqa 0x110(%rsp),%xmm15
|
||||
fninit
|
||||
fldcw 0x120(%rsp)
|
||||
addq \$0x130,%rsp
|
||||
popf
|
||||
addq \$0x128,%rsp
|
||||
popq %rax
|
||||
popq %rbx
|
||||
popq %rcx
|
||||
|
@ -304,6 +304,8 @@ sigdelayed:
|
|||
popq %r14
|
||||
popq %r15
|
||||
movq %rbp,%rsp
|
||||
subq \$8, %rsp
|
||||
popf
|
||||
popq %rbp
|
||||
xchgq %r10,(%rsp)
|
||||
ret
|
||||
|
@ -366,7 +368,7 @@ stabilize_sig_stack:
|
|||
movq %gs:8,%r12
|
||||
1: movl \$1,%r10d
|
||||
xchgl %r10d,$tls::stacklock(%r12)
|
||||
movl %r10d,$tls::spinning(%r12) # flag if we are waiting for lock
|
||||
movl %r10d,$tls::spinning(%r12) # flag if we are waiting for lock
|
||||
testl %r10d,%r10d
|
||||
jz 2f
|
||||
pause
|
||||
|
@ -374,14 +376,14 @@ stabilize_sig_stack:
|
|||
2: incl $tls::incyg(%r12)
|
||||
cmpl \$0,$tls::sig(%r12)
|
||||
jz 3f
|
||||
decl $tls::stacklock(%r12) # unlock
|
||||
movq \$$tls::start_offset,%rcx # point to beginning
|
||||
addq %r12,%rcx # of tls block
|
||||
decl $tls::stacklock(%r12) # unlock
|
||||
movq \$$tls::start_offset,%rcx # point to beginning
|
||||
addq %r12,%rcx # of tls block
|
||||
call _ZN7_cygtls19call_signal_handlerEv
|
||||
jmp 1b
|
||||
3: decl $tls::incyg(%r12)
|
||||
addq \$0x20,%rsp
|
||||
movq %r12,%r11 # return tls addr in r11
|
||||
movq %r12,%r11 # return tls addr in r11
|
||||
popq %r12
|
||||
ret
|
||||
.seh_endproc
|
||||
|
@ -393,13 +395,13 @@ EOF
|
|||
__sigfe_maybe:
|
||||
pushl %ebx
|
||||
pushl %edx
|
||||
movl %fs:4,%ebx # location of bottom of stack
|
||||
addl \$$tls::initialized,%ebx # where we will be looking
|
||||
cmpl %ebx,%esp # stack loc > than tls
|
||||
jge 0f # yep. we don't have a tls.
|
||||
subl \$$tls::initialized,%ebx # where we will be looking
|
||||
movl %fs:4,%ebx # location of bottom of stack
|
||||
addl \$$tls::initialized,%ebx # where we will be looking
|
||||
cmpl %ebx,%esp # stack loc > than tls
|
||||
jge 0f # yep. we don't have a tls.
|
||||
subl \$$tls::initialized,%ebx # where we will be looking
|
||||
movl $tls::initialized(%ebx),%eax
|
||||
cmpl \$0xc763173f,%eax # initialized?
|
||||
cmpl \$0xc763173f,%eax # initialized?
|
||||
je 1f
|
||||
0: popl %edx
|
||||
popl %ebx
|
||||
|
@ -408,43 +410,43 @@ __sigfe_maybe:
|
|||
__sigfe:
|
||||
pushl %ebx
|
||||
pushl %edx
|
||||
movl %fs:4,%ebx # location of bottom of stack
|
||||
1: movl \$1,%eax # potential lock value
|
||||
xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
|
||||
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
|
||||
testl %eax,%eax # it will be zero
|
||||
jz 2f # if so
|
||||
call _yield # should be a short-time thing, so
|
||||
jmp 1b # sleep and loop
|
||||
2: movl \$4,%eax # have the lock, now increment the
|
||||
xadd %eax,$tls::stackptr(%ebx) # stack pointer and get pointer
|
||||
leal __sigbe,%edx # new place to return to
|
||||
xchgl %edx,12(%esp) # exchange with real return value
|
||||
movl %edx,(%eax) # store real return value on alt stack
|
||||
movl %fs:4,%ebx # location of bottom of stack
|
||||
1: movl \$1,%eax # potential lock value
|
||||
xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
|
||||
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
|
||||
testl %eax,%eax # it will be zero
|
||||
jz 2f # if so
|
||||
call _yield # should be a short-time thing, so
|
||||
jmp 1b # sleep and loop
|
||||
2: movl \$4,%eax # have the lock, now increment the
|
||||
xadd %eax,$tls::stackptr(%ebx) # stack pointer and get pointer
|
||||
leal __sigbe,%edx # new place to return to
|
||||
xchgl %edx,12(%esp) # exchange with real return value
|
||||
movl %edx,(%eax) # store real return value on alt stack
|
||||
incl $tls::incyg(%ebx)
|
||||
decl $tls::stacklock(%ebx) # remove lock
|
||||
popl %edx # restore saved value
|
||||
decl $tls::stacklock(%ebx) # remove lock
|
||||
popl %edx # restore saved value
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
.global __sigbe
|
||||
__sigbe: # return here after cygwin syscall
|
||||
pushl %eax # don't clobber
|
||||
pushl %ebx # tls pointer
|
||||
1: movl %fs:4,%ebx # address of bottom of tls
|
||||
movl \$1,%eax # potential lock value
|
||||
xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
|
||||
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
|
||||
testl %eax,%eax # it will be zero
|
||||
jz 2f # if so
|
||||
call _yield # sleep
|
||||
jmp 1b # and loop
|
||||
2: movl \$-4,%eax # now decrement aux stack
|
||||
xadd %eax,$tls::stackptr(%ebx) # and get pointer
|
||||
movl -4(%eax),%eax # get return address from signal stack
|
||||
xchgl %eax,4(%esp) # swap return address with saved eax
|
||||
__sigbe: # return here after cygwin syscall
|
||||
pushl %eax # don't clobber
|
||||
pushl %ebx # tls pointer
|
||||
1: movl %fs:4,%ebx # address of bottom of tls
|
||||
movl \$1,%eax # potential lock value
|
||||
xchgl %eax,$tls::stacklock(%ebx) # see if we can grab it
|
||||
movl %eax,$tls::spinning(%ebx) # flag if we are waiting for lock
|
||||
testl %eax,%eax # it will be zero
|
||||
jz 2f # if so
|
||||
call _yield # sleep
|
||||
jmp 1b # and loop
|
||||
2: movl \$-4,%eax # now decrement aux stack
|
||||
xadd %eax,$tls::stackptr(%ebx) # and get pointer
|
||||
movl -4(%eax),%eax # get return address from signal stack
|
||||
xchgl %eax,4(%esp) # swap return address with saved eax
|
||||
decl $tls::incyg(%ebx)
|
||||
decl $tls::stacklock(%ebx) # release lock
|
||||
decl $tls::stacklock(%ebx) # release lock
|
||||
popl %ebx
|
||||
ret
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* globals.cc - Define global variables here.
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -69,7 +69,7 @@ int NO_COPY dynamically_loaded;
|
|||
/* Some CYGWIN environment variable variables. */
|
||||
bool allow_glob = true;
|
||||
bool detect_bloda;
|
||||
bool dos_file_warning = true;
|
||||
bool dos_file_warning;
|
||||
bool ignore_case_with_glob;
|
||||
bool pipe_byte;
|
||||
bool reset_com;
|
||||
|
|
|
@ -26,6 +26,8 @@ time_t __cdecl timegm (struct tm *);
|
|||
|
||||
#ifndef __STRICT_ANSI__
|
||||
|
||||
extern int stime (const time_t *);
|
||||
|
||||
extern int daylight __asm__ (_SYMSTR (_daylight));
|
||||
|
||||
#ifndef __timezonefunc__
|
||||
|
|
|
@ -43,7 +43,7 @@ details. */
|
|||
changes to the DLL and is mainly informative in nature. */
|
||||
|
||||
#define CYGWIN_VERSION_DLL_MAJOR 1007
|
||||
#define CYGWIN_VERSION_DLL_MINOR 32
|
||||
#define CYGWIN_VERSION_DLL_MINOR 33
|
||||
|
||||
/* Major numbers before CYGWIN_VERSION_DLL_EPOCH are
|
||||
incompatible. */
|
||||
|
@ -448,12 +448,19 @@ details. */
|
|||
272: Export tm_gmtoff and tm_zone members.
|
||||
273: Skipped.
|
||||
274: Export __cxa_atexit and __cxa_finalize.
|
||||
275: Add CW_SETENT, CW_GETENT, CW_ENDENT, CW_GETNSSSEP, CW_GETPWSID,
|
||||
CW_GETGRSID, CW_CYGNAME_FROM_WINNAME as no-ops for forward compat.
|
||||
276: Export ffsl, ffsll.
|
||||
277: Add setsockopt(SO_PEERCRED).
|
||||
278: Add quotactl.
|
||||
279: Export stime.
|
||||
280: Static atexit in libcygwin.a, CW_FIXED_ATEXIT.
|
||||
*/
|
||||
|
||||
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
|
||||
|
||||
#define CYGWIN_VERSION_API_MAJOR 0
|
||||
#define CYGWIN_VERSION_API_MINOR 274
|
||||
#define CYGWIN_VERSION_API_MINOR 280
|
||||
|
||||
/* There is also a compatibity version number associated with the
|
||||
shared memory regions. It is incremented when incompatible
|
||||
|
|
|
@ -150,7 +150,8 @@ typedef enum
|
|||
CW_GETNSSSEP,
|
||||
CW_GETPWSID,
|
||||
CW_GETGRSID,
|
||||
CW_CYGNAME_FROM_WINNAME
|
||||
CW_CYGNAME_FROM_WINNAME,
|
||||
CW_FIXED_ATEXIT
|
||||
} cygwin_getinfo_types;
|
||||
|
||||
#define CW_LOCK_PINFO CW_LOCK_PINFO
|
||||
|
@ -208,6 +209,7 @@ typedef enum
|
|||
#define CW_GETPWSID CW_GETPWSID
|
||||
#define CW_GETGRSID CW_GETGRSID
|
||||
#define CW_CYGNAME_FROM_WINNAME CW_CYGNAME_FROM_WINNAME
|
||||
#define CW_FIXED_ATEXIT CW_FIXED_ATEXIT
|
||||
|
||||
/* Token type for CW_SET_EXTERNAL_TOKEN */
|
||||
enum
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* sys/mount.h
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2008, 2009, 2010, 2012
|
||||
Red Hat, Inc.
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2008, 2009, 2010, 2012,
|
||||
2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -12,6 +12,9 @@ details. */
|
|||
#ifndef _SYS_MOUNT_H
|
||||
#define _SYS_MOUNT_H
|
||||
|
||||
#define BLOCK_SIZE 1024
|
||||
#define BLOCK_SIZE_BITS 10
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
/* Copyright (c) 1982, 1986 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Robert Elz at The University of Melbourne.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SYS_QUOTA_H
|
||||
#define _SYS_QUOTA_H 1
|
||||
|
||||
#include <features.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* This file is copied from Linux and kept verbatim, except for the below
|
||||
Cygwin-specific blocks. */
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
/* On Linux these defines live in <linux/quota.h>. Move them here for easier
|
||||
access. */
|
||||
/* Quota format type IDs */
|
||||
#define QFMT_VFS_OLD 1
|
||||
#define QFMT_VFS_V0 2
|
||||
#define QFMT_OCFS2 3
|
||||
#define QFMT_VFS_V1 4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Select between different incompatible quota versions.
|
||||
* Default to the version used by Linux kernel version 2.4.22
|
||||
* or later. */
|
||||
#ifndef _LINUX_QUOTA_VERSION
|
||||
# define _LINUX_QUOTA_VERSION 2
|
||||
#endif
|
||||
|
||||
#if defined (__CYGWIN__) && _LINUX_QUOTA_VERSION != 2
|
||||
#error Cygwin only supports quota version 2.
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert diskblocks to blocks and the other way around.
|
||||
* currently only to fool the BSD source. :-)
|
||||
*/
|
||||
#define dbtob(num) ((num) << 10)
|
||||
#define btodb(num) ((num) >> 10)
|
||||
|
||||
/*
|
||||
* Convert count of filesystem blocks to diskquota blocks, meant
|
||||
* for filesystems where i_blksize != BLOCK_SIZE
|
||||
*/
|
||||
#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / BLOCK_SIZE)
|
||||
|
||||
/*
|
||||
* Definitions for disk quotas imposed on the average user
|
||||
* (big brother finally hits Linux).
|
||||
*
|
||||
* The following constants define the amount of time given a user
|
||||
* before the soft limits are treated as hard limits (usually resulting
|
||||
* in an allocation failure). The timer is started when the user crosses
|
||||
* their soft limit, it is reset when they go below their soft limit.
|
||||
*/
|
||||
#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */
|
||||
#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */
|
||||
|
||||
#define MAXQUOTAS 2
|
||||
#define USRQUOTA 0 /* element used for user quotas */
|
||||
#define GRPQUOTA 1 /* element used for group quotas */
|
||||
|
||||
/*
|
||||
* Definitions for the default names of the quotas files.
|
||||
*/
|
||||
#define INITQFNAMES { \
|
||||
"user", /* USRQUOTA */ \
|
||||
"group", /* GRPQUOTA */ \
|
||||
"undefined", \
|
||||
};
|
||||
|
||||
#define QUOTAFILENAME "quota"
|
||||
#define QUOTAGROUP "staff"
|
||||
|
||||
#define NR_DQHASH 43 /* Just an arbitrary number any suggestions ? */
|
||||
#define NR_DQUOTS 256 /* Number of quotas active at one time */
|
||||
|
||||
/*
|
||||
* Command definitions for the 'quotactl' system call.
|
||||
* The commands are broken into a main command defined below
|
||||
* and a subcommand that is used to convey the type of
|
||||
* quota that is being manipulated (see above).
|
||||
*/
|
||||
#define SUBCMDMASK 0x00ff
|
||||
#define SUBCMDSHIFT 8
|
||||
#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
|
||||
|
||||
#if _LINUX_QUOTA_VERSION < 2
|
||||
# define Q_QUOTAON 0x0100 /* enable quotas */
|
||||
# define Q_QUOTAOFF 0x0200 /* disable quotas */
|
||||
# define Q_GETQUOTA 0x0300 /* get limits and usage */
|
||||
# define Q_SETQUOTA 0x0400 /* set limits and usage */
|
||||
# define Q_SETUSE 0x0500 /* set usage */
|
||||
# define Q_SYNC 0x0600 /* sync disk copy of a filesystems quotas */
|
||||
# define Q_SETQLIM 0x0700 /* set limits */
|
||||
# define Q_GETSTATS 0x0800 /* get collected stats */
|
||||
# define Q_RSQUASH 0x1000 /* set root_squash option */
|
||||
#else
|
||||
# define Q_SYNC 0x800001 /* sync disk copy of a filesystems quotas */
|
||||
# define Q_QUOTAON 0x800002 /* turn quotas on */
|
||||
# define Q_QUOTAOFF 0x800003 /* turn quotas off */
|
||||
# define Q_GETFMT 0x800004 /* get quota format used on given filesystem */
|
||||
# define Q_GETINFO 0x800005 /* get information about quota files */
|
||||
# define Q_SETINFO 0x800006 /* set information about quota files */
|
||||
# define Q_GETQUOTA 0x800007 /* get user quota structure */
|
||||
# define Q_SETQUOTA 0x800008 /* set user quota structure */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following structure defines the format of the disk quota file
|
||||
* (as it appears on disk) - the file is an array of these structures
|
||||
* indexed by user or group number.
|
||||
*/
|
||||
#if _LINUX_QUOTA_VERSION < 2
|
||||
struct dqblk
|
||||
{
|
||||
u_int32_t dqb_bhardlimit; /* absolute limit on disk blks alloc */
|
||||
u_int32_t dqb_bsoftlimit; /* preferred limit on disk blks */
|
||||
u_int32_t dqb_curblocks; /* current block count */
|
||||
u_int32_t dqb_ihardlimit; /* maximum # allocated inodes */
|
||||
u_int32_t dqb_isoftlimit; /* preferred inode limit */
|
||||
u_int32_t dqb_curinodes; /* current # allocated inodes */
|
||||
time_t dqb_btime; /* time limit for excessive disk use */
|
||||
time_t dqb_itime; /* time limit for excessive files */
|
||||
};
|
||||
#else
|
||||
|
||||
/* Flags that indicate which fields in dqblk structure are valid. */
|
||||
#define QIF_BLIMITS 1
|
||||
#define QIF_SPACE 2
|
||||
#define QIF_ILIMITS 4
|
||||
#define QIF_INODES 8
|
||||
#define QIF_BTIME 16
|
||||
#define QIF_ITIME 32
|
||||
#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
|
||||
#define QIF_USAGE (QIF_SPACE | QIF_INODES)
|
||||
#define QIF_TIMES (QIF_BTIME | QIF_ITIME)
|
||||
#define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES)
|
||||
|
||||
struct dqblk
|
||||
{
|
||||
u_int64_t dqb_bhardlimit; /* absolute limit on disk quota blocks alloc */
|
||||
u_int64_t dqb_bsoftlimit; /* preferred limit on disk quota blocks */
|
||||
u_int64_t dqb_curspace; /* current quota block count */
|
||||
u_int64_t dqb_ihardlimit; /* maximum # allocated inodes */
|
||||
u_int64_t dqb_isoftlimit; /* preferred inode limit */
|
||||
u_int64_t dqb_curinodes; /* current # allocated inodes */
|
||||
u_int64_t dqb_btime; /* time limit for excessive disk use */
|
||||
u_int64_t dqb_itime; /* time limit for excessive files */
|
||||
u_int32_t dqb_valid; /* bitmask of QIF_* constants */
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Shorthand notation.
|
||||
*/
|
||||
#define dq_bhardlimit dq_dqb.dqb_bhardlimit
|
||||
#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit
|
||||
#if _LINUX_QUOTA_VERSION < 2
|
||||
# define dq_curblocks dq_dqb.dqb_curblocks
|
||||
#else
|
||||
# define dq_curspace dq_dqb.dqb_curspace
|
||||
# define dq_valid dq_dqb.dqb_valid
|
||||
#endif
|
||||
#define dq_ihardlimit dq_dqb.dqb_ihardlimit
|
||||
#define dq_isoftlimit dq_dqb.dqb_isoftlimit
|
||||
#define dq_curinodes dq_dqb.dqb_curinodes
|
||||
#define dq_btime dq_dqb.dqb_btime
|
||||
#define dq_itime dq_dqb.dqb_itime
|
||||
|
||||
#define dqoff(UID) ((loff_t)((UID) * sizeof (struct dqblk)))
|
||||
|
||||
#if _LINUX_QUOTA_VERSION < 2
|
||||
struct dqstats
|
||||
{
|
||||
u_int32_t lookups;
|
||||
u_int32_t drops;
|
||||
u_int32_t reads;
|
||||
u_int32_t writes;
|
||||
u_int32_t cache_hits;
|
||||
u_int32_t pages_allocated;
|
||||
u_int32_t allocated_dquots;
|
||||
u_int32_t free_dquots;
|
||||
u_int32_t syncs;
|
||||
};
|
||||
#else
|
||||
|
||||
/* Flags that indicate which fields in dqinfo structure are valid. */
|
||||
# define IIF_BGRACE 1
|
||||
# define IIF_IGRACE 2
|
||||
# define IIF_FLAGS 4
|
||||
# define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS)
|
||||
|
||||
struct dqinfo
|
||||
{
|
||||
u_int64_t dqi_bgrace;
|
||||
u_int64_t dqi_igrace;
|
||||
u_int32_t dqi_flags;
|
||||
u_int32_t dqi_valid;
|
||||
};
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
extern int quotactl (int __cmd, const char *__special, int __id,
|
||||
caddr_t __addr) __THROW;
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* sys/quota.h */
|
|
@ -1,6 +1,6 @@
|
|||
/* kernel32.cc: Win32 replacement functions.
|
||||
|
||||
Copyright 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -311,7 +311,8 @@ CreateFileMappingW (HANDLE hFile, LPSECURITY_ATTRIBUTES lpAttributes,
|
|||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
ULONG flags = 0;
|
||||
ACCESS_MASK access = READ_CONTROL | SECTION_QUERY | SECTION_MAP_READ;
|
||||
ACCESS_MASK access = STANDARD_RIGHTS_REQUIRED
|
||||
| SECTION_QUERY | SECTION_MAP_READ;
|
||||
ULONG prot = flProtect & (PAGE_NOACCESS | PAGE_READONLY | PAGE_READWRITE
|
||||
| PAGE_WRITECOPY | PAGE_EXECUTE
|
||||
| PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/* atexit.c: atexit entry point
|
||||
|
||||
Copyright 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/cygwin.h>
|
||||
#include <windows.h>
|
||||
|
||||
/* Statically linked replacement for the former cygwin_atexit. We need
|
||||
the function here to be able to access the correct __dso_handle of the
|
||||
caller's DSO. */
|
||||
|
||||
int
|
||||
atexit (void (*fn) (void))
|
||||
{
|
||||
extern int __cxa_atexit(void (*)(void*), void*, void*);
|
||||
extern void *__dso_handle;
|
||||
extern void *__ImageBase;
|
||||
|
||||
void *fixed_dso_handle = &__dso_handle;
|
||||
/* Check for being called from inside the executable. If so, use NULL
|
||||
as __dso_handle. This allows to link executables with GCC versions
|
||||
not providing __dso_handle in crtbegin{S}.o. In this case our own
|
||||
__dso_handle defined in lib/dso_handle.c is used. However, our
|
||||
__dso_handle always points to &__ImageBase, while the __dso_handle
|
||||
for executables provided by crtbegin.o usually points to NULL.
|
||||
That's what we remodel here. */
|
||||
if (&__ImageBase == (void **) GetModuleHandleW (NULL))
|
||||
fixed_dso_handle = NULL;
|
||||
/* With recent Cygwin versions starting with API version 0.280 we call
|
||||
__cxa_atexit (which is actually the cygwin__cxa_atexit wrapper in
|
||||
dcrt0.cc) with the address of __dso_handle since that's how g++ generates
|
||||
calls to __cxa_atexit as well. However, when running an application
|
||||
built with this atexit under an older Cygwin version, the __cxa_atexit
|
||||
entry point is the one from newlib, which expects the *value* of
|
||||
__dso_handle. So, check for the Cygwin version we're running under.
|
||||
Older version prior to 0.280 don't know CW_FIXED_ATEXIT and return -1.
|
||||
0.280 and later return 0. */
|
||||
else if (cygwin_internal (CW_FIXED_ATEXIT) != 0)
|
||||
fixed_dso_handle = __dso_handle;
|
||||
|
||||
return __cxa_atexit ((void (*)(void*))fn, NULL, fixed_dso_handle);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
/* dso_handle.c: Provide default __dso_handle.
|
||||
|
||||
Copyright 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
extern void *__ImageBase;
|
||||
void *__dso_handle = &__ImageBase;
|
|
@ -249,8 +249,7 @@ getprogname (void)
|
|||
extern "C" void
|
||||
setprogname (const char *newprogname)
|
||||
{
|
||||
myfault efault;
|
||||
if (!efault.faulted (EFAULT))
|
||||
__try
|
||||
{
|
||||
/* Per BSD man page, setprogname keeps a pointer to the last
|
||||
path component of the argument. It does *not* copy the
|
||||
|
@ -261,6 +260,8 @@ setprogname (const char *newprogname)
|
|||
else
|
||||
__progname = (char *)newprogname;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
|
|
|
@ -312,100 +312,101 @@ extern "C" int
|
|||
cygwin_rexec (char **ahost, unsigned short rport, char *name, char *pass,
|
||||
char *cmd, int *fd2p)
|
||||
{
|
||||
struct sockaddr_in sin, sin2, from;
|
||||
struct hostent *hp;
|
||||
u_short port = 0;
|
||||
int s, timo = 1, s3;
|
||||
char c;
|
||||
static char ahostbuf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
struct sockaddr_in sin, sin2, from;
|
||||
struct hostent *hp;
|
||||
u_short port = 0;
|
||||
int s, timo = 1, s3;
|
||||
char c;
|
||||
static char ahostbuf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
hp = cygwin_gethostbyname(*ahost);
|
||||
if (hp == 0) {
|
||||
cygwin_herror(*ahost);
|
||||
return (-1);
|
||||
}
|
||||
*ahost = strcpy (ahostbuf, hp->h_name);
|
||||
ruserpass(hp->h_name, &name, &pass, NULL);
|
||||
if (!name)
|
||||
name = getlogin ();
|
||||
if (!pass)
|
||||
pass = almost_null;
|
||||
__try
|
||||
{
|
||||
hp = cygwin_gethostbyname(*ahost);
|
||||
if (hp == 0) {
|
||||
cygwin_herror(*ahost);
|
||||
return (-1);
|
||||
}
|
||||
*ahost = strcpy (ahostbuf, hp->h_name);
|
||||
ruserpass(hp->h_name, &name, &pass, NULL);
|
||||
if (!name)
|
||||
name = getlogin ();
|
||||
if (!pass)
|
||||
pass = almost_null;
|
||||
retry:
|
||||
s = cygwin_socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
perror("rexec: socket");
|
||||
return (-1);
|
||||
}
|
||||
sin.sin_family = hp->h_addrtype;
|
||||
sin.sin_port = rport;
|
||||
bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
|
||||
if (cygwin_connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
|
||||
if (errno == ECONNREFUSED && timo <= 16) {
|
||||
(void) close(s);
|
||||
sleep(timo);
|
||||
timo *= 2;
|
||||
goto retry;
|
||||
}
|
||||
perror(hp->h_name);
|
||||
return (-1);
|
||||
}
|
||||
if (fd2p == 0) {
|
||||
(void) write(s, "", 1);
|
||||
} else {
|
||||
char num[8];
|
||||
int s2, sin2len;
|
||||
s = cygwin_socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
perror("rexec: socket");
|
||||
return (-1);
|
||||
}
|
||||
sin.sin_family = hp->h_addrtype;
|
||||
sin.sin_port = rport;
|
||||
bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
|
||||
if (cygwin_connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
|
||||
if (errno == ECONNREFUSED && timo <= 16) {
|
||||
(void) close(s);
|
||||
sleep(timo);
|
||||
timo *= 2;
|
||||
goto retry;
|
||||
}
|
||||
perror(hp->h_name);
|
||||
return (-1);
|
||||
}
|
||||
if (fd2p == 0) {
|
||||
(void) write(s, "", 1);
|
||||
} else {
|
||||
char num[8];
|
||||
int s2, sin2len;
|
||||
|
||||
s2 = cygwin_socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s2 < 0) {
|
||||
(void) close(s);
|
||||
return (-1);
|
||||
s2 = cygwin_socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s2 < 0) {
|
||||
(void) close(s);
|
||||
return (-1);
|
||||
}
|
||||
cygwin_listen(s2, 1);
|
||||
sin2len = sizeof (sin2);
|
||||
if (cygwin_getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 ||
|
||||
sin2len != sizeof (sin2)) {
|
||||
perror("getsockname");
|
||||
(void) close(s2);
|
||||
goto bad;
|
||||
}
|
||||
port = ntohs((u_short)sin2.sin_port);
|
||||
(void) sprintf(num, "%u", port);
|
||||
(void) write(s, num, strlen(num)+1);
|
||||
{ int len = sizeof (from);
|
||||
s3 = cygwin_accept(s2, (struct sockaddr *)&from, &len);
|
||||
close(s2);
|
||||
if (s3 < 0) {
|
||||
perror("accept");
|
||||
port = 0;
|
||||
goto bad;
|
||||
}
|
||||
cygwin_listen(s2, 1);
|
||||
sin2len = sizeof (sin2);
|
||||
if (cygwin_getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 ||
|
||||
sin2len != sizeof (sin2)) {
|
||||
perror("getsockname");
|
||||
(void) close(s2);
|
||||
goto bad;
|
||||
}
|
||||
port = ntohs((u_short)sin2.sin_port);
|
||||
(void) sprintf(num, "%u", port);
|
||||
(void) write(s, num, strlen(num)+1);
|
||||
{ int len = sizeof (from);
|
||||
s3 = cygwin_accept(s2, (struct sockaddr *)&from, &len);
|
||||
close(s2);
|
||||
if (s3 < 0) {
|
||||
perror("accept");
|
||||
port = 0;
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
*fd2p = s3;
|
||||
}
|
||||
(void) write(s, name, strlen(name) + 1);
|
||||
/* should public key encypt the password here */
|
||||
(void) write(s, pass, strlen(pass) + 1);
|
||||
(void) write(s, cmd, strlen(cmd) + 1);
|
||||
if (read(s, &c, 1) != 1) {
|
||||
perror(*ahost);
|
||||
goto bad;
|
||||
}
|
||||
if (c != 0) {
|
||||
while (read(s, &c, 1) == 1) {
|
||||
(void) write(2, &c, 1);
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
goto bad;
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
*fd2p = s3;
|
||||
}
|
||||
(void) write(s, name, strlen(name) + 1);
|
||||
/* should public key encypt the password here */
|
||||
(void) write(s, pass, strlen(pass) + 1);
|
||||
(void) write(s, cmd, strlen(cmd) + 1);
|
||||
if (read(s, &c, 1) != 1) {
|
||||
perror(*ahost);
|
||||
goto bad;
|
||||
}
|
||||
if (c != 0) {
|
||||
while (read(s, &c, 1) == 1) {
|
||||
(void) write(2, &c, 1);
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
goto bad;
|
||||
}
|
||||
return (s);
|
||||
bad:
|
||||
if (port)
|
||||
(void) close(*fd2p);
|
||||
(void) close(s);
|
||||
return (-1);
|
||||
if (port)
|
||||
(void) close(*fd2p);
|
||||
(void) close(s);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return (-1);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -146,8 +146,8 @@ cygwin_strncasecmp (const char *cs, const char *ct, size_t n)
|
|||
return RtlCompareUnicodeString (&us, &ut, TRUE);
|
||||
}
|
||||
|
||||
extern "C" char * __stdcall
|
||||
cygwin_strlwr (char *string)
|
||||
extern "C" char *
|
||||
strlwr (char *string)
|
||||
{
|
||||
UNICODE_STRING us;
|
||||
size_t len = (strlen (string) + 1) * sizeof (WCHAR);
|
||||
|
@ -160,8 +160,8 @@ cygwin_strlwr (char *string)
|
|||
return string;
|
||||
}
|
||||
|
||||
extern "C" char * __stdcall
|
||||
cygwin_strupr (char *string)
|
||||
extern "C" char *
|
||||
strupr (char *string)
|
||||
{
|
||||
UNICODE_STRING us;
|
||||
size_t len = (strlen (string) + 1) * sizeof (WCHAR);
|
||||
|
@ -202,35 +202,38 @@ check_iovec (const struct iovec *iov, int iovcnt, bool forwrite)
|
|||
return -1;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
size_t tot = 0;
|
||||
|
||||
while (iovcnt != 0)
|
||||
__try
|
||||
{
|
||||
if (iov->iov_len > SSIZE_MAX || (tot += iov->iov_len) > SSIZE_MAX)
|
||||
|
||||
size_t tot = 0;
|
||||
|
||||
while (iovcnt != 0)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (iov->iov_len > SSIZE_MAX || (tot += iov->iov_len) > SSIZE_MAX)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
|
||||
volatile char *p = ((char *) iov->iov_base) + iov->iov_len - 1;
|
||||
if (!iov->iov_len)
|
||||
/* nothing to do */;
|
||||
else if (!forwrite)
|
||||
*p = dummytest (p);
|
||||
else
|
||||
dummytest (p);
|
||||
|
||||
iov++;
|
||||
iovcnt--;
|
||||
}
|
||||
|
||||
volatile char *p = ((char *) iov->iov_base) + iov->iov_len - 1;
|
||||
if (!iov->iov_len)
|
||||
/* nothing to do */;
|
||||
else if (!forwrite)
|
||||
*p = dummytest (p);
|
||||
else
|
||||
dummytest (p);
|
||||
assert (tot <= SSIZE_MAX);
|
||||
|
||||
iov++;
|
||||
iovcnt--;
|
||||
return (ssize_t) tot;
|
||||
}
|
||||
|
||||
assert (tot <= SSIZE_MAX);
|
||||
|
||||
return (ssize_t) tot;
|
||||
__except (EFAULT)
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try hard to schedule another thread.
|
||||
|
@ -436,18 +439,23 @@ slashify (const char *src, char *dst, bool trailing_slash_p)
|
|||
void * __reg1
|
||||
__import_address (void *imp)
|
||||
{
|
||||
if (*((uint16_t *) imp) != 0x25ff)
|
||||
return NULL;
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return NULL;
|
||||
const char *ptr = (const char *) imp;
|
||||
__try
|
||||
{
|
||||
if (*((uint16_t *) imp) == 0x25ff)
|
||||
{
|
||||
const char *ptr = (const char *) imp;
|
||||
#ifdef __x86_64__
|
||||
const uintptr_t *jmpto = (uintptr_t *) (ptr + 6 + *(int32_t *)(ptr + 2));
|
||||
const uintptr_t *jmpto = (uintptr_t *)
|
||||
(ptr + 6 + *(int32_t *)(ptr + 2));
|
||||
#else
|
||||
const uintptr_t *jmpto = (uintptr_t *) *((uintptr_t *) (ptr + 2));
|
||||
const uintptr_t *jmpto = (uintptr_t *) *((uintptr_t *) (ptr + 2));
|
||||
#endif
|
||||
return (void *) *jmpto;
|
||||
return (void *) *jmpto;
|
||||
}
|
||||
}
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* CygwinCreateThread.
|
||||
|
|
|
@ -1772,50 +1772,54 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
|
|||
isn't really supported except from fstab? */
|
||||
int res = -1;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
/* errno set */;
|
||||
else if (!*posix_path)
|
||||
set_errno (EINVAL);
|
||||
else if (strpbrk (posix_path, "\\:"))
|
||||
set_errno (EINVAL);
|
||||
else if (flags & MOUNT_CYGDRIVE) /* normal mount */
|
||||
__try
|
||||
{
|
||||
/* When flags include MOUNT_CYGDRIVE, take this to mean that
|
||||
we actually want to change the cygdrive prefix and flags
|
||||
without actually mounting anything. */
|
||||
res = mount_table->write_cygdrive_info (posix_path, flags);
|
||||
win32_path = NULL;
|
||||
}
|
||||
else if (!*win32_path)
|
||||
set_errno (EINVAL);
|
||||
else
|
||||
{
|
||||
char *w32_path = (char *) win32_path;
|
||||
if (flags & MOUNT_BIND)
|
||||
if (!*posix_path)
|
||||
set_errno (EINVAL);
|
||||
else if (strpbrk (posix_path, "\\:"))
|
||||
set_errno (EINVAL);
|
||||
else if (flags & MOUNT_CYGDRIVE) /* normal mount */
|
||||
{
|
||||
/* Prepend root path to bound path. */
|
||||
tmp_pathbuf tp;
|
||||
device dev;
|
||||
|
||||
unsigned conv_flags = 0;
|
||||
const char *bound_path = w32_path;
|
||||
|
||||
w32_path = tp.c_get ();
|
||||
int error = mount_table->conv_to_win32_path (bound_path, w32_path,
|
||||
dev, &conv_flags);
|
||||
if (error || strlen (w32_path) >= MAX_PATH)
|
||||
return true;
|
||||
if ((flags & ~MOUNT_SYSTEM) == (MOUNT_BIND | MOUNT_BINARY))
|
||||
flags = (MOUNT_BIND | conv_flags)
|
||||
& ~(MOUNT_IMMUTABLE | MOUNT_AUTOMATIC);
|
||||
/* When flags include MOUNT_CYGDRIVE, take this to mean that
|
||||
we actually want to change the cygdrive prefix and flags
|
||||
without actually mounting anything. */
|
||||
res = mount_table->write_cygdrive_info (posix_path, flags);
|
||||
win32_path = NULL;
|
||||
}
|
||||
/* Make sure all mounts are user mounts, even those added via mount -a. */
|
||||
flags &= ~MOUNT_SYSTEM;
|
||||
res = mount_table->add_item (w32_path, posix_path, flags);
|
||||
}
|
||||
else if (!*win32_path)
|
||||
set_errno (EINVAL);
|
||||
else
|
||||
{
|
||||
char *w32_path = (char *) win32_path;
|
||||
if (flags & MOUNT_BIND)
|
||||
{
|
||||
/* Prepend root path to bound path. */
|
||||
tmp_pathbuf tp;
|
||||
device dev;
|
||||
|
||||
syscall_printf ("%R = mount(%s, %s, %y)", res, win32_path, posix_path, flags);
|
||||
unsigned conv_flags = 0;
|
||||
const char *bound_path = w32_path;
|
||||
|
||||
w32_path = tp.c_get ();
|
||||
int error = mount_table->conv_to_win32_path (bound_path, w32_path,
|
||||
dev, &conv_flags);
|
||||
if (error || strlen (w32_path) >= MAX_PATH)
|
||||
return true;
|
||||
if ((flags & ~MOUNT_SYSTEM) == (MOUNT_BIND | MOUNT_BINARY))
|
||||
flags = (MOUNT_BIND | conv_flags)
|
||||
& ~(MOUNT_IMMUTABLE | MOUNT_AUTOMATIC);
|
||||
}
|
||||
/* Make sure all mounts are user mounts, even those added via
|
||||
mount -a. */
|
||||
flags &= ~MOUNT_SYSTEM;
|
||||
res = mount_table->add_item (w32_path, posix_path, flags);
|
||||
}
|
||||
|
||||
syscall_printf ("%R = mount(%s, %s, %y)",
|
||||
res, win32_path, posix_path, flags);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1827,15 +1831,18 @@ mount (const char *win32_path, const char *posix_path, unsigned flags)
|
|||
extern "C" int
|
||||
umount (const char *path)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (!*path)
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (!*path)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
return cygwin_umount (path, 0);
|
||||
}
|
||||
return cygwin_umount (path, 0);
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* cygwin_umount: This is like umount but takes an additional flags
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* msg.cc: XSI IPC interface for Cygwin.
|
||||
|
||||
Copyright 2002, 2003, 2004, 2005, 2008, 2009 Red Hat, Inc.
|
||||
Copyright 2002, 2003, 2004, 2005, 2008, 2009, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -91,38 +91,40 @@ client_request_msg::client_request_msg (int msqid,
|
|||
extern "C" int
|
||||
msgctl (int msqid, int cmd, struct msqid_ds *buf)
|
||||
{
|
||||
syscall_printf ("msgctl (msqid = %d, cmd = %y, buf = %p)",
|
||||
msqid, cmd, buf);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
switch (cmd)
|
||||
syscall_printf ("msgctl (msqid = %d, cmd = %y, buf = %p)", msqid, cmd, buf);
|
||||
__try
|
||||
{
|
||||
case IPC_STAT:
|
||||
break;
|
||||
case IPC_SET:
|
||||
break;
|
||||
case IPC_RMID:
|
||||
break;
|
||||
case IPC_INFO:
|
||||
break;
|
||||
case MSG_INFO:
|
||||
break;
|
||||
default:
|
||||
syscall_printf ("-1 [%d] = msgctl ()", EINVAL);
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
switch (cmd)
|
||||
{
|
||||
case IPC_STAT:
|
||||
break;
|
||||
case IPC_SET:
|
||||
break;
|
||||
case IPC_RMID:
|
||||
break;
|
||||
case IPC_INFO:
|
||||
break;
|
||||
case MSG_INFO:
|
||||
break;
|
||||
default:
|
||||
syscall_printf ("-1 [%d] = msgctl ()", EINVAL);
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
client_request_msg request (msqid, cmd, buf);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
syscall_printf ("-1 [%d] = msgctl ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
__leave;
|
||||
}
|
||||
return request.retval ();
|
||||
}
|
||||
client_request_msg request (msqid, cmd, buf);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
syscall_printf ("-1 [%d] = msgctl ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
}
|
||||
return request.retval ();
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -147,19 +149,22 @@ msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)
|
|||
syscall_printf ("msgrcv (msqid = %d, msgp = %p, msgsz = %ld, "
|
||||
"msgtyp = %d, msgflg = %y)",
|
||||
msqid, msgp, msgsz, msgtyp, msgflg);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
client_request_msg request (msqid, msgp, msgsz, msgtyp, msgflg);
|
||||
if (request.make_request () == -1 || request.rcvval () == -1)
|
||||
__try
|
||||
{
|
||||
syscall_printf ("-1 [%d] = msgrcv ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
client_request_msg request (msqid, msgp, msgsz, msgtyp, msgflg);
|
||||
if (request.make_request () == -1 || request.rcvval () == -1)
|
||||
{
|
||||
syscall_printf ("-1 [%d] = msgrcv ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
__leave;
|
||||
}
|
||||
return request.rcvval ();
|
||||
}
|
||||
return request.rcvval ();
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -167,17 +172,20 @@ msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)
|
|||
{
|
||||
syscall_printf ("msgsnd (msqid = %d, msgp = %p, msgsz = %ld, msgflg = %y)",
|
||||
msqid, msgp, msgsz, msgflg);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
client_request_msg request (msqid, msgp, msgsz, msgflg);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
__try
|
||||
{
|
||||
syscall_printf ("-1 [%d] = msgsnd ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
client_request_msg request (msqid, msgp, msgsz, msgflg);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
syscall_printf ("-1 [%d] = msgsnd ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
__leave;
|
||||
}
|
||||
return request.retval ();
|
||||
}
|
||||
return request.retval ();
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
1825
winsup/cygwin/net.cc
1825
winsup/cygwin/net.cc
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
/* ntdll.h. Contains ntdll specific stuff not defined elsewhere.
|
||||
|
||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||||
2011, 2012, 2013 Red Hat, Inc.
|
||||
2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -143,6 +143,19 @@
|
|||
#define HEAP_FLAG_EXECUTABLE 0x40000
|
||||
#define HEAP_FLAG_DEBUGGED 0x40000000
|
||||
|
||||
#define FILE_VC_QUOTA_NONE 0x00000000
|
||||
#define FILE_VC_QUOTA_TRACK 0x00000001
|
||||
#define FILE_VC_QUOTA_ENFORCE 0x00000002
|
||||
#define FILE_VC_QUOTA_MASK 0x00000003
|
||||
#define FILE_VC_CONTENT_INDEX_DISABLED 0x00000008
|
||||
#define FILE_VC_LOG_QUOTA_THRESHOLD 0x00000010
|
||||
#define FILE_VC_LOG_QUOTA_LIMIT 0x00000020
|
||||
#define FILE_VC_LOG_VOLUME_THRESHOLD 0x00000040
|
||||
#define FILE_VC_LOG_VOLUME_LIMIT 0x00000080
|
||||
#define FILE_VC_QUOTAS_INCOMPLETE 0x00000100
|
||||
#define FILE_VC_QUOTAS_REBUILDING 0x00000200
|
||||
#define FILE_VC_VALID_MASK 0x000003ff
|
||||
|
||||
/* IOCTL code to impersonate client of named pipe. */
|
||||
#define FSCTL_PIPE_IMPERSONATE CTL_CODE(FILE_DEVICE_NAMED_PIPE, 7, \
|
||||
METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
@ -999,6 +1012,16 @@ typedef struct _FILE_FS_SIZE_INFORMATION
|
|||
ULONG BytesPerSector;
|
||||
} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;
|
||||
|
||||
/* Checked on 64 bit. */
|
||||
typedef struct _FILE_FS_CONTROL_INFORMATION {
|
||||
LARGE_INTEGER FreeSpaceStartFiltering;
|
||||
LARGE_INTEGER FreeSpaceThreshold;
|
||||
LARGE_INTEGER FreeSpaceStopFiltering;
|
||||
LARGE_INTEGER DefaultQuotaThreshold;
|
||||
LARGE_INTEGER DefaultQuotaLimit;
|
||||
ULONG FileSystemControlFlags;
|
||||
} FILE_FS_CONTROL_INFORMATION, *PFILE_FS_CONTROL_INFORMATION;
|
||||
|
||||
/* Checked on 64 bit. */
|
||||
typedef struct _FILE_FS_FULL_SIZE_INFORMATION
|
||||
{
|
||||
|
@ -1066,6 +1089,24 @@ typedef struct _DIRECTORY_BASIC_INFORMATION
|
|||
UNICODE_STRING ObjectTypeName;
|
||||
} DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION;
|
||||
|
||||
/* Checked on 64 bit. */
|
||||
typedef struct _FILE_GET_QUOTA_INFORMATION {
|
||||
ULONG NextEntryOffset;
|
||||
ULONG SidLength;
|
||||
SID Sid;
|
||||
} FILE_GET_QUOTA_INFORMATION, *PFILE_GET_QUOTA_INFORMATION;
|
||||
|
||||
/* Checked on 64 bit. */
|
||||
typedef struct _FILE_QUOTA_INFORMATION {
|
||||
ULONG NextEntryOffset;
|
||||
ULONG SidLength;
|
||||
LARGE_INTEGER ChangeTime;
|
||||
LARGE_INTEGER QuotaUsed;
|
||||
LARGE_INTEGER QuotaThreshold;
|
||||
LARGE_INTEGER QuotaLimit;
|
||||
SID Sid;
|
||||
} FILE_QUOTA_INFORMATION, *PFILE_QUOTA_INFORMATION;
|
||||
|
||||
/* Checked on 64 bit. */
|
||||
typedef struct _FILE_GET_EA_INFORMATION
|
||||
{
|
||||
|
@ -1180,8 +1221,19 @@ typedef enum _SECTION_INHERIT
|
|||
|
||||
typedef VOID (APIENTRY *PTIMER_APC_ROUTINE)(PVOID, ULONG, ULONG);
|
||||
|
||||
/* Function declarations for ntdll.dll. These don't appear in any
|
||||
standard Win32 header. */
|
||||
#ifdef __x86_64__
|
||||
typedef struct _SCOPE_TABLE
|
||||
{
|
||||
ULONG Count;
|
||||
struct
|
||||
{
|
||||
ULONG BeginAddress;
|
||||
ULONG EndAddress;
|
||||
ULONG HandlerAddress;
|
||||
ULONG JumpTarget;
|
||||
} ScopeRecord[1];
|
||||
} SCOPE_TABLE, *PSCOPE_TABLE;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
/* This is the mapping of the KUSER_SHARED_DATA structure into the user
|
||||
|
@ -1190,6 +1242,9 @@ typedef VOID (APIENTRY *PTIMER_APC_ROUTINE)(PVOID, ULONG, ULONG);
|
|||
static volatile KUSER_SHARED_DATA &SharedUserData
|
||||
= *(volatile KUSER_SHARED_DATA *) 0x7ffe0000;
|
||||
|
||||
/* Function declarations for ntdll.dll. These don't appear in any
|
||||
standard Win32 header. */
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
@ -1287,8 +1342,11 @@ extern "C"
|
|||
ULONG, PULONG);
|
||||
NTSTATUS NTAPI NtQueryInformationToken (HANDLE, TOKEN_INFORMATION_CLASS,
|
||||
PVOID, ULONG, PULONG);
|
||||
NTSTATUS NTAPI NtQueryObject (HANDLE, OBJECT_INFORMATION_CLASS, VOID *,
|
||||
ULONG, ULONG *);
|
||||
NTSTATUS NTAPI NtQueryObject (HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG,
|
||||
PULONG);
|
||||
NTSTATUS NTAPI NtQueryQuotaInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
|
||||
ULONG, BOOLEAN, PVOID, ULONG,
|
||||
PSID, BOOLEAN);
|
||||
NTSTATUS NTAPI NtQuerySemaphore (HANDLE, SEMAPHORE_INFORMATION_CLASS,
|
||||
PVOID, ULONG, PULONG);
|
||||
NTSTATUS NTAPI NtQuerySystemInformation (SYSTEM_INFORMATION_CLASS,
|
||||
|
@ -1305,9 +1363,8 @@ extern "C"
|
|||
PULONG);
|
||||
NTSTATUS NTAPI NtQueryVirtualMemory (HANDLE, PVOID, MEMORY_INFORMATION_CLASS,
|
||||
PVOID, SIZE_T, PSIZE_T);
|
||||
NTSTATUS NTAPI NtQueryVolumeInformationFile (HANDLE, IO_STATUS_BLOCK *,
|
||||
VOID *, ULONG,
|
||||
FS_INFORMATION_CLASS);
|
||||
NTSTATUS NTAPI NtQueryVolumeInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
|
||||
ULONG, FS_INFORMATION_CLASS);
|
||||
NTSTATUS NTAPI NtReadFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
|
||||
PIO_STATUS_BLOCK, PVOID, ULONG, PLARGE_INTEGER,
|
||||
PULONG);
|
||||
|
@ -1319,6 +1376,8 @@ extern "C"
|
|||
NTSTATUS NTAPI NtSetInformationThread (HANDLE, THREADINFOCLASS, PVOID, ULONG);
|
||||
NTSTATUS NTAPI NtSetInformationToken (HANDLE, TOKEN_INFORMATION_CLASS, PVOID,
|
||||
ULONG);
|
||||
NTSTATUS NTAPI NtSetQuotaInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
|
||||
ULONG);
|
||||
NTSTATUS NTAPI NtSetSecurityObject (HANDLE, SECURITY_INFORMATION,
|
||||
PSECURITY_DESCRIPTOR);
|
||||
NTSTATUS NTAPI NtSetTimer (HANDLE, PLARGE_INTEGER, PTIMER_APC_ROUTINE, PVOID,
|
||||
|
@ -1326,6 +1385,8 @@ extern "C"
|
|||
NTSTATUS NTAPI NtSetTimerResolution (ULONG, BOOLEAN, PULONG);
|
||||
NTSTATUS NTAPI NtSetValueKey (HANDLE, PUNICODE_STRING, ULONG, ULONG, PVOID,
|
||||
ULONG);
|
||||
NTSTATUS NTAPI NtSetVolumeInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
|
||||
ULONG, FS_INFORMATION_CLASS);
|
||||
NTSTATUS NTAPI NtUnlockFile (HANDLE, PIO_STATUS_BLOCK, PLARGE_INTEGER,
|
||||
PLARGE_INTEGER, ULONG);
|
||||
NTSTATUS NTAPI NtUnlockVirtualMemory (HANDLE, PVOID *, PSIZE_T, ULONG);
|
||||
|
|
|
@ -60,169 +60,173 @@ read_ea (HANDLE hdl, path_conv &pc, const char *name, char *value, size_t size)
|
|||
EA in the file is returned twice. */
|
||||
char lastname[MAX_EA_NAME_LEN];
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
goto out;
|
||||
|
||||
pc.get_object_attr (attr, sec_none_nih);
|
||||
|
||||
debug_printf ("read_ea (%S, %s, %p, %lu)",
|
||||
attr.ObjectName, name, value, size);
|
||||
|
||||
/* Early open if handle is NULL. This allows to return error codes like
|
||||
ENOENT before we actually check for the correctness of the EA name and
|
||||
stuff like that. */
|
||||
if (!hdl)
|
||||
__try
|
||||
{
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
goto out;
|
||||
}
|
||||
hdl = NULL;
|
||||
}
|
||||
pc.get_object_attr (attr, sec_none_nih);
|
||||
|
||||
fea = (PFILE_FULL_EA_INFORMATION) tp.w_get ();
|
||||
debug_printf ("read_ea (%S, %s, %p, %lu)",
|
||||
attr.ObjectName, name, value, size);
|
||||
|
||||
if (name)
|
||||
{
|
||||
size_t nlen;
|
||||
|
||||
/* For compatibility with Linux, we only allow user xattrs and
|
||||
return ENOTSUP otherwise. */
|
||||
if (ascii_strncasematch (name, "user.", 5))
|
||||
name += 5;
|
||||
else
|
||||
/* Early open if handle is NULL. This allows to return error codes like
|
||||
ENOENT before we actually check for the correctness of the EA name and
|
||||
stuff like that. */
|
||||
if (!hdl)
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
glen = sizeof (FILE_GET_EA_INFORMATION) + nlen;
|
||||
gea = (PFILE_GET_EA_INFORMATION) alloca (glen);
|
||||
|
||||
gea->NextEntryOffset = 0;
|
||||
gea->EaNameLength = nlen;
|
||||
strcpy (gea->EaName, name);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (h)
|
||||
{
|
||||
status = NtQueryEaFile (h, &io, fea, EA_BUFSIZ, TRUE, gea, glen,
|
||||
NULL, TRUE);
|
||||
if (status != STATUS_ACCESS_DENIED || !hdl)
|
||||
break;
|
||||
}
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
hdl = NULL;
|
||||
}
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_NO_EAS_ON_FILE:
|
||||
ret = 0;
|
||||
break;
|
||||
case STATUS_INVALID_DEVICE_REQUEST:
|
||||
set_errno (ENOTSUP);
|
||||
break;
|
||||
case STATUS_NOT_FOUND:
|
||||
/* STATUS_NOT_FOUND is returned when calling NtQueryEaFile on NFS.
|
||||
In theory this should mean that the file just has no EAs, but in
|
||||
fact NFS doesn't support EAs, other than the EAs which are used
|
||||
for NFS requests. We're playing safe and convert STATUS_NOT_FOUND
|
||||
to ENOATTR, unless we're on NFS, where we convert it to ENOTSUP. */
|
||||
set_errno (pc.fs_is_nfs () ? ENOTSUP : ENOATTR);
|
||||
break;
|
||||
case STATUS_NONEXISTENT_EA_ENTRY:
|
||||
/* Actually STATUS_NONEXISTENT_EA_ENTRY is either never generated, or
|
||||
it was only generated in some old and long forgotton NT version.
|
||||
See below. For safty reasons, we handle it here, nevertheless. */
|
||||
set_errno (ENOATTR);
|
||||
break;
|
||||
default:
|
||||
__seterrno_from_nt_status (status);
|
||||
break;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
if (name)
|
||||
{
|
||||
/* Another weird behaviour of NtQueryEaFile. If you ask for a
|
||||
specific EA which is not present in the file's EA list, you don't
|
||||
get a useful error code like STATUS_NONEXISTENT_EA_ENTRY. Rather
|
||||
NtQueryEaFile returns success with the entry's EaValueLength
|
||||
set to 0. */
|
||||
if (!fea->EaValueLength)
|
||||
{
|
||||
set_errno (ENOATTR);
|
||||
goto out;
|
||||
}
|
||||
if (size > 0)
|
||||
{
|
||||
if (size < fea->EaValueLength)
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
set_errno (ERANGE);
|
||||
goto out;
|
||||
__seterrno_from_nt_status (status);
|
||||
__leave;
|
||||
}
|
||||
memcpy (value, fea->EaName + fea->EaNameLength + 1,
|
||||
fea->EaValueLength);
|
||||
}
|
||||
ret = fea->EaValueLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
do
|
||||
|
||||
fea = (PFILE_FULL_EA_INFORMATION) tp.w_get ();
|
||||
|
||||
if (name)
|
||||
{
|
||||
fea->EaNameLength += 5; /* "user." */
|
||||
size_t nlen;
|
||||
|
||||
/* For compatibility with Linux, we only allow user xattrs and
|
||||
return ENOTSUP otherwise. */
|
||||
if (ascii_strncasematch (name, "user.", 5))
|
||||
name += 5;
|
||||
else
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
__leave;
|
||||
}
|
||||
|
||||
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
glen = sizeof (FILE_GET_EA_INFORMATION) + nlen;
|
||||
gea = (PFILE_GET_EA_INFORMATION) alloca (glen);
|
||||
|
||||
gea->NextEntryOffset = 0;
|
||||
gea->EaNameLength = nlen;
|
||||
strcpy (gea->EaName, name);
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (h)
|
||||
{
|
||||
status = NtQueryEaFile (h, &io, fea, EA_BUFSIZ, TRUE, gea, glen,
|
||||
NULL, TRUE);
|
||||
if (status != STATUS_ACCESS_DENIED || !hdl)
|
||||
break;
|
||||
pc.init_reopen_attr (attr, h);
|
||||
}
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_READ_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
hdl = NULL;
|
||||
}
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_NO_EAS_ON_FILE:
|
||||
ret = 0;
|
||||
break;
|
||||
case STATUS_INVALID_DEVICE_REQUEST:
|
||||
set_errno (ENOTSUP);
|
||||
break;
|
||||
case STATUS_NOT_FOUND:
|
||||
/* STATUS_NOT_FOUND is returned when calling NtQueryEaFile on NFS.
|
||||
In theory this should mean that the file just has no EAs, but
|
||||
in fact NFS doesn't support EAs, other than the EAs which are
|
||||
used for NFS requests. We're playing safe and convert
|
||||
STATUS_NOT_FOUND to ENOATTR, unless we're on NFS, where we
|
||||
convert it to ENOTSUP. */
|
||||
set_errno (pc.fs_is_nfs () ? ENOTSUP : ENOATTR);
|
||||
break;
|
||||
case STATUS_NONEXISTENT_EA_ENTRY:
|
||||
/* Actually STATUS_NONEXISTENT_EA_ENTRY is either never generated,
|
||||
or it was only generated in some old and long forgotton NT
|
||||
version. See below. For safty reasons, we handle it here,
|
||||
nevertheless. */
|
||||
set_errno (ENOATTR);
|
||||
break;
|
||||
default:
|
||||
__seterrno_from_nt_status (status);
|
||||
break;
|
||||
}
|
||||
__leave;
|
||||
}
|
||||
if (name)
|
||||
{
|
||||
/* Another weird behaviour of NtQueryEaFile. If you ask for a
|
||||
specific EA which is not present in the file's EA list, you don't
|
||||
get a useful error code like STATUS_NONEXISTENT_EA_ENTRY. Rather
|
||||
NtQueryEaFile returns success with the entry's EaValueLength
|
||||
set to 0. */
|
||||
if (!fea->EaValueLength)
|
||||
{
|
||||
set_errno (ENOATTR);
|
||||
__leave;
|
||||
}
|
||||
if (size > 0)
|
||||
{
|
||||
if ((size_t) ret + fea->EaNameLength + 1 > size)
|
||||
if (size < fea->EaValueLength)
|
||||
{
|
||||
set_errno (ERANGE);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
/* For compatibility with Linux, we always prepend "user." to
|
||||
the attribute name, so effectively we only support user
|
||||
attributes from a application point of view. */
|
||||
char tmpbuf[MAX_EA_NAME_LEN * 2];
|
||||
char *tp = stpcpy (tmpbuf, "user.");
|
||||
stpcpy (tp, fea->EaName);
|
||||
/* NTFS stores all EA names in uppercase unfortunately. To keep
|
||||
compatibility with ext/xfs EA namespaces and accompanying
|
||||
tools, which expect the namespaces to be lower case, we return
|
||||
EA names in lowercase if the file is on a native NTFS. */
|
||||
if (pc.fs_is_ntfs ())
|
||||
strlwr (tp);
|
||||
tp = stpcpy (value, tmpbuf) + 1;
|
||||
ret += tp - value;
|
||||
value = tp;
|
||||
memcpy (value, fea->EaName + fea->EaNameLength + 1,
|
||||
fea->EaValueLength);
|
||||
}
|
||||
else
|
||||
ret += fea->EaNameLength + 1;
|
||||
strcpy (lastname, fea->EaName);
|
||||
status = NtQueryEaFile (h, &io, fea, EA_BUFSIZ, TRUE, NULL, 0,
|
||||
NULL, FALSE);
|
||||
ret = fea->EaValueLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
do
|
||||
{
|
||||
fea->EaNameLength += 5; /* "user." */
|
||||
if (size > 0)
|
||||
{
|
||||
if ((size_t) ret + fea->EaNameLength + 1 > size)
|
||||
{
|
||||
set_errno (ERANGE);
|
||||
__leave;
|
||||
}
|
||||
/* For compatibility with Linux, we always prepend "user." to
|
||||
the attribute name, so effectively we only support user
|
||||
attributes from a application point of view. */
|
||||
char tmpbuf[MAX_EA_NAME_LEN * 2];
|
||||
char *tp = stpcpy (tmpbuf, "user.");
|
||||
stpcpy (tp, fea->EaName);
|
||||
/* NTFS stores all EA names in uppercase unfortunately. To
|
||||
keep compatibility with ext/xfs EA namespaces and
|
||||
accompanying tools, which expect the namespaces to be
|
||||
lower case, we return EA names in lowercase if the file
|
||||
is on a native NTFS. */
|
||||
if (pc.fs_is_ntfs ())
|
||||
strlwr (tp);
|
||||
tp = stpcpy (value, tmpbuf) + 1;
|
||||
ret += tp - value;
|
||||
value = tp;
|
||||
}
|
||||
else
|
||||
ret += fea->EaNameLength + 1;
|
||||
strcpy (lastname, fea->EaName);
|
||||
status = NtQueryEaFile (h, &io, fea, EA_BUFSIZ, TRUE, NULL, 0,
|
||||
NULL, FALSE);
|
||||
}
|
||||
while (NT_SUCCESS (status) && strcmp (lastname, fea->EaName) != 0);
|
||||
}
|
||||
while (NT_SUCCESS (status) && strcmp (lastname, fea->EaName) != 0);
|
||||
}
|
||||
|
||||
out:
|
||||
if (!hdl)
|
||||
CloseHandle (h);
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
if (!hdl && h)
|
||||
NtClose (h);
|
||||
debug_printf ("%d = read_ea(%S, %s, %p, %lu)",
|
||||
ret, attr.ObjectName, name, value, size);
|
||||
return ret;
|
||||
|
@ -241,122 +245,123 @@ write_ea (HANDLE hdl, path_conv &pc, const char *name, const char *value,
|
|||
ULONG flen;
|
||||
size_t nlen;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
goto out;
|
||||
|
||||
pc.get_object_attr (attr, sec_none_nih);
|
||||
|
||||
debug_printf ("write_ea (%S, %s, %p, %lu, %d)",
|
||||
attr.ObjectName, name, value, size, flags);
|
||||
|
||||
/* Early open if handle is NULL. This allows to return error codes like
|
||||
ENOENT before we actually check for the correctness of the EA name and
|
||||
stuff like that. */
|
||||
if (!hdl)
|
||||
__try
|
||||
{
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
pc.get_object_attr (attr, sec_none_nih);
|
||||
|
||||
debug_printf ("write_ea (%S, %s, %p, %lu, %d)",
|
||||
attr.ObjectName, name, value, size, flags);
|
||||
|
||||
/* Early open if handle is NULL. This allows to return error codes like
|
||||
ENOENT before we actually check for the correctness of the EA name and
|
||||
stuff like that. */
|
||||
if (!hdl)
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
goto out;
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
__leave;
|
||||
}
|
||||
}
|
||||
hdl = NULL;
|
||||
}
|
||||
|
||||
/* For compatibility with Linux, we only allow user xattrs and
|
||||
return ENOTSUP otherwise. */
|
||||
if (!ascii_strncasematch (name, "user.", 5))
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
goto out;
|
||||
}
|
||||
/* For compatibility with Linux, we only allow user xattrs and
|
||||
return ENOTSUP otherwise. */
|
||||
if (!ascii_strncasematch (name, "user.", 5))
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
__leave;
|
||||
}
|
||||
|
||||
/* removexattr is supposed to fail with ENOATTR if the requested EA is not
|
||||
available. This is equivalent to the XATTR_REPLACE flag for setxattr. */
|
||||
if (!value)
|
||||
flags = XATTR_REPLACE;
|
||||
/* removexattr is supposed to fail with ENOATTR if the requested EA is
|
||||
not available. This is equivalent to XATTR_REPLACE for setxattr. */
|
||||
if (!value)
|
||||
flags = XATTR_REPLACE;
|
||||
|
||||
if (flags)
|
||||
{
|
||||
if (flags != XATTR_CREATE && flags != XATTR_REPLACE)
|
||||
if (flags)
|
||||
{
|
||||
if (flags != XATTR_CREATE && flags != XATTR_REPLACE)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
ssize_t rret = read_ea (hdl, pc, name, NULL, 0);
|
||||
if (flags == XATTR_CREATE && rret > 0)
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
__leave;
|
||||
}
|
||||
if (flags == XATTR_REPLACE && rret < 0)
|
||||
__leave;
|
||||
}
|
||||
|
||||
/* Skip "user." prefix. */
|
||||
name += 5;
|
||||
|
||||
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
ssize_t rret = read_ea (hdl, pc, name, NULL, 0);
|
||||
if (flags == XATTR_CREATE && rret > 0)
|
||||
flen = sizeof (FILE_FULL_EA_INFORMATION) + nlen + 1 + size;
|
||||
fea = (PFILE_FULL_EA_INFORMATION) alloca (flen);
|
||||
fea->NextEntryOffset = 0;
|
||||
fea->Flags = 0;
|
||||
fea->EaNameLength = nlen;
|
||||
fea->EaValueLength = size;
|
||||
strcpy (fea->EaName, name);
|
||||
if (value)
|
||||
memcpy (fea->EaName + fea->EaNameLength + 1, value, size);
|
||||
|
||||
while (true)
|
||||
{
|
||||
set_errno (EEXIST);
|
||||
goto out;
|
||||
}
|
||||
if (flags == XATTR_REPLACE && rret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Skip "user." prefix. */
|
||||
name += 5;
|
||||
|
||||
if ((nlen = strlen (name)) >= MAX_EA_NAME_LEN)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
goto out;
|
||||
}
|
||||
flen = sizeof (FILE_FULL_EA_INFORMATION) + nlen + 1 + size;
|
||||
fea = (PFILE_FULL_EA_INFORMATION) alloca (flen);
|
||||
fea->NextEntryOffset = 0;
|
||||
fea->Flags = 0;
|
||||
fea->EaNameLength = nlen;
|
||||
fea->EaValueLength = size;
|
||||
strcpy (fea->EaName, name);
|
||||
if (value)
|
||||
memcpy (fea->EaName + fea->EaNameLength + 1, value, size);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (h)
|
||||
{
|
||||
status = NtSetEaFile (h, &io, fea, flen);
|
||||
if (status != STATUS_ACCESS_DENIED || !hdl)
|
||||
if (h)
|
||||
{
|
||||
status = NtSetEaFile (h, &io, fea, flen);
|
||||
if (status != STATUS_ACCESS_DENIED || !hdl)
|
||||
break;
|
||||
pc.init_reopen_attr (attr, h);
|
||||
}
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
hdl = NULL;
|
||||
}
|
||||
status = NtOpenFile (&h, READ_CONTROL | FILE_WRITE_EA, &attr, &io,
|
||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
hdl = NULL;
|
||||
}
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_EA_TOO_LARGE:
|
||||
/* STATUS_EA_TOO_LARGE has a matching Win32 error ERROR_EA_TABLE_FULL.
|
||||
For some unknown reason RtlNtStatusToDosError does not translate
|
||||
STATUS_EA_TOO_LARGE to ERROR_EA_TABLE_FULL, but instead to
|
||||
ERROR_EA_LIST_INCONSISTENT. This error code is also returned for
|
||||
STATUS_EA_LIST_INCONSISTENT, which means the incoming EA list is...
|
||||
inconsistent. For obvious reasons we translate
|
||||
ERROR_EA_LIST_INCONSISTENT to EINVAL, so we have to handle
|
||||
STATUS_EA_TOO_LARGE explicitely here, to get the correct mapping
|
||||
to ENOSPC. */
|
||||
set_errno (ENOSPC);
|
||||
break;
|
||||
case STATUS_INVALID_DEVICE_REQUEST:
|
||||
set_errno (ENOTSUP);
|
||||
break;
|
||||
default:
|
||||
__seterrno_from_nt_status (status);
|
||||
break;
|
||||
switch (status)
|
||||
{
|
||||
case STATUS_EA_TOO_LARGE:
|
||||
/* STATUS_EA_TOO_LARGE has a matching Win32 error code
|
||||
ERROR_EA_TABLE_FULL. For some reason RtlNtStatusToDosError
|
||||
does not translate STATUS_EA_TOO_LARGE to ERROR_EA_TABLE_FULL,
|
||||
but instead to ERROR_EA_LIST_INCONSISTENT. This error code is
|
||||
also returned for STATUS_EA_LIST_INCONSISTENT, which means the
|
||||
incoming EA list is... inconsistent. For obvious reasons we
|
||||
translate ERROR_EA_LIST_INCONSISTENT to EINVAL, so we have to
|
||||
handle STATUS_EA_TOO_LARGE explicitely here, to get the correct
|
||||
mapping to ENOSPC. */
|
||||
set_errno (ENOSPC);
|
||||
break;
|
||||
case STATUS_INVALID_DEVICE_REQUEST:
|
||||
set_errno (ENOTSUP);
|
||||
break;
|
||||
default:
|
||||
__seterrno_from_nt_status (status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
if (!hdl)
|
||||
CloseHandle (h);
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
if (!hdl && h)
|
||||
NtClose (h);
|
||||
debug_printf ("%d = write_ea(%S, %s, %p, %lu, %d)",
|
||||
ret, attr.ObjectName, name, value, size, flags);
|
||||
return ret;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -281,14 +281,15 @@ class path_conv
|
|||
NULL, sa.lpSecurityDescriptor);
|
||||
return &attr;
|
||||
}
|
||||
inline void init_reopen_attr (POBJECT_ATTRIBUTES attr, HANDLE h)
|
||||
inline POBJECT_ATTRIBUTES init_reopen_attr (OBJECT_ATTRIBUTES &attr, HANDLE h)
|
||||
{
|
||||
if (has_buggy_reopen ())
|
||||
InitializeObjectAttributes (attr, get_nt_native_path (),
|
||||
InitializeObjectAttributes (&attr, get_nt_native_path (),
|
||||
objcaseinsensitive (), NULL, NULL)
|
||||
else
|
||||
InitializeObjectAttributes (attr, &ro_u_empty, objcaseinsensitive (),
|
||||
InitializeObjectAttributes (&attr, &ro_u_empty, objcaseinsensitive (),
|
||||
h, NULL);
|
||||
return &attr;
|
||||
}
|
||||
inline size_t get_wide_win32_path_len ()
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* poll.cc. Implements poll(2) via usage of select(2) call.
|
||||
|
||||
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011,
|
||||
2012 Red Hat, Inc.
|
||||
2012, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -143,16 +143,19 @@ ppoll (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts,
|
|||
int timeout;
|
||||
sigset_t oldset = _my_tls.sigmask;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
timeout = (timeout_ts == NULL)
|
||||
? -1
|
||||
: (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
|
||||
if (sigmask)
|
||||
set_signal_mask (_my_tls.sigmask, *sigmask);
|
||||
int ret = poll (fds, nfds, timeout);
|
||||
if (sigmask)
|
||||
set_signal_mask (_my_tls.sigmask, oldset);
|
||||
return ret;
|
||||
__try
|
||||
{
|
||||
timeout = (timeout_ts == NULL)
|
||||
? -1
|
||||
: (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
|
||||
if (sigmask)
|
||||
set_signal_mask (_my_tls.sigmask, *sigmask);
|
||||
int ret = poll (fds, nfds, timeout);
|
||||
if (sigmask)
|
||||
set_signal_mask (_my_tls.sigmask, oldset);
|
||||
return ret;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1134,6 +1134,8 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
|
|||
feenableexcept
|
||||
fedisableexcept
|
||||
fegetexcept
|
||||
ffsl
|
||||
ffsll
|
||||
fgetxattr
|
||||
flistxattr
|
||||
fopencookie
|
||||
|
@ -1166,6 +1168,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
|
|||
pthread_getattr_np
|
||||
pthread_sigqueue
|
||||
ptsname_r
|
||||
quotactl
|
||||
rawmemchr
|
||||
removexattr
|
||||
scandirat
|
||||
|
@ -1296,6 +1299,7 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
|
|||
rindex (SUSv3)
|
||||
scalb (SUSv3)
|
||||
setutent (XPG2)
|
||||
stime (SVID)
|
||||
sys_errlist (BSD)
|
||||
sys_nerr (BSD)
|
||||
sys_siglist (BSD)
|
||||
|
@ -1553,4 +1557,8 @@ return -1 and set errno to ENOSYS. <function>grantpt</function> and
|
|||
<function>msgrcv</function> and <function>msgsnd</function> are only
|
||||
available when cygserver is running.</para>
|
||||
|
||||
<para>The Linux-specific function <function>quotactl</function> only implements
|
||||
what works on Windows: Windows only supports user block quotas on NTFS, no
|
||||
group quotas, no inode quotas, no time constraints.</para>
|
||||
|
||||
</sect1>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,341 @@
|
|||
/* quotactl.cc: code for manipulating disk quotas
|
||||
|
||||
Copyright 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#include "winsup.h"
|
||||
#include "cygtls.h"
|
||||
#include "security.h"
|
||||
#include "path.h"
|
||||
#include "fhandler.h"
|
||||
#include "dtable.h"
|
||||
#include "cygheap.h"
|
||||
#include "ntdll.h"
|
||||
#include "tls_pbuf.h"
|
||||
#include "pwdgrp.h"
|
||||
#include <sys/mount.h>
|
||||
#include <sys/quota.h>
|
||||
|
||||
#define PGQI_SIZE (sizeof (FILE_GET_QUOTA_INFORMATION) + SECURITY_MAX_SID_SIZE)
|
||||
#define PFQI_SIZE (sizeof (FILE_QUOTA_INFORMATION) + SECURITY_MAX_SID_SIZE)
|
||||
|
||||
/* Modelled after the Linux quotactl function. */
|
||||
extern "C" int
|
||||
quotactl (int cmd, const char *special, int id, caddr_t addr)
|
||||
{
|
||||
ACCESS_MASK access = FILE_READ_DATA;
|
||||
cygsid sid;
|
||||
path_conv pc;
|
||||
tmp_pathbuf tp;
|
||||
UNICODE_STRING path;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
NTSTATUS status;
|
||||
HANDLE fh;
|
||||
IO_STATUS_BLOCK io;
|
||||
FILE_FS_CONTROL_INFORMATION ffci;
|
||||
int ret = 0;
|
||||
|
||||
uint32_t subcmd = (uint32_t) cmd >> SUBCMDSHIFT;
|
||||
uint32_t type = (uint32_t) cmd & SUBCMDMASK;
|
||||
|
||||
if (type != USRQUOTA && type != GRPQUOTA)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
switch (subcmd)
|
||||
{
|
||||
case Q_SYNC:
|
||||
if (!special)
|
||||
return 0;
|
||||
access |= FILE_WRITE_DATA;
|
||||
break;
|
||||
case Q_QUOTAON:
|
||||
if (id < QFMT_VFS_OLD || id > QFMT_VFS_V1)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
/*FALLTHRU*/
|
||||
case Q_QUOTAOFF:
|
||||
case Q_SETINFO:
|
||||
access |= FILE_WRITE_DATA;
|
||||
break;
|
||||
case Q_GETFMT:
|
||||
case Q_GETINFO:
|
||||
break;
|
||||
case Q_SETQUOTA:
|
||||
access |= FILE_WRITE_DATA;
|
||||
/*FALLTHRU*/
|
||||
case Q_GETQUOTA:
|
||||
/* Windows feature: Default limits. Get or set them with id == -1. */
|
||||
if (id != -1)
|
||||
{
|
||||
struct passwd *pw = NULL;
|
||||
struct group *gr = NULL;
|
||||
|
||||
if (type == USRQUOTA)
|
||||
pw = internal_getpwuid (id);
|
||||
else
|
||||
gr = internal_getgrgid (id);
|
||||
if (pw)
|
||||
sid.getfrompw (pw);
|
||||
else if (gr)
|
||||
sid.getfromgr (gr);
|
||||
else
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
/* Check path */
|
||||
pc.check (special, PC_SYM_FOLLOW | PC_NOWARN, stat_suffixes);
|
||||
if (pc.error)
|
||||
{
|
||||
set_errno (pc.error);
|
||||
return -1;
|
||||
}
|
||||
if (!pc.exists ())
|
||||
{
|
||||
set_errno (ENOENT);
|
||||
return -1;
|
||||
}
|
||||
if (!S_ISBLK (pc.dev.mode))
|
||||
{
|
||||
set_errno (ENOTBLK);
|
||||
return -1;
|
||||
}
|
||||
pc.get_object_attr (attr, sec_none_nih);
|
||||
/* For the following functions to work, we must attach the virtual path to
|
||||
the quota file to the device path.
|
||||
|
||||
FIXME: Note that this is NTFS-specific. Adding ReFS in another step. */
|
||||
tp.u_get (&path);
|
||||
RtlCopyUnicodeString (&path, attr.ObjectName);
|
||||
RtlAppendUnicodeToString (&path, L"\\$Extend\\$Quota:$Q:$INDEX_ALLOCATION");
|
||||
attr.ObjectName = &path;
|
||||
|
||||
/* Open filesystem */
|
||||
status = NtOpenFile (&fh, access, &attr, &io, FILE_SHARE_VALID_FLAGS, 0);
|
||||
if (NT_SUCCESS (status))
|
||||
switch (subcmd)
|
||||
{
|
||||
case Q_SYNC:
|
||||
/* No sync, just report success. */
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
case Q_QUOTAON:
|
||||
case Q_QUOTAOFF:
|
||||
/* Ignore filename in addr. */
|
||||
status = NtQueryVolumeInformationFile (fh, &io, &ffci, sizeof ffci,
|
||||
FileFsControlInformation);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
ffci.FileSystemControlFlags &= ~FILE_VC_QUOTA_ENFORCE
|
||||
& ~FILE_VC_QUOTA_TRACK
|
||||
& ~FILE_VC_QUOTAS_INCOMPLETE
|
||||
& ~FILE_VC_QUOTAS_REBUILDING;
|
||||
if (subcmd == Q_QUOTAON)
|
||||
ffci.FileSystemControlFlags |= FILE_VC_QUOTA_ENFORCE;
|
||||
status = NtSetVolumeInformationFile (fh, &io, &ffci, sizeof ffci,
|
||||
FileFsControlInformation);
|
||||
break;
|
||||
case Q_GETFMT:
|
||||
__try
|
||||
{
|
||||
uint32_t *retval = (uint32_t *) addr;
|
||||
|
||||
/* Always fake the latest format. */
|
||||
*retval = QFMT_VFS_V1;
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
__endtry
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
case Q_GETINFO:
|
||||
__try
|
||||
{
|
||||
struct dqinfo *dqi = (struct dqinfo *) addr;
|
||||
|
||||
dqi->dqi_bgrace = dqi->dqi_igrace = UINT64_MAX;
|
||||
dqi->dqi_flags = 0;
|
||||
dqi->dqi_valid = IIF_BGRACE | IIF_IGRACE;
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
__endtry
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
case Q_SETINFO:
|
||||
/* No settings possible, just report success. */
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
case Q_GETQUOTA:
|
||||
/* Windows feature: Default limits. Get or set them with id == -1. */
|
||||
if (id == -1)
|
||||
{
|
||||
status = NtQueryVolumeInformationFile (fh, &io, &ffci, sizeof ffci,
|
||||
FileFsControlInformation);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
__try
|
||||
{
|
||||
struct dqblk *dq = (struct dqblk *) addr;
|
||||
|
||||
dq->dqb_bhardlimit = (uint64_t) ffci.DefaultQuotaLimit.QuadPart;
|
||||
if (dq->dqb_bhardlimit != UINT64_MAX)
|
||||
dq->dqb_bhardlimit /= BLOCK_SIZE;
|
||||
dq->dqb_bsoftlimit =
|
||||
(uint64_t) ffci.DefaultQuotaThreshold.QuadPart;
|
||||
if (dq->dqb_bsoftlimit != UINT64_MAX)
|
||||
dq->dqb_bsoftlimit /= BLOCK_SIZE;
|
||||
dq->dqb_curspace = 0;
|
||||
dq->dqb_ihardlimit = UINT64_MAX;
|
||||
dq->dqb_isoftlimit = UINT64_MAX;
|
||||
dq->dqb_curinodes = 0;
|
||||
dq->dqb_btime = UINT64_MAX;
|
||||
dq->dqb_itime = UINT64_MAX;
|
||||
dq->dqb_valid = QIF_BLIMITS;
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
__endtry
|
||||
}
|
||||
else
|
||||
{
|
||||
PFILE_GET_QUOTA_INFORMATION pgqi = (PFILE_GET_QUOTA_INFORMATION)
|
||||
alloca (PGQI_SIZE);
|
||||
PFILE_QUOTA_INFORMATION pfqi = (PFILE_QUOTA_INFORMATION)
|
||||
alloca (PFQI_SIZE);
|
||||
|
||||
pgqi->NextEntryOffset = 0;
|
||||
pgqi->SidLength = RtlLengthSid (sid);
|
||||
RtlCopySid (RtlLengthSid (sid), &pgqi->Sid, sid);
|
||||
status = NtQueryQuotaInformationFile (fh, &io, pfqi, PFQI_SIZE,
|
||||
TRUE, pgqi, PGQI_SIZE,
|
||||
NULL, TRUE);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
__try
|
||||
{
|
||||
struct dqblk *dq = (struct dqblk *) addr;
|
||||
|
||||
dq->dqb_bhardlimit = (uint64_t) pfqi->QuotaLimit.QuadPart;
|
||||
if (dq->dqb_bhardlimit != UINT64_MAX)
|
||||
dq->dqb_bhardlimit /= BLOCK_SIZE;
|
||||
dq->dqb_bsoftlimit = (uint64_t) pfqi->QuotaThreshold.QuadPart;
|
||||
if (dq->dqb_bsoftlimit != UINT64_MAX)
|
||||
dq->dqb_bsoftlimit /= BLOCK_SIZE;
|
||||
dq->dqb_curspace = (uint64_t) pfqi->QuotaUsed.QuadPart;
|
||||
if (dq->dqb_curspace != UINT64_MAX)
|
||||
dq->dqb_curspace /= BLOCK_SIZE;
|
||||
dq->dqb_ihardlimit = UINT64_MAX;
|
||||
dq->dqb_isoftlimit = UINT64_MAX;
|
||||
dq->dqb_curinodes = 0;
|
||||
dq->dqb_btime = UINT64_MAX;
|
||||
dq->dqb_itime = UINT64_MAX;
|
||||
dq->dqb_valid = QIF_BLIMITS | QIF_SPACE;
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
__endtry
|
||||
}
|
||||
break;
|
||||
case Q_SETQUOTA:
|
||||
/* Windows feature: Default limits. Get or set them with id == -1. */
|
||||
if (id == -1)
|
||||
{
|
||||
status = NtQueryVolumeInformationFile (fh, &io, &ffci, sizeof ffci,
|
||||
FileFsControlInformation);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
__try
|
||||
{
|
||||
struct dqblk *dq = (struct dqblk *) addr;
|
||||
|
||||
if (!(dq->dqb_valid & QIF_BLIMITS))
|
||||
break;
|
||||
ffci.DefaultQuotaLimit.QuadPart = dq->dqb_bhardlimit;
|
||||
if (ffci.DefaultQuotaLimit.QuadPart != -1)
|
||||
ffci.DefaultQuotaLimit.QuadPart *= BLOCK_SIZE;
|
||||
ffci.DefaultQuotaThreshold.QuadPart = dq->dqb_bsoftlimit;
|
||||
if (ffci.DefaultQuotaThreshold.QuadPart != -1)
|
||||
ffci.DefaultQuotaThreshold.QuadPart *= BLOCK_SIZE;
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
__endtry
|
||||
status = NtSetVolumeInformationFile (fh, &io, &ffci, sizeof ffci,
|
||||
FileFsControlInformation);
|
||||
}
|
||||
else
|
||||
{
|
||||
PFILE_GET_QUOTA_INFORMATION pgqi = (PFILE_GET_QUOTA_INFORMATION)
|
||||
alloca (PGQI_SIZE);
|
||||
PFILE_QUOTA_INFORMATION pfqi = (PFILE_QUOTA_INFORMATION)
|
||||
alloca (PFQI_SIZE);
|
||||
|
||||
pgqi->NextEntryOffset = 0;
|
||||
pgqi->SidLength = RtlLengthSid (sid);
|
||||
RtlCopySid (RtlLengthSid (sid), &pgqi->Sid, sid);
|
||||
status = NtQueryQuotaInformationFile (fh, &io, pfqi, PFQI_SIZE,
|
||||
TRUE, pgqi, PGQI_SIZE,
|
||||
NULL, TRUE);
|
||||
if (!NT_SUCCESS (status))
|
||||
break;
|
||||
__try
|
||||
{
|
||||
struct dqblk *dq = (struct dqblk *) addr;
|
||||
|
||||
if (!(dq->dqb_valid & QIF_BLIMITS))
|
||||
break;
|
||||
pfqi->QuotaLimit.QuadPart = dq->dqb_bhardlimit;
|
||||
if (pfqi->QuotaLimit.QuadPart != -1)
|
||||
pfqi->QuotaLimit.QuadPart *= BLOCK_SIZE;
|
||||
pfqi->QuotaThreshold.QuadPart = dq->dqb_bsoftlimit;
|
||||
if (pfqi->QuotaThreshold.QuadPart != -1)
|
||||
pfqi->QuotaThreshold.QuadPart *= BLOCK_SIZE;
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
__endtry
|
||||
status = NtSetQuotaInformationFile (fh, &io, pfqi, PFQI_SIZE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
__seterrno_from_nt_status (status);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
What's new:
|
||||
-----------
|
||||
|
||||
- /proc/cygdrive is a new symlink pointing to the current cygdrive prefix.
|
||||
This can be utilized in scripts to access paths via cygdrive prefix, even
|
||||
if the cygdrive prefix has been changed by the user.
|
||||
|
||||
- /proc/partitions now prints the windows mount points the device is mounted
|
||||
on. This allows to recognize the underlying Windows devices of the Cygwin
|
||||
raw device names.
|
||||
|
||||
- New API: quotactl, designed after the Linux/BSD function, but severely
|
||||
restricted: Windows only supports user block quotas on NTFS, no group
|
||||
quotas, no inode quotas, no time constraints.
|
||||
|
||||
- New APIs: ffsl, ffsll (glibc extensions).
|
||||
|
||||
- New API: stime (SVr4).
|
||||
|
||||
|
||||
What changed:
|
||||
-------------
|
||||
|
||||
- New internal exception handling based on SEH on 64 bit Cygwin.
|
||||
|
||||
- When exec'ing applications, check if $PATH exists and is non-empty. If not,
|
||||
add PATH variable with Cygwin installation directory as content to Windows
|
||||
environment to allow loading of Cygwin system DLLs.
|
||||
|
||||
- Disable CYGWIN "dosfilewarning" option by default.
|
||||
|
||||
- Improve various header files for C++- and standards-compliance.
|
||||
|
||||
- Doug Lea malloc implementation update from 2.8.3 to the latest 2.8.6.
|
||||
|
||||
- atexit is now exported as statically linked function from libcygwin.a.
|
||||
This allows reliable access to the DSO handle of the caller for newly
|
||||
built executables. The former atexit entry point into the DLL remains
|
||||
for backward compatibility only.
|
||||
|
||||
|
||||
Bug Fixes
|
||||
---------
|
||||
|
||||
- Per POSIX, dirfd(3) now returns EINVAL rather than EBADF on invalid
|
||||
directory stream.
|
||||
|
||||
- Fix a resource leak in rmdir(2).
|
||||
|
||||
- Fix fchmod(2)/fchown(2)/fsetxattr(2) in case the file got renamed after
|
||||
open and before calling one of the affected functions.
|
||||
Addresses: https://cygwin.com/ml/cygwin/2014-08/msg00517.html
|
||||
|
||||
- Handle Netapp-specific problem in statvfs(2)/fstatvfs(2).
|
||||
Addresses: https://cygwin.com/ml/cygwin/2014-06/msg00425.html
|
||||
|
||||
- Fix chown(2) on ptys in a corner case.
|
||||
|
||||
- Generate correct error when a path is inaccessible due to missing permissions.
|
||||
Addresses: https://cygwin.com/ml/cygwin-developers/2014-10/msg00010.html
|
||||
|
||||
- Don't hang in accept calls if socket is no listener. Set errno to EINVAL
|
||||
instead.
|
||||
|
||||
- Don't allow seeking on serial lines and sockets. Set errno to ESPIPE
|
||||
instead.
|
||||
Addresses: https://cygwin.com/ml/cygwin/2014-08/msg00319.html
|
||||
|
||||
- Fix output of /proc/<PID>/statm.
|
||||
|
||||
- Fix a SEGV in cygcheck if the environment variable COMSPEC is not, or
|
||||
incorrectly set.
|
||||
Addresses: https://cygwin.com/ml/cygwin/2014-10/msg00292.html
|
||||
|
||||
- Fix a SEGV in some 64 bit applications explicitely dlclosing DLLs.
|
||||
Addresses: https://cygwin.com/ml/cygwin/2014-10/msg00402.html
|
||||
|
||||
- Fix -fuse-cxa-atexit handling where dlclose fails to trigger calling
|
||||
global dtors in dynamically loaded modules in C++ applications (and
|
||||
thus another potential SEGV).
|
|
@ -1,7 +1,7 @@
|
|||
/* resource.cc: getrusage () and friends.
|
||||
|
||||
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2005, 2008, 2009, 2010,
|
||||
2011, 2012, 2013 Red Hat, Inc.
|
||||
2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
Written by Steve Chamberlain (sac@cygnus.com), Doug Evans (dje@cygnus.com),
|
||||
Geoffrey Noer (noer@cygnus.com) of Cygnus Support.
|
||||
|
@ -116,53 +116,51 @@ getrlimit (int resource, struct rlimit *rlp)
|
|||
{
|
||||
MEMORY_BASIC_INFORMATION m;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
rlp->rlim_cur = RLIM_INFINITY;
|
||||
rlp->rlim_max = RLIM_INFINITY;
|
||||
|
||||
switch (resource)
|
||||
__try
|
||||
{
|
||||
case RLIMIT_CPU:
|
||||
case RLIMIT_FSIZE:
|
||||
case RLIMIT_DATA:
|
||||
case RLIMIT_AS:
|
||||
break;
|
||||
case RLIMIT_STACK:
|
||||
if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
|
||||
debug_printf ("couldn't get stack info, returning def.values. %E");
|
||||
else
|
||||
rlp->rlim_cur = RLIM_INFINITY;
|
||||
rlp->rlim_max = RLIM_INFINITY;
|
||||
|
||||
switch (resource)
|
||||
{
|
||||
rlp->rlim_cur = (rlim_t) &m - (rlim_t) m.AllocationBase;
|
||||
rlp->rlim_max = (rlim_t) m.BaseAddress + m.RegionSize
|
||||
- (rlim_t) m.AllocationBase;
|
||||
case RLIMIT_CPU:
|
||||
case RLIMIT_FSIZE:
|
||||
case RLIMIT_DATA:
|
||||
case RLIMIT_AS:
|
||||
break;
|
||||
case RLIMIT_STACK:
|
||||
if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
|
||||
debug_printf ("couldn't get stack info, returning def.values. %E");
|
||||
else
|
||||
{
|
||||
rlp->rlim_cur = (rlim_t) &m - (rlim_t) m.AllocationBase;
|
||||
rlp->rlim_max = (rlim_t) m.BaseAddress + m.RegionSize
|
||||
- (rlim_t) m.AllocationBase;
|
||||
}
|
||||
break;
|
||||
case RLIMIT_NOFILE:
|
||||
rlp->rlim_cur = getdtablesize ();
|
||||
if (rlp->rlim_cur < OPEN_MAX)
|
||||
rlp->rlim_cur = OPEN_MAX;
|
||||
rlp->rlim_max = OPEN_MAX_MAX;
|
||||
break;
|
||||
case RLIMIT_CORE:
|
||||
rlp->rlim_cur = cygheap->rlim_core;
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
break;
|
||||
case RLIMIT_NOFILE:
|
||||
rlp->rlim_cur = getdtablesize ();
|
||||
if (rlp->rlim_cur < OPEN_MAX)
|
||||
rlp->rlim_cur = OPEN_MAX;
|
||||
rlp->rlim_max = OPEN_MAX_MAX;
|
||||
break;
|
||||
case RLIMIT_CORE:
|
||||
rlp->rlim_cur = cygheap->rlim_core;
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
setrlimit (int resource, const struct rlimit *rlp)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
struct rlimit oldlimits;
|
||||
|
||||
/* Check if the request is to actually change the resource settings.
|
||||
|
@ -170,29 +168,35 @@ setrlimit (int resource, const struct rlimit *rlp)
|
|||
if (getrlimit (resource, &oldlimits) < 0)
|
||||
return -1;
|
||||
|
||||
if (oldlimits.rlim_cur == rlp->rlim_cur &&
|
||||
oldlimits.rlim_max == rlp->rlim_max)
|
||||
/* No change in resource requirements, succeed immediately */
|
||||
return 0;
|
||||
|
||||
if (rlp->rlim_cur > rlp->rlim_max)
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
if (oldlimits.rlim_cur == rlp->rlim_cur &&
|
||||
oldlimits.rlim_max == rlp->rlim_max)
|
||||
/* No change in resource requirements, succeed immediately */
|
||||
return 0;
|
||||
|
||||
switch (resource)
|
||||
{
|
||||
case RLIMIT_CORE:
|
||||
cygheap->rlim_core = rlp->rlim_cur;
|
||||
break;
|
||||
case RLIMIT_NOFILE:
|
||||
if (rlp->rlim_cur != RLIM_INFINITY)
|
||||
return setdtablesize (rlp->rlim_cur);
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (rlp->rlim_cur > rlp->rlim_max)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
|
||||
switch (resource)
|
||||
{
|
||||
case RLIMIT_CORE:
|
||||
cygheap->rlim_core = rlp->rlim_cur;
|
||||
break;
|
||||
case RLIMIT_NOFILE:
|
||||
if (rlp->rlim_cur != RLIM_INFINITY)
|
||||
return setdtablesize (rlp->rlim_cur);
|
||||
break;
|
||||
default:
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
__except (EFAULT)
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ LONG
|
|||
get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd,
|
||||
bool justcreated)
|
||||
{
|
||||
NTSTATUS status;
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
ULONG len = SD_MAXIMUM_SIZE, rlen;
|
||||
|
@ -57,20 +57,19 @@ get_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd,
|
|||
status = NtQuerySecurityObject (fh, ALL_SECURITY_INFORMATION,
|
||||
sd, len, &rlen);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
debug_printf ("NtQuerySecurityObject (%S), status %y",
|
||||
pc.get_nt_native_path (), status);
|
||||
fh = NULL;
|
||||
}
|
||||
debug_printf ("NtQuerySecurityObject (%S), status %y",
|
||||
pc.get_nt_native_path (), status);
|
||||
}
|
||||
/* If the handle was NULL, or fetching with the original handle didn't work,
|
||||
try to reopen the file with READ_CONTROL and fetch the security descriptor
|
||||
using that handle. */
|
||||
if (!fh)
|
||||
if (!fh || !NT_SUCCESS (status))
|
||||
{
|
||||
status = NtOpenFile (&fh, READ_CONTROL,
|
||||
pc.get_object_attr (attr, sec_none_nih), &io,
|
||||
FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
fh ? pc.init_reopen_attr (attr, fh)
|
||||
: pc.get_object_attr (attr, sec_none_nih),
|
||||
&io, FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
sd.free ();
|
||||
|
@ -217,8 +216,10 @@ set_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd, bool is_chown)
|
|||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
status = NtOpenFile (&fh, (is_chown ? WRITE_OWNER : 0) | WRITE_DAC,
|
||||
pc.get_object_attr (attr, sec_none_nih),
|
||||
&io, FILE_SHARE_VALID_FLAGS,
|
||||
fh ? pc.init_reopen_attr (attr, fh)
|
||||
: pc.get_object_attr (attr, sec_none_nih),
|
||||
&io,
|
||||
FILE_SHARE_VALID_FLAGS,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT);
|
||||
if (!NT_SUCCESS (status))
|
||||
{
|
||||
|
@ -506,7 +507,7 @@ alloc_sd (path_conv &pc, uid_t uid, gid_t gid, int attribute,
|
|||
/* NOTE: If the high bit of attribute is set, we have just created
|
||||
a file or directory. See below for an explanation. */
|
||||
|
||||
debug_printf("uid %u, gid %u, attribute %y", uid, gid, attribute);
|
||||
debug_printf("uid %u, gid %u, attribute 0%o", uid, gid, attribute);
|
||||
|
||||
/* Get owner and group from current security descriptor. */
|
||||
PSID cur_owner_sid = NULL;
|
||||
|
@ -964,7 +965,7 @@ set_file_attribute (HANDLE handle, path_conv &pc,
|
|||
}
|
||||
else
|
||||
ret = 0;
|
||||
syscall_printf ("%d = set_file_attribute(%S, %d, %d, %y)",
|
||||
syscall_printf ("%d = set_file_attribute(%S, %d, %d, 0%o)",
|
||||
ret, pc.get_nt_native_path (), uid, gid, attribute);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* select.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -230,21 +230,24 @@ pselect(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||
struct timeval tv;
|
||||
sigset_t oldset = _my_tls.sigmask;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (ts)
|
||||
__try
|
||||
{
|
||||
tv.tv_sec = ts->tv_sec;
|
||||
tv.tv_usec = ts->tv_nsec / 1000;
|
||||
if (ts)
|
||||
{
|
||||
tv.tv_sec = ts->tv_sec;
|
||||
tv.tv_usec = ts->tv_nsec / 1000;
|
||||
}
|
||||
if (set)
|
||||
set_signal_mask (_my_tls.sigmask, *set);
|
||||
int ret = cygwin_select (maxfds, readfds, writefds, exceptfds,
|
||||
ts ? &tv : NULL);
|
||||
if (set)
|
||||
set_signal_mask (_my_tls.sigmask, oldset);
|
||||
return ret;
|
||||
}
|
||||
if (set)
|
||||
set_signal_mask (_my_tls.sigmask, *set);
|
||||
int ret = cygwin_select (maxfds, readfds, writefds, exceptfds,
|
||||
ts ? &tv : NULL);
|
||||
if (set)
|
||||
set_signal_mask (_my_tls.sigmask, oldset);
|
||||
return ret;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Call cleanup functions for all inspected fds. Gets rid of any
|
||||
|
@ -470,6 +473,9 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
|
|||
if (me->read_selected && me->read_ready)
|
||||
{
|
||||
UNIX_FD_SET (me->fd, readfds);
|
||||
/* Special AF_LOCAL handling. */
|
||||
if ((sock = me->fh->is_socket ()) && sock->connect_state () == connect_pending)
|
||||
sock->connect_state (connected);
|
||||
ready++;
|
||||
}
|
||||
if (me->write_selected && me->write_ready)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* sem.cc: XSI IPC interface for Cygwin.
|
||||
|
||||
Copyright 2002, 2003, 2004, 2005, 2008, 2009, 2012 Red Hat, Inc.
|
||||
Copyright 2002, 2003, 2004, 2005, 2008, 2009, 2012, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -85,19 +85,22 @@ semctl (int semid, int semnum, int cmd, ...)
|
|||
}
|
||||
syscall_printf ("semctl (semid = %d, semnum = %d, cmd = %d, arg = %p)",
|
||||
semid, semnum, cmd, arg.buf);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
client_request_sem request (semid, semnum, cmd, &arg);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
__try
|
||||
{
|
||||
syscall_printf ("-1 [%d] = semctl ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
client_request_sem request (semid, semnum, cmd, &arg);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
syscall_printf ("-1 [%d] = semctl ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
__leave;
|
||||
}
|
||||
return request.retval ();
|
||||
}
|
||||
return request.retval ();
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -122,17 +125,20 @@ semop (int semid, struct sembuf *sops, size_t nsops)
|
|||
{
|
||||
syscall_printf ("semop (semid = %d, sops = %p, nsops = %ld)",
|
||||
semid, sops, nsops);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
client_request_sem request (semid, sops, nsops);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
__try
|
||||
{
|
||||
syscall_printf ("-1 [%d] = semop ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
client_request_sem request (semid, sops, nsops);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
syscall_printf ("-1 [%d] = semop ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
__leave;
|
||||
}
|
||||
return request.retval ();
|
||||
}
|
||||
return request.retval ();
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ setlsapwd (const char *passwd, const char *username)
|
|||
}
|
||||
if (data_buf)
|
||||
{
|
||||
memset (data.Buffer, 0, data.Length);
|
||||
RtlSecureZeroMemory (data.Buffer, data.Length);
|
||||
free (data_buf);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -260,41 +260,45 @@ shmctl (int shmid, int cmd, struct shmid_ds *buf)
|
|||
{
|
||||
syscall_printf ("shmctl (shmid = %d, cmd = %d, buf = %p)",
|
||||
shmid, cmd, buf);
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
client_request_shm request (shmid, cmd, buf);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
__try
|
||||
{
|
||||
syscall_printf ("-1 [%d] = shmctl ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
return -1;
|
||||
}
|
||||
if (cmd == IPC_RMID)
|
||||
{
|
||||
/* Cleanup */
|
||||
shm_shmid_list *ssh_entry, *ssh_next_entry;
|
||||
SLIST_LOCK ();
|
||||
SLIST_FOREACH_SAFE (ssh_entry, &ssh_list, ssh_next, ssh_next_entry)
|
||||
client_request_shm request (shmid, cmd, buf);
|
||||
if (request.make_request () == -1 || request.retval () == -1)
|
||||
{
|
||||
if (ssh_entry->shmid == shmid)
|
||||
{
|
||||
/* Remove this entry from the list and close the handle
|
||||
only if it's not in use anymore. */
|
||||
if (ssh_entry->ref_count <= 0)
|
||||
{
|
||||
SLIST_REMOVE (&ssh_list, ssh_entry, shm_shmid_list, ssh_next);
|
||||
CloseHandle (ssh_entry->hdl);
|
||||
delete ssh_entry;
|
||||
}
|
||||
break;
|
||||
}
|
||||
syscall_printf ("-1 [%d] = shmctl ()", request.error_code ());
|
||||
set_errno (request.error_code ());
|
||||
if (request.error_code () == ENOSYS)
|
||||
raise (SIGSYS);
|
||||
__leave;
|
||||
}
|
||||
SLIST_UNLOCK ();
|
||||
if (cmd == IPC_RMID)
|
||||
{
|
||||
/* Cleanup */
|
||||
shm_shmid_list *ssh_entry, *ssh_next_entry;
|
||||
SLIST_LOCK ();
|
||||
SLIST_FOREACH_SAFE (ssh_entry, &ssh_list, ssh_next, ssh_next_entry)
|
||||
{
|
||||
if (ssh_entry->shmid == shmid)
|
||||
{
|
||||
/* Remove this entry from the list and close the handle
|
||||
only if it's not in use anymore. */
|
||||
if (ssh_entry->ref_count <= 0)
|
||||
{
|
||||
SLIST_REMOVE (&ssh_list, ssh_entry, shm_shmid_list,
|
||||
ssh_next);
|
||||
CloseHandle (ssh_entry->hdl);
|
||||
delete ssh_entry;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
SLIST_UNLOCK ();
|
||||
}
|
||||
return request.retval ();
|
||||
}
|
||||
return request.retval ();
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* signal.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
|
||||
Significant changes by Sergey Okhapkin <sos@prospect.com.ru>
|
||||
|
@ -197,33 +197,37 @@ handle_sigprocmask (int how, const sigset_t *set, sigset_t *oldset, sigset_t& op
|
|||
return EINVAL;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return EFAULT;
|
||||
|
||||
if (oldset)
|
||||
*oldset = opmask;
|
||||
|
||||
if (set)
|
||||
{
|
||||
sigset_t newmask = opmask;
|
||||
switch (how)
|
||||
__try
|
||||
{
|
||||
case SIG_BLOCK:
|
||||
/* add set to current mask */
|
||||
newmask |= *set;
|
||||
break;
|
||||
case SIG_UNBLOCK:
|
||||
/* remove set from current mask */
|
||||
newmask &= ~*set;
|
||||
break;
|
||||
case SIG_SETMASK:
|
||||
/* just set it */
|
||||
newmask = *set;
|
||||
break;
|
||||
if (oldset)
|
||||
*oldset = opmask;
|
||||
|
||||
if (set)
|
||||
{
|
||||
sigset_t newmask = opmask;
|
||||
switch (how)
|
||||
{
|
||||
case SIG_BLOCK:
|
||||
/* add set to current mask */
|
||||
newmask |= *set;
|
||||
break;
|
||||
case SIG_UNBLOCK:
|
||||
/* remove set from current mask */
|
||||
newmask &= ~*set;
|
||||
break;
|
||||
case SIG_SETMASK:
|
||||
/* just set it */
|
||||
newmask = *set;
|
||||
break;
|
||||
}
|
||||
set_signal_mask (opmask, newmask);
|
||||
}
|
||||
set_signal_mask (opmask, newmask);
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
return EFAULT;
|
||||
}
|
||||
__endtry
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -382,8 +386,7 @@ sigaction_worker (int sig, const struct sigaction *newact,
|
|||
struct sigaction *oldact, bool isinternal)
|
||||
{
|
||||
int res = -1;
|
||||
myfault efault;
|
||||
if (!efault.faulted (EFAULT))
|
||||
__try
|
||||
{
|
||||
sig_dispatch_pending ();
|
||||
/* check that sig is in right range */
|
||||
|
@ -394,14 +397,17 @@ sigaction_worker (int sig, const struct sigaction *newact,
|
|||
struct sigaction oa = global_sigs[sig];
|
||||
|
||||
if (!newact)
|
||||
sigproc_printf ("signal %d, newact %p, oa %p", sig, newact, oa, oa.sa_handler);
|
||||
sigproc_printf ("signal %d, newact %p, oa %p",
|
||||
sig, newact, oa, oa.sa_handler);
|
||||
else
|
||||
{
|
||||
sigproc_printf ("signal %d, newact %p (handler %p), oa %p", sig, newact, newact->sa_handler, oa, oa.sa_handler);
|
||||
sigproc_printf ("signal %d, newact %p (handler %p), oa %p",
|
||||
sig, newact, newact->sa_handler, oa,
|
||||
oa.sa_handler);
|
||||
if (sig == SIGKILL || sig == SIGSTOP)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
goto out;
|
||||
__leave;
|
||||
}
|
||||
struct sigaction na = *newact;
|
||||
struct sigaction& gs = global_sigs[sig];
|
||||
|
@ -430,8 +436,8 @@ sigaction_worker (int sig, const struct sigaction *newact,
|
|||
res = 0;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -560,41 +566,41 @@ sigwait (const sigset_t *set, int *sig_ptr)
|
|||
extern "C" int
|
||||
sigwaitinfo (const sigset_t *set, siginfo_t *info)
|
||||
{
|
||||
int res = -1;
|
||||
|
||||
pthread_testcancel ();
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return EFAULT;
|
||||
|
||||
set_signal_mask (_my_tls.sigwait_mask, *set);
|
||||
sig_dispatch_pending (true);
|
||||
|
||||
int res;
|
||||
switch (cygwait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self))
|
||||
__try
|
||||
{
|
||||
case WAIT_SIGNALED:
|
||||
if (!sigismember (set, _my_tls.infodata.si_signo))
|
||||
{
|
||||
set_errno (EINTR);
|
||||
res = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_my_tls.lock ();
|
||||
if (info)
|
||||
*info = _my_tls.infodata;
|
||||
res = _my_tls.infodata.si_signo;
|
||||
_my_tls.sig = 0;
|
||||
if (_my_tls.retaddr () == (__stack_t) sigdelayed)
|
||||
_my_tls.pop ();
|
||||
_my_tls.unlock ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
__seterrno ();
|
||||
res = -1;
|
||||
}
|
||||
set_signal_mask (_my_tls.sigwait_mask, *set);
|
||||
sig_dispatch_pending (true);
|
||||
|
||||
switch (cygwait (NULL, cw_infinite, cw_sig_eintr | cw_cancel | cw_cancel_self))
|
||||
{
|
||||
case WAIT_SIGNALED:
|
||||
if (!sigismember (set, _my_tls.infodata.si_signo))
|
||||
set_errno (EINTR);
|
||||
else
|
||||
{
|
||||
_my_tls.lock ();
|
||||
if (info)
|
||||
*info = _my_tls.infodata;
|
||||
res = _my_tls.infodata.si_signo;
|
||||
_my_tls.sig = 0;
|
||||
if (_my_tls.retaddr () == (__stack_t) sigdelayed)
|
||||
_my_tls.pop ();
|
||||
_my_tls.unlock ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
__seterrno ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
__except (EFAULT) {
|
||||
res = -1;
|
||||
}
|
||||
__endtry
|
||||
sigproc_printf ("returning signal %d", res);
|
||||
return res;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -79,13 +79,8 @@ int __stdcall cygwin_strncasecmp (const char *, const char *, size_t);
|
|||
#define strcasematch(s1,s2) (!cygwin_strcasecmp ((s1),(s2)))
|
||||
#define strncasematch(s1,s2,n) (!cygwin_strncasecmp ((s1),(s2),(n)))
|
||||
|
||||
#undef strlwr
|
||||
#define strlwr cygwin_strlwr
|
||||
char * __stdcall cygwin_strlwr (char *);
|
||||
|
||||
#undef strupr
|
||||
#define strupr cygwin_strupr
|
||||
char * __stdcall cygwin_strupr (char *);
|
||||
char *strlwr (char *);
|
||||
char *strupr (char *);
|
||||
|
||||
#endif /* __INSIDE_CYGWIN__ */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
/* thread.cc: Locking and threading module functions
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
||||
2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -38,12 +38,7 @@ extern "C" void __fp_lock_all ();
|
|||
extern "C" void __fp_unlock_all ();
|
||||
extern "C" int valid_sched_parameters(const struct sched_param *);
|
||||
extern "C" int sched_set_thread_priority(HANDLE thread, int priority);
|
||||
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 7
|
||||
/* FIXME: Temporarily workaround gcc 4.7+ bug. */
|
||||
static verifyable_object_state
|
||||
#else
|
||||
static inline verifyable_object_state
|
||||
#endif
|
||||
verifyable_object_isvalid (void const * objectptr, thread_magic_t magic,
|
||||
void *static_ptr1 = NULL,
|
||||
void *static_ptr2 = NULL,
|
||||
|
@ -122,28 +117,29 @@ __cygwin_lock_unlock (_LOCK_T *lock)
|
|||
paranoid_printf ("threadcount %d. unlocked", MT_INTERFACE->threadcount);
|
||||
}
|
||||
|
||||
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 7
|
||||
/* FIXME: Temporarily workaround gcc 4.7+ bug. */
|
||||
static verifyable_object_state
|
||||
#else
|
||||
static inline verifyable_object_state
|
||||
#endif
|
||||
verifyable_object_isvalid (void const *objectptr, thread_magic_t magic, void *static_ptr1,
|
||||
void *static_ptr2, void *static_ptr3)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (objectptr))
|
||||
return INVALID_OBJECT;
|
||||
verifyable_object_state state = INVALID_OBJECT;
|
||||
|
||||
verifyable_object **object = (verifyable_object **) objectptr;
|
||||
__try
|
||||
{
|
||||
if (!objectptr || !(*(const char **) objectptr))
|
||||
__leave;
|
||||
|
||||
if ((static_ptr1 && *object == static_ptr1) ||
|
||||
(static_ptr2 && *object == static_ptr2) ||
|
||||
(static_ptr3 && *object == static_ptr3))
|
||||
return VALID_STATIC_OBJECT;
|
||||
if ((*object)->magic != magic)
|
||||
return INVALID_OBJECT;
|
||||
return VALID_OBJECT;
|
||||
verifyable_object **object = (verifyable_object **) objectptr;
|
||||
|
||||
if ((static_ptr1 && *object == static_ptr1) ||
|
||||
(static_ptr2 && *object == static_ptr2) ||
|
||||
(static_ptr3 && *object == static_ptr3))
|
||||
state = VALID_STATIC_OBJECT;
|
||||
else if ((*object)->magic == magic)
|
||||
state = VALID_OBJECT;
|
||||
}
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
return state;
|
||||
}
|
||||
|
||||
/* static members */
|
||||
|
@ -2684,18 +2680,20 @@ pthread_cond::init (pthread_cond_t *cond, const pthread_condattr_t *attr)
|
|||
return EAGAIN;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
int ret = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
*cond = new_cond;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
delete new_cond;
|
||||
cond_initialization_lock.unlock ();
|
||||
return EINVAL;
|
||||
ret = EINVAL;
|
||||
}
|
||||
|
||||
*cond = new_cond;
|
||||
__endtry
|
||||
cond_initialization_lock.unlock ();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -2747,45 +2745,47 @@ pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
|||
struct timespec tp;
|
||||
LARGE_INTEGER timeout;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return EINVAL;
|
||||
|
||||
pthread_testcancel ();
|
||||
|
||||
int err = __pthread_cond_wait_init (cond, mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* According to SUSv3, the abstime value must be checked for validity. */
|
||||
if (abstime->tv_sec < 0
|
||||
|| abstime->tv_nsec < 0
|
||||
|| abstime->tv_nsec > 999999999)
|
||||
return EINVAL;
|
||||
|
||||
clock_gettime ((*cond)->clock_id, &tp);
|
||||
|
||||
/* Check for immediate timeout before converting */
|
||||
if (tp.tv_sec > abstime->tv_sec
|
||||
|| (tp.tv_sec == abstime->tv_sec
|
||||
&& tp.tv_nsec > abstime->tv_nsec))
|
||||
return ETIMEDOUT;
|
||||
|
||||
timeout.QuadPart = abstime->tv_sec * NSPERSEC
|
||||
+ (abstime->tv_nsec + 99LL) / 100LL;
|
||||
|
||||
switch ((*cond)->clock_id)
|
||||
__try
|
||||
{
|
||||
case CLOCK_REALTIME:
|
||||
timeout.QuadPart += FACTOR;
|
||||
break;
|
||||
default:
|
||||
/* other clocks must be handled as relative timeout */
|
||||
timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
|
||||
timeout.QuadPart *= -1LL;
|
||||
break;
|
||||
int err = __pthread_cond_wait_init (cond, mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* According to SUSv3, the abstime value must be checked for validity. */
|
||||
if (abstime->tv_sec < 0
|
||||
|| abstime->tv_nsec < 0
|
||||
|| abstime->tv_nsec > 999999999)
|
||||
__leave;
|
||||
|
||||
clock_gettime ((*cond)->clock_id, &tp);
|
||||
|
||||
/* Check for immediate timeout before converting */
|
||||
if (tp.tv_sec > abstime->tv_sec
|
||||
|| (tp.tv_sec == abstime->tv_sec
|
||||
&& tp.tv_nsec > abstime->tv_nsec))
|
||||
return ETIMEDOUT;
|
||||
|
||||
timeout.QuadPart = abstime->tv_sec * NSPERSEC
|
||||
+ (abstime->tv_nsec + 99LL) / 100LL;
|
||||
|
||||
switch ((*cond)->clock_id)
|
||||
{
|
||||
case CLOCK_REALTIME:
|
||||
timeout.QuadPart += FACTOR;
|
||||
break;
|
||||
default:
|
||||
/* other clocks must be handled as relative timeout */
|
||||
timeout.QuadPart -= tp.tv_sec * NSPERSEC + tp.tv_nsec / 100LL;
|
||||
timeout.QuadPart *= -1LL;
|
||||
break;
|
||||
}
|
||||
return (*cond)->wait (*mutex, &timeout);
|
||||
}
|
||||
return (*cond)->wait (*mutex, &timeout);
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -2910,18 +2910,20 @@ pthread_rwlock::init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr
|
|||
return EAGAIN;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
int ret = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
*rwlock = new_rwlock;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
delete new_rwlock;
|
||||
rwlock_initialization_lock.unlock ();
|
||||
return EINVAL;
|
||||
ret = EINVAL;
|
||||
}
|
||||
|
||||
*rwlock = new_rwlock;
|
||||
__endtry
|
||||
rwlock_initialization_lock.unlock ();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -3133,15 +3135,17 @@ pthread_mutex::init (pthread_mutex_t *mutex,
|
|||
new_mutex->type = PTHREAD_MUTEX_ERRORCHECK;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
__try
|
||||
{
|
||||
*mutex = new_mutex;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
delete new_mutex;
|
||||
mutex_initialization_lock.unlock ();
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*mutex = new_mutex;
|
||||
__endtry
|
||||
}
|
||||
mutex_initialization_lock.unlock ();
|
||||
pthread_printf ("*mutex %p, attr %p, initializer %p", *mutex, attr, initializer);
|
||||
|
@ -3230,16 +3234,17 @@ pthread_spinlock::init (pthread_spinlock_t *spinlock, int pshared)
|
|||
return EAGAIN;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
__try
|
||||
{
|
||||
*spinlock = new_spinlock;
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
delete new_spinlock;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
*spinlock = new_spinlock;
|
||||
__endtry
|
||||
pthread_printf ("*spinlock %p, pshared %d", *spinlock, pshared);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3502,35 +3507,38 @@ semaphore::_timedwait (const struct timespec *abstime)
|
|||
{
|
||||
LARGE_INTEGER timeout;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
__try
|
||||
{
|
||||
timeout.QuadPart = abstime->tv_sec * NSPERSEC
|
||||
+ (abstime->tv_nsec + 99) / 100 + FACTOR;
|
||||
|
||||
switch (cygwait (win32_obj_id, &timeout, cw_cancel | cw_cancel_self | cw_sig_eintr))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
break;
|
||||
case WAIT_SIGNALED:
|
||||
set_errno (EINTR);
|
||||
return -1;
|
||||
case WAIT_TIMEOUT:
|
||||
set_errno (ETIMEDOUT);
|
||||
return -1;
|
||||
default:
|
||||
pthread_printf ("cygwait failed. %E");
|
||||
__seterrno ();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
/* According to SUSv3, abstime need not be checked for validity,
|
||||
if the semaphore can be locked immediately. */
|
||||
if (!_trywait ())
|
||||
return 0;
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
timeout.QuadPart = abstime->tv_sec * NSPERSEC
|
||||
+ (abstime->tv_nsec + 99) / 100 + FACTOR;
|
||||
|
||||
switch (cygwait (win32_obj_id, &timeout, cw_cancel | cw_cancel_self | cw_sig_eintr))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
break;
|
||||
case WAIT_SIGNALED:
|
||||
set_errno (EINTR);
|
||||
return -1;
|
||||
case WAIT_TIMEOUT:
|
||||
set_errno (ETIMEDOUT);
|
||||
return -1;
|
||||
default:
|
||||
pthread_printf ("cygwait failed. %E");
|
||||
__seterrno ();
|
||||
return -1;
|
||||
if (_trywait ())
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
__endtry
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3761,36 +3769,38 @@ semaphore::post (sem_t *sem)
|
|||
int
|
||||
semaphore::getvalue (sem_t *sem, int *sval)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted () || !is_good_object (sem))
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (is_good_object (sem))
|
||||
return (*sem)->_getvalue (sval);
|
||||
}
|
||||
|
||||
return (*sem)->_getvalue (sval);
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
semaphore::getinternal (sem_t *sem, int *sfd, unsigned long long *shash,
|
||||
LUID *sluid, unsigned int *sval)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted () || !is_good_object (sem))
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (!is_good_object (sem))
|
||||
__leave;
|
||||
if ((*sfd = (*sem)->fd) < 0)
|
||||
__leave;
|
||||
*shash = (*sem)->hash;
|
||||
*sluid = (*sem)->luid;
|
||||
/* POSIX defines the value in calls to sem_init/sem_open as unsigned,
|
||||
but the sem_getvalue gets a pointer to int to return the value.
|
||||
Go figure! */
|
||||
return (*sem)->_getvalue ((int *)sval);
|
||||
}
|
||||
if ((*sfd = (*sem)->fd) < 0)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
*shash = (*sem)->hash;
|
||||
*sluid = (*sem)->luid;
|
||||
/* POSIX defines the value in calls to sem_init/sem_open as unsigned, but
|
||||
the sem_getvalue gets a pointer to int to return the value. Go figure! */
|
||||
return (*sem)->_getvalue ((int *)sval);
|
||||
__except (NO_ERROR) {}
|
||||
__endtry
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* pthread_null */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* timer.cc
|
||||
|
||||
Copyright 2004, 2005, 2006, 2008, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
Copyright 2004, 2005, 2006, 2008, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -219,45 +219,49 @@ it_bad (const timespec& t)
|
|||
int
|
||||
timer_tracker::settime (int in_flags, const itimerspec *value, itimerspec *ovalue)
|
||||
{
|
||||
if (!value)
|
||||
int ret = -1;
|
||||
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
if (!value)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT)
|
||||
|| it_bad (value->it_value)
|
||||
|| it_bad (value->it_interval))
|
||||
return -1;
|
||||
if (it_bad (value->it_value) || it_bad (value->it_interval))
|
||||
__leave;
|
||||
|
||||
long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs ();
|
||||
long long now = in_flags & TIMER_ABSTIME ? 0 : gtod.usecs ();
|
||||
|
||||
lock_timer_tracker here;
|
||||
cancel ();
|
||||
lock_timer_tracker here;
|
||||
cancel ();
|
||||
|
||||
if (ovalue)
|
||||
gettime (ovalue);
|
||||
if (ovalue)
|
||||
gettime (ovalue);
|
||||
|
||||
if (!value->it_value.tv_sec && !value->it_value.tv_nsec)
|
||||
interval_us = sleepto_us = 0;
|
||||
else
|
||||
{
|
||||
sleepto_us = now + to_us (value->it_value);
|
||||
interval_us = to_us (value->it_interval);
|
||||
it_interval = value->it_interval;
|
||||
if (!hcancel)
|
||||
hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||
if (!value->it_value.tv_sec && !value->it_value.tv_nsec)
|
||||
interval_us = sleepto_us = 0;
|
||||
else
|
||||
ResetEvent (hcancel);
|
||||
if (!syncthread)
|
||||
syncthread = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||
else
|
||||
ResetEvent (syncthread);
|
||||
new cygthread (timer_thread, this, "itimer", syncthread);
|
||||
{
|
||||
sleepto_us = now + to_us (value->it_value);
|
||||
interval_us = to_us (value->it_interval);
|
||||
it_interval = value->it_interval;
|
||||
if (!hcancel)
|
||||
hcancel = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||
else
|
||||
ResetEvent (hcancel);
|
||||
if (!syncthread)
|
||||
syncthread = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
|
||||
else
|
||||
ResetEvent (syncthread);
|
||||
new cygthread (timer_thread, this, "itimer", syncthread);
|
||||
}
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -280,43 +284,51 @@ timer_tracker::gettime (itimerspec *ovalue)
|
|||
extern "C" int
|
||||
timer_gettime (timer_t timerid, struct itimerspec *ovalue)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
int ret = -1;
|
||||
|
||||
timer_tracker *tt = (timer_tracker *) timerid;
|
||||
if (tt->magic != TT_MAGIC)
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
timer_tracker *tt = (timer_tracker *) timerid;
|
||||
if (tt->magic != TT_MAGIC)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tt->gettime (ovalue);
|
||||
return 0;
|
||||
tt->gettime (ovalue);
|
||||
ret = 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
timer_create (clockid_t clock_id, struct sigevent *__restrict evp,
|
||||
timer_t *__restrict timerid)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
int ret = -1;
|
||||
|
||||
if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id))
|
||||
__try
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
return -1;
|
||||
}
|
||||
if (CLOCKID_IS_PROCESS (clock_id) || CLOCKID_IS_THREAD (clock_id))
|
||||
{
|
||||
set_errno (ENOTSUP);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (clock_id != CLOCK_REALTIME)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
if (clock_id != CLOCK_REALTIME)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*timerid = (timer_t) new timer_tracker (clock_id, evp);
|
||||
return 0;
|
||||
*timerid = (timer_t) new timer_tracker (clock_id, evp);
|
||||
ret = 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
|
@ -324,42 +336,52 @@ timer_settime (timer_t timerid, int flags,
|
|||
const struct itimerspec *__restrict value,
|
||||
struct itimerspec *__restrict ovalue)
|
||||
{
|
||||
timer_tracker *tt = (timer_tracker *) timerid;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (tt->magic != TT_MAGIC)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
int ret = -1;
|
||||
|
||||
return tt->settime (flags, value, ovalue);
|
||||
__try
|
||||
{
|
||||
timer_tracker *tt = (timer_tracker *) timerid;
|
||||
if (tt->magic != TT_MAGIC)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
ret = tt->settime (flags, value, ovalue);
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int
|
||||
timer_delete (timer_t timerid)
|
||||
{
|
||||
timer_tracker *in_tt = (timer_tracker *) timerid;
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
if (in_tt->magic != TT_MAGIC)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
int ret = -1;
|
||||
|
||||
lock_timer_tracker here;
|
||||
for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next)
|
||||
if (tt->next == in_tt)
|
||||
{
|
||||
tt->next = in_tt->next;
|
||||
delete in_tt;
|
||||
return 0;
|
||||
}
|
||||
set_errno (EINVAL);
|
||||
return 0;
|
||||
__try
|
||||
{
|
||||
timer_tracker *in_tt = (timer_tracker *) timerid;
|
||||
if (in_tt->magic != TT_MAGIC)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
__leave;
|
||||
}
|
||||
|
||||
lock_timer_tracker here;
|
||||
for (timer_tracker *tt = &ttstart; tt->next != NULL; tt = tt->next)
|
||||
if (tt->next == in_tt)
|
||||
{
|
||||
tt->next = in_tt->next;
|
||||
delete in_tt;
|
||||
ret = 0;
|
||||
__leave;
|
||||
}
|
||||
set_errno (EINVAL);
|
||||
ret = 0;
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -412,18 +434,13 @@ setitimer (int which, const struct itimerval *__restrict value,
|
|||
extern "C" int
|
||||
getitimer (int which, struct itimerval *ovalue)
|
||||
{
|
||||
int ret;
|
||||
int ret = -1;
|
||||
|
||||
if (which != ITIMER_REAL)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
ret = -1;
|
||||
}
|
||||
set_errno (EINVAL);
|
||||
else
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
ret = -1;
|
||||
else
|
||||
__try
|
||||
{
|
||||
struct itimerspec spec_ovalue;
|
||||
ret = timer_gettime ((timer_t) &ttstart, &spec_ovalue);
|
||||
|
@ -435,6 +452,8 @@ getitimer (int which, struct itimerval *ovalue)
|
|||
ovalue->it_value.tv_usec = spec_ovalue.it_value.tv_nsec / 1000;
|
||||
}
|
||||
}
|
||||
__except (EFAULT) {}
|
||||
__endtry
|
||||
}
|
||||
syscall_printf ("%R = getitimer()", ret);
|
||||
return ret;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* times.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -59,35 +59,39 @@ __to_clock_t (PLARGE_INTEGER src, int flag)
|
|||
extern "C" clock_t
|
||||
times (struct tms *buf)
|
||||
{
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return ((clock_t) -1);
|
||||
|
||||
static SYSTEM_TIMEOFDAY_INFORMATION stodi;
|
||||
KERNEL_USER_TIMES kut;
|
||||
LARGE_INTEGER ticks;
|
||||
clock_t tc = (clock_t) -1;
|
||||
|
||||
/* Fetch boot time if we haven't already. */
|
||||
if (!stodi.BootTime.QuadPart)
|
||||
NtQuerySystemInformation (SystemTimeOfDayInformation,
|
||||
&stodi, sizeof stodi, NULL);
|
||||
__try
|
||||
{
|
||||
/* Fetch boot time if we haven't already. */
|
||||
if (!stodi.BootTime.QuadPart)
|
||||
NtQuerySystemInformation (SystemTimeOfDayInformation,
|
||||
&stodi, sizeof stodi, NULL);
|
||||
|
||||
NtQueryInformationProcess (NtCurrentProcess (), ProcessTimes,
|
||||
&kut, sizeof kut, NULL);
|
||||
get_system_time (&ticks);
|
||||
NtQueryInformationProcess (NtCurrentProcess (), ProcessTimes,
|
||||
&kut, sizeof kut, NULL);
|
||||
get_system_time (&ticks);
|
||||
|
||||
/* uptime */
|
||||
ticks.QuadPart -= stodi.BootTime.QuadPart;
|
||||
/* ticks is in in 100ns, convert to clock ticks. */
|
||||
clock_t tc = (clock_t) (ticks.QuadPart * CLOCKS_PER_SEC / NSPERSEC);
|
||||
|
||||
buf->tms_stime = __to_clock_t (&kut.KernelTime, 0);
|
||||
buf->tms_utime = __to_clock_t (&kut.UserTime, 0);
|
||||
timeval_to_filetime (&myself->rusage_children.ru_stime, &kut.KernelTime);
|
||||
buf->tms_cstime = __to_clock_t (&kut.KernelTime, 1);
|
||||
timeval_to_filetime (&myself->rusage_children.ru_utime, &kut.UserTime);
|
||||
buf->tms_cutime = __to_clock_t (&kut.UserTime, 1);
|
||||
/* uptime */
|
||||
ticks.QuadPart -= stodi.BootTime.QuadPart;
|
||||
/* ticks is in in 100ns, convert to clock ticks. */
|
||||
tc = (clock_t) (ticks.QuadPart * CLOCKS_PER_SEC / NSPERSEC);
|
||||
|
||||
buf->tms_stime = __to_clock_t (&kut.KernelTime, 0);
|
||||
buf->tms_utime = __to_clock_t (&kut.UserTime, 0);
|
||||
timeval_to_filetime (&myself->rusage_children.ru_stime, &kut.KernelTime);
|
||||
buf->tms_cstime = __to_clock_t (&kut.KernelTime, 1);
|
||||
timeval_to_filetime (&myself->rusage_children.ru_utime, &kut.UserTime);
|
||||
buf->tms_cutime = __to_clock_t (&kut.UserTime, 1);
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
tc = (clock_t) -1;
|
||||
}
|
||||
__endtry
|
||||
syscall_printf ("%D = times(%p)", tc, buf);
|
||||
return tc;
|
||||
}
|
||||
|
@ -100,38 +104,49 @@ settimeofday (const struct timeval *tv, const struct timezone *tz)
|
|||
{
|
||||
SYSTEMTIME st;
|
||||
struct tm *ptm;
|
||||
int res;
|
||||
int res = -1;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
if (tv->tv_usec < 0 || tv->tv_usec >= 1000000)
|
||||
__try
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (tv->tv_usec < 0 || tv->tv_usec >= 1000000)
|
||||
{
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptm = gmtime (&tv->tv_sec);
|
||||
st.wYear = ptm->tm_year + 1900;
|
||||
st.wMonth = ptm->tm_mon + 1;
|
||||
st.wDayOfWeek = ptm->tm_wday;
|
||||
st.wDay = ptm->tm_mday;
|
||||
st.wHour = ptm->tm_hour;
|
||||
st.wMinute = ptm->tm_min;
|
||||
st.wSecond = ptm->tm_sec;
|
||||
st.wMilliseconds = tv->tv_usec / 1000;
|
||||
|
||||
res = -!SetSystemTime (&st);
|
||||
gtod.reset ();
|
||||
|
||||
if (res)
|
||||
set_errno (EPERM);
|
||||
}
|
||||
|
||||
ptm = gmtime (&tv->tv_sec);
|
||||
st.wYear = ptm->tm_year + 1900;
|
||||
st.wMonth = ptm->tm_mon + 1;
|
||||
st.wDayOfWeek = ptm->tm_wday;
|
||||
st.wDay = ptm->tm_mday;
|
||||
st.wHour = ptm->tm_hour;
|
||||
st.wMinute = ptm->tm_min;
|
||||
st.wSecond = ptm->tm_sec;
|
||||
st.wMilliseconds = tv->tv_usec / 1000;
|
||||
|
||||
res = -!SetSystemTime (&st);
|
||||
gtod.reset ();
|
||||
|
||||
if (res)
|
||||
set_errno (EPERM);
|
||||
|
||||
__except (EFAULT)
|
||||
{
|
||||
res = -1;
|
||||
}
|
||||
__endtry
|
||||
syscall_printf ("%R = settimeofday(%p, %p)", res, tv, tz);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* stime: SVr4 */
|
||||
extern "C" int
|
||||
stime (const time_t *t)
|
||||
{
|
||||
struct timeval tv = { *t, 0 };
|
||||
return settimeofday(&tv, NULL);
|
||||
}
|
||||
|
||||
/* timezone: standards? */
|
||||
extern "C" char *
|
||||
timezone (void)
|
||||
|
|
|
@ -8,7 +8,6 @@ details. */
|
|||
|
||||
#include <winsup.h>
|
||||
#include <malloc.h>
|
||||
#include "cygtls.h"
|
||||
#include "tls_pbuf.h"
|
||||
|
||||
#define tls_pbuf _my_tls.locals.pathbufs
|
||||
|
@ -16,23 +15,12 @@ details. */
|
|||
void
|
||||
tls_pathbuf::destroy ()
|
||||
{
|
||||
for (unsigned i = 0; i < TP_NUM_C_BUFS && c_buf[i]; ++i)
|
||||
for (uint32_t i = 0; i < TP_NUM_C_BUFS && c_buf[i]; ++i)
|
||||
free (c_buf[i]);
|
||||
for (unsigned i = 0; i < TP_NUM_W_BUFS && w_buf[i]; ++i)
|
||||
for (uint32_t i = 0; i < TP_NUM_W_BUFS && w_buf[i]; ++i)
|
||||
free (w_buf[i]);
|
||||
}
|
||||
|
||||
tmp_pathbuf::tmp_pathbuf ()
|
||||
: c_buf_old (tls_pbuf.c_cnt),
|
||||
w_buf_old (tls_pbuf.w_cnt)
|
||||
{}
|
||||
|
||||
tmp_pathbuf::~tmp_pathbuf ()
|
||||
{
|
||||
tls_pbuf.c_cnt = c_buf_old;
|
||||
tls_pbuf.w_cnt = w_buf_old;
|
||||
}
|
||||
|
||||
char *
|
||||
tmp_pathbuf::c_get ()
|
||||
{
|
||||
|
|
|
@ -6,15 +6,24 @@ This software is a copyrighted work licensed under the terms of the
|
|||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#pragma once
|
||||
|
||||
class tmp_pathbuf
|
||||
{
|
||||
unsigned c_buf_old;
|
||||
unsigned w_buf_old;
|
||||
uint32_t c_buf_old;
|
||||
uint32_t w_buf_old;
|
||||
public:
|
||||
tmp_pathbuf ();
|
||||
~tmp_pathbuf ();
|
||||
tmp_pathbuf () __attribute__ ((always_inline))
|
||||
: c_buf_old (_my_tls.locals.pathbufs.c_cnt),
|
||||
w_buf_old (_my_tls.locals.pathbufs.w_cnt)
|
||||
{}
|
||||
~tmp_pathbuf () __attribute__ ((always_inline))
|
||||
{
|
||||
_my_tls.locals.pathbufs.c_cnt = c_buf_old;
|
||||
_my_tls.locals.pathbufs.w_cnt = w_buf_old;
|
||||
}
|
||||
|
||||
inline bool check_usage (unsigned c_need, unsigned w_need)
|
||||
inline bool check_usage (uint32_t c_need, uint32_t w_need)
|
||||
{
|
||||
return c_need + c_buf_old < TP_NUM_C_BUFS
|
||||
&& w_need + w_buf_old < TP_NUM_W_BUFS;
|
||||
|
|
|
@ -191,10 +191,15 @@ getlogin_r (char *name, size_t namesize)
|
|||
size_t len = strlen (login) + 1;
|
||||
if (len > namesize)
|
||||
return ERANGE;
|
||||
myfault efault;
|
||||
if (efault.faulted ())
|
||||
return EFAULT;
|
||||
strncpy (name, login, len);
|
||||
__try
|
||||
{
|
||||
strncpy (name, login, len);
|
||||
}
|
||||
__except (NO_ERROR)
|
||||
{
|
||||
return EFAULT;
|
||||
}
|
||||
__endtry
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* uname.cc
|
||||
|
||||
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2006, 2007, 2008, 2013 Red Hat, Inc.
|
||||
2006, 2007, 2008, 2013, 2014 Red Hat, Inc.
|
||||
Written by Steve Chamberlain of Cygnus Support, sac@cygnus.com
|
||||
Rewritten by Geoffrey Noer of Cygnus Solutions, noer@cygnus.com
|
||||
|
||||
|
@ -22,74 +22,82 @@ uname (struct utsname *name)
|
|||
{
|
||||
SYSTEM_INFO sysinfo;
|
||||
|
||||
myfault efault;
|
||||
if (efault.faulted (EFAULT))
|
||||
return -1;
|
||||
|
||||
char *snp = strstr (cygwin_version.dll_build_date, "SNP");
|
||||
|
||||
memset (name, 0, sizeof (*name));
|
||||
__small_sprintf (name->sysname, "CYGWIN_%s", wincap.osname ());
|
||||
|
||||
/* Add a hint to the sysname, that we're running under WOW64. This might
|
||||
give an early clue if somebody encounters problems. */
|
||||
if (wincap.is_wow64 ())
|
||||
strncat (name->sysname, "-WOW64",
|
||||
sizeof name->sysname - strlen (name->sysname) - 1);
|
||||
|
||||
GetSystemInfo (&sysinfo);
|
||||
|
||||
/* Computer name */
|
||||
cygwin_gethostname (name->nodename, sizeof (name->nodename) - 1);
|
||||
|
||||
/* Cygwin dll release */
|
||||
__small_sprintf (name->release, "%d.%d.%d%s(%d.%d/%d/%d)",
|
||||
cygwin_version.dll_major / 1000,
|
||||
cygwin_version.dll_major % 1000,
|
||||
cygwin_version.dll_minor,
|
||||
snp ? "s" : "",
|
||||
cygwin_version.api_major,
|
||||
cygwin_version.api_minor,
|
||||
cygwin_version.shared_data,
|
||||
cygwin_version.mount_registry);
|
||||
|
||||
/* Cygwin "version" aka build date */
|
||||
strcpy (name->version, cygwin_version.dll_build_date);
|
||||
if (snp)
|
||||
name->version[snp - cygwin_version.dll_build_date] = '\0';
|
||||
|
||||
/* CPU type */
|
||||
switch (sysinfo.wProcessorArchitecture)
|
||||
__try
|
||||
{
|
||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||
unsigned int ptype;
|
||||
if (sysinfo.wProcessorLevel < 3) /* Shouldn't happen. */
|
||||
ptype = 3;
|
||||
else if (sysinfo.wProcessorLevel > 9) /* P4 */
|
||||
ptype = 6;
|
||||
else
|
||||
ptype = sysinfo.wProcessorLevel;
|
||||
__small_sprintf (name->machine, "i%d86", ptype);
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_IA64:
|
||||
strcpy (name->machine, "ia64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_AMD64:
|
||||
strcpy (name->machine, "x86_64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
|
||||
strcpy (name->machine, "ia32-win64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_ALPHA:
|
||||
strcpy (name->machine, "alpha");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_MIPS:
|
||||
strcpy (name->machine, "mips");
|
||||
break;
|
||||
default:
|
||||
strcpy (name->machine, "unknown");
|
||||
break;
|
||||
}
|
||||
char *snp = strstr (cygwin_version.dll_build_date, "SNP");
|
||||
|
||||
memset (name, 0, sizeof (*name));
|
||||
__small_sprintf (name->sysname, "CYGWIN_%s", wincap.osname ());
|
||||
|
||||
/* Add a hint to the sysname, that we're running under WOW64. This might
|
||||
give an early clue if somebody encounters problems. */
|
||||
if (wincap.is_wow64 ())
|
||||
strncat (name->sysname, "-WOW64",
|
||||
sizeof name->sysname - strlen (name->sysname) - 1);
|
||||
|
||||
GetSystemInfo (&sysinfo);
|
||||
|
||||
/* Computer name */
|
||||
cygwin_gethostname (name->nodename, sizeof (name->nodename) - 1);
|
||||
|
||||
/* Cygwin dll release */
|
||||
__small_sprintf (name->release, "%d.%d.%d%s(%d.%d/%d/%d)",
|
||||
cygwin_version.dll_major / 1000,
|
||||
cygwin_version.dll_major % 1000,
|
||||
cygwin_version.dll_minor,
|
||||
#if 0
|
||||
snp ? "s" : "",
|
||||
#else
|
||||
/* Add a hint to allow to recognize updates */
|
||||
"-2",
|
||||
#endif
|
||||
cygwin_version.api_major,
|
||||
cygwin_version.api_minor,
|
||||
cygwin_version.shared_data,
|
||||
cygwin_version.mount_registry);
|
||||
|
||||
/* Cygwin "version" aka build date */
|
||||
strcpy (name->version, cygwin_version.dll_build_date);
|
||||
if (snp)
|
||||
name->version[snp - cygwin_version.dll_build_date] = '\0';
|
||||
|
||||
/* CPU type */
|
||||
switch (sysinfo.wProcessorArchitecture)
|
||||
{
|
||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||
unsigned int ptype;
|
||||
if (sysinfo.wProcessorLevel < 3) /* Shouldn't happen. */
|
||||
ptype = 3;
|
||||
else if (sysinfo.wProcessorLevel > 9) /* P4 */
|
||||
ptype = 6;
|
||||
else
|
||||
ptype = sysinfo.wProcessorLevel;
|
||||
__small_sprintf (name->machine, "i%d86", ptype);
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_IA64:
|
||||
strcpy (name->machine, "ia64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_AMD64:
|
||||
strcpy (name->machine, "x86_64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
|
||||
strcpy (name->machine, "ia32-win64");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_ALPHA:
|
||||
strcpy (name->machine, "alpha");
|
||||
break;
|
||||
case PROCESSOR_ARCHITECTURE_MIPS:
|
||||
strcpy (name->machine, "mips");
|
||||
break;
|
||||
default:
|
||||
strcpy (name->machine, "unknown");
|
||||
break;
|
||||
}
|
||||
}
|
||||
__except (EFAULT)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
__endtry
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -58,11 +58,6 @@ details. */
|
|||
#include <lmcons.h>
|
||||
#include <ntdef.h>
|
||||
|
||||
/* Temporary kludge for missing flag in Mingw64's w32api. */
|
||||
#ifndef PIPE_REJECT_REMOTE_CLIENTS
|
||||
#define PIPE_REJECT_REMOTE_CLIENTS 8
|
||||
#endif
|
||||
|
||||
#ifdef __undef_IN
|
||||
#undef IN
|
||||
#endif
|
||||
|
@ -79,6 +74,17 @@ details. */
|
|||
#undef CRITICAL
|
||||
#endif
|
||||
|
||||
/* So-called "Microsoft Account" SIDs (S-1-11-...) have a netbios domain name
|
||||
"MicrosoftAccounts". The new "Application Container SIDs" (S-1-15-...)
|
||||
have a netbios domain name "APPLICATION PACKAGE AUTHORITY"
|
||||
|
||||
The problem is, DNLEN is 15, but these domain names have a length of 16
|
||||
resp. 29 chars :-P So we override DNLEN here to be 31, so that calls
|
||||
to LookupAccountSid/Name don't fail if the buffer is based on DNLEN.
|
||||
Hope that's enough for a while... */
|
||||
#undef DNLEN
|
||||
#define DNLEN 31
|
||||
|
||||
/* When Terminal Services are installed, the GetWindowsDirectory function
|
||||
does not return the system installation dir, but a user specific directory
|
||||
instead. That's not what we have in mind when calling GetWindowsDirectory
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* winsup.h: main Cygwin header file.
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -26,6 +26,11 @@ details. */
|
|||
|
||||
#define _NO_W32_PSEUDO_MODIFIERS
|
||||
|
||||
/* Newlib's guarding functions more diligently based on their origin, starting
|
||||
since 2013. To be sure to get everything and the kitchen sink, we have to
|
||||
define _GNU_SOURCE. */
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/strace.h>
|
||||
|
||||
|
|
|
@ -1,3 +1,39 @@
|
|||
2014-11-05 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* new-features.xml (ov-new1.7.33): Document atexit.
|
||||
|
||||
2014-10-28 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygwinenv.xml: Change default setting of dosfilewarning.
|
||||
* new-features.xml (ov-new1.7.33): Document aforementioned change.
|
||||
|
||||
2014-10-27 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* new-features.xml (ov-new1.7.33): Document empty $PATH handling.
|
||||
|
||||
2014-10-22 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* posix.xml (std-gnu): Add ffsl, ffsll, quotactl.
|
||||
(std-notes): Add restrictions of quotactl.
|
||||
|
||||
2014-10-22 Yaakov Selkowitz <yselkowi@redhat.com>
|
||||
|
||||
* new-features.xml (ov-new1.7.33): Document stime.
|
||||
* posix.xml (std-deprec): Add stime.
|
||||
|
||||
2014-10-22 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* new-features.xml (ov-new1.7.33): s/Linux/glibc.
|
||||
|
||||
2014-10-22 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* new-features.xml (ov-new1.7.33): Update to current state.
|
||||
|
||||
2014-08-13 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* new-features.xml (ov-new1.7.33): Add new section.
|
||||
(ov-new1.7.32): Reflect intermediate 1.7.32 release.
|
||||
|
||||
2014-08-03 Yaakov Selkowitz <yselkowitz@cygwin.com>
|
||||
|
||||
* faq-what.xml (faq.what.who): Remove mention of retired setup
|
||||
|
|
|
@ -28,7 +28,7 @@ down every thread and socket creation!</para>
|
|||
<listitem>
|
||||
<para><envar>(no)dosfilewarning</envar> - If set, Cygwin will warn the
|
||||
first time a user uses an "MS-DOS" style path name rather than a POSIX-style
|
||||
path name. Defaults to set.</para>
|
||||
path name. Defaults to off.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
|
|
|
@ -2,7 +2,75 @@
|
|||
<!DOCTYPE sect1 PUBLIC "-//OASIS//DTD DocBook V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
|
||||
|
||||
<sect1 id="ov-new1.7"><title>What's new and what changed in Cygwin 1.7</title>
|
||||
<sect1 id="ov-new1.7"><title>What's new and what changed in Cygwin</title>
|
||||
|
||||
<sect2 id="ov-new1.7.33"><title>What's new and what changed in 1.7.33</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
<listitem><para>
|
||||
/proc/cygdrive is a new symlink pointing to the current cygdrive prefix.
|
||||
This can be utilized in scripts to access paths via cygdrive prefix,
|
||||
even if the cygdrive prefix has been changed by the user.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
/proc/partitions now prints the windows mount points the device is
|
||||
mounted on. This allows to recognize the underlying Windows devices of
|
||||
the Cygwin raw device names.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
New API: quotactl, designed after the Linux/BSD function, but severely
|
||||
restricted: Windows only supports user block quotas on NTFS, no group
|
||||
quotas, no inode quotas, no time constraints.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
New APIs: ffsl, ffsll (glibc extensions).
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
New API: stime (SVr4).
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Provide Cygwin documentation (PDFs and HTML) for offline usage in
|
||||
<filename>/usr/share/doc/cygwin-${version}</filename>.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
New internal exception handling based on SEH on 64 bit Cygwin.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
When exec'ing applications, check if $PATH exists and is non-empty. If
|
||||
not, add PATH variable with Cygwin installation directory as content to
|
||||
Windows environment to allow loading of Cygwin system DLLs.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Disable CYGWIN "dosfilewarning" option by default.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Improve various header files for C++- and standards-compliance.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Doug Lea malloc implementation update from 2.8.3 to the latest 2.8.6.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
atexit(3) is now exported as statically linked function from libcygwin.a.
|
||||
This allows reliable access to the DSO handle of the caller for newly
|
||||
built executables. The former atexit entry point into the DLL remains
|
||||
for backward compatibility only.
|
||||
</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.32"><title>What's new and what changed in 1.7.32</title>
|
||||
|
||||
|
@ -26,7 +94,7 @@ Support more recent CPU flags in /proc/cpuinfo.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.31"><title>What's new and what changed from 1.7.30 to 1.7.31</title>
|
||||
<sect2 id="ov-new1.7.31"><title>What's new and what changed in 1.7.31</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -53,7 +121,7 @@ as on Linux.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.29"><title>What's new and what changed from 1.7.28 to 1.7.29</title>
|
||||
<sect2 id="ov-new1.7.29"><title>What's new and what changed in 1.7.29</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -70,7 +138,7 @@ Console screen clearing works more like xterm or mintty.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.28"><title>What's new and what changed from 1.7.27 to 1.7.28</title>
|
||||
<sect2 id="ov-new1.7.28"><title>What's new and what changed in 1.7.28</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -93,7 +161,7 @@ if it only has been read from.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.27"><title>What's new and what changed from 1.7.26 to 1.7.27</title>
|
||||
<sect2 id="ov-new1.7.27"><title>What's new and what changed in 1.7.27</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -108,7 +176,7 @@ points to a native NTFS symlink with a target path prefixed with "\\?\".
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.26"><title>What's new and what changed from 1.7.25 to 1.7.26</title>
|
||||
<sect2 id="ov-new1.7.26"><title>What's new and what changed in 1.7.26</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -148,7 +216,7 @@ New associated header /usr/include/spawn.h.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.25"><title>What's new and what changed from 1.7.24 to 1.7.25</title>
|
||||
<sect2 id="ov-new1.7.25"><title>What's new and what changed in 1.7.25</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -166,7 +234,7 @@ partitions on a tape.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.24"><title>What's new and what changed from 1.7.23 to 1.7.24</title>
|
||||
<sect2 id="ov-new1.7.24"><title>What's new and what changed in 1.7.24</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -178,7 +246,7 @@ Allow application override of posix_memalign.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.23"><title>What's new and what changed from 1.7.22 to 1.7.23</title>
|
||||
<sect2 id="ov-new1.7.23"><title>What's new and what changed in 1.7.23</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -191,7 +259,7 @@ send the full windows command line to any subprocesses.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.22"><title>What's new and what changed from 1.7.21 to 1.7.22</title>
|
||||
<sect2 id="ov-new1.7.22"><title>What's new and what changed in 1.7.22</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -215,7 +283,7 @@ containing arbitrary byte values as GLibc's regcomp.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.21"><title>What's new and what changed from 1.7.20 to 1.7.21</title>
|
||||
<sect2 id="ov-new1.7.21"><title>What's new and what changed in 1.7.21</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -227,7 +295,7 @@ New API: rawmemchr.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.19"><title>What's new and what changed from 1.7.18 to 1.7.19</title>
|
||||
<sect2 id="ov-new1.7.19"><title>What's new and what changed in 1.7.19</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -263,7 +331,7 @@ arc4random_buf, arc4random_stir, arc4random_uniform.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.18"><title>What's new and what changed from 1.7.17 to 1.7.18</title>
|
||||
<sect2 id="ov-new1.7.18"><title>What's new and what changed in 1.7.18</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -299,7 +367,7 @@ New API: cfsetspeed.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.17"><title>What's new and what changed from 1.7.16 to 1.7.17</title>
|
||||
<sect2 id="ov-new1.7.17"><title>What's new and what changed in 1.7.17</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -317,7 +385,7 @@ allows to open the file with the O_EXCL flag set.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.16"><title>What's new and what changed from 1.7.15 to 1.7.16</title>
|
||||
<sect2 id="ov-new1.7.16"><title>What's new and what changed in 1.7.16</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -333,7 +401,7 @@ Recognize ReFS filesystem.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.15"><title>What's new and what changed from 1.7.14 to 1.7.15</title>
|
||||
<sect2 id="ov-new1.7.15"><title>What's new and what changed in 1.7.15</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -345,7 +413,7 @@ CYGWIN=pipe_byte option now forces the opening of pipes in byte mode rather than
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.14"><title>What's new and what changed from 1.7.13 to 1.7.14</title>
|
||||
<sect2 id="ov-new1.7.14"><title>What's new and what changed in 1.7.14</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -357,7 +425,7 @@ Add mouse reporting modes 1005, 1006 and 1015 to console window.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.13"><title>What's new and what changed from 1.7.12 to 1.7.13</title>
|
||||
<sect2 id="ov-new1.7.13"><title>What's new and what changed in 1.7.13</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -375,7 +443,7 @@ is now properly flushed.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.12"><title>What's new and what changed from 1.7.11 to 1.7.12</title>
|
||||
<sect2 id="ov-new1.7.12"><title>What's new and what changed in 1.7.12</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -410,7 +478,7 @@ finding potential BLODAs.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.11"><title>What's new and what changed from 1.7.10 to 1.7.11</title>
|
||||
<sect2 id="ov-new1.7.11"><title>What's new and what changed in 1.7.11</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -437,7 +505,7 @@ changed using the pthread_attr_setstacksize call.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.10"><title>What's new and what changed from 1.7.9 to 1.7.10</title>
|
||||
<sect2 id="ov-new1.7.10"><title>What's new and what changed in 1.7.10</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -561,7 +629,7 @@ pthread_sigqueue, sysinfo.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.9"><title>What's new and what changed from 1.7.8 to 1.7.9</title>
|
||||
<sect2 id="ov-new1.7.9"><title>What's new and what changed in 1.7.9</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -573,7 +641,7 @@ New API: strchrnul.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.8"><title>What's new and what changed from 1.7.7 to 1.7.8</title>
|
||||
<sect2 id="ov-new1.7.8"><title>What's new and what changed in 1.7.8</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -641,7 +709,7 @@ Support TIOCGPGRP, TIOCSPGRP ioctls.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.7"><title>What's new and what changed from 1.7.6 to 1.7.7</title>
|
||||
<sect2 id="ov-new1.7.7"><title>What's new and what changed in 1.7.7</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -668,7 +736,7 @@ See <xref linkend="textbin-devel"></xref> for details.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.6"><title>What's new and what changed from 1.7.5 to 1.7.6</title>
|
||||
<sect2 id="ov-new1.7.6"><title>What's new and what changed in 1.7.6</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -725,7 +793,7 @@ be out of the way. [...]
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.5"><title>What's new and what changed from 1.7.3 to 1.7.5</title>
|
||||
<sect2 id="ov-new1.7.5"><title>What's new and what changed in 1.7.5</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -738,7 +806,7 @@ in Windows console.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.3"><title>What's new and what changed from 1.7.2 to 1.7.3</title>
|
||||
<sect2 id="ov-new1.7.3"><title>What's new and what changed in 1.7.3</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -756,7 +824,7 @@ Modification and access timestamps of devices reflect the current time.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7.2"><title>What's new and what changed from 1.7.1 to 1.7.2</title>
|
||||
<sect2 id="ov-new1.7.2"><title>What's new and what changed in 1.7.2</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -908,7 +976,9 @@ Procedure Call (RPC) and NFS.
|
|||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="ov-new1.7-os"><title>OS related changes</title>
|
||||
<sect2 id="ov-new1.7.1"><title>What's new and what changed from 1.5 to 1.7</title>
|
||||
|
||||
<sect3 id="ov-new1.7-os"><title>OS related changes</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -923,9 +993,9 @@ Add support for Windows 7 and Windows Server 2008 R2.
|
|||
|
||||
</itemizedlist>
|
||||
|
||||
</sect2>
|
||||
</sect3>
|
||||
|
||||
<sect2 id="ov-new1.7-file"><title>File Access related changes</title>
|
||||
<sect3 id="ov-new1.7-file"><title>File Access related changes</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -1111,9 +1181,9 @@ eaccess, euidaccess, canonicalize_file_name, fexecve, execvpe.
|
|||
|
||||
</itemizedlist>
|
||||
|
||||
</sect2>
|
||||
</sect3>
|
||||
|
||||
<sect2 id="ov-new1.7-net"><title>Network related changes</title>
|
||||
<sect3 id="ov-new1.7-net"><title>Network related changes</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -1179,9 +1249,9 @@ Add /proc/net/if_inet6.
|
|||
|
||||
</itemizedlist>
|
||||
|
||||
</sect2>
|
||||
</sect3>
|
||||
|
||||
<sect2 id="ov-new1.7-device"><title>Device related changes</title>
|
||||
<sect3 id="ov-new1.7-device"><title>Device related changes</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -1230,9 +1300,9 @@ get_phys_pages, posix_openpt.
|
|||
|
||||
</itemizedlist>
|
||||
|
||||
</sect2>
|
||||
</sect3>
|
||||
|
||||
<sect2 id="ov-new1.7-posix"><title>Other POSIX related changes</title>
|
||||
<sect3 id="ov-new1.7-posix"><title>Other POSIX related changes</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -1294,9 +1364,9 @@ vfwscanf, vswscanf.
|
|||
|
||||
</itemizedlist>
|
||||
|
||||
</sect2>
|
||||
</sect3>
|
||||
|
||||
<sect2 id="ov-new1.7-sec"><title>Security related changes</title>
|
||||
<sect3 id="ov-new1.7-sec"><title>Security related changes</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -1327,9 +1397,9 @@ options have a slightly changed behaviour.
|
|||
|
||||
</itemizedlist>
|
||||
|
||||
</sect2>
|
||||
</sect3>
|
||||
|
||||
<sect2 id="ov-new1.7-misc"><title>Miscellaneous</title>
|
||||
<sect3 id="ov-new1.7-misc"><title>Miscellaneous</title>
|
||||
|
||||
<itemizedlist mark="bullet">
|
||||
|
||||
|
@ -1424,6 +1494,8 @@ having multiple concurrent Cygwin installations.
|
|||
|
||||
</itemizedlist>
|
||||
|
||||
</sect3>
|
||||
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2014-10-21 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* cygcheck.cc (CYGLSA64_DLL): Remove unused macro.
|
||||
(dump_sysinfo): If COMSPEC isn't set in the MSVCRT environment, set it.
|
||||
Explain why.
|
||||
|
||||
2014-06-16 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* passwd.c (main): Fix typo in error output.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* cygcheck.cc
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
|
||||
2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||
2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -587,9 +587,6 @@ cygwin_info (HANDLE h)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Special case. Don't complain about this one. */
|
||||
#define CYGLSA64_DLL "\\cyglsa64.dll"
|
||||
|
||||
static void
|
||||
dll_info (const char *path, HANDLE fh, int lvl, int recurse)
|
||||
{
|
||||
|
@ -1436,6 +1433,20 @@ dump_sysinfo ()
|
|||
DWORD obcaseinsensitive = 1;
|
||||
HKEY key;
|
||||
|
||||
/* MSVCRT popen (called by pretty_id and dump_sysinfo_services) SEGVs if
|
||||
COMSPEC isn't set correctly. Simply enforce it here. Using
|
||||
Get/SetEnvironmentVariable to set the dir does *not* help, btw.
|
||||
Apparently MSVCRT keeps its own copy of the environment and changing
|
||||
that requires to use _wputenv. */
|
||||
if (!_wgetenv (L"COMSPEC"))
|
||||
{
|
||||
WCHAR comspec[MAX_PATH + 17];
|
||||
wcscpy (comspec, L"COMSPEC=");
|
||||
GetSystemDirectoryW (comspec + 8, MAX_PATH);
|
||||
wcsncat (comspec, L"\\cmd.exe", sizeof comspec);
|
||||
_wputenv (comspec);
|
||||
}
|
||||
|
||||
printf ("\nCygwin Configuration Diagnostics\n");
|
||||
time (&now);
|
||||
printf ("Current System Time: %s\n", ctime (&now));
|
||||
|
|
Loading…
Reference in New Issue