diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2007-07-29 12:27:22 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2007-07-29 12:27:22 +0000 |
commit | ed7ec849f625609f8c8e061386adfcb593fcd54a (patch) | |
tree | bc8c388227696693176470ab0bc71d012c5a5a1d /winsup/cygwin/fhandler_disk_file.cc | |
parent | 4368984a7be56fc3a94f18488d1b8c6341327ce3 (diff) | |
download | cygnal-ed7ec849f625609f8c8e061386adfcb593fcd54a.tar.gz cygnal-ed7ec849f625609f8c8e061386adfcb593fcd54a.tar.bz2 cygnal-ed7ec849f625609f8c8e061386adfcb593fcd54a.zip |
* fhandler_disk_file.cc (fhandler_disk_file::link): Use FILE_ANY_ACCESS.
(fhandler_base::utimes_fs): Fix white space.
(fhandler_disk_file::lock): Remove 9x blurb from comment.
(fhandler_disk_file::mkdir): Use NtCreateFile/NtClose instead of
CreateDirectoryA.
(fhandler_disk_file::rmdir): Accommodate changes to unlink_nt.
Simplify post-delete SMB-related tests. Use NtQueryAttributesFile
instead of GetFileAttributes.
* ntdll.h (STATUS_DIRECTORY_NOT_EMPTY): Define.
(NtQueryAttributesFile): Declare.
* syscalls.cc (unlink_nt): Return NTSTATUS. Drop setattrs parameter.
Never use FILE_DELETE_ON_CLOSE, always use
NtSetInformationFile(FileDispositionInformation) instead.
Check for R/O attributes and open file with FILE_WRITE_ATTRIBUTES
access if any of them are set. Remove R/O attributes before
marking for delete if necessary. Revert them afterwards if necessary.
(unlink): Accommodate changes to unlink_nt.
Diffstat (limited to 'winsup/cygwin/fhandler_disk_file.cc')
-rw-r--r-- | winsup/cygwin/fhandler_disk_file.cc | 93 |
1 files changed, 50 insertions, 43 deletions
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index afb5ae466..07e499e67 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1094,7 +1094,8 @@ fhandler_disk_file::link (const char *newpath) NTSTATUS status; OBJECT_ATTRIBUTES attr; IO_STATUS_BLOCK io; - status = NtOpenFile (&fh, 0, pc.get_object_attr (attr, sec_none_nih), &io, + status = NtOpenFile (&fh, FILE_ANY_ACCESS, + pc.get_object_attr (attr, sec_none_nih), &io, FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT); if (!NT_SUCCESS (status)) @@ -1182,7 +1183,7 @@ fhandler_base::utimes_fs (const struct timeval *tvp) IO_STATUS_BLOCK io; FILE_BASIC_INFORMATION fbi; fbi.CreationTime.QuadPart = 0LL; - fbi.LastAccessTime= lastaccess; + fbi.LastAccessTime = lastaccess; fbi.LastWriteTime = lastwrite; fbi.ChangeTime.QuadPart = 0LL; fbi.FileAttributes = 0; @@ -1318,11 +1319,7 @@ fhandler_disk_file::pwrite (void *buf, size_t count, _off64_t offset) /* FIXME: The correct way to do this to get POSIX locking semantics is to keep a linked list of posix lock requests and map them into Win32 locks. he problem is that Win32 does not deal correctly with overlapping lock - requests. Also another pain is that Win95 doesn't do non-blocking or - non-exclusive locks at all. For '95 just convert all lock requests into - blocking,exclusive locks. This shouldn't break many apps but denying all - locking would. For now just convert to Win32 locks and hope for - the best. */ + requests. */ int fhandler_disk_file::lock (int cmd, struct __flock64 *fl) @@ -1471,17 +1468,31 @@ fhandler_disk_file::mkdir (mode_t mode) set_security_attribute (S_IFDIR | ((mode & 07777) & ~cygheap->umask), &sa, sd); - if (CreateDirectoryA (get_win32_name (), &sa)) - { + NTSTATUS status; + HANDLE dir; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + ULONG fattr = FILE_ATTRIBUTE_DIRECTORY; #ifdef HIDDEN_DOT_FILES - char *c = strrchr (real_dir.get_win32 (), '\\'); - if ((c && c[1] == '.') || *get_win32_name () == '.') - SetFileAttributes (get_win32_name (), FILE_ATTRIBUTE_HIDDEN); + UNICODE_STRING basename; + + RtlSplitUnicodePath (pc.get_nt_native_path (), NULL, &basename); + if (basename.Buffer[0] == L'.') + fattr |= FILE_ATTRIBUTE_HIDDEN; #endif + status = NtCreateFile (&dir, FILE_LIST_DIRECTORY | SYNCHRONIZE, + pc.get_object_attr (attr, sa), &io, NULL, + fattr, FILE_SHARE_VALID_FLAGS, FILE_CREATE, + FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT + | FILE_OPEN_FOR_BACKUP_INTENT, + NULL, 0); + if (NT_SUCCESS (status)) + { + NtClose (dir); res = 0; } else - __seterrno (); + __seterrno_from_nt_status (status); return res; } @@ -1489,47 +1500,43 @@ fhandler_disk_file::mkdir (mode_t mode) int fhandler_disk_file::rmdir () { - extern DWORD unlink_nt (path_conv &win32_name, bool setattrs); - - int res = -1; + extern NTSTATUS unlink_nt (path_conv &pc); if (!pc.isdir ()) { set_errno (ENOTDIR); return -1; } - /* Even own directories can't be removed if R/O attribute is set. */ - if (pc.has_attribute (FILE_ATTRIBUTE_READONLY)) - SetFileAttributes (get_win32_name (), - (DWORD) pc & ~FILE_ATTRIBUTE_READONLY); - - DWORD err, att = 0; - - int rc = !(err = unlink_nt (pc, pc.has_attribute (FILE_ATTRIBUTE_READONLY))); - if (err) - SetLastError (err); + if (!pc.exists ()) + { + set_errno (ENOENT); + return -1; + } - if (isremote () && exists ()) - att = GetFileAttributes (get_win32_name ()); + NTSTATUS status = unlink_nt (pc); - /* Sometimes smb indicates failure when it really succeeds, so check for - this case specifically. */ - if (rc || att == INVALID_FILE_ATTRIBUTES) + /* Check for existence of remote dirs after trying to delete them. + Two reasons: + - Sometimes SMB indicates failure when it really succeeds. + - Removeing a directory on a samba drive doesn't return an error if the + directory can't be removed because it's not empty. */ + if (isremote ()) { - /* RemoveDirectory on a samba drive doesn't return an error if the - directory can't be removed because it's not empty. Checking for - existence afterwards keeps us informed about success. */ - if (!isremote () || att == INVALID_FILE_ATTRIBUTES) - return 0; + OBJECT_ATTRIBUTES attr; + FILE_BASIC_INFORMATION fbi; - err = ERROR_DIR_NOT_EMPTY; + if (NT_SUCCESS (NtQueryAttributesFile + (pc.get_object_attr (attr, sec_none_nih), &fbi))) + status = STATUS_DIRECTORY_NOT_EMPTY; + else + status = STATUS_SUCCESS; } - else - err = GetLastError (); - - __seterrno_from_win_error (err); - - return res; + if (!NT_SUCCESS (status)) + { + __seterrno_from_nt_status (status); + return -1; + } + return 0; } /* This is the minimal number of entries which fit into the readdir cache. |