Reputation:
I'm experiencing a lot of difficulty getting Semaphores to work on a Linux based system in C.
The process of my application is such:
sem_open
with a common name to open the semaphore.If I create the semaphore before forking, it works fine. However, requirements prevent me from doing so. When I try to call sem_open
for the second time, I get a "Permission Denied" error (via errno
).
Is it possible to do this in any way? Or is there any way to open the semaphore in one process and used a shared memory mechanism to share it with the child process?
Upvotes: 9
Views: 22426
Reputation: 15406
Don't forget to specify the mode and value parameter when using O_CREAT in the flags. Here is a working example :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/wait.h>
static void parent(void)
{
sem_t * sem_id;
sem_id=sem_open("mysem", O_CREAT, 0600, 0);
if(sem_id == SEM_FAILED) {
perror("parent sem_open");
return;
}
printf("waiting for child\n");
if(sem_wait(sem_id) < 0) {
perror("sem_wait");
}
}
static void child(void)
{
sem_t * sem_id;
sem_id=sem_open("mysem", O_CREAT, 0600, 0);
if(sem_id == SEM_FAILED) {
perror("child sem_open");
return;
}
printf("Posting for parent\n");
if(sem_post(sem_id) < 0) {
perror("sem_post");
}
}
int main(int argc, char *argv[])
{
pid_t pid;
pid=fork();
if(pid < 0) {
perror("fork");
exit(EXIT_FAILURE);
}
if(!pid) {
child();
} else {
int status;
parent();
wait(&status);
}
return 0;
}
Upvotes: 10
Reputation: 76541
Are you using the 4 parameter or 2 parameter version of sem_open?
Make sure to use the 4 parameter version and use a mode that will allow other processes to open the semaphore. Assuming all the processes are owned by the same user, a mode of 0600 (S_IRUSR | S_IWUSR
) will be sufficient.
You may also want to verify that you umask is not masking out any of the necessary permissions.
Upvotes: 8