Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PATCH] File::Spec Cygwin/Win32 case_tolerant improvement #9362

Closed
p5pRT opened this issue Jun 1, 2008 · 27 comments
Closed

[PATCH] File::Spec Cygwin/Win32 case_tolerant improvement #9362

p5pRT opened this issue Jun 1, 2008 · 27 comments

Comments

@p5pRT
Copy link

p5pRT commented Jun 1, 2008

Migrated from rt.perl.org#55162 (status was 'rejected')

Searchable as RT55162$

@p5pRT
Copy link
Author

p5pRT commented Jun 1, 2008

From @rurban

This is a bug report for perl from rurban@​cpan.org,
generated with the help of perlbug 1.36 running under perl 5.11.0.


Module​::Build is super slow in mod->prepare and so forth for cygwin and Win32
because of a bad File​::Spec->case_tolerant implementation.

The patch in a forthcoming attachment is a significant performance
improvement of my initial case_tolerant patch,
which is esp. noticable on Module​::Build



Flags​:
  category=core
  severity=medium


This perlbug was built using Perl 5.11.0 - Sun Mar 2 15​:14​:10 GMT 2008
It is being executed now by Perl 5.11.0 - Sun Apr 13 19​:53​:41 WEDT 2008.

Site configuration information for perl 5.11.0​:

Configured by rurban at Sun Apr 13 19​:53​:41 WEDT 2008.

Summary of my perl5 (revision 5 version 11 subversion 0 patch 33673)
configuration​:
  Platform​:
  osname=cygwin, osvers=1.5.25(0.15642), archname=cygwin-thread-multi-64int
  uname='cygwin_nt-5.1 atgrzwn502840 1.5.25(0.15642) 2008-03-05
19​:27 i686 cygwin '
  config_args='-de -Dmksymlinks -Duse64bitint -Dusethreads
-Dusemymalloc -Dusedevel -DDEBUGGING -Doptimize=-O0 -g -Dmad=y'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=define, usemultiplicity=define
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=define, use64bitall=undef, uselongdouble=undef
  usemymalloc=y, bincompat5005=undef
  Compiler​:
  cc='gcc', ccflags ='-DPERL_USE_SAFE_PUTENV -U__STRICT_ANSI__
-DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include',
  optimize='-O0 -g',
  cppflags='-DPERL_USE_SAFE_PUTENV -U__STRICT_ANSI__ -DDEBUGGING
-fno-strict-aliasing -pipe -I/usr/local/include'
  ccversion='', gccversion='3.4.4 (cygming special, gdc 0.12, using
dmd 0.125)', gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
  ivtype='long long', ivsize=8, nvtype='double', nvsize=8,
Off_t='off_t', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='g++', ldflags =' -Wl,--enable-auto-import
-Wl,--export-all-symbols -Wl,--stack,8388608
-Wl,--enable-auto-image-base -L/usr/local/lib'
  libpth=/usr/local/lib /usr/lib /lib
  libs=-lgdbm -ldb -ldl -lcrypt -lgdbm_compat
  perllibs=-ldl -lcrypt -lgdbm_compat
  libc=/usr/lib/libc.a, so=dll, useshrplib=true, libperl=libperl.a
  gnulibc_version=''
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
  cccdlflags=' ', lddlflags=' --shared -Wl,--enable-auto-import
-Wl,--export-all-symbols -Wl,--stack,8388608
-Wl,--enable-auto-image-base -L/usr/local/lib'

Locally applied patches​:
  CYG04 major version
  CYG11 no-bs
  DEVEL


@​INC for perl 5.11.0​:
  /usr/lib/perl5/5.11/i686-debug-cygwin
  /usr/lib/perl5/5.11
  /usr/lib/perl5/site_perl/5.11/i686-debug-cygwin
  /usr/lib/perl5/site_perl/5.11
  /usr/lib/perl5/vendor_perl/5.11/i686-debug-cygwin
  /usr/lib/perl5/vendor_perl/5.11
  /usr/lib/perl5/vendor_perl/5.11
  /usr/lib/perl5/site_perl/5.10
  /usr/lib/perl5/site_perl/5.8
  .


Environment for perl 5.11.0​:
  HOME=/home/URBANR
  LANG (unset)
  LANGUAGE (unset)
  LD_LIBRARY_PATH (unset)
  LOGDIR (unset)
  PATH=/home/URBANR/bin​:/usr/local/bin​:/usr/bin​:/bin​:/usr/X11R6/bin​:/cygdrive/c/WINDOWS/System32​:/cygdrive/c/WINDOWS​:/cygdrive/c/WINDOWS/System32/WBEM​:/cygdrive/c/PROGRA1/ATT/Graphviz/bin​:/cygdrive/c/PROGRA1/ATT/Graphviz/bin/tools​:/usr/lib/lapack
  PERL_BADLANG (unset)
  SHELL (unset)

@p5pRT
Copy link
Author

p5pRT commented Jun 1, 2008

From @rurban

File​::Spec Cygwin/Win32 case_tolerant improvement patches for 5.10 and
blead are attached, which fix bug #55162.

The Module-Build tests in core, like
lib/CPANPLUS/Dist/Build/t/02_CPANPLUS-Dist-Build.t
went from 5minutes to 10 seconds.

Initially I searched for accessing not-available network paths like //
as in the recent
Module​::Install patch, but it was just accessive usage of run-time
eval {require Win32API​::​:File}
and unnecessary case_tolerant calls.
--
Reini Urban
http​://phpwiki.org/ http​://murbreak.at/

@p5pRT
Copy link
Author

p5pRT commented Jun 1, 2008

From @rurban

pl-CYG18-case_tol-510.patch
difforig perl-5.10.0/lib/File

2008-06-01 rurban@cpan.org
	* File::Spec->case_tolerant performance improvement on cygwin and Win32.
	Esp. noticable in Module::Build. 

diff -u  perl-5.10.0/lib/File/Spec.pm.orig
--- perl-5.10.0/lib/File/Spec.pm.orig	2007-12-18 11:47:07.000000000 +0100
+++ perl-5.10.0/lib/File/Spec.pm	2008-06-01 14:02:07.687500000 +0200
@@ -3,7 +3,7 @@
 use strict;
 use vars qw(@ISA $VERSION);
 
