Consider the following example:
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
const char* const sem_name = "lock.sem";
if (argc == 1) {
sem_t* const sem = sem_open(sem_name, O_CREAT, 0644, 0);
if (sem == NULL) {
perror("sem_open");
return 1;
}
sem_wait(sem); // Will block
sem_close(sem);
sem_unlink(sem_name);
} else {
sem_t* const sem = sem_open(sem_name, 0);
if (sem == NULL) {
perror("sem_open");
return 1;
}
sem_post(sem); // Will unblock the other process
sem_close(sem);
}
return 0;
}
I'm using the argument count to control the behavior of the program.
If I supply no parameters (i.e., when argc == 1), then the program will open the semaphore, creating it if it does not already exist; it initializes the value of the semaphore to 0. It then does a sem_wait() on the sem object. Since the semaphore was initialized to 0, this causes the process to block.
Now if I run a second instance of this same program, but this time with any non-zero number of arguments (i.e., when argc != 1), then the program will open the semaphore, but will not create it if it does not already exist. Note here that I pass 0 for the oflag parameter (i.e., I'm not passing any flags). The program then does a sem_post(), incrementing the semaphore from 0 to 1. This unblocks the first process. Both processes will close their references to the semaphore, and terminate.
If I understand your question correctly, the second case is what you're looking for.
If I try to run the second case first (i.e., when there isn't a running instance of the first case), then I get:
$ ./a.out foo
sem_open: No such file or directory
That's comming from the call to perror() because a semaphore with the given name does not exist.