[PATCH 3/4] Make io_stream::exists() directory aware
Jon TURNEY
jon.turney@dronecode.org.uk
Fri Nov 26 15:40:00 GMT 2010
At the moment io_stream::exists() returns FALSE for file:// paths
which refer to an existing directory. Inconsistently, for
cygfile:// paths which refer to an existing directory, it returns
TRUE.
Return a new state, IO_STREAM_EXISTS_DIRECTORY, to indicate if
pathname exists as a directory and update all uses appropriately
Not sure if the use of access() in the legacy branch of
io_stream_cygfile::exists() is correct, looks like it's inverted
Not sure if current exists() implementation deals correctly when other
attributes are set for a file, e.g. FILE_ATTRIBUTE_COMPRESSED or
FILE_ATTRIBUTE_ENCRYPTED, since it checks attributes against an
expected value rather than checking for bits being set?
2010-11-26 Jon TURNEY <jon.turney@dronecode.org.uk>
* io_stream.h (io_stream_exists_t, io_stream::exists): Change io_stream::exists
return type to new enum io_stream_exists_t.
* io_stream.cc (exists): Ditto.
* IOStreamProvider.h (IOStreamProvider): Ditto.
* io_stream_file.h (io_stream): Ditto.
* io_stream_file.cc (IOStreamProvider, exists): Ditto.
* io_stream_cygfile.h (io_stream): Ditto.
* io_stream_cygfile.cc (IOStreamProvider, exists): Ditto.
* script.cc (try_run_script): Update use of io_stream::exists().
* install.cc (installOne): Ditto.
* download.cc (check_for_cached): Ditto.
Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
---
IOStreamProvider.h | 2 +-
download.cc | 4 ++--
install.cc | 2 +-
io_stream.cc | 2 +-
io_stream.h | 10 +++++++++-
io_stream_cygfile.cc | 23 +++++++++++++++++------
io_stream_cygfile.h | 2 +-
io_stream_file.cc | 15 ++++++++++-----
io_stream_file.h | 2 +-
script.cc | 2 +-
10 files changed, 44 insertions(+), 20 deletions(-)
diff --git a/IOStreamProvider.h b/IOStreamProvider.h
index b30362e..1c12f42 100644
--- a/IOStreamProvider.h
+++ b/IOStreamProvider.h
@@ -25,7 +25,7 @@
class IOStreamProvider
{
public:
- virtual int exists (const std::string& ) const = 0;
+ virtual io_stream_exists_t exists (const std::string& ) const = 0;
virtual int remove (const std::string& ) const = 0;
virtual int mklink (const std::string&, const std::string&,
io_stream_link_t) const = 0;
diff --git a/download.cc b/download.cc
index 86723f6..3567715 100644
--- a/download.cc
+++ b/download.cc
@@ -91,7 +91,7 @@ check_for_cached (packagesource & pkgsource)
* std::string-ified, and doesn't use overcomplex semantics. */
std::string fullname = prefix +
(pkgsource.Canonical() ? pkgsource.Canonical() : "");
- if (io_stream::exists(fullname))
+ if (io_stream::exists(fullname) == IO_STREAM_EXISTS_FILE)
{
if (validateCachedPackage (fullname, pkgsource))
pkgsource.set_cached (fullname);
@@ -110,7 +110,7 @@ check_for_cached (packagesource & pkgsource)
{
std::string fullname = prefix + rfc1738_escape_part (n->key) + "/" +
pkgsource.Canonical ();
- if (io_stream::exists(fullname))
+ if (io_stream::exists(fullname) == IO_STREAM_EXISTS_FILE)
{
if (validateCachedPackage (fullname, pkgsource))
pkgsource.set_cached (fullname);
diff --git a/install.cc b/install.cc
index 51c20d9..f77b52b 100644
--- a/install.cc
+++ b/install.cc
@@ -261,7 +261,7 @@ Installer::installOne (packagemeta &pkgm, const packageversion &ver,
io_stream *pkgfile = NULL;
- if (!source.Cached() || !io_stream::exists (source.Cached ())
+ if (!source.Cached() || (io_stream::exists (source.Cached ()) != IO_STREAM_EXISTS_FILE)
|| !(pkgfile = io_stream::open (source.Cached (), "rb", 0)))
{
note (NULL, IDS_ERR_OPEN_READ, source.Cached (), "No such file");
diff --git a/io_stream.cc b/io_stream.cc
index 08ecae4..23c7e36 100644
--- a/io_stream.cc
+++ b/io_stream.cc
@@ -241,7 +241,7 @@ io_stream::gets (char *buffer, size_t length)
return buffer;
}
-int
+io_stream_exists_t
io_stream::exists (const std::string& name)
{
IOStreamProvider const *p = findProvider (name);
diff --git a/io_stream.h b/io_stream.h
index 3968acc..97528a8 100644
--- a/io_stream.h
+++ b/io_stream.h
@@ -74,6 +74,14 @@ typedef enum
}
io_stream_seek_t;
+typedef enum
+{
+ IO_STREAM_EXISTS_NO = 0,
+ IO_STREAM_EXISTS_FILE,
+ IO_STREAM_EXISTS_DIRECTORY,
+}
+io_stream_exists_t;
+
class io_stream
{
public:
@@ -103,7 +111,7 @@ public:
*/
static io_stream *open (const std::string&, const std::string&, mode_t);
static int remove (const std::string& );
- static int exists (const std::string& );
+ static io_stream_exists_t exists (const std::string& );
/* moves physical stream source to dest. A copy will be attempted if a
* pointer flip fails.
*/
diff --git a/io_stream_cygfile.cc b/io_stream_cygfile.cc
index 8da97e7..7b768b6 100644
--- a/io_stream_cygfile.cc
+++ b/io_stream_cygfile.cc
@@ -27,6 +27,7 @@ static const char *cvsid =
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
+#include <sys/stat.h>
#include "mount.h"
#include "mkdir.h"
#include "mklink2.h"
@@ -40,7 +41,7 @@ static const char *cvsid =
class CygFileProvider : public IOStreamProvider
{
public:
- int exists (const std::string& path) const
+ io_stream_exists_t exists (const std::string& path) const
{return io_stream_cygfile::exists(path);}
int remove (const std::string& path) const
{return io_stream_cygfile::remove(path);}
@@ -182,12 +183,12 @@ io_stream_cygfile::~io_stream_cygfile ()
}
/* Static members */
-int
+io_stream_exists_t
io_stream_cygfile::exists (const std::string& path)
{
get_root_dir_now ();
if (!get_root_dir ().size())
- return 0;
+ return IO_STREAM_EXISTS_NO;
if (IsWindowsNT ())
{
@@ -196,11 +197,21 @@ io_stream_cygfile::exists (const std::string& path)
mklongpath (wname, cygpath (normalise(path)).c_str (), len);
DWORD attr = GetFileAttributesW (wname);
if (attr != INVALID_FILE_ATTRIBUTES)
- return 1;
+ return (attr & FILE_ATTRIBUTE_DIRECTORY) ? IO_STREAM_EXISTS_DIRECTORY : IO_STREAM_EXISTS_FILE;
}
else if (_access (cygpath (normalise(path)).c_str (), 0))
- return 1;
- return 0;
+ {
+ struct _stat s;
+ if (!_stat (cygpath (normalise(path)).c_str (), &s))
+ {
+ if (s.st_mode & S_IFDIR)
+ return IO_STREAM_EXISTS_DIRECTORY;
+
+ if (s.st_mode & S_IFREG)
+ return IO_STREAM_EXISTS_FILE;
+ }
+ }
+ return IO_STREAM_EXISTS_NO;
}
int
diff --git a/io_stream_cygfile.h b/io_stream_cygfile.h
index 1ece242..d0a6bcb 100644
--- a/io_stream_cygfile.h
+++ b/io_stream_cygfile.h
@@ -28,7 +28,7 @@ extern int cygmkdir_p (path_type_t isadir, const std::string& path, mode_t mode)
class io_stream_cygfile:public io_stream
{
public:
- static int exists (const std::string& );
+ static io_stream_exists_t exists (const std::string& );
static int remove (const std::string& );
static int mklink (const std::string& , const std::string& , io_stream_link_t);
io_stream_cygfile (const std::string&, const std::string&, mode_t);
diff --git a/io_stream_file.cc b/io_stream_file.cc
index 91f9afa..422f081 100644
--- a/io_stream_file.cc
+++ b/io_stream_file.cc
@@ -46,7 +46,7 @@ using namespace std;
class FileProvider : public IOStreamProvider
{
public:
- int exists (const std::string& path) const
+ io_stream_exists_t exists (const std::string& path) const
{return io_stream_file::exists(path);}
int remove (const std::string& path) const
{return io_stream_file::remove(path);}
@@ -114,7 +114,7 @@ io_stream_file::~io_stream_file ()
delete [] wname;
}
-int
+io_stream_exists_t
io_stream_file::exists (const std::string& path)
{
DWORD attr;
@@ -127,9 +127,14 @@ io_stream_file::exists (const std::string& path)
mklongpath (wname, path.c_str (), len);
attr = GetFileAttributesW (wname);
}
- return attr != INVALID_FILE_ATTRIBUTES
- && attr != FILE_ATTRIBUTE_DIRECTORY
- && attr != FILE_ATTRIBUTE_DEVICE;
+
+ if (attr != INVALID_FILE_ATTRIBUTES
+ && !(attr & FILE_ATTRIBUTE_DEVICE))
+ {
+ return (attr & FILE_ATTRIBUTE_DIRECTORY) ? IO_STREAM_EXISTS_DIRECTORY : IO_STREAM_EXISTS_FILE;
+ }
+
+ return IO_STREAM_EXISTS_NO;
}
int
diff --git a/io_stream_file.h b/io_stream_file.h
index b1d7f2e..2ec56a3 100644
--- a/io_stream_file.h
+++ b/io_stream_file.h
@@ -25,7 +25,7 @@
class io_stream_file:public io_stream
{
public:
- static int exists (const std::string& );
+ static io_stream_exists_t exists (const std::string& );
static int remove (const std::string& );
static int mklink (const std::string& , const std::string& , io_stream_link_t);
io_stream_file (const std::string&, const std::string&, mode_t);
diff --git a/script.cc b/script.cc
index ec363d8..f64fecf 100644
--- a/script.cc
+++ b/script.cc
@@ -305,7 +305,7 @@ try_run_script (const std::string& dir,
const std::string& fname,
const std::string& ext)
{
- if (io_stream::exists ("cygfile://" + dir + fname + ext))
+ if (io_stream::exists ("cygfile://" + dir + fname + ext) == IO_STREAM_EXISTS_FILE)
return Script (dir + fname + ext).run ();
return NO_ERROR;
}
--
1.7.2.3
More information about the Cygwin-apps
mailing list