I know that when i create a shared memory block, we set the permission so that every proccess can read and write in that block with 0777 (no idea why, my teacher just said to use it like that).
I'm creating with shmget as:
shmget(IPC_PRIVATE, sizeof(server_config), IPC_CREAT|0777)
However I'd like to know:
What each number means
How to change the flag after the shared memory block is created
How to only allow 1 proccess to write, while all the other proccesses can only read
It's an octal number of OR
ed options the same ones that you use for directory permissions.
This is their meaning (source)
rwx rwx rwx = 111 111 111
rw- rw- rw- = 110 110 110
rwx --- --- = 111 000 000
and so on...
rwx = 111 in binary = 7
rw- = 110 in binary = 6
r-x = 101 in binary = 5
r-- = 100 in binary = 4
Where of course, r
stands for read and w
for write then x
means execute.
There are also constants defined with these values (see man open(2)
)
S_IRWXU 00700 user (file owner) has read, write and execute permission
S_IRUSR 00400 user has read permission
S_IWUSR 00200 user has write permission
S_IXUSR 00100 user has execute permission
S_IRWXG 00070 group has read, write and execute permission
S_IRGRP 00040 group has read permission
S_IWGRP 00020 group has write permission
S_IXGRP 00010 group has execute permission
S_IRWXO 00007 others have read, write and execute permission
S_IROTH 00004 others have read permission
S_IWOTH 00002 others have write permission
S_IXOTH 00001 others have execute permission
As you can see 0777
has a leading 0
because it's octal and is equivalent to S_IRWXU | S_IRWXG | S_IRWXO
.
To answer your other two questions:
You can change the permissions on a shared memory block with shmctl
. It goes something like this -- completely untested, may be buggy:
int change_shm_perm(int shmid, mode_t new_permissions)
{
struct shmid_ds buf;
if (shmctl(shmid, IPC_STAT, &buf)) {
perror("shmctl(IPC_STAT)");
return -1;
}
buf.shm_perm = (buf.shm_perm & ~0777) | (new_permissions & 0777);
if (shmctl(shmid, IPC_SET, &buf)) {
perror("shmctl(IPC_SET)");
return -1;
}
return 0;
}
To allow only one process to write, while all others can only read, the process with write privileges must run under its own uid. Then you have that process create the memory segment and set its permissions to 0644
. It should be clear from the explanation of mode bits why this has the desired effect.