Boost logo

Boost :

From: Robert Mathews (rmathews_at_[hidden])
Date: 2005-03-14 14:58:43


Hi:

I was trying to do something simple with the boost::filesystem library on
Win32 && I noticed that it has trouble with UNC paths. I think I noticed 2
bugs with boost::filesystem::exists (possible patch attached). Finally, I
also had a question about what consistutes a "part" of a path.

Here's the context: I was trying to get all of the parts of a path, starting
at the front and moving to the end in order to find out at which point a
path was invalid. So, I wrote a path-checker that went something like this:

using namespace std;
namespace fs = boost::filesystem;

void check_path(const string iPath)
{
   fs::path::default_name_check(fs::native);
   fs::path aCurrentPath;
   for(fs::path::iterator aItr1=iPath.begin(); aItr1!=iPath.end(); aItr1++)
  {
      aCurrentPath /= *aItr1;
      bool aExists(fs::exists(aCurrentPath));
      if(!aExists)
      {
           cout << "Hey, this was invalid path and it failed at
aCurrentPath" << endl;
           return false;
      }
   }
   return true;
}

The function works fine if you give it paths like "D:/foo/bar", but a UNC
path like \\computername\share\foo\bar doesn't work. The reason is that the
path::iterator returns the following results for the beginning of the UNC
path:
"//computername"
"/"
"share"
"/"
"foo"
... etc
and "//computername" is not a valid path.

I've got a couple of questions about this:
1) Why is the separator "/" a separate part of the path? Shouldn't there be
a way to only get the directory parts of the path w/o the separators? Just
curious .. I couldn't find a reference to that in the discussion list.
2) boost::filesystem::exists("//computername") will return false, always.
That seems like the wrong answer, given that the path::iterator has returned
it as a part of the path. I notice that the filesystem code does otherwise
understand UNC paths otherwise.
3) boost::filesystem::exists("//computername/nofreelunch") will return true,
if even "nofreelunch" doesn't exist.

Looking at the implementation of filesystem::exists in boost
libs/filesystems/src/operations_posix_windows.cpp line 324, I'd like to
propose the following changes to fix cases 2 & 3.

To fix case 3 above, the error code return for an invalid share is not
PATH_NOT_FOUND, but ERROR_BAD_NETPATH. That's a simple addition to the list
of error codes to check. That should be uncontroversial.
To fix case 2 above, one must notice that you have a UNC path with 1
element - ie, a computer name. At the point you can either follow the hint
in the code and simply return true, or you can call a different WIN32
function to see if the server exists.

Attached is a proposed patch for both issues.

Thanks.

