System V共享内存权限位:含义,以及如何更改

时间:2015-10-20 01:40:49

标签: c unix shared-memory sysv-ipc

我知道当我创建一个共享内存块时,我们设置了权限,这样每个进程都可以用0777读取和写入该块(不知道为什么,我的老师只是说这样使用它)。

我用shmget创建:

shmget(IPC_PRIVATE, sizeof(server_config), IPC_CREAT|0777)

但是我想知道:

  • 每个数字的含义

  • 如何在创建共享内存块后更改标志

  • 如何只允许1个进程写入,而所有其他进程只能读取

1 个答案:

答案 0 :(得分:2)

它是OR个选项的八进制数,与您用于目录权限的选项相同。

这是他们的意思(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

当然,r代表w代表,然后x代表执行

还有使用这些值定义的常量(参见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

正如您所看到的,0777有一个前导0,因为它是八进制且相当于S_IRWXU | S_IRWXG | S_IRWXO

回答你的另外两个问题:

  • 您可以使用shmctl更改共享内存块的权限。它是这样的 - 完全未经测试,可能是错误的:

    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;
    }
    
  • 要只允许一个进程写入,而所有其他进程只能读取,具有写入权限的进程必须在其自己的uid下运行。然后,您可以创建内存段并将其权限设置为0644。从模式位的解释中应该清楚为什么这会产生预期的效果。