ofstream failing to create file when program runs with sudo - c++

I'm writing an application that is using libusb, and I'm working on a section that involves writing the data of the devices to an XML file.
I've realised that the program will likely need to be run with sudo, as when I tried to transfer to a device there wasn't sufficient permissions. However, when I run the program with sudo, the ofstream will no longer create the file. Why is this, and how can I fix it?
int writeDeviceList(const char* fileName, libusb_device **devs, ssize_t deviceCount)
{
std::ofstream file;
file.open(fileName, std::ios::trunc);
if(!file)
{
//Code enters here when run with root
std::cout << "\"" << fileName << "\" file failed to open\n";
return -1;
}
file << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
file << "<USB>\n";
ssize_t i;
for(i = 0; i < deviceCount; i++)
{
if(printdev(devs[i], &file) == -1)
{
return -1;
}
}
file << "</USB>\n";
file.close();
return 0;
}

One reason is if you are root on the local machine you run on, but the file is on an nfs mount of a remote machine, e.g. your normal user's home dir. Then root on the local machine will not be able to write or even open the file.

Related

Write file to Linux Application data directory

I need to write files to the Application Data directory of the application that I'm designing. Im developing under Ubuntu using Qt. The following snippet shows my write function:
FileOperations::Error FileOperations::saveUsage(SensorIdentification sensorID, QList<UsageListModel::Usage> &usageList)
{
QString fileName(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
fileName.append("/");
fileName.append("testnaam");
fileName.append(FILE_EXTENSION);
this->sensorID = sensorID;
QFile file(fileName);
if(!file.open(QIODevice::WriteOnly))
{
return Error::FileNotOpen;
}
QDataStream out(&file);
out << sensorID;
for(int i = 0; i < usageList.size(); i++)
out << usageList.at(i).date << usageList.at(i).totalSteps << usageList.at(i).wearTime;
if(file.size())
{
file.close();
return Error::NoError;
}
else
{
file.close();
return Error::WritingToFileFailed;
}
}
The fileName after the appends is: "/home/jan/.local/share/Foo/Bar With Spaces/testnaam.liv"
For some reason I cant write a file in that directory. It does work correctly when i write to the users documents folder. Why cant i write to the appdata folder?

How can i open a file in visual c++?

I'm using visual studio and having problem opening this text file I've put it in the folder with all the source code yet i get an "No such file or directory" error. Here's my code
void Game::load_map(const char *filename)
{
int width,height,current;
std::ifstream in(filename);
if(in.fail()){
std::cout << "problem opening the file" <<std::endl;
perror(filename);
}
else
{
in >> width;
in >> height;
for(int i = 0; i < height; i++)
{
std::vector<int> vec;
for(int j = 0; j<width;j++)
{
if(in.eof())
{
std::cout<< "file ends error" << std::endl;;
return;
}
in >> current;
if(current>=0 && current<=1)
{
vec.push_back(current);
}else{
vec.push_back(0);
}
}
map.push_back(vec);
}
}
in.close();
}
and this how I'm calling this function:
load_map("map.map");
You program probably doesn't run in the same directory where the source code is placed, but rather in the Solution\Debug directory.
Either pass a file path relative to this directory to your function
load_map("..\\Project\\map.map");
or move the file you want to open there. Or 3rd option if you're not sure where you program's working directory is, provide a full path
load_map("c:\\Blah\\Blub\\Project\\map.map");

Calling ofstream.close doesn't release the file

After executing code like this:
{
ofstream ofs("file.txt", ios::app);
ofs << "Output" << endl;
ofs.close();
Sleep(100); //just in case
bool opened = ofs.is_open(); //always false
} //ofs out of scope
I would expect file.txt to be completely free, but if I open it with notepad I cant edit the file because it's owned by process until my program exits. How do I make the file accessible?

Detect if file is open in C++

Is there any way in C++ to detect if a file is already open in another program?.I want to delete and rewrite some files, but in case a file is opened I want to display an error message. I am using Windows OS.
Taking an action depending on the result of the "is file open query" is a race condition (the query returns false and then a program opens the file before your program attempts to delete it for example).
Attempt to delete the file using DeleteFile() and if it fails display the reason the file delete failed, using GetLastError(). See System Error Codes for the list of error codes (ERROR_SHARING_VIOLATION which states "The process cannot access the file because it is being used by another process.")
You can use CreateFile API function with the share mode of NULL, which opens the file for exclusive use.
You can use remove("filename") function.
you can use is_open() to check if the file is open. If it is you can close it or do somehting else.
Here is an exampe:
int main ()
{
fstream filestr;
filestr.open ("test.txt");
if (filestr.is_open())
{
filestr << "File successfully open";
filestr.close();
}
else
{
cout << "Error opening file";
}
return 0;
}
#include <iostream> // std::cout
#include <fstream> // std::ofstream
int main () {
std::ofstream ofs;
ofs.open ("example.txt");
if (ofs.is_open())
{
ofs << "anything";
std::cout << "operation successfully performed\n";
ofs.close();
}
else
{
std::cout << "Error opening file";
}
return 0;
}

C++ Trouble Reading a Text File

I'm trying to read a text file but nothing is coming out. I feel like maybe It's not linking correctly in my Visual Studio Resources folder but if I double click it - it opens fine in visual studio and it doesn't run into any problems if I test to see if it opens or if it is good. The program compiles fine right now but there's not output. Nothing prints to my command prompt. Any suggestions?
Code
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
int main()
{
char str[100];
ifstream test;
test.open("test.txt");
while(test.getline(str, 100, '#'))
{
cout << str << endl;
}
test.close();
return 0;
}
Text File
This is a test Textfile#Read more lines here#and here
You try to open file by name without path, this means the file shall be in current working directory of your program.
The problem is with current directory when you run your program from VS IDE. VS by default sets current working directory for runnning program to project directory $(ProjectDir). But your test file resides in resources directory. So open() function could not find it and getline() immediately fails.
Solution is simple - copy your test file to project directory. Or copy it to target directory (where your program .exe file is created, typically $(ProjectDir)\Debug or $(ProjectDir)\Release) and change working directory setting in VS IDE: Project->Properties->Debugging->Working Directory, set to $(TargetDir). In this case it will work both from IDE and command line/Windows Explorer.
Another possible solution - set correct path to file in your open() call. For testing/education purposes you could hardcode it, but actually this is not good style of software development.
Not sure if this will help but I wanted to simply open a text file for output and then read it back in. Visual Studio (2012) seems to make this difficult. My solution is demonstrated below:
#include <iostream>
#include <fstream>
using namespace std;
string getFilePath(const string& fileName) {
string path = __FILE__; //gets source code path, include file name
path = path.substr(0, 1 + path.find_last_of('\\')); //removes file name
path += fileName; //adds input file to path
path = "\\" + path;
return path;
}
void writeFile(const string& path) {
ofstream os{ path };
if (!os) cout << "file create error" << endl;
for (int i = 0; i < 15; ++i) {
os << i << endl;
}
os.close();
}
void readFile(const string& path) {
ifstream is{ path };
if (!is) cout << "file open error" << endl;
int val = -1;
while (is >> val) {
cout << val << endl;
}
is.close();
}
int main(int argc, char* argv[]) {
string path = getFilePath("file.txt");
cout << "Writing file..." << endl;
writeFile(path);
cout << "Reading file..." << endl;
readFile(path);
return 0;
}