begin 666 operations_posix_windows.cpp.patch
M26YD97_at_Z(&]P97)A=&EO;G-?<&]S:7A?=VEN9&]W<RYC<' -"CT]/3T]/3T]
M/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]/3T]
M/3T]/3T]/3T]/3T]/3T-"BTM+2!O<&5R871I;VYS7W!O<VEX7W=I;F1O=W,N
M8W!P"2AR979I<VEO;B R-3(W,2D-"BLK*R!O<&5R871I;VYS7W!O<VEX7W=I
M;F1O=W,N8W!P"2AW;W)K:6YG(&-O<'DI#0I 0" M,S(Q+#$P("LS,C$L,S@@
M0$ -"B @(" @("!]#0H@(" @(" @<F5T=7)N('1R=64[#0H@(R @(&5L<V4-
M"BT@(" @("!I9B_at_Z.D=E=$9I;&5!='1R:6)U=&5S02@@<&@N<W1R:6YG*"DN
M8U]S='(H*2 I(#T](#!X1D9&1D9&1D8I#0HK"2 @<W1R:6YG(&%0871H*'!H
M+G-T<FEN9R_at_I*3L-"BL)("!B;V]L(&ES54Y#4&%T:"AA4&%T:"YS:7IE*"D@
M/B S("8F(&%0871H+G-U8G-T<B_at_P+#(I(#T]("(O+R(I.R O+R T/4QA<F=E
M(&5N;W5G:"!P871H('1O(&AA=F4_at_82!L96%D:6YG("\O(&%N9"!A="!L96%S
M=" Q(&UO<F4_at_8VAA<F%C=&5R#0HK"2 @<W1R:6YG.CIS:7IE7W1Y<&4_at_84YE
M>'13;&%S:"AA4&%T:"YF:6YD7V9I<G-T7V]F*"(O(BPR*2D[#0HK"2 @8F]O
M;"!I<T]N;'E#;VUP=71E<DYA;64H:7-53D-0871H("8F"0D)"0D)+R\@;6%K
M92!S=7)E('1H:7,@82!53D,@<&%T:"!O9B!S;VUE('1Y<&4N#0HK"0D)"0D)
M"2 @*&%.97AT4VQA<V@@/3T@<W1R:6YG.CIN<&]S('Q\"2\O(&QO;VL_at_9F]R
M("\O8V]M<'5T97)N86UE#0HK"0D)"0D)"2 @("AA3F5X=%-L87-H(#T]("AA
M4&%T:"YS:7IE*"D@+2 Q*2 F)B!A4&%T:"YS:7IE*"D@/B S("\O(&%L;&]W
M("\O8V]M<'5T97)N86UE+R!A;F0_at_9F5N8V4@;V9F("<O+R\G(&EN<'5T( T*
M*PD)"0D)"0D@(" I*2D[#0HK"2 @:68H:7-/;FQY0V]M<'5T97).86UE*0T*
M*R-I9F1E9B!F86YC>5]C:&5C:VEN9PT**PD)(" O+R!)(&1O;B=T(&MN;W<@
M:68@>6]U('=A;G0@=&\@9V\@=&AI<R!F87(@;W(@;F]T/PT**PD)(" O+R!9
M;W4G;&P@:&%V92!T;R C:6YC;'5D92 \;&TN:#X_at_86YD(&QI;FL_at_86=A:6YS
M="!.971A<&DS,BYL:6(@)B8@=&AE;B!W;W)R>2!A8F]U="!A;&P@=F%R:6]U
M<R!V97)S:6]N<R!O9B!W:6YD;W=S("XN( T**PD@('L-"BL)"2 @3%!315)6
M15)?24Y&3U\Q,# @85-E<G9E<DEN9F\H3E5,3"D[#0HK"0D@($Y%5%]!4$E?
M4U1!5%53(&%3=&%T=7,H3F5T4V5R=F5R1V5T26YF;T$H#0HK"0D)"0D)"0D)
M"2 @<&@N<W1R:6YG*"DL#0HK"0D)"0D)"0D)"2 @,3 P+ T**PD)"0D)"0D)
M"0D@("A,4$)95$4J*2 F85-E<G9E<DEN9F\-"BL)"0D)"0D)"0D)("D[#0HK
M"0D@(&EF*&%397)V97));F9O*0T**PD)"2 @3F5T07!I0G5F9F5R1G)E92AA
M4V5R=F5R26YF;RD[#0HK"0D@(')E='5R;B!A4W1A='5S(#T]($Y%4E)?4W5C
M8V5S<SL-"BL)("!]#0HK(V5L<V4-"BL)(" O+R!!="!L96%S="P@:68@>6]U
M(')E8V]G;FEZ92!T:&%T('1H:7,@82!C;VUP=71E<B!N86UE+"!Y;W4_at_8V]U
M;&0_at_9&\@=V]R<V4@=&AA;B!T;R!A<W-U;64@:70@;6EG:'0_at_97AI<W0N#0HK
M"2 @<F5T=7)N('1R=64["0D)#0HK(V5N9&EF"2 @#0HK"2 @96QS92!I9B_at_Z
M.D=E=$9I;&5!='1R:6)U=&5S02@@<&@N<W1R:6YG*"DN8U]S='(H*2 I(#T]
M(#!X1D9&1D9&1D8I#0H@(" @(" @>PT*(" @(" @(" @(%5)3E0_at_97)R(#T@
M.CI'971,87-T17)R;W(H*3L-"BT@(" @(" @("!I9B_at_H97)R(#T]($524D]2
M7T9)3$5?3D]47T9/54Y$*2!\?" H97)R(#T]($524D]27TE.5D%,241?4$%2
M04U%5$52*2!\?" H97)R(#T]($524D]27U!!5$A?3D]47T9/54Y$*2!\?" H
M97)R(#T]($524D]27TE.5D%,241?3D%-12DI#0HK(" @(" @(" @:68H*&5R
M<B ]/2!%4E)/4E]&24Q%7TY/5%]&3U5.1"D@?'P@*&5R<B ]/2!%4E)/4E])
M3E9!3$E$7U!!4D%-151%4BD@?'P@*&5R<B ]/2!%4E)/4E]0051(7TY/5%]&
M3U5.1"D@?'P@*&5R<B ]/2!%4E)/4E])3E9!3$E$7TY!344I#0HK"0D)*&5R
M<B ]/2!%4E)/4E]"041?3D544$%42"D-"BL)"2 @("D-"B @(" @(" @(" @
M("!R971U<FX_at_9F%L<V4[("\O($=E=$9I;&5!='1R:6)U=&5S(&9A:6QE9"!B
M96-A=7-E('1H92!P871H(&1O97,@;F]T(&5X:7-T#0H@(" @(" @(" @+R\@
M9F]R(&%N>2!O=&AE<B!E<G)O<B!W92!A<W-U;64@=&AE(&9I;&4_at_9&]E<R!E
M>&ES="!A;F0_at_9F%L;"!T:')O=6=H+ T*(" @(" @(" @("\O('1H:7,@;6%Y
M(&YO="!B92!T:&4_at_8F5S="!P;VQI8WD@=&AO=6=H+BXN(" H2DT@,C P-# S
%,S I#0H`
`
end


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk