Fixing file permissions after modifying in C++? - c++

I'm saving my data in the executable file of the program. I copy it to a temporary file, overwrite a part starting at a 'magic string' and rename it to the original. I know this is a bad idea, but I'm doing it just for experimenting.
I got everything to work so far, except for that I have to re-enable "Allow running as an executable" each time the file is replaced. What ways are there to solve this?
Additional information: I use linux.

If you want to avoid using system(), you can use
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
It is documented in http://linux.die.net/man/3/chmod.
See also: C++ - How to set file permissions (cross platform).

If you include stdlib.h, you can use system("command").
Try it:
system("chmod 755 yourExeFile")

Related

Setting permissions to a directory using C++

I try to create new directory and set its permissions (using at most c++11 and without boost) so user, group and others can list files inside read them and write new files (linux environment).
#include <sys/stat.h>
#include <sys/types.h>
int main(void) {
const char* path = "/tmp/newDir";
mode_t process_mask = umask(0);
int syscall_status = mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO);
umask(process_mask);
return syscall_status;
}
This code is based on the man (2) page of mkdir (and umask).
However the created directory has rwxr-xr-x permissions (no write for group and others).
I also tried using chmod syscall on the directory but it didn't solve the problem. Other sources in stackoverflow treated files (rather than folders), and trying to apply the file-methods on my directory didn't work as well.
Also, I want to avoid calling system() from stdlib, this is the last option I'll use if I don't find a solution (security considerations).
char* path = "/tmp/newDir";
Besides the syntax error, this is ill-formed since C++11. Prior to that, this would be using a deprecated conversion. String literals are const in C++ -> Use pointer to const.
Other than that, the program is correct assuming a POSIX system. If it fails, then you can check errno to see why. If you don't get all permissions: Check if the parent directory has a default ACL; that would override umask.
A portable way of creating a directory in C++ is std::filesystem::create_directory and a way of setting permissions is std::filesystem::permissions.

How to create a text file in a folder on the desktop

I have a problem in my project. There is a project folder on my desktop. I want to create a text file and write something include this text file. That is my code:
ofstream example("/Users/sample/Desktop/save.txt");
But I want to it could been run the other mac. I don't know what I should write addres for save.txt.
Can anyone help me?
Create a file and write some text to it is simple, here is a sample code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
std::ofstream o("/Users/sample/Desktop/save.txt");
o << "Hello, World\n" << std::endl;
return 0;
}
I hope that answers your question but I am not sure if i understand your question correctly, If not please add the details correctly of what you are trying to acheive.
[Update]:
Okay I guess the comment clears the problem.
Your real question is, You want to save the file in the desktop of the user who is playing the game. So getting the path of the current user's desktop is the problem.
I am not sure if there is an portable way to get desktop path but it can be done in following ways:
In Windows:
Using the SHGetSpecialFolderPath() function.
Sample code:
char saveLocation[MAX_PATH] = {0};
SHGetSpecialFolderPath(NULL, saveLocation, CSIDL_DESKTOPDIRECTORY, FALSE);
//Now saveLocation contains the path to the desktop
//Append your file name to it
strcat(saveLocation,"\\save.txt");
ofstream o(saveLocation);
In Linux:
By using environment variables $HOME
sample code:
string path(getenv("HOME"));
path += "/Desktop/save.txt";
ofstream o(path);
Rules defining where-you-should-save-file vary from platform to platform. One option would be to have it part of your compile script (that is you #define SAVEGAME_PATH as part of your compilation configuration), and thus your code itself remain more platform-agnostic.
The alternative is to find a save-data-management library that is already designed to be ported across different platforms. Whether it'd be a C or C++ or whatever-binary-interoperable library then no longer matters.
Just don't expect that to be part of C++ (the language).
if you want your program to run across platform,you'd better use the
relative path.
eg. "./output.txt",or better “GetSystemDirectory()”to obtain the system
directory to create a file,and then you could write or read the file
with the same path..

Creating a new file with group permissions

This seems straight forward enough , but i have not been able to identify how i could achive this in C++.
I am creating a file as
ofstream logfile(LOG_FILE, ios::out | ios::app);
The file is created with the following permissions.
-rw-r--r--
What i really want is
-rw-rw-rw-
For obvious reasons , i do not want to change the system umask for the same.
Thanks!
Take a look at the chmod call. This is used to change the permissions of a file.
There is currently no way to set the file permissions with standard C++. I suggest you use the chmod() system call, or equivalent if running on a non-unix OS.
include
mode_t mode=00777;
chmod("operate.sh", mode);

How to pass parameters with spaces via cstdlib system

I have this windows console app which takes a file, do some calculations, and then writes the output to a specified file. The input is specified in "app.exe -input fullfilename" format. I need to call this application from my C++ program, but I have a problem with spaces in paths to files. When I call the app directly from cmd.exe by typing (without specifying output file for clarity)
"c:\first path\app.exe" -input "c:\second path\input.file"
everything works as expected. But, when I try using cstdlib std::system() function, i.e.
std::system(" \"c:\\first path\\app.exe\" -input \"c:\\second path\\input.file\" ");
the console prints out that c:\first is not any valid command. It's probably common mistake and has simple solution, but I have been unable to find any. Thx for any help.
Instead of std::system(), you should use the _wspawnv function from the Windows API. Use _wspawnvp if you want to search for the program in PATH, rather than specifying a full path to it.
#include <stdio.h>
#include <wchar.h>
...
const WCHAR *app = L"C:\\path to\\first app.exe";
const WCHAR *argv[] = {app, L"-input", L"c:\\second path\\input file.txt"};
_wpspawnv(_P_WAIT, app, argv);
You could also use _spawnv / _spawnvp if you are 100% sure that your input filename will never, ever contain anything else than ASCII.
Don't try to put the quotes in the std::system() call. Try the following:
std::system("c:\\first\\ path\\app.exe -input c:\\second\\ path\\input.file");

Lock / Prevent edit of source files on Linux using C++

How can I programmatically lock/unlock, or otherwise prevent/enable editing, a source file on Linux using C++.
I want to be able to lock source file so that if I open it in an editor it will not allow me to save back to the same source file.
I am thinking of maybe changing the permissions to read-only (and change it back to read-write later): how do I do that from C++?
Try man fchmod:
NAME
chmod, fchmod - change permissions of a file
SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
int chmod(const char *path, mode_t mode);
int fchmod(int fildes, mode_t mode);
Why aren't you using a source code management tool like CVS or Subversion? CVS does nice locking (so does Subversion). More importantly, you have the history of changes. Better still (with CVS anyway) you have to make the step of doing a "checkout" to make the file writeable.
Yes, it is a bit hard to tell what you are looking for
Security against other users editing you files -> use "chmod, fchmod"
Security against you yourself accidentally messing with your source files -> you should really change your thinking and use a source control tool. Like Subversion (SVN) or even better Mercurial.