セマフォを使ってロックをするプログラム
#include <fcntl.h> // O_CREAT #include <semaphore.h> // sem_wait #include <stdio.h> // printf #include <unistd.h> // sleep int main() { sem_t *sem = sem_open("/unko", O_CREAT, 0666, 1); // ★パーミッション全開のつもり if(sem==NULL){ perror("sem_open"); return 1; } printf("ロック\n"); sem_wait(sem); printf("30秒スリープ\n"); sleep(30); printf("アンロック\n"); sem_post(sem); return 0; }
これを、異なるユーザで起動すると もう片方ではエラーになる。
root権限で起動中に一般権限で起動した例
★root権限側 # ./a.out ロック 30秒スリープ ★一般権限側 $ ./a.out sem_open: Permission denied
なぜかというと、sem_openでのパーミッション設定も、umask に引っ張られてしまうため
umask が 0022 の場合はマスクされてしまい、 0666 にしようとしても 0644 になってしまう。
$ umask 0022 $ ls -l /dev/shm/sem.unko -rw-r--r-- 1 root root 32 4月 11 11:35 /dev/shm/sem.unko
最初にroot権限でセマフォファイルが作られると一般権限ではreadonlyになるので sem_openで失敗してしまう
よって、umask(0) など必要に応じてマスク狩りをする
#include <fcntl.h> // O_CREAT #include <semaphore.h> // sem_wait #include <stdio.h> // printf #include <unistd.h> // sleep #include <sys/stat.h> // umask int main() { umask(0); // ★★マスク狩り sem_t *sem = sem_open("/unko", O_CREAT, 0666, 1); // ★パーミッション全開 if(sem==NULL){ perror("sem_open"); return 1; } printf("ロック\n"); sem_wait(sem); printf("30秒スリープ\n"); sleep(30); printf("アンロック\n"); sem_post(sem); return 0; }