Creating a new file with group permissions - c++

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);

Related

Create accessible file from root privilege process

I'm having a bunch of processes from different privileges, all running a shared code that open (and create if needed) a file for write using fopen_s with "a+" flag.
However, since no permissions that supplied to this command, and a root process create the file first, than other non-root processes couldn't access this file.
I could use int open(const char *pathname, int flags, mode_t mode); and thus control the file permissions (represented by mode_t) to allow access for everyone, but I need the file descriptor (FILE *) and not fileID. so I can use FILE *fdopen(int fd, const char *mode); in order to make the conversion.
Perhaps there's a more straight forward way to do it ?
No. The technique you described (open followed by fdopen) is the correct way to achieve what you want to do. As Some programmer dude pointed out, you could call chmod from your program to change the file permissions after it's created, but that's a more roundabout way to do it.
I could use int open(const char *pathname, int flags, mode_t mode); and thus control the file permissions (represented by mode_t)
Not really. Unless you set your process's umask setting. Because the permissions passed to open() are not the permissions the created file is necessarily created with.
Per POSIX open() (bolding mine):
the access permission bits (see <sys/stat.h>) of the file mode shall be set to the value of the argument following the oflag argument taken as type mode_t modified as follows: a bitwise AND is performed on the file-mode bits and the corresponding bits in the complement of the process' file mode creation mask. Thus, all bits in the file mode whose corresponding bit in the file mode creation mask is set are cleared.
So
int fd = open( someFileName, O_CREAT | O_RDWR, 0644 );
is NOT guaranteed to set the file permissions to 0644.
If your file creation mask is set to 0077, then the file will actually be created with permissions set to 0600.
Note that the umask() setting is a process-wide property, and it's not really a good idea to change it much. And if you're trying to write general-purpose code that has no side effects, it's a bad idea to change it at all. For example, changing the umask() setting in a multithreaded process in order to allow wider access to files being created can cause
security problems if another thread creates a file at the same time.
The best way to set file permissions to be exactly what you want is to set file permissions to be exactly what you want with fchmod():
FILE *f = fopen(...);
fchmod( fileno( f ), 0644 );
In fact, since the umask() setting is a process-wide property, it's always possible in general that it can be changed by another thread at any time, so setting the permissions explicitly via chmod() or fchmod() is the only guaranteed way to get exactly the permissions specified in all circumstances.

How to open file with ofstream so that other users can append/write to same file?

We have a binary which creates a daily CSV report with some file name like Sample_20170523 i.e filename appended with current date but now the issue is when some other runs the binary on the same day then there is error unable to open the file.Code snippet for this issue is as follows:
std::ofstream of;
of.open("FileName_20170523",ios::out);
if(!of)
std::cout<<"Unable to open file..."<<std::endl;
So after checking it seems this problem arises because the file was already created by another user. So just wanted to know is there any mechanism in c++ in which we can give 777 permissions to programmatically created file ?
You can use either chmod() or fchmod() to change the permission of a file.
system() allows to execute system commands.
system("chmod 777 diretory_to_file/name");
gives r+w+x to everyone if it already exits
std::ofstream of;
of.open("FileName_20170523",ios::out);

Setting file permissions when opening a file with ofstream

Is there a way in C++'s standard libraries (or linux sys/stat.h, sys/types.h, sys/.... libraries) to set the file permissions of a file when creating it with ofstream (or using something else from those libraries)?
When I create a file it just gets created with some default set of file permissions (I assume whatever the current umask is), but I want to explicitly set the permissions to something other than the default (ex. 600), and I can't just set the umask before starting the program (b/c others will run it).
// Example of creating a file by writing to it
ofstream fp(filename.c_str())
/* write something to it */
Is there a way to do this in C++ or if not, a way to set the umask within the C++ program?
For example, in C's standard library you can just do:
open(filename, O_RDWR|O_CREAT, 0666)
but I don't want to resort to using the C function, as it'd be nice to be able to use the functions associated with fstream objects.
(Side Note: there was a question whose title was exactly what I was looking for, but it turned out to be unrelated.)
You cannot. The standard library must be platform agnostic, and permissions like 0600 are meaningless on Windows for example. If you want to use platform-specific features, you'll need to use platform-specific APIs. Of course, you can always call umask() before you open the file, but that's not part of the C++ standard library, it's part of the platform API.
Note: open() isn't part of the C standard library either. It's a platform API. The C standard library function to open a file is fopen().
In C++17, std::filesystem::permissions was introduced. It will enable you to get and set permissions in a platform-agnostic manner.
Get permissions:
using fs = std::filesystem;
bool owner_can_read =
fs::status("my_file.txt").permissions() & fs::perms::owner_read != fs::perms::none;
Set permissions (add all permissions for owner and group, that is, add modes 0x770 on unix):
using fs = std::filesystem;
fs::permissions("my_file.txt",
fs::perms::owner_all | fs::perms::group_all,
fs::perm_options::add);
Example based on an example from cppreference.

Fixing file permissions after modifying in 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")

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.