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.
readdir_get_ino.
* fhandler.h (fhandler_disk_file::readdir_helper): Switch file name
parameter to PUNICODE_STRING.
* fhandler_disk_file.cc: Drop including ntdef.h.
(class __DIR_mounts): Store mount points in UNICODE. Additionally
store cygdrive prefix in unicode here. Change methods accordingly.
(__DIR_mounts::eval_ino): Call new stat_worker instead of lstat64.
(__DIR_mounts::~__DIR_mounts): New destructor to free UNICODE buffers.
(path_conv::ndisk_links): Rewrite using native NT functions.
(fhandler_base::fstat_by_handle): Use NAME_MAX instead of CYG_MAX_PATH.
Always set pfvi->VolumeSerialNumber to non-0. Remove last resort
code.
(fhandler_base::fstat_by_name): Rewrite using native NT functions.
(fhandler_base::fstat_fs): Always call fstat_by_name if fstat_by_handle
fails.
(fhandler_base::fstat_helper): Rely on dwVolumeSerialNumber.
(fhandler_disk_file::facl): Call fstat_by_name if fstat_by_handle fails.
(DIR_BUF_SIZE): Define using NAME_MAX instead of CYG_MAX_PATH.
(__DIR_cache): Remove __name.
(d_dirname): Remove.
(fhandler_disk_file::opendir): Drop pathname length check.
Remove outdated comment. Use get_name method instead of accessing
pc.normalized_path directly.
(readdir_get_ino): Drop unused dir parameter. Accomodate throughout.
Allocate fname dynamically. Call new stat_worker instead of lstat64.
Call NtOpenFile instead of CreateFile. Call NtClose instead of
CloseHandle.
(fhandler_disk_file::readdir_helper): Use native NT functions.
Check for volume mount points and use correct inode number.
(fhandler_disk_file::readdir): Simplify slightly.
Use get_name instead of pc.normalized_path.
(fhandler_disk_file::rewinddir): Use RtlInitUnicodeString.
(fhandler_cygdrive::fstat): Ignore floppy drives. Set st_nlink
correctly.
(fhandler_cygdrive::readdir): Ignore floppy drives.
* fhandler_netdrive.cc (fhandler_netdrive::readdir): Accommodate
change to readdir_get_ino.
* fhandler_proc.cc (PROC_DIR_COUNT): Define.
(fhandler_proc::fstat): Evaluate correct link count for /proc.
* ntdll.h (struct _FILE_DIRECTORY_INFORMATION): Define.
(NtFsControlFile): Declare.
(RtlAppendUnicodeToString): Declare.
(RtlAppendUnicodeStringToString): Declare.
(RtlCompareUnicodeString): Declare.
(RtlCopyUnicodeString): Declare.
(RtlCreateUnicodeStringFromAsciiz): Declare.
(RtlEqualUnicodeString): Declare.
(RtlFreeUnicodeString): Declare.
(RtlInitEmptyUnicodeString): Declare.
(RtlSecondsSince1970ToTime): Declare.
(RtlInitEmptyUnicodeString): Define as inline function.
(RtlInitCountedUnicodeString): Define as inline function.
* path.cc (path_conv::check): New method with PUNICODE_STRING as path,
preliminary implementation.
(mount_info::get_mounts_here): Change to create UNICODE_STRINGs.
Also copy cygpath prefix into UNICODE_STRING.
(is_floppy): Drop 9x consideration.
* path.h: Drop including ntdef.h.
(path_conv::check): Add declaration.
(path_conv::path_conv): Add constructor for UNICODE_STRING paths.
* shared_info.h (mount_info::get_mounts_here): Change declaration.
* syscalls.cc: Drop forward declaration of stat_worker.
(stat_worke): Take path_conv as parameter. Drop nofollow flag.
(stat64): Create matching path_conv and call stat_worker with it.
(lstat64): Ditto.
* winsup.h: Include ntdef.h.
(stat_worker): Declare.
(readdir_get_ino): Change declaration.
Drop remote fs handling entirely since unreliable inode numbers
are now recognized differently.
(path_conv::is_samba): Make inline.
(fhandler_disk_file::opendir): Reformat comment.
(fhandler_base::fstat_helper): Special case remote file systems
returning (unreliable) 32 bit inode numbers.
(fhandler_base::readdir): Ditto.
* fhandler_netdrive.cc (fhandler_netdrive::readdir): Ditto.
cygthread to handle extra argument, throughout.
* cygthread.h (cygthread::callproc): Declare new method.
(cygthread::cygthread): Add optional length argument to allow copying arguments
to executing thread.
* cygthread.cc (cygthread::callproc): Define new method.
(cygthread::stub): Use callfunc to invoke thread func to allow potentially
allocating stack memory which will be returned.
(cygthread::simplestub): Ditto.
(cygthread::cygthread): Accept arglen argument. Reset ev here prior to
activating thread. Wait for ev after activating thread if we're copying
contents to the thread. Wait until the end before setting h, to allow thread
synchronization.
(cygthread::release): Don't reset ev here. Rely on that happening the next
time the thread is activated.
* pinfo.h (commune_process): Rename declaration from _pinfo::commune_process.
* pinfo.cc (commune_process): Ditto for definition. Modify slightly to allow
running as a separate cygthread.
* sigproc.cc (child_info::sync): Always wait for both subproc_ready and any
hProcess if we have a cygwin parent.
(talktome): Change argument to be a pointer to siginfo_t. Contiguously
allocate whole siginfo_t structure + any needed extra for eventual passing to
commune_process thread.
(wait_sig): Accommodate change in talktome argument.
* pipe.cc (fhandler_pipe::fixup_after_exec): Remove debugging.
* fhandler.cc (fhandler_base::raw_read): Ditto for debug message.
* dcrt0.cc (do_exit): Add some more synchronization tests.
* fhandler_fifo.cc (fhandler_fifo::dup): Don't duplicate a nonexistent handle.
Use derived return value rather than always retuning 0.
* fhandler_netdrive.cc (fhandler_netdrive::exists): Wnet -> WNet.
* winsup.h (exit_states): Add a couple of new exit states.
* fhandler_netdrive.cc (struct netdriveinf): New structure to
store thread arguments.
(thread_netdrive): Thread handling all potentially blocking
WNet... calls.
(create_thread_and_wait): Start and wait for above thread.
(fhandler_netdrive::exists): Change to call create_thread_and_wait
instead of calling WNet... function.
(fhandler_netdrive::readdir): Ditto. Fix error handling.
(fhandler_netdrive::rewinddir): New method.
return code from GetFileSize and set file size to 0 if necessary.
* fhandler_netdrive.cc (fhandler_netdrive::fstat): Set permissions
to read/execute for all.
* dir.cc (mkdir): Check path for writability.
(rmdir): Ditto. Remove check for special directories.
* path.cc (path_conv::check): Set PATH_RO for virtual devices. Set error if
read-only and asked for writability.
* path.h (pathconv_arg): Add PC_WRITABLE.
(path_types): Add PATH_RO.
(path_conv::isro): Add (currently unused) check for read-only filesystem.
Return "ENOSHARE" when we know a share doesn't exist.
* include/sys/mount.h: Add MOUNT_RO flag.
* autoload.cc (WNetGetResourceInformationA): Import.
* fhandler_netdrive.cc (fhandler_netdrive::exists): Detect actual existence of
remote system rather than always assuming that it exists.