Pinguin San Pinguin San - 6 months ago 16
Linux Question

Will File I/O In Current Working Directory Ever Fail?

On my home Linux laptop, I like to write wrapper programs and GUI helpers for things I use frequently. However, I don't like Bash scripting very much, so I do a lot of stuff in C++. However, a lot of times, this requires me to use the system() function from the cstdlib.

This system() command is awesome, but I wanted a way to call system() and receive the stdout/stderror. The system() command only returns the return code from the command. So, in a Bash script, one can do:

myVar=$(ls -a | grep 'search string')
echo $myVar


and myVar will output whatever the stdout was for the command. So I began writing a wrapper class that will add a pipe-to-file to the end of the command, open the file, read all of the piped stdout, and return it as either one long string or as a vector of strings. The intricacies of the class are not really relevant here (I don't think anyway), but the above example would be done like this:

SystemCommand systemCommand;
systemCommand.setCommand("ls -a | grep \'search string\' ");
systemCommand.execute();
std::cout << systemCommand.outputAsString() << std::endl;


Behind the scenes, when systemCommand.execute() is called, the class ensures that the command will properly pipe all stdout/stderr to a randomly generated filename, in the current working directory. So for example, the above command would end up being

"ls -a | grep 'search string' >> 1452-24566.txt 2>&1".


The class then goes attempts to open and read from that file, using ifstream:

std::ifstream readFromFile;
readFromFile.open(_outputFilename);
if (readFromFile.is_open()) {
//Read all contents of file into class member vector
...
readFromFile.close();

//Remove temporary file
...
} else {
//Handle read failure
}


So here is my main question will std::ifstream ever fail to open a recently created file in the current working directory? If so, what would be a way to make it more robust (specifically on Linux)?

A side/secondary question: Is there a very simplified way to achieve what I'm trying to achieve without using file pipes? Perhaps some stuff available in unistd.h? Thanks for your time.

Answer

So here is my main question will std::ifstream ever fail to open a recently created file in the current working directory?

Yes.

  1. Mount a USB thumb drive (or some other removable media)
  2. cd to the mount
  3. Execute your program. While it's executing, remove the drive.
  4. Watch the IO error happen.

There's a ton of other reasons too. Filesystem corruption, hitting the file descriptor limit, etc.

If so, what would be a way to make it more robust (specifically on Linux)?

Make temporary files in /tmp, whose entire purpose is for temporary files. Or don't create a file at all, and use pipes for communication instead (Like what popen does, like harmic suggested). Even so, there are no guarantees; try to gracefully handle errors.