Why ofstream would fail to open the file in C++? Reasons? - c++

I am trying to open an output file which I am sure has a unique name but it fails once in a while. I could not find any information for what reasons the ofstream constructor would fail.
EDIT:
It starts failing at some point of time and after that it continuously fails until I stop the running program which write this file.
EDIT:
once in a while = 22-24 hours
code snippet ( I don't this would help but still someone asked for it )
ofstream theFile( sLocalFile.c_str(), ios::binary | ios::out );
if ( theFile.fail() )
{
std::string sErr = " failed to open ";
sErr += sLocalFile;
log_message( sErr );
return FILE_OPEN_FAILED;
}

Too many file handles open? Out of space? Access denied? Intermittent network drive problem? File already exists? File locked? It's awfully hard to say without more details. Edit: Based on the extra details you gave, it sounds like you might be leaking file handles (opening files and failing to close them and so running out of a per-process file handle limit).
I assume that you're familiar with using the exceptions method to control whether iostream failures are communicated as exceptions or as status flags.
In my experience, the iostream classes give very little details on what went wrong when they fail during an I/O operation. However, because they're generally implemented using lower-level Standard C and OS API functions, you can often get at the underlying C or OS error code for more details. I've had good luck using the following function to do this.
std::string DescribeIosFailure(const std::ios& stream)
{
std::string result;
if (stream.eof()) {
result = "Unexpected end of file.";
}
#ifdef WIN32
// GetLastError() gives more details than errno.
else if (GetLastError() != 0) {
result = FormatSystemMessage(GetLastError());
}
#endif
else if (errno) {
#if defined(__unix__)
// We use strerror_r because it's threadsafe.
// GNU's strerror_r returns a string and may ignore buffer completely.
char buffer[255];
result = std::string(strerror_r(errno, buffer, sizeof(buffer)));
#else
result = std::string(strerror(errno));
#endif
}
else {
result = "Unknown file error.";
}
boost::trim_right(result); // from Boost String Algorithms library
return result;
}

You could be out of space, or there could be a permission issue. The OS may have locked the file as well. Try a different name/path for kicks and see if it works then.

One possibility is that you have another instance of the same program running.
Another is that perhaps you run two instances (for debugging purposes?) right after each other, and the OS hasn't finished closing the file and resetting the locks before your next instance of the program comes along and asks for it.

Related

How does one test if a file is LOCKED and/or read-only without opening?

Is there a portable (std::filesystem) method of testing if a file is "locked" or has "read-only" permissions? MacOS Finder, for example, has a "Locked" setting, which is DIFFERENT than the standard POSIX "permissions".
I need to test if a file can be deleted BEFORE I try to do the delete operation. Ideally, I'd like to avoid OPENING the file for R/W as a test.
This is during a SAVE/RENAME process, and (at least in past MacOS filesystems), OS calls to "exchange" two files worked even if the file was "Locked" in the Finder. Because the of the complexity surrounding how files are saved, and how PREVIOUS versions are "preserved", it's just better to know ahead of time so the operation can be avoided.
FURTHER NOTE: Opening a stream as R/W (std::ios::out | std::ios::in) on a LOCKED file with Read & Write permissions will fail with errno = 1 (operation not permitted). If the file is Read only but not locked, it'll fail with errno 13 (permission denied).
A MacOS (Cocoa) specific approach to testing the lock bit is discussed here:
How to check whether a file is locked in Cocoa?
OK -- this may not be the precise answer, but it APPEARS that you can do THIS (as suggested here:
#include <sys/stat.h>
bool IsLocked(std::string& thePath)
{
bool isLocked = false;
struct stat buf;
int retval = stat(thePath.c_str(), &buf); // NOTE: retval could be an error, like ENOENT (file doesn't exist)
if (0 != (buf.st_flags & UF_IMMUTABLE)) {
isLocked = true;
//is immutable
}
return isLocked;
}
In my own code I deal with retval errors in a more robust manner. You should, too!
But NOTE: while this DOES correctly indicate the status of the Finder's Lock bit/flag for the file, it DOES NOT reflect if the file is "read only". The documentation on UF_IMMUTABLE says "file may not be changed" -- which is obviously NOT accurate.

Portable temporary files with C++ (C++ standard libraries or Boost)?

Is there a portable way of creating temporary files with C++ that get automatically deleted when the program terminates (regardless of whether it crashes, gets killed, or just reaches return 0; in main().).
On Unix systems, I can open a file, delete it and then keep the still existing handle. This works with FILE *, std::fstream etc.
On Windows, this appears not to work. The only way I found is using CreateFile with the FILE_FLAG_DELETE_ON_CLOSE flag.
Is there something smarter that (1) works both on Linux and Windows, (2) has the "the file is removed on when the program terminates" behaviour as on Linux. I would be fine with #ifdef code as long as the file type that I work with is the same on both systems (e.g. std::fstream or FILE *).
I know about this solution, but this appears only to work on graceful exits and would require me to either set up central handlers and manage all temporarily opened files.
Edit: Rephrased the question to "how can I get files on Windows that are automatically removed as removed-but-still-open files in Linux.
http://www.cplusplus.com/reference/cstdio/tmpfile/
Creates a temporary binary file, open for update ("wb+" mode, see
fopen for details) with a filename guaranteed to be different from any
other existing file.
The temporary file created is automatically deleted when the stream is
closed (fclose) or when the program terminates normally. If the
program terminates abnormally, whether the file is deleted depends on
the specific system and library implementation.
For abnormal termination, handle std::terminate by using: http://en.cppreference.com/w/cpp/error/set_terminate
Clean up the file with std::remove and then re-throw. I haven't tested this abornmal termination stuff yet but it should work. The temporary file creation works for sure. I've used it before.
It can be wrapped in a streambuf for usage with streams.
Also as a partial solution you can write a class, that deletes the file on destruction. On windows you can use MoveFileExW(filepathFull, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) if that fails to have the file deleted on reboot. All of this can be hidden in the class. See for example: tmpfile.h tmpFile.cpp
Alternatively you can use something like:
struct TmpFile{
FILE* file;
TmpFile(std::string path){
#ifdef _WIN32
HANDLE handle = CreateFile(path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0,
OPEN_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, 0);
if(handle == INVALID_HANDLE_VALUE) throw "Error";
int fd = _open_osfhandle((intptr_t)h, _O_APPEND | _O_RDONLY);
if(fd == -1){ CloseHandle(handle); throw "Error"; }
file = _fdopen(fd, "a+");
if(f == NULL){ _close(fd); throw "Error"; }
#else
file = fopen(path.c_str(), "w+");
unlink(path.c_str());
#endif
}
~TmpFile(){
fclose(file);
}
};
Check the access modifiers and adjust to your needs (especially the error handling) This has the nice properties of RAII and will delete the file even in exception cases. However some failures where the dtor is not called will leak the handle in which case the file might not be deleted on windows.
The Win32 handling is taken from here: https://stackoverflow.com/a/7369662/1930508 Check the explanations there.

Is my logging-module thread safe?

Guys, I am a beginner in threading and logging.
Btw, I am not a native English speaker, so pardon me if there is any mistake in my English.
I have created a multiple-thread software, where each thread uses logging module like the following:
Each thread uses different log files, so I believe that the chances of data conflicts occurred are 0.
__inline void print_logW(int _level,const wchar_t *domain,const wchar_t *msg)
{
wchar_t mess[200] = _T("");
if(_level<=traceLevel)
{
__time64_t timer;
struct tm t_st;
_time64(&timer);
localtime_s(&t_st,&timer);
if (domain == NULL)
{
domain = _T("");
}
if (msg != NULL)
{
if (showTimeStampFlag == true)
{
swprintf_s(mess,200,_T("%s : %ld"),msg,GetTickCount());
}
else
{
wcscpy_s(mess,200,msg);
}
}
if(oldTime.tm_year != t_st.tm_year || oldTime.tm_mon != t_st.tm_mon || oldTime.tm_mday != t_st.tm_mday)
{
oldTime = t_st;
print_log_preparebyDateW();
}
FILE* fp;
errno_t err = _wfopen_s(&fp, this->m_pathW, _T("at+, ccs=UTF-8"));
if (err != 0)
{
// error
return;
}
fwprintf_s(fp, m_logFormatW,
_level,
1900 + t_st.tm_year, t_st.tm_mon + 1, t_st.tm_mday,
t_st.tm_hour, t_st.tm_min, t_st.tm_sec,
domain, mess
);
fflush(fp);
fclose(fp);
}
}
When I see the log of the software that I made, I found a problem where sometimes the thread process becomes so slow (a process (such as getting pointer of an image) that usually only take 16 ms max, would take 0.2 seconds or more to finish). I am still investigating the cause of this problem, but at first, I would like to know whether the logging module is already thread safe or not.
By the way, for the parameters,
"_level" is the logging level to print or unprint the details of the process
I use "domain" to show the class where the logging is performed
"msg" is the content of the log (e.g. "process 1 started")
And as for the m_logFormatW,
m_logFormatW = _T("[%.2d][%.4d-%.2d-%.2dT%.2d:%.2d:%.2d][%s] %s\n");
If there is any question or anything unclear, feel free to ask.
As long as you are linking to the multi-threaded runtime libraries and oldTime is not a global or static variable your log function will be thread safe. If oldTime is a global or static variable you will need to serialize access to it when you access or modify it otherwise you risk a race condition. The only other thing that may not be thread safe is print_log_preparebyDateW but it's hard to say since you haven't included the code for it. As long as oldTime is not global or static and all the runtime library functions that you use are marked as thread safe or are part of a library marked as thread safe in the MSDN you'll be OK.
The only other problem I can see is when you open the file. If the file is already open and another thread attempts to log information the open call will fail causing the information to be lost. This is because _wfopen_s opens the file without any sharing modes. You can fix this by using std::mutex and locking it while the file is open and unlocking it after the file is closed.
One possible reason your worker threads are taking longer to execute than expected is that opening the log file, writing the information, flushing the file and closing it can take a bit of extra time. This can happen any time file I/O occurs even when caching is involved. Usually you can reduce the time by opening the log file once and then closing it when your application terminates.
Another possible solution to reduce the time it takes your worker threads to execute is to use a pipe. In this scenario you write the log text to a pipe and have an additional thread that reads from the pipe and writes to the log file. This will eliminate any disk I/O that may occur when your worker threads log information. You may encounter some instances where the logging takes a bit of extra time if the pipe is full but it won't happen as often.
Your approach is good for single threaded application and will not work in multithreaded environment as you are not serializing the log message requests.
Its better you look into some well written logger class in opensource such as
a) AsynchronousAndSynchronouslogger - http://www.codeproject.com/Articles/288827/g2log-An-efficient-asynchronous-logger-using-Cplus
b) Simplethreadsafe - http://cpplogging.codeplex.com/
c) Log4Cpp - http://log4cpp.sourceforge.net/

