Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog15
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc3
-rw-r--r--winsup/cygwin/mount.cc16
-rw-r--r--winsup/cygwin/mount.h2
-rw-r--r--winsup/cygwin/path.cc28
-rw-r--r--winsup/cygwin/wincap.cc10
-rw-r--r--winsup/cygwin/wincap.h2
7 files changed, 73 insertions, 3 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 8924885df..9eb93adac 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,18 @@
+2009-01-29 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_disk_file.cc (fhandler_disk_file::readdir): Fix inode number
+ evaluation for faked "." entry.
+
+ * mount.cc (fs_info::update): Move setting of is_cdrom after checking
+ for caseinsensitivity. Recognize UDF in is_cdrom case and set
+ caseinsensitive flag according to UDF brokenness determined by OS.
+ Add comment to explain why.
+ * mount.h (class fs_info): Add is_udf status flag.
+ * path.cc (symlink_info::check): Add workaround for UDF bug in
+ terms of casesensitivity on certain OSes.
+ * wincap.h (wincaps::has_broken_udf): New element.
+ (wincaps::has_broken_udf): New element
+
2009-01-27 Christopher Faylor <me+cygwin@cgf.cx>
* fhandler.cc (fhandler_base::wait_overlapped): Set bytes to -1 on
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index 2aad2ff79..7fd66b843 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -1928,7 +1928,8 @@ go_ahead:
else if (!(dir->__flags & dirent_saw_dot))
{
strcpy (de->d_name , ".");
- de->d_ino = get_ino_by_handle (get_handle ());
+ if (pc.isgood_inode (de->d_ino))
+ de->d_ino = get_ino_by_handle (get_handle ());
dir->__d_position++;
dir->__flags |= dirent_saw_dot;
res = 0;
diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
index 0797d1bb3..a7cc07efb 100644
--- a/winsup/cygwin/mount.cc
+++ b/winsup/cygwin/mount.cc
@@ -262,7 +262,6 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
}
is_ntfs (RtlEqualUnicodeString (&fsname, &testname, FALSE)
&& !is_samba () && !is_netapp ());
- is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM);
has_acls (flags () & FS_PERSISTENT_ACLS);
hasgood_inode (((flags () & FILE_PERSISTENT_ACLS) && !is_netapp ())
@@ -274,6 +273,21 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
caseinsensitive ((!(flags () & FILE_CASE_SENSITIVE_SEARCH) || is_samba ())
&& !is_nfs ());
+ is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM);
+ if (is_cdrom ())
+ {
+ RtlInitUnicodeString (&testname, L"UDF");
+ is_udf (RtlEqualUnicodeString (&fsname, &testname, FALSE));
+ /* UDF on NT 5.x is broken (at least) in terms of case sensitivity. The
+ UDF driver reports the FILE_CASE_SENSITIVE_SEARCH capability but:
+ - Opening the root directory for query seems to work at first, but the
+ filenames in the directory listing are mutilated.
+ - When trying to open a file or directory case sensitive, the file
+ appears to be non-existant. */
+ if (is_udf () && wincap.has_broken_udf ())
+ caseinsensitive (true);
+ }
+
if (!in_vol)
NtClose (vol);
return true;
diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h
index c6c0bb1e0..4537f465a 100644
--- a/winsup/cygwin/mount.h
+++ b/winsup/cygwin/mount.h
@@ -31,6 +31,7 @@ class fs_info
unsigned is_nfs : 1;
unsigned is_netapp : 1;
unsigned is_cdrom : 1;
+ unsigned is_udf : 1;
} status;
ULONG sernum;
public:
@@ -52,6 +53,7 @@ class fs_info
IMPLEMENT_STATUS_FLAG (bool, is_nfs)
IMPLEMENT_STATUS_FLAG (bool, is_netapp)
IMPLEMENT_STATUS_FLAG (bool, is_cdrom)
+ IMPLEMENT_STATUS_FLAG (bool, is_udf)
ULONG serial_number () const { return sernum; }
bool update (PUNICODE_STRING, HANDLE) __attribute__ ((regparm (3)));
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index aa635103d..ae01109a1 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -2140,6 +2140,7 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
NTSTATUS status;
IO_STATUS_BLOCK io;
bool no_ea = false;
+ bool fs_update_called = false;
error = 0;
get_nt_native_path (suffix.path, upath);
@@ -2179,6 +2180,30 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
FILE_OPEN_REPARSE_POINT
| FILE_OPEN_FOR_BACKUP_INTENT);
}
+ if (status == STATUS_OBJECT_NAME_NOT_FOUND && ci_flag == 0
+ && wincap.has_broken_udf ())
+ {
+ /* On NT 5.x UDF is broken (at least) in terms of case sensitivity.
+ When trying to open a file case sensitive, the file appears to be
+ non-existant. Another bug is described in fs_info::update. */
+ attr.Attributes = OBJ_CASE_INSENSITIVE;
+ status = NtOpenFile (&h, READ_CONTROL | FILE_READ_ATTRIBUTES,
+ &attr, &io, FILE_SHARE_VALID_FLAGS,
+ FILE_OPEN_REPARSE_POINT
+ | FILE_OPEN_FOR_BACKUP_INTENT);
+ attr.Attributes = ci_flag;
+ if (NT_SUCCESS (status))
+ {
+ fs.update (&upath, h);
+ if (fs.is_udf ())
+ fs_update_called = true;
+ else
+ {
+ NtClose (h);
+ status = STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+ }
+ }
if (NT_SUCCESS (status)
&& NT_SUCCESS (status
= NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
@@ -2271,7 +2296,8 @@ symlink_info::check (char *path, const suffix_info *suffixes, unsigned opt,
/* Check file system while we're having the file open anyway.
This speeds up path_conv noticably (~10%). */
- fs.update (&upath, h);
+ if (!fs_update_called)
+ fs.update (&upath, h);
ext_tacked_on = !!*ext_here;
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index 9fc2b211f..082343a40 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -53,6 +53,7 @@ wincaps wincap_unknown __attribute__((section (".cygwin_dll_common"), shared)) =
ts_has_dep_problem:false,
has_recvmsg:false,
has_sendmsg:false,
+ has_broken_udf:false,
};
wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -88,6 +89,7 @@ wincaps wincap_nt4 __attribute__((section (".cygwin_dll_common"), shared)) = {
ts_has_dep_problem:false,
has_recvmsg:false,
has_sendmsg:false,
+ has_broken_udf:false,
};
wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -123,6 +125,7 @@ wincaps wincap_nt4sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
ts_has_dep_problem:false,
has_recvmsg:false,
has_sendmsg:false,
+ has_broken_udf:false,
};
wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -158,6 +161,7 @@ wincaps wincap_2000 __attribute__((section (".cygwin_dll_common"), shared)) = {
ts_has_dep_problem:false,
has_recvmsg:false,
has_sendmsg:false,
+ has_broken_udf:true,
};
wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -193,6 +197,7 @@ wincaps wincap_2000sp4 __attribute__((section (".cygwin_dll_common"), shared)) =
ts_has_dep_problem:false,
has_recvmsg:false,
has_sendmsg:false,
+ has_broken_udf:true,
};
wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -228,6 +233,7 @@ wincaps wincap_xp __attribute__((section (".cygwin_dll_common"), shared)) = {
ts_has_dep_problem:false,
has_recvmsg:true,
has_sendmsg:false,
+ has_broken_udf:true,
};
wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -263,6 +269,7 @@ wincaps wincap_xpsp1 __attribute__((section (".cygwin_dll_common"), shared)) = {
ts_has_dep_problem:false,
has_recvmsg:true,
has_sendmsg:false,
+ has_broken_udf:true,
};
wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -298,6 +305,7 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
ts_has_dep_problem:false,
has_recvmsg:true,
has_sendmsg:false,
+ has_broken_udf:true,
};
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -333,6 +341,7 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
ts_has_dep_problem:false,
has_recvmsg:true,
has_sendmsg:false,
+ has_broken_udf:true,
};
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -368,6 +377,7 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
ts_has_dep_problem:false,
has_recvmsg:true,
has_sendmsg:true,
+ has_broken_udf:false,
};
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index 703527526..e3ab4d70d 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -45,6 +45,7 @@ struct wincaps
unsigned ts_has_dep_problem : 1;
unsigned has_recvmsg : 1;
unsigned has_sendmsg : 1;
+ unsigned has_broken_udf : 1;
};
class wincapc
@@ -96,6 +97,7 @@ public:
bool IMPLEMENT (ts_has_dep_problem)
bool IMPLEMENT (has_recvmsg)
bool IMPLEMENT (has_sendmsg)
+ bool IMPLEMENT (has_broken_udf)
#undef IMPLEMENT
};