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:
Corinna Vinschen 2014-11-13 12:53:12 +00:00
parent a6aa222d5c
commit b4dc8397e9
77 changed files with 10873 additions and 7406 deletions

View File

@ -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.

View File

@ -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 \
)

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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
{

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 ();

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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 = &el;
};
~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 = &el;
#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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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 ();

View File

@ -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)
{

View File

@ -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;

View File

@ -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)
{

View File

@ -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" {

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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));

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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__

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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

View File

@ -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 ()
{

View File

@ -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;
}

View File

@ -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

341
winsup/cygwin/quotactl.cc Normal file
View File

@ -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;
}

View File

@ -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).

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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;

View File

@ -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)

View File

@ -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 ()
{

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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.

View File

@ -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));