Check for writing permissions to file in Windows/Linux

I would like to know how to check if I have write permissions to a folder.
I'm writing a C++ project and I should print some data to a result.txt file, but I need to know if I have permissions or not.
Is the check different between Linux and Windows? Because my project should run on Linux and currently I'm working in Visual Studio.
The portable way to check permissions is to try to open the file and check if that succeeded. If not, and errno (from the header <cerrno> is set to the value EACCES [yes, with one S], then you did not have sufficient permissions. This should work on both Unix/Linux and Windows. Example for stdio:
FILE *fp = fopen("results.txt", "w");
if (fp == NULL) {
if (errno == EACCES)
cerr << "Permission denied" << endl;
else
cerr << "Something went wrong: " << strerror(errno) << endl;
}
Iostreams will work a bit differently. AFAIK, they do not guarantee to set errno on both platforms, or report more specific errors than just "failure".
As Jerry Coffin wrote, don't rely on separate access test functions since your program will be prone to race conditions and security holes.
About the only reasonable thing to do is try to create the file, and if it fails, tell the user there was a problem. Any attempt at testing ahead of time, and only trying to create the file if you'll be able to create and write to it is open to problems from race conditions (had permission when you checked, but it was removed by the time you tried to use it, or vice versa) and corner cases (e.g., you have permission to create a file in that directory, but attempting to write there will exceed your disk quota). The only way to know is to try...
The most correct way to actually test for file write permission is to attempt to write to the file. The reason for this is because different platforms expose write permissions in very different ways. Even worse, just because the operating system tells you that you can (or cannot) write to a file, it might actually be lying, for instance, on a unix system, the file modes might allow writing, but the file is on read only media, or conversely, the file might actually be a character device created by the kernel for the processes' own use, so even though its filemodes are set to all zeroes, the kernel allows that process (and only that process) to muck with it all it likes.
Similar to the accepted answer but using the non-deprecated fopen_s function as well as modern C++ and append open mode to avoid destroying the file contents:
bool is_file_writable(const std::filesystem::path &file_path)
{
FILE* file_handle;
errno_t file_open_error;
if ((file_open_error = fopen_s(&file_handle, file_path.string().c_str(), "a")) != 0)
{
return false;
}
fclose(file_handle);
return true;
}

Error while reading files with native code on windows mobile

I'm new here and my english is not really good. Apologize any inconvenience!
I'm programming an application for windows mobile with native code (MFC). I'm trying to open a file and this is driving me crazy. I've tried to open it in a thousand diferent ways... And I really achieve it, but when I try to read (fread or getline) the program crashes without any explanation:
The program 'x' finalize with code 0 (0x0)
The GetLastError() method, in some cases, returns me a 183.
Then, I put the code I've used to open the file:
std::wifstream file(L"\\Archivos de programa\\Prog\\properties.ini");
wchar_t lol[100];
if (file) {
if(!file.eof()) {
file.getline(lol,99);
}
}
It enters on all the if's, but the getline crashes.
FILE * lol = NULL;
lol = _wfope n(ruta, L"rb");
DWORD a = GetLastError();
if ( lol != NULL )
return 1;
else
return -1;
It returns 1 (correct), and after, in a later getline, it stores trash on the string. However, it doesn't crash!!
fp.open (ruta, ifstream::in);
if ( fp.is_open() ) {
return 1;
}else{
return -1;
}
It enters on the return 1, but when executing the later getline() crashes.
I've debugged the getline() method and it crashes on the library fstream, right there:
if ((_Meta = fget c (_File)) == EOF)
return (false);
In the if. The fgetc(), I supose.
I'm going completely crazy!! I need some clue, please!!
The path of the file is correct. First, because, in theory, the methods open the file, and second, I obtain the path dinamically and it matches.
Emphasize that the fread method also crashes.
Thanks in advance!
P.S.:
Say that when I do any fopen, the method fp.good() returns me FALSE, and the GetLastError returns me 183. By the other hand, if I use fp.fopen(path, ifstream::in); or std::wifstream fp(path); the fp.good(); returns me TRUE, and the GetLastError() doesn't throw any error (0).
A hint: use the Process Monitor tool to see what goes wrong in the file system calls.
The path accepted by wifstream is lacking a drive ("C:" or the like) (I don't know what the ruta variable points to)
Apart from the streams problem itself, you can save yourself a lot of trouble by using the GetProfileString and related functions, when using a windows .ini file.
I'm shooting in the dark here, but your description sounds like a runtime mismatch story. Check that MFC and your project use the same runtime link model (static/dynamic). If you link to MFC dynamically, then the restriction is stricter: both MFC and your project have to use dynamic runtime.
I don't know why, but with the CFile class... it works...
Programming mysteries!
Shooting in the dark too.
Unexplained random crash in MFC often comes from a mismatch message handler prototype.
For example the following code is wrong but it won't generate any warning during compilation and it may work most of the time :
ON_MESSAGE(WM_LBUTTONDOWN, onClick)
...
void onClick(void) //wrong prototype given the macro used (ON_MESSAGE)
{
//do some stuff
}
Here the prototype should be :
LRESULT onClick(WPARAM, LPARAM)
{
}
It often happens when people get confident enough to start modifying manually the message maps.