X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f2346d3fd62de2307531c91062ff87a0cc97a42f..01ad5e43bfb45c4d7622f2d615dd28a411e60367:/src/common/filefn.cpp diff --git a/src/common/filefn.cpp b/src/common/filefn.cpp index 73c0a0c036..1f87e838c5 100644 --- a/src/common/filefn.cpp +++ b/src/common/filefn.cpp @@ -24,13 +24,15 @@ #pragma hdrstop #endif +#include "wx/filefn.h" + #ifndef WX_PRECOMP #include "wx/intl.h" #include "wx/log.h" #include "wx/utils.h" #endif -#include "wx/file.h" // This does include filefn.h +#include "wx/file.h" #include "wx/filename.h" #include "wx/dir.h" @@ -150,11 +152,49 @@ WXDLLEXPORT int wxOpen( const wxChar *pathname, int flags, mode_t mode ) #endif // wxNEED_WX_UNISTD_H +#if wxUSE_UNICODE && defined __BORLANDC__ \ + && __BORLANDC__ >= 0x550 && __BORLANDC__ <= 0x551 + +// BCC 5.5 and 5.5.1 have a bug in _wopen where files are created read only +// regardless of the mode parameter. This hack works around the problem by +// setting the mode with _wchmod. +// +int wxOpen(const wchar_t *pathname, int flags, mode_t mode) +{ + int moreflags = 0; + + // we only want to fix the mode when the file is actually created, so + // when creating first try doing it O_EXCL so we can tell if the file + // was already there. + if ((flags & O_CREAT) && !(flags & O_EXCL) && (mode & wxS_IWUSR) != 0) + moreflags = O_EXCL; + + int fd = _wopen(pathname, flags | moreflags, mode); + + // the file was actually created and needs fixing + if (fd != -1 && (flags & O_CREAT) != 0 && (mode & wxS_IWUSR) != 0) + { + close(fd); + _wchmod(pathname, mode); + fd = _wopen(pathname, flags & ~(O_EXCL | O_CREAT)); + } + // the open failed, but it may have been because the added O_EXCL stopped + // the opening of an existing file, so try again without. + else if (fd == -1 && moreflags != 0) + { + fd = _wopen(pathname, flags & ~O_CREAT); + } + + return fd; +} + +#endif + // ---------------------------------------------------------------------------- // wxPathList // ---------------------------------------------------------------------------- -void wxPathList::Add(const wxString& path) +bool wxPathList::Add(const wxString& path) { // add a path separator to force wxFileName to interpret it always as a directory // (i.e. if we are called with '/home/user' we want to consider it a folder and @@ -162,11 +202,17 @@ void wxPathList::Add(const wxString& path) wxFileName fn(path + wxFileName::GetPathSeparator()); // add only normalized relative/absolute paths - fn.Normalize(wxPATH_NORM_DOTS|wxPATH_NORM_TILDE|wxPATH_NORM_LONG|wxPATH_NORM_ENV_VARS); + // NB: we won't do wxPATH_NORM_DOTS in order to avoid problems when trying to + // normalize paths which starts with ".." (which can be normalized only if + // we use also wxPATH_NORM_ABSOLUTE - which we don't want to use). + if (!fn.Normalize(wxPATH_NORM_TILDE|wxPATH_NORM_LONG|wxPATH_NORM_ENV_VARS)) + return false; wxString toadd = fn.GetPath(); if (Index(toadd) == wxNOT_FOUND) wxArrayString::Add(toadd); // do not add duplicates + + return true; } void wxPathList::Add(const wxArrayString &arr) @@ -205,21 +251,17 @@ void wxPathList::AddEnvList (const wxString& WXUNUSED_IN_WINCE(envVariable)) // Given a full filename (with path), ensure that that file can // be accessed again USING FILENAME ONLY by adding the path // to the list if not already there. -void wxPathList::EnsureFileAccessible (const wxString& path) +bool wxPathList::EnsureFileAccessible (const wxString& path) { - wxString path_only(wxPathOnly(path)); - if ( !path_only.empty() ) - { - if ( Index(path_only) == wxNOT_FOUND ) - Add(path_only); - } + return Add(wxPathOnly(path)); } -// deprecated ! +#if WXWIN_COMPATIBILITY_2_6 bool wxPathList::Member (const wxString& path) const { return Index(path) != wxNOT_FOUND; } +#endif wxString wxPathList::FindValidPath (const wxString& file) const { @@ -228,8 +270,13 @@ wxString wxPathList::FindValidPath (const wxString& file) const wxFileName fn(file); wxString strend; - // NB: normalize without making absolute ! - fn.Normalize(wxPATH_NORM_DOTS|wxPATH_NORM_TILDE|wxPATH_NORM_LONG|wxPATH_NORM_ENV_VARS); + // NB: normalize without making absolute otherwise calling this function with + // e.g. "b/c.txt" would result in removing the directory 'b' and the for loop + // below would only add to the paths of this list the 'c.txt' part when doing + // the existence checks... + // NB: we don't use wxPATH_NORM_DOTS here, too (see wxPathList::Add for more info) + if (!fn.Normalize(wxPATH_NORM_TILDE|wxPATH_NORM_LONG|wxPATH_NORM_ENV_VARS)) + return wxEmptyString; wxASSERT_MSG(!fn.IsDir(), wxT("Cannot search for directories; only for files")); if (fn.IsAbsolute()) @@ -1223,7 +1270,7 @@ bool wxRmdir(const wxString& dir, int WXUNUSED(flags)) #elif defined(__OS2__) return (::DosDeleteDir((PSZ)dir.c_str()) == 0); #elif defined(__WXWINCE__) - return (CreateDirectory(dir, NULL) != 0); + return (RemoveDirectory(dir) != 0); #elif defined(__WXPALMOS__) // TODO with VFSFileRename() return false; @@ -1528,6 +1575,14 @@ wxString wxGetCwd() bool wxSetWorkingDirectory(const wxString& d) { #if defined(__OS2__) + if (d[1] == ':') + { + ::DosSetDefaultDisk(1 + wxToupper(d[0]) - _T('A')); + // do not call DosSetCurrentDir when just changing drive, + // since it requires e.g. "d:." instead of "d:"! + if (d.length() == 2) + return true; + } return (::DosSetCurrentDir((PSZ)d.c_str()) == 0); #elif defined(__UNIX__) || defined(__WXMAC__) || defined(__DOS__) return (chdir(wxFNSTRINGCAST d.fn_str()) == 0); @@ -1770,7 +1825,7 @@ int WXDLLEXPORT wxParseCommonDialogsFilter(const wxString& filterStr, return filters.GetCount(); } -#if defined( __WINDOWS__ ) +#if defined(__WINDOWS__) && !(defined(__UNIX__) || defined(__OS2__)) static bool wxCheckWin32Permission(const wxString& path, DWORD access) { // quoting the MSDN: "To obtain a handle to a directory, call the @@ -1803,7 +1858,7 @@ static bool wxCheckWin32Permission(const wxString& path, DWORD access) bool wxIsWritable(const wxString &path) { -#if defined( __UNIX__ ) +#if defined( __UNIX__ ) || defined(__OS2__) // access() will take in count also symbolic links return access(wxConvFile.cWX2MB(path), W_OK) == 0; #elif defined( __WINDOWS__ ) @@ -1817,7 +1872,7 @@ bool wxIsWritable(const wxString &path) bool wxIsReadable(const wxString &path) { -#if defined( __UNIX__ ) +#if defined( __UNIX__ ) || defined(__OS2__) // access() will take in count also symbolic links return access(wxConvFile.cWX2MB(path), R_OK) == 0; #elif defined( __WINDOWS__ ) @@ -1831,7 +1886,7 @@ bool wxIsReadable(const wxString &path) bool wxIsExecutable(const wxString &path) { -#if defined( __UNIX__ ) +#if defined( __UNIX__ ) || defined(__OS2__) // access() will take in count also symbolic links return access(wxConvFile.cWX2MB(path), X_OK) == 0; #elif defined( __WINDOWS__ ) @@ -1843,6 +1898,79 @@ bool wxIsExecutable(const wxString &path) #endif } +// Return the type of an open file +// +// Some file types on some platforms seem seekable but in fact are not. +// The main use of this function is to allow such cases to be detected +// (IsSeekable() is implemented as wxGetFileKind() == wxFILE_KIND_DISK). +// +// This is important for the archive streams, which benefit greatly from +// being able to seek on a stream, but which will produce corrupt archives +// if they unknowingly seek on a non-seekable stream. +// +// wxFILE_KIND_DISK is a good catch all return value, since other values +// disable features of the archive streams. Some other value must be returned +// for a file type that appears seekable but isn't. +// +// Known examples: +// * Pipes on Windows +// * Files on VMS with a record format other than StreamLF +// +wxFileKind wxGetFileKind(int fd) +{ +#if defined __WXMSW__ && !defined __WXWINCE__ && defined wxGetOSFHandle + switch (::GetFileType(wxGetOSFHandle(fd)) & ~FILE_TYPE_REMOTE) + { + case FILE_TYPE_CHAR: + return wxFILE_KIND_TERMINAL; + case FILE_TYPE_DISK: + return wxFILE_KIND_DISK; + case FILE_TYPE_PIPE: + return wxFILE_KIND_PIPE; + } + + return wxFILE_KIND_UNKNOWN; + +#elif defined(__UNIX__) + if (isatty(fd)) + return wxFILE_KIND_TERMINAL; + + struct stat st; + fstat(fd, &st); + + if (S_ISFIFO(st.st_mode)) + return wxFILE_KIND_PIPE; + if (!S_ISREG(st.st_mode)) + return wxFILE_KIND_UNKNOWN; + + #if defined(__VMS__) + if (st.st_fab_rfm != FAB$C_STMLF) + return wxFILE_KIND_UNKNOWN; + #endif + + return wxFILE_KIND_DISK; + +#else + #define wxFILEKIND_STUB + (void)fd; + return wxFILE_KIND_DISK; +#endif +} + +wxFileKind wxGetFileKind(FILE *fp) +{ + // Note: The watcom rtl dll doesn't have fileno (the static lib does). + // Should be fixed in version 1.4. +#if defined(wxFILEKIND_STUB) || wxONLY_WATCOM_EARLIER_THAN(1,4) + (void)fp; + return wxFILE_KIND_DISK; +#elif defined(__WINDOWS__) && !defined(__CYGWIN__) && !defined(__WATCOMC__) && !defined(__WINE__) + return fp ? wxGetFileKind(_fileno(fp)) : wxFILE_KIND_UNKNOWN; +#else + return fp ? wxGetFileKind(fileno(fp)) : wxFILE_KIND_UNKNOWN; +#endif +} + //------------------------------------------------------------------------ // wild character routines @@ -1975,77 +2103,6 @@ bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special ) } } -// Return the type of an open file -// -// Some file types on some platforms seem seekable but in fact are not. -// The main use of this function is to allow such cases to be detected -// (IsSeekable() is implemented as wxGetFileKind() == wxFILE_KIND_DISK). -// -// This is important for the archive streams, which benefit greatly from -// being able to seek on a stream, but which will produce corrupt archives -// if they unknowingly seek on a non-seekable stream. -// -// wxFILE_KIND_DISK is a good catch all return value, since other values -// disable features of the archive streams. Some other value must be returned -// for a file type that appears seekable but isn't. -// -// Known examples: -// * Pipes on Windows -// * Files on VMS with a record format other than StreamLF -// -wxFileKind wxGetFileKind(int fd) -{ -#if defined __WXMSW__ && !defined __WXWINCE__ && defined wxGetOSFHandle - switch (::GetFileType(wxGetOSFHandle(fd)) & ~FILE_TYPE_REMOTE) - { - case FILE_TYPE_CHAR: - return wxFILE_KIND_TERMINAL; - case FILE_TYPE_DISK: - return wxFILE_KIND_DISK; - case FILE_TYPE_PIPE: - return wxFILE_KIND_PIPE; - } - - return wxFILE_KIND_UNKNOWN; - -#elif defined(__UNIX__) - if (isatty(fd)) - return wxFILE_KIND_TERMINAL; - - struct stat st; - fstat(fd, &st); - - if (S_ISFIFO(st.st_mode)) - return wxFILE_KIND_PIPE; - if (!S_ISREG(st.st_mode)) - return wxFILE_KIND_UNKNOWN; - - #if defined(__VMS__) - if (st.st_fab_rfm != FAB$C_STMLF) - return wxFILE_KIND_UNKNOWN; - #endif - - return wxFILE_KIND_DISK; - -#else - #define wxFILEKIND_STUB - (void)fd; - return wxFILE_KIND_DISK; -#endif -} - -wxFileKind wxGetFileKind(FILE *fp) -{ - // Note: The watcom rtl dll doesn't have fileno (the static lib does). - // Should be fixed in version 1.4. -#if defined(wxFILEKIND_STUB) || wxONLY_WATCOM_EARLIER_THAN(1,4) - (void)fp; - return wxFILE_KIND_DISK; -#else - return fp ? wxGetFileKind(fileno(fp)) : wxFILE_KIND_UNKNOWN; -#endif -} - #ifdef __VISUALC__ #pragma warning(default:4706) // assignment within conditional expression #endif // VC++