Revamp advisory file locking to avoid cross reference pointers as well
as to allow BSD flock semantics. More agressively delete unused nodes
and sync objects.
* fhandler.h (fhandler_base::ino): Rename from namehash. Fix comment.
(fhandler_base::node): Remove.
(fhandler_base::unique_id): Add.
(fhandler_base::del_my_locks): New method.
(get_ino): Rename from get_namehash. Change usage throughout Cygwin.
(get_unique_id): New method.
* fhandler.cc (fhandler_base::close): Call own del_my_locks method.
Fix comment.
(fhandler_base::fhandler_base): Accommodate new and changed members.
(fhandler_base::fixup_after_fork): Call del_my_locks.
(fhandler_base::fixup_after_exec): Ditto for files with close-on-exec
flag set.
* fhandler_disk_file.cc (get_ino_by_handle): Rename from
readdir_get_ino_by_handle. Accommodate throughout.
(fhandler_base::open_fs): Fill ino with inode number if FS has good
inodes. Allocate a LUID and store in unique_id to recognize file
descriptors referencing the same file object.
* flock.cc: Drop flock TODO comments. Use explicit types __dev32_t
and __ino64_t instead of dev_t and ino_t.
(LOCK_OBJ_NAME_LEN): Change to reflect longer lf_id length.
(get_obj_handle_count): New method.
(lockf_t::lf_id): Change type to long long.
(inode_t::get_lock_obj_handle_count): Drop in favor of static function
get_obj_handle_count.
(inode_t::del_locks): Remove.
(inode_t::get): Add create_if_missing flag argument.
(inode_t::del_my_locks): Reimplement to handle POSIX and BSD flock
locks. Return if node can be deleted or not.
(inode_t::~inode_t): Ditto. Close handles to i_dir and i_mtx.
(fixup_lockf_after_fork): Remove.
(fhandler_base::del_my_locks): New method.
(fixup_lockf_after_exec): Check if node can be deleted.
(inode_t::get): Only create node if create_if_missing is set. Lock
the returned node here before unlocking the node list.
(inode_t::get_all_locks_list): Accommodate new lf_id length.
(inode_t::create_lock_obj): Ditto.
(lockf_t::open_lock_obj): Ditto. Change return type to bool. De-const.
Set lf_obj instead of returning a handle.
(lockf_t::del_lock_obj): Call SetEvent only if new incoming parameters
allow it. Explain how it's supposed to work.
(fhandler_disk_file::lock): Only fetch file length in SEEK_END case.
Use NtQueryInformationFile(FileStandardInformation) instead of
calling fstat_by_handle. Always unlock node before returning.
Use fhandler's unique id to create lf_id for BSD flock locks.
Rely on node lock from inode_t::get. Call del_lock_obj on removed
locks here to allow explicit unlocking. Delete node if no lock exists
on the file anymore.
(lf_setlock): Get file handle as additional parameter. Handle the fact
that lf_getblock now always opens the attached event object. Reactivate
erroneously applied patch which deactivates setting thread priority.
Additionally handle blocking on BSD flock locks.
(lf_clearlock): Get file handle as additional parameter.
(lf_getlock): Close event handle opened by lf_getblock.
(lf_getblock): Open potentially blocking event object here and check
its signal state if it's a BSD flock lock.
(lf_wakelock): Get file handle as additional parameter.
* fork.cc (frok::child): Drop call to fixup_lockf_after_fork.
* ntdll.h (struct _EVENT_BASIC_INFORMATION): Define.
(enum _EVENT_INFORMATION_CLASS): Define.
(NtQueryEvent): Declare.
* fhandler.h (fhandler_base::fs_flags): Remove.
(fhandler_base::set_fs_flags): Remove.
(fhandler_base::get_fs_flags): Remove.
* fhandler.cc (fhandler_base::write): Check for sparse file using
pc.fs_flags().
* fhandler_disk_file.cc (fhandler_disk_file::ftruncate): Ditto.
The return of the volume serial number in fs_info.
* fhandler.h (get_dev): New method.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Drop call to
NtQueryVolumeInformationFile(FileFsVolumeInformation). Just use
get_dev() method.
* fhandler_fifo.cc (fhandler_fifo::open) Use device ID and inode number
to generate fifo name.
* path.h (fs_info::sernum): New member.
(fs_info::serial_number): New method.
(path_conv::fs_serial_number): New method.
* path.cc (fs_info::update): Fetch volume serial number and store in
sernum.
cmalloc instead of ccalloc in the default operator. Add comments.
(inode_t::operator new): Call cmalloc instead of ccalloc.
(inode_t::get_all_locks_list): Return lockf_t pointer.
(inode_t::del_all_locks_list): Delete. Remove calls throughout.
(inode_t::get): Handle failing new gracefully.
(MAX_LOCKF_CNT): Define.
(inode_t::get_all_locks_list): Use pre-allocated buffer in i_all_lf
instead of allocating every lock. Return pointer to start of linked
list of locks.
(lockf_t::open_lock_obj): Create event object non-inheritable.
(fhandler_disk_file::lock): Handle failing new gracefully.
(lf_setlock): Allocate temporary buffer for node->i_all_lf from TLS.
Remove erroneous NtClose call.
(lf_getlock): Allocate temporary buffer for node->i_all_lf from TLS.
(lf_getblock): Set lf to return value of get_all_locks_list.
(FLOCK_INODE_DIR_ACCESS): Define.
(FLOCK_MUTANT_ACCESS): Define.
(FLOCK_EVENT_ACCESS): Define.
(SD_MIN_SIZE): Define.
(everyone_sd): Define to simplify calling _everyone_sd.
(_everyone_sd): Replace everyone_sync_sd. Take SECURITY_DESCRIPTOR as
argument and allow to specify access mask.
(get_lock_parent_dir): Open/Create parent dir with
FLOCK_PARENT_DIR_ACCESS. Add text to api_fatal message.
(inode_t::inode_t): Open/Create dir with FLOCK_INODE_DIR_ACCESS.
Open/Create mutant with FLOCK_MUTANT_ACCESS. Add text to api_fatal
message.
(lockf_t::create_lock_obj): Create event with FLOCK_EVENT_ACCESS.
Add text to api_fatal message.
(lockf_t::open_lock_obj): Open event with FLOCK_EVENT_ACCESS.
On failure, just return NULL pointer instead of calling api_fatal.
(lockf_t::get_lock_obj_handle_count): Replace call to small_printf
with call to debug_printf.
(lf_setlock): Handle a failure to open the lock event object as
EDEADLK. Call system_printf if opening sync objects fail.
* ntdll.h (DIRECTORY_TRAVERSE): Define.
(DIRECTORY_CREATE_OBJECT): Define.
(DIRECTORY_CREATE_SUBDIRECTORY): Define.
(EVENT_QUERY_STATE): Define.
* pinfo.cc (status_exit): New function. Issue message when dll not found. Use
find_first_notloaded_dll to find a nonexistent dll.
(pinfo::maybe_set_exit_code_from_windows): Call status_exit when exit code >=
0xc0000000UL.
* sigproc.cc (child_info::proc_retry): Return exit code when
STATUS_DLL_NOT_FOUND.
* spawn.cc (spawn_guts): Minor cleanup.
* syscalls.cc (close_all_files): Don't actually close stderr filehandle. Just
make it noninheritable.
* winsup.h (find_first_notloaded_dll): Declare new function.
* ntdll.h: Add several missing NTSTATUS defines.
in lock event object name.
(lockf_t::create_lock_obj): Ditto.
(lockf_t::open_lock_obj): Ditto.
(lf_setlock): Only check POSIX locks for deadlock condition.
(lf_findoverlap): Don't let POSIX and flock locks interact.
constants.
(dtable::init_std_file_from_handle): Reorganize pipe handling to try to catch
special tty case.
(build_fh_name_worker): Declare for common use.
(build_fh_name): Define char version.
(build_fh_name): Define (currently unused) UNICODE_STRING version.
(decode_tty): Detect if pipe is actually a cygwin tty, returning the tty name
in the buffer.
(handle_to_fn): Reorganize to use wide characters.
* dtable.h (build_fh_name): Declare (currently unused) UNICODE_STRING version.
* fhandler_tty.cc (fhandler_pty_master::setup): Use
fhandler_pipe::create_selectable to create a pipe with a given name.
* pipe.cc (pipe_handler): Make returned handle inheritable.
(fhandler_pipe::create_selectable): Take an optional name. Use a standard
cygwin introducer for the name.
* path.cc (path_conv::check): Make first argument const.
* path.h (path_conv::check): Ditto for declaration.
(path_conv::path_conv): Ditto for UNICODE_STRING version.
* include/mprapi.h: Add guard for MprAdminAcceptReauthentication function
and MPR_INTERFACE_3 structure since they are available only in Windows
Server 2008
(is_symlink): Rewrite. Just read the whole file in memory rather
than by parts. Account for an ITEMIDLIST if present, as well as
the new style of Cygwin shortcut supporting targets > MAX_PATH.
for new path API.
* security.sgml: New file to document cygwin_set_impersonation_token
and cygwin_logon_user with only eight years of delay.
* shared.sgml: Remove file.
* include/sys/cygwin.h (cygwin32_attach_handle_to_fd): Move declaration
into fully deprecated function block.
(cygwin_logon_user): Move declaration down to declaration of
cygwin_set_impersonation_token.
munging. Convert all chars in the 0xf0xx area to it's ascii equivalent.
* path.cc (normalize_posix_path): Don't treat "X:foo" as windows path,
only "a:\foo".
(tfx_chars): New transformation table for special DOS chars.
(tfx_chars_managed): Ditto, plus transformation of uppercase ASCII
chars.
(transform_chars): New function.
(get_nt_native_path): Make static. Call transform_chars for all valid
FS paths. Get additional flag if file is managed or not. Accommodate
throughout.
(getfileattr): Get additional flag if file is managed or not.
Accommodate throughout.
(path_conv::check): Disable special handling for trailing dots and
spaces.
(mount_item::build_win32): Disable code for managed paths.
(mount_info::conv_to_posix_path): Ditto.
* path.h (get_nt_native_path): Remove declaration.
Accommodate change throughout.
* cygwin.din (cygwin_conv_path): Export.
(cygwin_conv_path_list): Export.
(cygwin_create_path): Export.
* dcrt0.cc (dll_crt0_1): Use cygwin_conv_path.
* dtable.cc (handle_to_fn): Ditto. Don't expect UNICODE_STRING being
0-terminated.
* environ.cc (env_plist_to_posix): New helper function.
(env_plist_to_win32): Ditto.
(env_path_to_posix): Ditto.
(env_path_to_win32): Ditto.
(return_MAX_PATH): Remove.
(conv_envvars): Use new helper functions. Drop removed members.
(win_env::operator =): Accommodate removal of path length functions.
(win_env::add_cache): Accommodate new env helper function API.
(posify): Ditto.
* environ.h (struct win_env): Ditto. Remove path length function
pointers since they are unused.
* path.cc (warn_msdos): Use cygwin_conv_path.
(getfileattr): Use new tmp_pathbuf::u_get method.
(fillout_mntent): Ditto.
(symlink_info::check): Ditto.
(path_conv::check): Use sizeof (WCHAR) instead of constant 2.
(symlink_info::check_reparse_point): Ditto.
(conv_path_list): Get max size of target string as argument. Call
cygwin_conv_path as helper function.
(cygwin_conv_path): New function.
(cygwin_create_path): New function.
(cygwin_conv_to_win32_path): Just call cygwin_conv_path with size set
to MAX_PATH.
(cygwin_conv_to_full_win32_path): Ditto.
(cygwin_conv_to_posix_path): Ditto.
(cygwin_conv_to_full_posix_path): Ditto.
(conv_path_list_buf_size): Add FIXME comment.
(env_PATH_to_posix): Rename from env_win32_to_posix_path_list.
Add size argument as required for env helper functions.
(cygwin_win32_to_posix_path_list): Call conv_path_list with size set to
MAX_PATH.
(cygwin_posix_to_win32_path_list): Ditto.
(cygwin_conv_path_list): New function.
(cwdstuff::get): Fix length argument in call to sys_wcstombs.
* spawn.cc (find_exec): Use cygwin_conv_path_list.
* tls_pbuf.h (tmp_pathbuf::u_get: New method.
* uinfo.cc (cygheap_user::ontherange): Allocate temporary path buffers
using tmp_pathbuf. Use cygwin_conv_path.
* winf.cc (av::unshift): Use cygwin_conv_path.
* include/cygwin/version.h: Bump API minor number.
* include/sys/cygwin.h: Comment out old cygwin32_XXX API.
Mark old path handling API as deprecated.
(cygwin_conv_path_t): Typedef. Define values.
(cygwin_conv_path): Declare.
(cygwin_create_path): Declare.
(cygwin_conv_path_list): Declare.
(find_app_on_path): Use SYMLINK_MAX. Resolve symlink relative
to link's location. Adjust to the fact that cygpath already
normalizes its return value.
* path.cc (rel_vconcat): Add cwd parameter, and use it instead
of calling GetCurrentDirectory() if possible. Rename throughout.
(vcygpath): Rename from cygpath and accept cwd and va_list. Pass
cwd on to rel_vconcat().
(cygpath_rel): New front end for vcygpath.
(cygpath): Ditto.
* path.h (cygpath_rel): Declare.
(SYMLINK_MAX): Define to 4095.
paths. Add comments.
* spawn.cc (spawn_guts): Don't allow to start a native Win32 application
from a long path or a virtual path. Print an error message to stderr.
(regopt): Take tmp buffer as additional argument.
(environ_init): Alllcate tmpbuf earlier. Use as temporary buffer in
call to regopt.
* tls_pbuf.cc (tmp_pathbuf::c_get): Allocate one additional char.
(tmp_pathbuf::w_get): Allocate one additional WCHAR.
* winf.cc (av::unshift): Use tmp_pathbuf to allocate buffer.
* fhandler_console.cc (dev_console::con_to_str): Return number of
multibyte char bytes.
(fhandler_console::read): Set nread to number of multibyte char bytes
returned from con_to_str.
(fhandler_console::write_normal): Reorder trunc buffer preocessing.
Return after writing valid multibyte sequence out of trunc buffer.
Change comments slightly.
testsuite.exe from path-testsuite.o and testsuite.o.
* path.cc: Include testsuite.h.
(struct mnt): Change to a mnt_t typedef and don't define
mount_table when TESTSUITE is defined.
(find2): Don't include when TESTSUITE is defined to avoid warning.
(get_cygdrive0): Ditto.
(get_cygdrive): Ditto.
(read_mounts): Provide empty implementation when TESTSUITE is
defined.
(vconcat): Use the isslash macro.
(unconvert_slashes): New helper to convert to backslashses.
(rel_vconcat): Handle relative paths more gracefully.
(cygpath): Skip a leading "./" sequence. Avoid double-slashes.
Normalize final output to backslashes and remove redundant path
sequences.
* testsuite.cc: New file implementing testsuite driver.
* testsuite.h: New header implementing harness mount table and
series of tests.
name in terms of sizeof(WCHAR).
(fhandler_disk_file::readdir_helper): Convert *all* of fname.
* path.cc (fillout_mntent): Use tmp_pathbuf for path buffer.
(symlink_worker): Ditto.
(SCAN_JUSTCHECKTHIS): New state for suffix_scan to define
that only the actual name gets cheked and a suffix is never attached.
(suffix_scan::has): If filename + suffix would be > NAME_MAX, start
in SCAN_JUSTCHECKTHIS state.
(suffix_scan::next): Add case for SCAN_JUSTCHECKTHIS.
(symlink_info::check): Use tmp_pathbuf for path buffer. Goto
file_not_symlink in case of invalid file name.
(realpath): Use tmp_pathbuf for path buffer.