Add wxFile::{Get,Clear}LastError() functions.
Remember the errno of the last file operation instead of just remembering whether there was an error or not. See #12636. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66150 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
0547ad09cc
commit
65fe93d8a5
@ -408,6 +408,7 @@ All:
|
|||||||
- Added cwd and env arguments to wxExecute() (Emilien Kia).
|
- Added cwd and env arguments to wxExecute() (Emilien Kia).
|
||||||
- Added "rest" argument to wxString::Before{First,Last}().
|
- Added "rest" argument to wxString::Before{First,Last}().
|
||||||
- Added wxThread::OnKill() and OnDelete() callbacks.
|
- Added wxThread::OnKill() and OnDelete() callbacks.
|
||||||
|
- Added wxFile::GetLastError() and ClearLastError() (ryazanov).
|
||||||
|
|
||||||
All (GUI):
|
All (GUI):
|
||||||
|
|
||||||
|
@ -49,11 +49,11 @@ public:
|
|||||||
// ctors
|
// ctors
|
||||||
// -----
|
// -----
|
||||||
// def ctor
|
// def ctor
|
||||||
wxFile() { m_fd = fd_invalid; m_error = false; }
|
wxFile() { m_fd = fd_invalid; m_lasterror = 0; }
|
||||||
// open specified file (may fail, use IsOpened())
|
// open specified file (may fail, use IsOpened())
|
||||||
wxFile(const wxString& fileName, OpenMode mode = read);
|
wxFile(const wxString& fileName, OpenMode mode = read);
|
||||||
// attach to (already opened) file
|
// attach to (already opened) file
|
||||||
wxFile(int lfd) { m_fd = lfd; m_error = false; }
|
wxFile(int lfd) { m_fd = lfd; m_lasterror = 0; }
|
||||||
|
|
||||||
// open/close
|
// open/close
|
||||||
// create a new file (with the default value of bOverwrite, it will fail if
|
// create a new file (with the default value of bOverwrite, it will fail if
|
||||||
@ -65,7 +65,7 @@ public:
|
|||||||
bool Close(); // Close is a NOP if not opened
|
bool Close(); // Close is a NOP if not opened
|
||||||
|
|
||||||
// assign an existing file descriptor and get it back from wxFile object
|
// assign an existing file descriptor and get it back from wxFile object
|
||||||
void Attach(int lfd) { Close(); m_fd = lfd; m_error = false; }
|
void Attach(int lfd) { Close(); m_fd = lfd; m_lasterror = 0; }
|
||||||
void Detach() { m_fd = fd_invalid; }
|
void Detach() { m_fd = fd_invalid; }
|
||||||
int fd() const { return m_fd; }
|
int fd() const { return m_fd; }
|
||||||
|
|
||||||
@ -95,10 +95,15 @@ public:
|
|||||||
// is end of file reached?
|
// is end of file reached?
|
||||||
bool Eof() const;
|
bool Eof() const;
|
||||||
// has an error occurred?
|
// has an error occurred?
|
||||||
bool Error() const { return m_error; }
|
bool Error() const { return m_lasterror != 0; }
|
||||||
|
// get last errno
|
||||||
|
int GetLastError() const { return m_lasterror; }
|
||||||
|
// reset error state
|
||||||
|
void ClearLastError() { m_lasterror = 0; }
|
||||||
// type such as disk or pipe
|
// type such as disk or pipe
|
||||||
wxFileKind GetKind() const { return wxGetFileKind(m_fd); }
|
wxFileKind GetKind() const { return wxGetFileKind(m_fd); }
|
||||||
|
|
||||||
|
|
||||||
// dtor closes the file if opened
|
// dtor closes the file if opened
|
||||||
~wxFile() { Close(); }
|
~wxFile() { Close(); }
|
||||||
|
|
||||||
@ -109,8 +114,16 @@ private:
|
|||||||
wxFile(const wxFile&);
|
wxFile(const wxFile&);
|
||||||
wxFile& operator=(const wxFile&);
|
wxFile& operator=(const wxFile&);
|
||||||
|
|
||||||
|
// Copy the value of errno into m_lasterror if rc == -1 and return true in
|
||||||
|
// this case (indicating that we've got an error). Otherwise return false.
|
||||||
|
//
|
||||||
|
// Notice that we use the possibly 64 bit wxFileOffset instead of int here so
|
||||||
|
// that it works for checking the result of functions such as tell() too.
|
||||||
|
bool CheckForError(wxFileOffset rc) const;
|
||||||
|
|
||||||
|
|
||||||
int m_fd; // file descriptor or INVALID_FD if not opened
|
int m_fd; // file descriptor or INVALID_FD if not opened
|
||||||
bool m_error; // error memory
|
int m_lasterror; // errno value of last error
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -231,6 +231,32 @@ public:
|
|||||||
*/
|
*/
|
||||||
~wxFile();
|
~wxFile();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the error code for the last unsuccessful operation.
|
||||||
|
|
||||||
|
The error code is system-dependent and corresponds to the value of the
|
||||||
|
standard @c errno variable when the last error occurred.
|
||||||
|
|
||||||
|
Notice that only simple accessors such as IsOpened() and Eof() (and
|
||||||
|
this method itself) don't modify the last error value, all other
|
||||||
|
methods can potentially change it if an error occurs, including the
|
||||||
|
const ones such as Tell() or Length().
|
||||||
|
|
||||||
|
@since 2.9.2
|
||||||
|
|
||||||
|
@see ClearLastError()
|
||||||
|
*/
|
||||||
|
int GetLastError() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Resets the error code.
|
||||||
|
|
||||||
|
GetLastError() will return 0 until the next error occurs.
|
||||||
|
|
||||||
|
@since 2.9.2
|
||||||
|
*/
|
||||||
|
void ClearLastError();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function verifies if we may access the given file in specified mode.
|
This function verifies if we may access the given file in specified mode.
|
||||||
Only values of @c wxFile::read or @c wxFile::write really make sense here.
|
Only values of @c wxFile::read or @c wxFile::write really make sense here.
|
||||||
|
@ -88,6 +88,10 @@
|
|||||||
|
|
||||||
#include <stdio.h> // SEEK_xxx constants
|
#include <stdio.h> // SEEK_xxx constants
|
||||||
|
|
||||||
|
#ifndef __WXWINCE__
|
||||||
|
#include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Windows compilers don't have these constants
|
// Windows compilers don't have these constants
|
||||||
#ifndef W_OK
|
#ifndef W_OK
|
||||||
enum
|
enum
|
||||||
@ -176,11 +180,27 @@ bool wxFile::Access(const wxString& name, OpenMode mode)
|
|||||||
wxFile::wxFile(const wxString& fileName, OpenMode mode)
|
wxFile::wxFile(const wxString& fileName, OpenMode mode)
|
||||||
{
|
{
|
||||||
m_fd = fd_invalid;
|
m_fd = fd_invalid;
|
||||||
m_error = false;
|
m_lasterror = 0;
|
||||||
|
|
||||||
Open(fileName, mode);
|
Open(fileName, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxFile::CheckForError(wxFileOffset rc) const
|
||||||
|
{
|
||||||
|
if ( rc != -1 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const_cast<wxFile *>(this)->m_lasterror =
|
||||||
|
#ifndef __WXWINCE__
|
||||||
|
errno
|
||||||
|
#else
|
||||||
|
::GetLastError()
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// create the file, fail if it already exists and bOverwrite
|
// create the file, fail if it already exists and bOverwrite
|
||||||
bool wxFile::Create(const wxString& fileName, bool bOverwrite, int accessMode)
|
bool wxFile::Create(const wxString& fileName, bool bOverwrite, int accessMode)
|
||||||
{
|
{
|
||||||
@ -190,7 +210,7 @@ bool wxFile::Create(const wxString& fileName, bool bOverwrite, int accessMode)
|
|||||||
O_BINARY | O_WRONLY | O_CREAT |
|
O_BINARY | O_WRONLY | O_CREAT |
|
||||||
(bOverwrite ? O_TRUNC : O_EXCL),
|
(bOverwrite ? O_TRUNC : O_EXCL),
|
||||||
accessMode );
|
accessMode );
|
||||||
if ( fd == -1 )
|
if ( CheckForError(fd) )
|
||||||
{
|
{
|
||||||
wxLogSysError(_("can't create file '%s'"), fileName);
|
wxLogSysError(_("can't create file '%s'"), fileName);
|
||||||
return false;
|
return false;
|
||||||
@ -242,7 +262,7 @@ bool wxFile::Open(const wxString& fileName, OpenMode mode, int accessMode)
|
|||||||
|
|
||||||
int fd = wxOpen( fileName, flags, accessMode);
|
int fd = wxOpen( fileName, flags, accessMode);
|
||||||
|
|
||||||
if ( fd == -1 )
|
if ( CheckForError(fd) )
|
||||||
{
|
{
|
||||||
wxLogSysError(_("can't open file '%s'"), fileName);
|
wxLogSysError(_("can't open file '%s'"), fileName);
|
||||||
return false;
|
return false;
|
||||||
@ -256,7 +276,7 @@ bool wxFile::Open(const wxString& fileName, OpenMode mode, int accessMode)
|
|||||||
bool wxFile::Close()
|
bool wxFile::Close()
|
||||||
{
|
{
|
||||||
if ( IsOpened() ) {
|
if ( IsOpened() ) {
|
||||||
if (wxClose(m_fd) == -1)
|
if ( CheckForError(wxClose(m_fd)) )
|
||||||
{
|
{
|
||||||
wxLogSysError(_("can't close file descriptor %d"), m_fd);
|
wxLogSysError(_("can't close file descriptor %d"), m_fd);
|
||||||
m_fd = fd_invalid;
|
m_fd = fd_invalid;
|
||||||
@ -280,7 +300,7 @@ ssize_t wxFile::Read(void *pBuf, size_t nCount)
|
|||||||
|
|
||||||
ssize_t iRc = wxRead(m_fd, pBuf, nCount);
|
ssize_t iRc = wxRead(m_fd, pBuf, nCount);
|
||||||
|
|
||||||
if ( iRc == -1 )
|
if ( CheckForError(iRc) )
|
||||||
{
|
{
|
||||||
wxLogSysError(_("can't read from file descriptor %d"), m_fd);
|
wxLogSysError(_("can't read from file descriptor %d"), m_fd);
|
||||||
return wxInvalidOffset;
|
return wxInvalidOffset;
|
||||||
@ -296,10 +316,9 @@ size_t wxFile::Write(const void *pBuf, size_t nCount)
|
|||||||
|
|
||||||
ssize_t iRc = wxWrite(m_fd, pBuf, nCount);
|
ssize_t iRc = wxWrite(m_fd, pBuf, nCount);
|
||||||
|
|
||||||
if ( iRc == -1 )
|
if ( CheckForError(iRc) )
|
||||||
{
|
{
|
||||||
wxLogSysError(_("can't write to file descriptor %d"), m_fd);
|
wxLogSysError(_("can't write to file descriptor %d"), m_fd);
|
||||||
m_error = true;
|
|
||||||
iRc = 0;
|
iRc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +348,7 @@ bool wxFile::Flush()
|
|||||||
// call it then
|
// call it then
|
||||||
if ( IsOpened() && GetKind() == wxFILE_KIND_DISK )
|
if ( IsOpened() && GetKind() == wxFILE_KIND_DISK )
|
||||||
{
|
{
|
||||||
if ( wxFsync(m_fd) == -1 )
|
if ( CheckForError(wxFsync(m_fd)) )
|
||||||
{
|
{
|
||||||
wxLogSysError(_("can't flush file descriptor %d"), m_fd);
|
wxLogSysError(_("can't flush file descriptor %d"), m_fd);
|
||||||
return false;
|
return false;
|
||||||
@ -371,7 +390,7 @@ wxFileOffset wxFile::Seek(wxFileOffset ofs, wxSeekMode mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
wxFileOffset iRc = wxSeek(m_fd, ofs, origin);
|
wxFileOffset iRc = wxSeek(m_fd, ofs, origin);
|
||||||
if ( iRc == wxInvalidOffset )
|
if ( CheckForError(iRc) )
|
||||||
{
|
{
|
||||||
wxLogSysError(_("can't seek on file descriptor %d"), m_fd);
|
wxLogSysError(_("can't seek on file descriptor %d"), m_fd);
|
||||||
}
|
}
|
||||||
@ -385,7 +404,7 @@ wxFileOffset wxFile::Tell() const
|
|||||||
wxASSERT( IsOpened() );
|
wxASSERT( IsOpened() );
|
||||||
|
|
||||||
wxFileOffset iRc = wxTell(m_fd);
|
wxFileOffset iRc = wxTell(m_fd);
|
||||||
if ( iRc == wxInvalidOffset )
|
if ( CheckForError(iRc) )
|
||||||
{
|
{
|
||||||
wxLogSysError(_("can't get seek position on file descriptor %d"), m_fd);
|
wxLogSysError(_("can't get seek position on file descriptor %d"), m_fd);
|
||||||
}
|
}
|
||||||
@ -429,6 +448,7 @@ wxFileOffset wxFile::Length() const
|
|||||||
|
|
||||||
if ( iRc == wxInvalidOffset )
|
if ( iRc == wxInvalidOffset )
|
||||||
{
|
{
|
||||||
|
// last error was already set by Tell()
|
||||||
wxLogSysError(_("can't find length of file on file descriptor %d"), m_fd);
|
wxLogSysError(_("can't find length of file on file descriptor %d"), m_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user