From: Carlo Wood (carlo_at_[hidden])
Date: 2004-08-17 10:28:59


At several places in the code we find something like:

// BOOST_POSIX or BOOST_WINDOWS specify which API to use.
# if !defined( BOOST_WINDOWS ) && !defined( BOOST_POSIX )
# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
# define BOOST_WINDOWS
# else
# define BOOST_POSIX
# endif
# endif

(As in for example boost/libs/filesystem/src/path_posix_windows.cpp)

This sets BOOST_WINDOWS explicitely, as default, for cygwin - which
is a POSIX operating system with a single root.

This breaks a lot of code - if not all - of boost::filesystem.
For example, the following code:

#include <iostream>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>

int main()
{
  boost::filesystem::path p = "/usr";
  if (!boost::filesystem::exists(p))
    std::cerr << p.string() << " doesn't exist according to boost::filesystem" << std::endl;
}

indeed causes boost::filesystem::exists to return 'false' on cygwin
while "/usr" definitely exists.

The reason for that is obvious and looks like a clear bug:
The code of boost::filesystem::exists is as follows:

    BOOST_FILESYSTEM_DECL bool exists( const path & ph )
    {
# ifdef BOOST_POSIX
      struct stat path_stat;
      if(::stat( ph.string().c_str(), &path_stat ) != 0)
      {
         if((errno == ENOENT) || (errno == ENOTDIR))
            return false; // stat failed because the path does not exist
         // for any other error we assume the file does exist and fall through,
         // this may not be the best policy though... (JM 20040330)
      }
      return true;
# else
      if(::GetFileAttributesA( ph.string().c_str() ) == 0xFFFFFFFF)
      {
         UINT err = ::GetLastError();
         if((err == ERROR_FILE_NOT_FOUND) || (err == ERROR_PATH_NOT_FOUND) || (err == ERROR_INVALID_NAME))
            return false; // GetFileAttributes failed because the path does not exist
         // for any other error we assume the file does exist and fall through,
         // this may not be the best policy though... (JM 20040330)
         return true;
      }
      return true;
# endif
    }

Therefore, with BOOST_POSIX undefined, "/usr" is passed directly to ::GetFileAttributesA()
and that can obviously not work.

My question is therefore: shouldn't BOOST_POSIX be forced to be defined on cygwin?

-- 
Carlo Wood <carlo_at_[hidden]>
PS Please note that, looking at http://www.meta-comm.com/engineering/boost-regression/developer/summary.html
   nobody is running the testsuite on cygwin!  How broken on cygwin is boost really?