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
- Added cwd and env arguments to wxExecute() (Emilien Kia).
- Added "rest" argument to wxString::Before{First,Last}().
- Added wxThread::OnKill() and OnDelete() callbacks.
- Added cwd and env arguments to wxExecute() (Emilien Kia).
- Added "rest" argument to wxString::Before{First,Last}().
- Added wxThread::OnKill() and OnDelete() callbacks.
+- Added wxFile::GetLastError() and ClearLastError() (ryazanov).
// ctors
// -----
// def ctor
// ctors
// -----
// 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())
wxFile(const wxString& fileName, OpenMode mode = read);
// attach to (already opened) file
// open specified file (may fail, use IsOpened())
wxFile(const wxString& fileName, OpenMode mode = read);
// 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
// create a new file (with the default value of bOverwrite, it will fail if
// open/close
// create a new file (with the default value of bOverwrite, it will fail if
bool Close(); // Close is a NOP if not opened
// assign an existing file descriptor and get it back from wxFile object
bool Close(); // Close is a NOP if not opened
// 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; }
int fd() const { return m_fd; }
void Detach() { m_fd = fd_invalid; }
int fd() const { return m_fd; }
// is end of file reached?
bool Eof() const;
// has an error occurred?
// is end of file reached?
bool Eof() const;
// 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
wxFileKind GetKind() const { return wxGetFileKind(m_fd); }
// type such as disk or pipe
wxFileKind GetKind() const { return wxGetFileKind(m_fd); }
// dtor closes the file if opened
~wxFile() { Close(); }
// dtor closes the file if opened
~wxFile() { Close(); }
wxFile(const wxFile&);
wxFile& operator=(const wxFile&);
wxFile(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
};
// ----------------------------------------------------------------------------
};
// ----------------------------------------------------------------------------
+ /**
+ 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.
Only values of @c wxFile::read or @c wxFile::write really make sense here.
/**
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.
#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
#ifndef W_OK
enum
// Windows compilers don't have these constants
#ifndef W_OK
enum
wxFile::wxFile(const wxString& fileName, OpenMode mode)
{
m_fd = fd_invalid;
wxFile::wxFile(const wxString& fileName, OpenMode mode)
{
m_fd = fd_invalid;
+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
bool wxFile::Create(const wxString& fileName, bool bOverwrite, int accessMode)
{
// create the file, fail if it already exists and bOverwrite
bool wxFile::Create(const wxString& fileName, bool bOverwrite, int accessMode)
{
O_BINARY | O_WRONLY | O_CREAT |
(bOverwrite ? O_TRUNC : O_EXCL),
accessMode );
O_BINARY | O_WRONLY | O_CREAT |
(bOverwrite ? O_TRUNC : O_EXCL),
accessMode );
+ if ( CheckForError(fd) )
{
wxLogSysError(_("can't create file '%s'"), fileName);
return false;
{
wxLogSysError(_("can't create file '%s'"), fileName);
return false;
int fd = wxOpen( fileName, flags, accessMode);
int fd = wxOpen( fileName, flags, accessMode);
+ if ( CheckForError(fd) )
{
wxLogSysError(_("can't open file '%s'"), fileName);
return false;
{
wxLogSysError(_("can't open file '%s'"), fileName);
return false;
bool wxFile::Close()
{
if ( IsOpened() ) {
bool wxFile::Close()
{
if ( IsOpened() ) {
- if (wxClose(m_fd) == -1)
+ if ( CheckForError(wxClose(m_fd)) )
{
wxLogSysError(_("can't close file descriptor %d"), m_fd);
m_fd = fd_invalid;
{
wxLogSysError(_("can't close file descriptor %d"), m_fd);
m_fd = fd_invalid;
ssize_t iRc = wxRead(m_fd, pBuf, nCount);
ssize_t iRc = wxRead(m_fd, pBuf, nCount);
+ if ( CheckForError(iRc) )
{
wxLogSysError(_("can't read from file descriptor %d"), m_fd);
return wxInvalidOffset;
{
wxLogSysError(_("can't read from file descriptor %d"), m_fd);
return wxInvalidOffset;
ssize_t iRc = wxWrite(m_fd, pBuf, nCount);
ssize_t iRc = wxWrite(m_fd, pBuf, nCount);
+ if ( CheckForError(iRc) )
{
wxLogSysError(_("can't write to file descriptor %d"), m_fd);
{
wxLogSysError(_("can't write to file descriptor %d"), m_fd);
// call it then
if ( IsOpened() && GetKind() == wxFILE_KIND_DISK )
{
// call it then
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);
return false;
{
wxLogSysError(_("can't flush file descriptor %d"), m_fd);
return false;
}
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);
}
wxASSERT( IsOpened() );
wxFileOffset iRc = wxTell(m_fd);
wxASSERT( IsOpened() );
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);
}
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);
}