-$VERSION = '3.2501';
+$VERSION = '3.2502';
 $VERSION = eval $VERSION;
 
 my %module = (MacOS   => 'Mac',
diff -u  perl-5.10.0/lib/File/Spec/Cygwin.pm.orig
--- perl-5.10.0/lib/File/Spec/Cygwin.pm.orig	2007-12-18 11:47:07.000000000 +0100
+++ perl-5.10.0/lib/File/Spec/Cygwin.pm	2008-06-01 14:02:16.671875000 +0200
@@ -4,7 +4,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2501';
+$VERSION = '3.2502';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -104,16 +104,23 @@
 Override Unix. Cygwin case-tolerance depends on managed mount settings and
 as with MsWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
+Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem. (TODO)
+See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-mount argument.
 Default: 1
 
 =cut
 
+my %tmp_case_tolerant;
 sub case_tolerant () {
   if ($^O ne 'cygwin') {
     return 1;
   }
   my $drive = shift;
+  $drive = shift if $drive =~ /^File::Spec/;
+  my $windrive;
   if (! $drive) {
+      $windrive = 'C:';
       my @flags = split(/,/, Cygwin::mount_flags('/cygwin'));
       my $prefix = pop(@flags);
       if (! $prefix || $prefix eq 'cygdrive') {
@@ -123,18 +130,19 @@
       } else {
           $drive = "$prefix/c";
       }
+  } else {
+      $windrive = Cygwin::posix_to_win_path($drive);
   }
+  return $tmp_case_tolerant{$drive} if exists $tmp_case_tolerant{$drive};
   my $mntopts = Cygwin::mount_flags($drive);
   if ($mntopts and ($mntopts =~ /,managed/)) {
+    $tmp_case_tolerant{$drive} = 0;
     return 0;
   }
-  eval { require Win32API::File; } or return 1;
-  my $osFsType = "\0"x256;
-  my $osVolName = "\0"x256;
-  my $ouFsFlags = 0;
-  Win32API::File::GetVolumeInformation($drive, $osVolName, 256, [], [], $ouFsFlags, $osFsType, 256 );
-  if ($ouFsFlags & Win32API::File::FS_CASE_SENSITIVE()) { return 0; }
-  else { return 1; }
+  require File::Spec::Win32;
+  $windrive =~ s/\\$//;
+  $tmp_case_tolerant{$drive} = File::Spec::Win32::case_tolerant($windrive);
+  return $tmp_case_tolerant{$drive};
 }
 
 =back
diff -u  perl-5.10.0/lib/File/Spec/Win32.pm.orig
--- perl-5.10.0/lib/File/Spec/Win32.pm.orig	2007-12-18 11:47:07.000000000 +0100
+++ perl-5.10.0/lib/File/Spec/Win32.pm	2008-06-01 14:02:25.312500000 +0200
@@ -5,7 +5,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2501';
+$VERSION = '3.2502';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -83,13 +83,21 @@
 indicating the case significance when comparing file specifications.
 Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem.
 See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-letter argument.
 Default: 1
 
 =cut
 
 sub case_tolerant () {
+  use Win32;
+  my @ver = Win32::GetOSVersion();
+  # From XP on this is disabled.
+  if ($ver[4] >= 2 and $ver[1] >= 5 and $ver[2] >= 1) { return 1; }
+  if ($ver[4] < 2) { return 1; } # Win32s,95,ME are always case_tolerant.
   eval { require Win32API::File; } or return 1;
-  my $drive = shift || "C:";
+  my $drive = shift || "C:";
+
+  $drive = shift if $drive =~ /^File::Spec/;
   my $osFsType = "\0"x256;
   my $osVolName = "\0"x256;
   my $ouFsFlags = 0;

@p5pRT
Copy link
Author

p5pRT commented Jun 1, 2008

From @rurban

pl-CYG18-case_tol-511.patch
difforig perl-current/lib/File

2008-06-01 rurban@cpan.org
	* File::Spec->case_tolerant performance improvement on cygwin and Win32.
	Esp. noticable in Module::Build. 

diff -u  perl-current/lib/File/Spec.pm.orig
--- perl-current/lib/File/Spec.pm.orig	2008-02-12 16:12:46.000000000 +0100
+++ perl-current/lib/File/Spec.pm	2008-06-01 14:10:03.703125000 +0200
@@ -3,7 +3,7 @@
 use strict;
 use vars qw(@ISA $VERSION);
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 $VERSION = eval $VERSION;
 
 my %module = (MacOS   => 'Mac',
@@ -166,6 +166,7 @@
 
 Returns a true or false value indicating, respectively, that alphabetic
 case is not or is significant when comparing file specifications.
+Cygwin and Win32 accept an optional drive argument.
 
     $is_case_tolerant = File::Spec->case_tolerant();
 
diff -u  perl-current/lib/File/Spec/Cygwin.pm.orig
--- perl-current/lib/File/Spec/Cygwin.pm.orig	2008-02-12 16:12:46.000000000 +0100
+++ perl-current/lib/File/Spec/Cygwin.pm	2008-06-01 14:08:20.781250000 +0200
@@ -4,7 +4,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -107,16 +107,23 @@
 Override Unix. Cygwin case-tolerance depends on managed mount settings and
 as with MsWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
+Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem. (TODO)
+See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-mount argument.
 Default: 1
 
 =cut
 
+my %tmp_case_tolerant;
 sub case_tolerant () {
   return 1 unless $^O eq 'cygwin'
     and defined &Cygwin::mount_flags;
 
   my $drive = shift;
+  $drive = shift if $drive =~ /^File::Spec/;
+  my $windrive;
   if (! $drive) {
+      $windrive = 'C:';
       my @flags = split(/,/, Cygwin::mount_flags('/cygwin'));
       my $prefix = pop(@flags);
       if (! $prefix || $prefix eq 'cygdrive') {
@@ -126,18 +133,19 @@
       } else {
           $drive = "$prefix/c";
       }
+  } else {
+      $windrive = Cygwin::posix_to_win_path($drive);
   }
+  return $tmp_case_tolerant{$drive} if exists $tmp_case_tolerant{$drive};
   my $mntopts = Cygwin::mount_flags($drive);
   if ($mntopts and ($mntopts =~ /,managed/)) {
+    $tmp_case_tolerant{$drive} = 0;
     return 0;
   }
-  eval { require Win32API::File; } or return 1;
-  my $osFsType = "\0"x256;
-  my $osVolName = "\0"x256;
-  my $ouFsFlags = 0;
-  Win32API::File::GetVolumeInformation($drive, $osVolName, 256, [], [], $ouFsFlags, $osFsType, 256 );
-  if ($ouFsFlags & Win32API::File::FS_CASE_SENSITIVE()) { return 0; }
-  else { return 1; }
+  require File::Spec::Win32;
+  $windrive =~ s/\\$//;
+  $tmp_case_tolerant{$drive} = File::Spec::Win32::case_tolerant($windrive);
+  return $tmp_case_tolerant{$drive};
 }
 
 =back
diff -u  perl-current/lib/File/Spec/Win32.pm.orig
--- perl-current/lib/File/Spec/Win32.pm.orig	2008-02-12 16:12:47.000000000 +0100
+++ perl-current/lib/File/Spec/Win32.pm	2008-06-01 14:08:57.250000000 +0200
@@ -5,7 +5,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -83,13 +83,21 @@
 indicating the case significance when comparing file specifications.
 Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem.
 See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-letter argument.
 Default: 1
 
 =cut
 
 sub case_tolerant () {
+  use Win32;
+  my @ver = Win32::GetOSVersion();
+  # From XP on this is disabled.
+  if ($ver[4] >= 2 and $ver[1] >= 5 and $ver[2] >= 1) { return 1; }
+  if ($ver[4] < 2) { return 1; } # Win32s,95,ME are always case_tolerant.
   eval { require Win32API::File; } or return 1;
-  my $drive = shift || "C:";
+  my $drive = shift || "C:";Accepts on optional drive-letter argument.
+
+  $drive = shift if $drive =~ /^File::Spec/;
   my $osFsType = "\0"x256;
   my $osVolName = "\0"x256;
   my $ouFsFlags = 0;

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

From @smpeters

On Sun Jun 01 06​:09​:03 2008, rurban wrote​:

File​::Spec Cygwin/Win32 case_tolerant improvement patches for 5.10 and
blead are attached, which fix bug #55162.

The Module-Build tests in core, like
lib/CPANPLUS/Dist/Build/t/02_CPANPLUS-Dist-Build.t
went from 5minutes to 10 seconds.

Initially I searched for accessing not-available network paths like //
as in the recent
Module​::Install patch, but it was just accessive usage of run-time
eval {require Win32API​::​:File}
and unnecessary case_tolerant calls.

From the 5.11 patch...

+ my $drive = shift || "C​:";Accepts on optional drive-letter argument.

I don't believe this code will compile after the patch is applied. Can
you please double-check your code, and provide a new patch.

Thanks,

Steve Peters

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

From @rurban

Sorry I thought that I already uploaded the revised patches, since the
original ones had syntax errors. Weird XEmacs auto-paste problems.
--
Reini Urban

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

From @rurban

pl-CYG18-case_tol-510.patch
difforig perl-5.10.0/lib/File

2008-06-01 rurban@cpan.org
	* File::Spec->case_tolerant performance improvement on cygwin and Win32.
	Esp. noticable in Module::Build. 

diff -u  perl-5.10.0/lib/File/Spec.pm.orig
--- perl-5.10.0/lib/File/Spec.pm.orig	2007-12-18 11:47:07.000000000 +0100
+++ perl-5.10.0/lib/File/Spec.pm	2008-06-01 14:02:07.687500000 +0200
@@ -3,7 +3,7 @@
 use strict;
 use vars qw(@ISA $VERSION);
 
-$VERSION = '3.2501';
+$VERSION = '3.2502';
 $VERSION = eval $VERSION;
 
 my %module = (MacOS   => 'Mac',
diff -u  perl-5.10.0/lib/File/Spec/Cygwin.pm.orig
--- perl-5.10.0/lib/File/Spec/Cygwin.pm.orig	2007-12-18 11:47:07.000000000 +0100
+++ perl-5.10.0/lib/File/Spec/Cygwin.pm	2008-06-01 14:02:16.671875000 +0200
@@ -4,7 +4,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2501';
+$VERSION = '3.2502';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -104,16 +104,23 @@
 Override Unix. Cygwin case-tolerance depends on managed mount settings and
 as with MsWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
+Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem. (TODO)
+See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-mount argument.
 Default: 1
 
 =cut
 
+my %tmp_case_tolerant;
 sub case_tolerant () {
   if ($^O ne 'cygwin') {
     return 1;
   }
   my $drive = shift;
+  $drive = shift if $drive =~ /^File::Spec/;
+  my $windrive;
   if (! $drive) {
+      $windrive = 'C:';
       my @flags = split(/,/, Cygwin::mount_flags('/cygwin'));
       my $prefix = pop(@flags);
       if (! $prefix || $prefix eq 'cygdrive') {
@@ -123,18 +130,19 @@
       } else {
           $drive = "$prefix/c";
       }
+  } else {
+      $windrive = Cygwin::posix_to_win_path($drive);
   }
+  return $tmp_case_tolerant{$drive} if exists $tmp_case_tolerant{$drive};
   my $mntopts = Cygwin::mount_flags($drive);
   if ($mntopts and ($mntopts =~ /,managed/)) {
+    $tmp_case_tolerant{$drive} = 0;
     return 0;
   }
-  eval { require Win32API::File; } or return 1;
-  my $osFsType = "\0"x256;
-  my $osVolName = "\0"x256;
-  my $ouFsFlags = 0;
-  Win32API::File::GetVolumeInformation($drive, $osVolName, 256, [], [], $ouFsFlags, $osFsType, 256 );
-  if ($ouFsFlags & Win32API::File::FS_CASE_SENSITIVE()) { return 0; }
-  else { return 1; }
+  require File::Spec::Win32;
+  $windrive =~ s/\\$//;
+  $tmp_case_tolerant{$drive} = File::Spec::Win32::case_tolerant($windrive);
+  return $tmp_case_tolerant{$drive};
 }
 
 =back
diff -u  perl-5.10.0/lib/File/Spec/Win32.pm.orig
--- perl-5.10.0/lib/File/Spec/Win32.pm.orig	2007-12-18 11:47:07.000000000 +0100
+++ perl-5.10.0/lib/File/Spec/Win32.pm	2008-06-01 14:02:25.312500000 +0200
@@ -5,7 +5,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2501';
+$VERSION = '3.2502';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -83,13 +83,21 @@
 indicating the case significance when comparing file specifications.
 Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem.
 See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-letter argument.
 Default: 1
 
 =cut
 
 sub case_tolerant () {
+  use Win32;
+  my @ver = Win32::GetOSVersion();
+  # From XP on this is disabled.
+  if ($ver[4] >= 2 and $ver[1] >= 5 and $ver[2] >= 1) { return 1; }
+  if ($ver[4] < 2) { return 1; } # Win32s,95,ME are always case_tolerant.
   eval { require Win32API::File; } or return 1;
-  my $drive = shift || "C:";
+  my $drive = shift || "C:";
+
+  $drive = shift if $drive =~ /^File::Spec/;
   my $osFsType = "\0"x256;
   my $osVolName = "\0"x256;
   my $ouFsFlags = 0;

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

From @rurban

pl-CYG18-case_tol-511.patch
difforig perl-current/lib/File

2008-06-01 rurban@cpan.org
	* File::Spec->case_tolerant performance improvement on cygwin and Win32.
	Esp. noticable in Module::Build.
	http://rt.perl.org/rt3/Ticket/Display.html?id=55162

diff -u  perl-current/lib/File/Spec.pm.orig
--- perl-current/lib/File/Spec.pm.orig	2008-02-12 16:12:46.000000000 +0100
+++ perl-current/lib/File/Spec.pm	2008-06-01 14:10:03.703125000 +0200
@@ -3,7 +3,7 @@
 use strict;
 use vars qw(@ISA $VERSION);
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 $VERSION = eval $VERSION;
 
 my %module = (MacOS   => 'Mac',
@@ -166,6 +166,7 @@
 
 Returns a true or false value indicating, respectively, that alphabetic
 case is not or is significant when comparing file specifications.
+Cygwin and Win32 accept an optional drive argument.
 
     $is_case_tolerant = File::Spec->case_tolerant();
 
diff -u  perl-current/lib/File/Spec/Cygwin.pm.orig
--- perl-current/lib/File/Spec/Cygwin.pm.orig	2008-02-12 16:12:46.000000000 +0100
+++ perl-current/lib/File/Spec/Cygwin.pm	2008-06-01 14:08:20.781250000 +0200
@@ -4,7 +4,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -107,16 +107,23 @@
 Override Unix. Cygwin case-tolerance depends on managed mount settings and
 as with MsWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
+Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem. (TODO)
+See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-mount argument.
 Default: 1
 
 =cut
 
+my %tmp_case_tolerant;
 sub case_tolerant () {
   return 1 unless $^O eq 'cygwin'
     and defined &Cygwin::mount_flags;
 
   my $drive = shift;
+  $drive = shift if $drive =~ /^File::Spec/;
+  my $windrive;
   if (! $drive) {
+      $windrive = 'C:';
       my @flags = split(/,/, Cygwin::mount_flags('/cygwin'));
       my $prefix = pop(@flags);
       if (! $prefix || $prefix eq 'cygdrive') {
@@ -126,18 +133,19 @@
       } else {
           $drive = "$prefix/c";
       }
+  } else {
+      $windrive = Cygwin::posix_to_win_path($drive);
   }
+  return $tmp_case_tolerant{$drive} if exists $tmp_case_tolerant{$drive};
   my $mntopts = Cygwin::mount_flags($drive);
   if ($mntopts and ($mntopts =~ /,managed/)) {
+    $tmp_case_tolerant{$drive} = 0;
     return 0;
   }
-  eval { require Win32API::File; } or return 1;
-  my $osFsType = "\0"x256;
-  my $osVolName = "\0"x256;
-  my $ouFsFlags = 0;
-  Win32API::File::GetVolumeInformation($drive, $osVolName, 256, [], [], $ouFsFlags, $osFsType, 256 );
-  if ($ouFsFlags & Win32API::File::FS_CASE_SENSITIVE()) { return 0; }
-  else { return 1; }
+  require File::Spec::Win32;
+  $windrive =~ s/\\$//;
+  $tmp_case_tolerant{$drive} = File::Spec::Win32::case_tolerant($windrive);
+  return $tmp_case_tolerant{$drive};
 }
 
 =back
diff -u  perl-current/lib/File/Spec/Win32.pm.orig
--- perl-current/lib/File/Spec/Win32.pm.orig	2008-02-12 16:12:47.000000000 +0100
+++ perl-current/lib/File/Spec/Win32.pm	2008-06-01 14:08:57.250000000 +0200
@@ -5,7 +5,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -83,13 +83,21 @@
 indicating the case significance when comparing file specifications.
 Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem.
 See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-letter argument.
 Default: 1
 
 =cut
 
 sub case_tolerant () {
+  use Win32;
+  my @ver = Win32::GetOSVersion();
+  # From XP on this is disabled.
+  if ($ver[4] >= 2 and $ver[1] >= 5 and $ver[2] >= 1) { return 1; }
+  if ($ver[4] < 2) { return 1; } # Win32s,95,ME are always case_tolerant.
   eval { require Win32API::File; } or return 1;
-  my $drive = shift || "C:";
+  my $drive = shift || "C:";Accepts on optional drive-letter argument.
+
+  $drive = shift if $drive =~ /^File::Spec/;
   my $osFsType = "\0"x256;
   my $osVolName = "\0"x256;
   my $ouFsFlags = 0;

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

From [Unknown Contact. See original ticket]

Sorry I thought that I already uploaded the revised patches, since the
original ones had syntax errors. Weird XEmacs auto-paste problems.
--
Reini Urban

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

From @rurban

Oops, I did it again.
Attached is the fixed 511 - blead patch without syntax error.

--
Reini Urban

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

From @rurban

pl-CYG18-case_tol-511.patch
difforig perl-current/lib/File

2008-06-01 rurban@cpan.org
	* File::Spec->case_tolerant performance improvement on cygwin and Win32.
	Esp. noticable in Module::Build.
	http://rt.perl.org/rt3/Ticket/Display.html?id=55162

diff -u  perl-current/lib/File/Spec.pm.orig
--- perl-current/lib/File/Spec.pm.orig	2008-02-12 16:12:46.000000000 +0100
+++ perl-current/lib/File/Spec.pm	2008-06-01 14:10:03.703125000 +0200
@@ -3,7 +3,7 @@
 use strict;
 use vars qw(@ISA $VERSION);
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 $VERSION = eval $VERSION;
 
 my %module = (MacOS   => 'Mac',
@@ -166,6 +166,7 @@
 
 Returns a true or false value indicating, respectively, that alphabetic
 case is not or is significant when comparing file specifications.
+Cygwin and Win32 accept an optional drive argument.
 
     $is_case_tolerant = File::Spec->case_tolerant();
 
diff -u  perl-current/lib/File/Spec/Cygwin.pm.orig
--- perl-current/lib/File/Spec/Cygwin.pm.orig	2008-02-12 16:12:46.000000000 +0100
+++ perl-current/lib/File/Spec/Cygwin.pm	2008-06-01 14:08:20.781250000 +0200
@@ -4,7 +4,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -107,16 +107,23 @@
 Override Unix. Cygwin case-tolerance depends on managed mount settings and
 as with MsWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
+Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem. (TODO)
+See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-mount argument.
 Default: 1
 
 =cut
 
+my %tmp_case_tolerant;
 sub case_tolerant () {
   return 1 unless $^O eq 'cygwin'
     and defined &Cygwin::mount_flags;
 
   my $drive = shift;
+  $drive = shift if $drive =~ /^File::Spec/;
+  my $windrive;
   if (! $drive) {
+      $windrive = 'C:';
       my @flags = split(/,/, Cygwin::mount_flags('/cygwin'));
       my $prefix = pop(@flags);
       if (! $prefix || $prefix eq 'cygdrive') {
@@ -126,18 +133,19 @@
       } else {
           $drive = "$prefix/c";
       }
+  } else {
+      $windrive = Cygwin::posix_to_win_path($drive);
   }
+  return $tmp_case_tolerant{$drive} if exists $tmp_case_tolerant{$drive};
   my $mntopts = Cygwin::mount_flags($drive);
   if ($mntopts and ($mntopts =~ /,managed/)) {
+    $tmp_case_tolerant{$drive} = 0;
     return 0;
   }
-  eval { require Win32API::File; } or return 1;
-  my $osFsType = "\0"x256;
-  my $osVolName = "\0"x256;
-  my $ouFsFlags = 0;
-  Win32API::File::GetVolumeInformation($drive, $osVolName, 256, [], [], $ouFsFlags, $osFsType, 256 );
-  if ($ouFsFlags & Win32API::File::FS_CASE_SENSITIVE()) { return 0; }
-  else { return 1; }
+  require File::Spec::Win32;
+  $windrive =~ s/\\$//;
+  $tmp_case_tolerant{$drive} = File::Spec::Win32::case_tolerant($windrive);
+  return $tmp_case_tolerant{$drive};
 }
 
 =back
diff -u  perl-current/lib/File/Spec/Win32.pm.orig
--- perl-current/lib/File/Spec/Win32.pm.orig	2008-02-12 16:12:47.000000000 +0100
+++ perl-current/lib/File/Spec/Win32.pm	2008-06-01 14:08:57.250000000 +0200
@@ -5,7 +5,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -83,13 +83,21 @@
 indicating the case significance when comparing file specifications.
 Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem.
 See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-letter argument.
 Default: 1
 
 =cut
 
 sub case_tolerant () {
+  use Win32;
+  my @ver = Win32::GetOSVersion();
+  # From XP on this is disabled.
+  if ($ver[4] >= 2 and $ver[1] >= 5 and $ver[2] >= 1) { return 1; }
+  if ($ver[4] < 2) { return 1; } # Win32s,95,ME are always case_tolerant.
   eval { require Win32API::File; } or return 1;
-  my $drive = shift || "C:";
+  my $drive = shift || "C:";
+
+  $drive = shift if $drive =~ /^File::Spec/;
   my $osFsType = "\0"x256;
   my $osVolName = "\0"x256;
   my $ouFsFlags = 0;

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

From @jandubois

On Mon, 02 Jun 2008, Reini Urban via RT wrote​:

Oops, I did it again.

My eyes! The goggles do nothing!

Attached is the fixed 511 - blead patch without
syntax error.

I don't like the hard-coded "C​:" in your patch. Assuming you want to
specify the drive where Windows itself was installed, you should
write something like this​:

  drive ||= $ENV{SYSTEMDRIVE} || substr($ENV{WINDIR}, 0, 2);

The reference to WINDIR is only for Win9X, which doesn't have
SYSTEMDRIVE. You could also probably just use WINDIR everywhere.

Cheers,
-Jan

PS​: If you do another patch to the file, could you also do
  s/MsWin32/MSWin32/g as well? Thanks!

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

From @rurban

Jan Dubois schrieb​:

On Mon, 02 Jun 2008, Reini Urban via RT wrote​:

Oops, I did it again.
My eyes! The goggles do nothing!

Attached is the fixed 511 - blead patch without
syntax error.

I don't like the hard-coded "C​:" in your patch. Assuming you want to
specify the drive where Windows itself was installed, you should
write something like this​:

No.

case_tolerant is normally used platform-specific only, and not
drive-specific. So the 99% usecase is without any argument,
hence just C​: (first drive) and not SYSTEMDRIVE // WINDIR

Only if someone really wants to check a drive, the hairy code is used,
with C​: being the default.

drive ||= $ENV{SYSTEMDRIVE} || substr($ENV{WINDIR}, 0, 2);

The reference to WINDIR is only for Win9X, which doesn't have
SYSTEMDRIVE. You could also probably just use WINDIR everywhere.

Cheers,
-Jan

PS​: If you do another patch to the file, could you also do
s/MsWin32/MSWin32/g as well? Thanks!

Oops, did I use the ugly "MsWin32". Bad.

Attached is another take, which fixes MsWin32 from last year and some
more bad wordings.
--
Reini Urban
http​://phpwiki.org/ http​://murbreak.at/

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

From @rurban

pl-55162-510.patch
difforig perl-5.10.0/lib/File

diff -u  perl-5.10.0/lib/File/Spec.pm.orig
--- perl-5.10.0/lib/File/Spec.pm.orig	2007-12-18 10:47:07.000000000 +0000
+++ perl-5.10.0/lib/File/Spec.pm	2008-06-01 16:09:16.078125000 +0000
@@ -3,7 +3,7 @@
 use strict;
 use vars qw(@ISA $VERSION);
 
-$VERSION = '3.2501';
+$VERSION = '3.2502';
 $VERSION = eval $VERSION;
 
 my %module = (MacOS   => 'Mac',
diff -u  perl-5.10.0/lib/File/Spec/Cygwin.pm.orig
--- perl-5.10.0/lib/File/Spec/Cygwin.pm.orig	2007-12-18 10:47:07.000000000 +0000
+++ perl-5.10.0/lib/File/Spec/Cygwin.pm	2008-06-02 21:09:15.703125000 +0000
@@ -4,7 +4,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2501';
+$VERSION = '3.2502';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -102,18 +102,23 @@
 =item case_tolerant
 
 Override Unix. Cygwin case-tolerance depends on managed mount settings and
-as with MsWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
+as with MSWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
+Accepts an optional drive-mount argument.
 Default: 1
 
 =cut
 
+my %tmp_case_tolerant;
 sub case_tolerant () {
   if ($^O ne 'cygwin') {
     return 1;
   }
   my $drive = shift;
+  $drive = shift if $drive =~ /^File::Spec/;
+  my $windrive;
   if (! $drive) {
+      $windrive = 'C:';
       my @flags = split(/,/, Cygwin::mount_flags('/cygwin'));
       my $prefix = pop(@flags);
       if (! $prefix || $prefix eq 'cygdrive') {
@@ -123,18 +128,19 @@
       } else {
           $drive = "$prefix/c";
       }
+  } else {
+      $windrive = Cygwin::posix_to_win_path($drive);
   }
+  return $tmp_case_tolerant{$drive} if exists $tmp_case_tolerant{$drive};
   my $mntopts = Cygwin::mount_flags($drive);
   if ($mntopts and ($mntopts =~ /,managed/)) {
+    $tmp_case_tolerant{$drive} = 0;
     return 0;
   }
-  eval { require Win32API::File; } or return 1;
-  my $osFsType = "\0"x256;
-  my $osVolName = "\0"x256;
-  my $ouFsFlags = 0;
-  Win32API::File::GetVolumeInformation($drive, $osVolName, 256, [], [], $ouFsFlags, $osFsType, 256 );
-  if ($ouFsFlags & Win32API::File::FS_CASE_SENSITIVE()) { return 0; }
-  else { return 1; }
+  require File::Spec::Win32;
+  $windrive =~ s/\\$//;
+  $tmp_case_tolerant{$drive} = File::Spec::Win32::case_tolerant($windrive);
+  return $tmp_case_tolerant{$drive};
 }
 
 =back
diff -u  perl-5.10.0/lib/File/Spec/Win32.pm.orig
--- perl-5.10.0/lib/File/Spec/Win32.pm.orig	2007-12-18 10:47:07.000000000 +0000
+++ perl-5.10.0/lib/File/Spec/Win32.pm	2008-06-02 21:08:55.671875000 +0000
@@ -5,7 +5,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2501';
+$VERSION = '3.2502';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -81,15 +81,23 @@
 
 MSWin32 case-tolerance depends on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
-Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem.
+Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsystem.
 See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-letter argument.
 Default: 1
 
 =cut
 
 sub case_tolerant () {
+  use Win32;
+  my @ver = Win32::GetOSVersion();
+  # From XP on this is disabled.
+  if ($ver[4] >= 2 and $ver[1] >= 5 and $ver[2] >= 1) { return 1; }
+  if ($ver[4] < 2) { return 1; } # Win32s,95,ME are always case_tolerant.
   eval { require Win32API::File; } or return 1;
   my $drive = shift || "C:";
+
+  $drive = shift if $drive =~ /^File::Spec/;
   my $osFsType = "\0"x256;
   my $osVolName = "\0"x256;
   my $ouFsFlags = 0;

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

From @rurban

pl-55162-511.patch
difforig perl-current/lib/File

diff -u  perl-current/lib/File/Spec.pm.orig
--- perl-current/lib/File/Spec.pm.orig	2008-02-12 15:12:46.000000000 +0000
+++ perl-current/lib/File/Spec.pm	2008-06-02 20:36:40.640625000 +0000
@@ -3,7 +3,7 @@
 use strict;
 use vars qw(@ISA $VERSION);
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 $VERSION = eval $VERSION;
 
 my %module = (MacOS   => 'Mac',
@@ -166,6 +166,7 @@
 
 Returns a true or false value indicating, respectively, that alphabetic
 case is not or is significant when comparing file specifications.
+Cygwin and Win32 accept an optional drive argument.
 
     $is_case_tolerant = File::Spec->case_tolerant();
 
diff -u  perl-current/lib/File/Spec/Cygwin.pm.orig
--- perl-current/lib/File/Spec/Cygwin.pm.orig	2008-02-12 15:12:46.000000000 +0000
+++ perl-current/lib/File/Spec/Cygwin.pm	2008-06-02 21:09:35.703125000 +0000
@@ -4,7 +4,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -105,18 +105,23 @@
 =item case_tolerant
 
 Override Unix. Cygwin case-tolerance depends on managed mount settings and
-as with MsWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
+as with MSWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
+Accepts an optional drive-mount argument.
 Default: 1
 
 =cut
 
+my %tmp_case_tolerant;
 sub case_tolerant () {
   return 1 unless $^O eq 'cygwin'
     and defined &Cygwin::mount_flags;
 
   my $drive = shift;
+  $drive = shift if $drive =~ /^File::Spec/;
+  my $windrive;
   if (! $drive) {
+      $windrive = 'C:';
       my @flags = split(/,/, Cygwin::mount_flags('/cygwin'));
       my $prefix = pop(@flags);
       if (! $prefix || $prefix eq 'cygdrive') {
@@ -126,18 +131,19 @@
       } else {
           $drive = "$prefix/c";
       }
+  } else {
+      $windrive = Cygwin::posix_to_win_path($drive);
   }
+  return $tmp_case_tolerant{$drive} if exists $tmp_case_tolerant{$drive};
   my $mntopts = Cygwin::mount_flags($drive);
   if ($mntopts and ($mntopts =~ /,managed/)) {
+    $tmp_case_tolerant{$drive} = 0;
     return 0;
   }
-  eval { require Win32API::File; } or return 1;
-  my $osFsType = "\0"x256;
-  my $osVolName = "\0"x256;
-  my $ouFsFlags = 0;
-  Win32API::File::GetVolumeInformation($drive, $osVolName, 256, [], [], $ouFsFlags, $osFsType, 256 );
-  if ($ouFsFlags & Win32API::File::FS_CASE_SENSITIVE()) { return 0; }
-  else { return 1; }
+  require File::Spec::Win32;
+  $windrive =~ s/\\$//;
+  $tmp_case_tolerant{$drive} = File::Spec::Win32::case_tolerant($windrive);
+  return $tmp_case_tolerant{$drive};
 }
 
 =back
diff -u  perl-current/lib/File/Spec/Win32.pm.orig
--- perl-current/lib/File/Spec/Win32.pm.orig	2008-02-12 15:12:47.000000000 +0000
+++ perl-current/lib/File/Spec/Win32.pm	2008-06-02 21:09:49.843750000 +0000
@@ -5,7 +5,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -81,15 +81,23 @@
 
 MSWin32 case-tolerance depends on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
-Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem.
+Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsystem.
 See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-letter argument.
 Default: 1
 
 =cut
 
 sub case_tolerant () {
+  use Win32;
+  my @ver = Win32::GetOSVersion();
+  # From XP on this is disabled.
+  if ($ver[4] >= 2 and $ver[1] >= 5 and $ver[2] >= 1) { return 1; }
+  if ($ver[4] < 2) { return 1; } # Win32s,95,ME are always case_tolerant.
   eval { require Win32API::File; } or return 1;
-  my $drive = shift || "C:";
+  my $drive = shift || "C:";Accepts on optional drive-letter argument.
+
+  $drive = shift if $drive =~ /^File::Spec/;
   my $osFsType = "\0"x256;
   my $osVolName = "\0"x256;
   my $ouFsFlags = 0;

@p5pRT
Copy link
Author

p5pRT commented Jun 2, 2008

From @jandubois

On Mon, 02 Jun 2008, Reini Urban wrote​:

Jan Dubois schrieb​:

I don't like the hard-coded "C​:" in your patch. Assuming you want to
specify the drive where Windows itself was installed, you should
write something like this​:

No.

case_tolerant is normally used platform-specific only, and not
drive-specific. So the 99% usecase is without any argument,
hence just C​: (first drive) and not SYSTEMDRIVE // WINDIR

I don't really understand what you are saying here. For example it
is definitely possible to have an XP system that doesn't even have
a C​: drive at all, so assuming that C​: is always available and the
first drive in the machine doesn't always hold. The only drive that
MUST be there is the SYSTEMDRIVE, because this is where the OS itself
and the local user profiles are installed.

Cheers,
-Jan

@p5pRT
Copy link
Author

p5pRT commented Jun 3, 2008

From @rurban

2008/6/2 Jan Dubois <jand@​activestate.com>​:

On Mon, 02 Jun 2008, Reini Urban wrote​:

Jan Dubois schrieb​:

I don't like the hard-coded "C​:" in your patch. Assuming you want to
specify the drive where Windows itself was installed, you should
write something like this​:

No.

case_tolerant is normally used platform-specific only, and not
drive-specific. So the 99% usecase is without any argument,
hence just C​: (first drive) and not SYSTEMDRIVE // WINDIR

I don't really understand what you are saying here.

The function case_tolerant() has on all other platforms no argument.
And it is used always without.
So this checks the platform specification and not the drive specs.
However case-tolerance is normally mount point / drive-letter specific.
Win32 and Cygwin accept now the drive-letter resp. mount point.
The modules and scripts which use File​::Spec​::case_tolerant should start
using the argument, to make sense. Unix and others ignore it as
long there's no case-tolerant mount point setting involved.
For NFS or samba shares we have known limitations so far.

For example it is definitely possible to have an XP system that doesn't even have
a C​: drive at all, so assuming that C​: is always available and the
first drive in the machine doesn't always hold. The only drive that
MUST be there is the SYSTEMDRIVE, because this is where the OS itself
and the local user profiles are installed.

Ok, I never thought about non-C​: Windows systems.
The cygwin logic is also simplified now.
I also added a comment about the missing mount-point arg.
Ken, okay for you?
Revised patches attached

TODO on Unix​:
Dropped HFS+ its case-intolerancy as announced?
FAT support (memory cards, usb sticks e.g.)
Samba
  check smb.cnf​:
  [global]
  case sensitive = no
NFS​: mount flag -o casesensitive

Don't we have acorn? There's nothing in Configure and no hints for acorn.
The Acorn FS would be case tolerant.
--
Reini Urban
http​://phpwiki.org/ http​://murbreak.at/

@p5pRT
Copy link
Author

p5pRT commented Jun 3, 2008

From @rurban

pl-CYG18-case_tol-510.patch
difforig perl-5.10.0/lib/File

diff -u  perl-5.10.0/lib/File/Spec.pm.orig
--- perl-5.10.0/lib/File/Spec.pm.orig	2007-12-18 11:47:07.000000000 +0100
+++ perl-5.10.0/lib/File/Spec.pm	2008-06-01 18:01:25.890625000 +0200
@@ -3,7 +3,7 @@
 use strict;
 use vars qw(@ISA $VERSION);
 
-$VERSION = '3.2501';
+$VERSION = '3.2502';
 $VERSION = eval $VERSION;
 
 my %module = (MacOS   => 'Mac',
diff -u  perl-5.10.0/lib/File/Spec/Cygwin.pm.orig
--- perl-5.10.0/lib/File/Spec/Cygwin.pm.orig	2007-12-18 11:47:07.000000000 +0100
+++ perl-5.10.0/lib/File/Spec/Cygwin.pm	2008-06-03 15:37:40.421875000 +0200
@@ -4,7 +4,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2501';
+$VERSION = '3.2502';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -102,39 +102,37 @@
 =item case_tolerant
 
 Override Unix. Cygwin case-tolerance depends on managed mount settings and
-as with MsWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
+as with MSWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
+Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsystem.
+See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-mount argument.
 Default: 1
 
 =cut
 
+my %tmp_case_tolerant;
 sub case_tolerant () {
-  if ($^O ne 'cygwin') {
-    return 1;
-  }
+  return 1 unless $^O eq 'cygwin'
+    and defined &Cygwin::mount_flags;
+
   my $drive = shift;
+  $drive = shift if $drive =~ /^File::Spec/;
+  my $windrive;
   if (! $drive) {
-      my @flags = split(/,/, Cygwin::mount_flags('/cygwin'));
-      my $prefix = pop(@flags);
-      if (! $prefix || $prefix eq 'cygdrive') {
-          $drive = '/cygdrive/c';
-      } elsif ($prefix eq '/') {
-          $drive = '/c';
-      } else {
-          $drive = "$prefix/c";
-      }
+      $windrive = $ENV{SYSTEMDRIVE} || substr($ENV{WINDIR}, 0, 2);
+      $drive = Cygwin::win_to_posix_path($windrive."\\");
   }
+  return $tmp_case_tolerant{$drive} if exists $tmp_case_tolerant{$drive};
   my $mntopts = Cygwin::mount_flags($drive);
   if ($mntopts and ($mntopts =~ /,managed/)) {
+    $tmp_case_tolerant{$drive} = 0;
     return 0;
   }
-  eval { require Win32API::File; } or return 1;
-  my $osFsType = "\0"x256;
-  my $osVolName = "\0"x256;
-  my $ouFsFlags = 0;
-  Win32API::File::GetVolumeInformation($drive, $osVolName, 256, [], [], $ouFsFlags, $osFsType, 256 );
-  if ($ouFsFlags & Win32API::File::FS_CASE_SENSITIVE()) { return 0; }
-  else { return 1; }
+  require File::Spec::Win32;
+  $windrive = substr(Cygwin::posix_to_win_path($drive),0,2);
+  $tmp_case_tolerant{$drive} = File::Spec::Win32::case_tolerant($windrive);
+  return $tmp_case_tolerant{$drive};
 }
 
 =back
diff -u  perl-5.10.0/lib/File/Spec/Win32.pm.orig
--- perl-5.10.0/lib/File/Spec/Win32.pm.orig	2007-12-18 11:47:07.000000000 +0100
+++ perl-5.10.0/lib/File/Spec/Win32.pm	2008-06-03 14:33:29.656250000 +0200
@@ -5,7 +5,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2501';
+$VERSION = '3.2502';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -81,15 +81,23 @@
 
 MSWin32 case-tolerance depends on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
-Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem.
+Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsystem.
 See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-letter argument.
 Default: 1
 
 =cut
 
 sub case_tolerant () {
+  use Win32;
+  my @ver = Win32::GetOSVersion();
+  # From XP on this is disabled.
+  if ($ver[4] >= 2 and $ver[1] >= 5 and $ver[2] >= 1) { return 1; }
+  if ($ver[4] < 2) { return 1; } # Win32s,95,ME are always case_tolerant.
   eval { require Win32API::File; } or return 1;
-  my $drive = shift || "C:";
+  my $drive = shift;
+  $drive = shift if $drive =~ /^File::Spec/;
+  $drive ||= $ENV{SYSTEMDRIVE} || substr($ENV{WINDIR}, 0, 2);
   my $osFsType = "\0"x256;
   my $osVolName = "\0"x256;
   my $ouFsFlags = 0;

@p5pRT
Copy link
Author

p5pRT commented Jun 3, 2008

From @rurban

Plus the blead patch.

--
Reini Urban
http​://phpwiki.org/ http​://murbreak.at/

@p5pRT
Copy link
Author

p5pRT commented Jun 3, 2008

From @rurban

pl-CYG18-case_tol-511.patch
difforig perl-current/lib/File

diff -u  perl-current/lib/File/Spec.pm.orig
--- perl-current/lib/File/Spec.pm.orig	2008-02-12 16:12:46.000000000 +0100
+++ perl-current/lib/File/Spec.pm	2008-06-03 16:13:11.359375000 +0200
@@ -3,7 +3,7 @@
 use strict;
 use vars qw(@ISA $VERSION);
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 $VERSION = eval $VERSION;
 
 my %module = (MacOS   => 'Mac',
@@ -166,8 +166,11 @@
 
 Returns a true or false value indicating, respectively, that alphabetic
 case is not or is significant when comparing file specifications.
+Cygwin and Win32 accept an optional mount point resp. drive ("C:") argument.
+On all other platforms the optional mount point argument is ignored.
+TODO: case-insensitive FAT, NFS, Samba mounts on Unix.
 
-    $is_case_tolerant = File::Spec->case_tolerant();
+    $is_case_tolerant = File::Spec->case_tolerant( $mount_point );
 
 =item file_name_is_absolute
 
diff -u  perl-current/lib/File/Spec/Cygwin.pm.orig
--- perl-current/lib/File/Spec/Cygwin.pm.orig	2008-02-12 16:12:46.000000000 +0100
+++ perl-current/lib/File/Spec/Cygwin.pm	2008-06-03 15:39:07.390625000 +0200
@@ -4,7 +4,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -105,39 +105,37 @@
 =item case_tolerant
 
 Override Unix. Cygwin case-tolerance depends on managed mount settings and
-as with MsWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
+as with MSWin32 on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
+Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsystem.
+See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-mount argument.
 Default: 1
 
 =cut
 
+my %tmp_case_tolerant;
 sub case_tolerant () {
   return 1 unless $^O eq 'cygwin'
     and defined &Cygwin::mount_flags;
 
   my $drive = shift;
+  $drive = shift if $drive =~ /^File::Spec/;
+  my $windrive;
   if (! $drive) {
-      my @flags = split(/,/, Cygwin::mount_flags('/cygwin'));
-      my $prefix = pop(@flags);
-      if (! $prefix || $prefix eq 'cygdrive') {
-          $drive = '/cygdrive/c';
-      } elsif ($prefix eq '/') {
-          $drive = '/c';
-      } else {
-          $drive = "$prefix/c";
-      }
+      $windrive = $ENV{SYSTEMDRIVE} || substr($ENV{WINDIR}, 0, 2);
+      $drive = Cygwin::win_to_posix_path($windrive."\\");
   }
+  return $tmp_case_tolerant{$drive} if exists $tmp_case_tolerant{$drive};
   my $mntopts = Cygwin::mount_flags($drive);
   if ($mntopts and ($mntopts =~ /,managed/)) {
+    $tmp_case_tolerant{$drive} = 0;
     return 0;
   }
-  eval { require Win32API::File; } or return 1;
-  my $osFsType = "\0"x256;
-  my $osVolName = "\0"x256;
-  my $ouFsFlags = 0;
-  Win32API::File::GetVolumeInformation($drive, $osVolName, 256, [], [], $ouFsFlags, $osFsType, 256 );
-  if ($ouFsFlags & Win32API::File::FS_CASE_SENSITIVE()) { return 0; }
-  else { return 1; }
+  require File::Spec::Win32;
+  $windrive = substr(Cygwin::posix_to_win_path($drive),0,2);
+  $tmp_case_tolerant{$drive} = File::Spec::Win32::case_tolerant($windrive);
+  return $tmp_case_tolerant{$drive};
 }
 
 =back
diff -u  perl-current/lib/File/Spec/Unix.pm.orig
--- perl-current/lib/File/Spec/Unix.pm.orig	2008-02-12 16:12:47.000000000 +0100
+++ perl-current/lib/File/Spec/Unix.pm	2008-06-03 15:53:40.734375000 +0200
@@ -3,7 +3,7 @@
 use strict;
 use vars qw($VERSION);
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 
 =head1 NAME
 
@@ -42,7 +42,7 @@
 sub canonpath {
     my ($self,$path) = @_;
     return unless defined $path;
-    
+
     # Handle POSIX-style node names beginning with double slash (qnx, nto)
     # (POSIX says: "a pathname that begins with two successive slashes
     # may be interpreted in an implementation-defined manner, although
@@ -187,6 +187,7 @@
 
 Returns a true or false value indicating, respectively, that alphabetic
 is not or is significant when comparing file specifications.
+Todo: Add mount point argument to support case-tolerant NFS and samba shares.
 
 =cut
 
diff -u  perl-current/lib/File/Spec/Win32.pm.orig
--- perl-current/lib/File/Spec/Win32.pm.orig	2008-02-12 16:12:47.000000000 +0100
+++ perl-current/lib/File/Spec/Win32.pm	2008-06-03 14:36:31.843750000 +0200
@@ -5,7 +5,7 @@
 use vars qw(@ISA $VERSION);
 require File::Spec::Unix;
 
-$VERSION = '3.2701';
+$VERSION = '3.2702';
 
 @ISA = qw(File::Spec::Unix);
 
@@ -81,15 +81,23 @@
 
 MSWin32 case-tolerance depends on GetVolumeInformation() $ouFsFlags == FS_CASE_SENSITIVE,
 indicating the case significance when comparing file specifications.
-Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsubsystem.
+Since XP FS_CASE_SENSITIVE is effectively disabled for the NT subsystem.
 See http://cygwin.com/ml/cygwin/2007-07/msg00891.html
+Accepts an optional drive-letter argument.
 Default: 1
 
 =cut
 
 sub case_tolerant () {
+  use Win32;
+  my @ver = Win32::GetOSVersion();
+  # From XP on this is disabled.
+  if ($ver[4] >= 2 and $ver[1] >= 5 and $ver[2] >= 1) { return 1; }
+  if ($ver[4] < 2) { return 1; } # Win32s,95,ME are always case_tolerant.
   eval { require Win32API::File; } or return 1;
-  my $drive = shift || "C:";
+  my $drive = shift;
+  $drive = shift if $drive =~ /^File::Spec/;
+  $drive ||= $ENV{SYSTEMDRIVE} || substr($ENV{WINDIR}, 0, 2);
   my $osFsType = "\0"x256;
   my $osVolName = "\0"x256;
   my $ouFsFlags = 0;

@p5pRT
Copy link
Author

p5pRT commented Jun 3, 2008

From ben@morrow.me.uk

Quoth rurban@​x-ray.at ("Reini Urban")​:

Don't we have acorn? There's nothing in Configure and no hints for acorn.
The Acorn FS would be case tolerant.

Trust me, you do *not* want to try and make File​::Spec handle RISCOS
filespecs... :)

Ben

--
Like all men in Babylon I have been a proconsul; like all, a slave ... During
one lunar year, I have been declared invisible; I shrieked and was not heard,
I stole my bread and was not decapitated.
~ ben@​morrow.me.uk ~ Jorge Luis Borges, 'The Babylon Lottery'

@p5pRT
Copy link
Author

p5pRT commented Nov 10, 2009

From @rurban

Marked as showstopper for 5.12

It slows down Module​::Build significantly.
This patch is already in the cygwin perl distro for over a year.
--
Reini Urban

@p5pRT
Copy link
Author

p5pRT commented Dec 16, 2009

From @obra

On Tue Nov 10 09​:52​:47 2009, rurban wrote​:

Marked as showstopper for 5.12

It slows down Module​::Build significantly.
This patch is already in the cygwin perl distro for over a year.

While a performance fix would be lovely, File​::Spec is maintained on CPAN
with bleadperl as a downstream and this issue doesn't appear to be serious
enough to hold back 5.12.0, so I'm going to unlink it.

@p5pRT
Copy link
Author

p5pRT commented Mar 14, 2010

From @iabyn

Reini, since this bug and patch relates to a CPAN distribution, I'm
going to mark it as rejected in the perl5 queue. Presumably if you wish you
can you can raise the issue of your patch directly with the pathtools
maintainers​:

https://rt.cpan.org/Public/Dist/Display.html?Name=PathTools

@p5pRT
Copy link
Author

p5pRT commented Mar 14, 2010

@iabyn - Status changed from 'open' to 'rejected'

@p5pRT p5pRT closed this as completed Mar 14, 2010
@p5pRT
Copy link
Author

p5pRT commented Mar 14, 2010

From @rurban

2010/3/14 Dave Mitchell via RT <perlbug-followup@​perl.org>​:

Reini, since this bug and patch relates to a CPAN distribution, I'm
going to mark it as rejected in the perl5 queue. Presumably if you wish you
can you can raise the issue of your patch directly with the pathtools
maintainers​:

https://rt.cpan.org/Public/Dist/Display.html?Name=PathTools

The pathtools maintainers do not care, and I'll keep it as cygwin maintainer
in the cygwin distro as the issue is blocking for cygwin.
https://rt.cpan.org/Public/Bug/Display.html?id=48182

It's a perl issue for me, not a PathTools issue.
Installing via cpan does not fix it, only an installation of perl.
Waiting 5 minutes for a Module​::Build installation can be called
severely broken.
--
Reini Urban
http​://phpwiki.org/ http​://murbreak.at/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant