C program to make a process
sleep by using "sem_wait". The Process would wake up by doing
sem_post in SIGTERM signal handler, to which the process has registered to.
Program:
neelkanth_surekha#cat sem.c 
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pthread.h>
#include <time.h>
#include <string.h>
#include <signal.h>
/* define macro printf for printf , where in printf takes same arguments as printf and
 *  also prints timestamp  */
#define LOG_INIT()          time_t ltime;
/* calendar time */ \
    char *ptr;\
#define printf(...) ltime = time(NULL); /* get current cal time */ \
                 
               ptr = asctime(
localtime(<ime));\
ptr[strlen(ptr)-1] = '\0';\
printf("%s: ", ptr); \
printf(__VA_ARGS__); printf("\n");
#define SEM_NAME "neel_semaphore"
#define SEM_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)
#define INITIAL_VALUE  0
void sig_handler(int signo)
{
    LOG_INIT();
    sem_t *semaphore = sem_open(SEM_NAME, O_CREAT ,
SEM_PERMS,
            0);
    int sem_value;
printf("INSIDE signal handler\n");
if (semaphore == SEM_FAILED) {
        printf("sem_open(3) error");
        exit(EXIT_FAILURE);
    }
if (signo == SIGTERM)
    {
        if (!sem_getvalue(semaphore,
&sem_value)) {
            printf("PID %d
semaphore value before sem_post: %d\n", getpid(), sem_value);
        }
if (sem_value == 0) {
            /* sem_post() increments (unlocks) the
semaphore pointed to by sem.  If
             * the semaphore's
value consequently becomes greater than zero, then
             * another process or
thread blocked in a sem_wait call will be woken
             * up and proceed to
lock the semaphore. */
            if (sem_post(semaphore)
< 0) {
               
printf("sem_post(3) error on child");
            }
            printf("Sem_post
done. i.e. semaphore count is incremented to 1\n");
        }
if (!sem_getvalue(semaphore, &sem_value)) {
            printf("PID %d
semaphore value after sem_post: %d\n", getpid(), sem_value);
        }
if (sem_close(semaphore) < 0) {
           
printf("sem_close(3) failed");
        }
    }
printf("EXIT signal handler\n");
    return;
}
void main()
{
    LOG_INIT();
    /* Register this process for SIGTERM signal handler so that 
     * the semaphore count will be incremented to 1
when the process
     * receives this signal
     */
    if (signal(SIGTERM, sig_handler) == SIG_ERR )
    {
        printf("can't catch
SIGTERM\n");
    }
int sem_value = 0;
/* We initialize the semaphore counter to 0 (INITIAL_VALUE)
     * If O_CREAT  is specified in oflag, then
the semaphore is created 
     * if it does not already exist.
     * If both O_CREAT and O_EXCL are specified in
oflag, then an error 
     * is returned if a semaphore
     * with the given name already exists.
     */
    /* sem_open() creates a new POSIX semaphore or opens
an existing
     * semaphore.  The semaphore is identified
by name. 
     */
    sem_t *semaphore = sem_open(SEM_NAME, O_CREAT ,
SEM_PERMS, INITIAL_VALUE);
    if (semaphore == SEM_FAILED) {
        printf("sem_open(3) error");
        exit(EXIT_FAILURE);
    }
printf("PID %ld trying to acquire semaphore", (long) getpid());
if (!sem_getvalue(semaphore, &sem_value)) {
        printf("PID %d semaphore value:
%d", getpid(), sem_value);
    }
/* check whether the semaphore is available of not. */
    if (sem_value ==  0)
    {
        printf("PID %d: Semaphore name:
%s\nSleep here till the semaphore count"
                "is
increased to 1 \n", getpid(), SEM_NAME);
    }
/* sem_wait() decrements (locks) the semaphore pointed to by sem. If
     * the semaphore's value is greater than zero,
then the decrement
     * proceeds, and the function returns, immediately. 
If the semaphore
     * currently has the value zero, then the call
blocks until either it
     * becomes possible to perform the decrement
(i.e., the semaphore value
     * rises above zero), or a signal handler
interrupts the call.*/
    /* If the semaphore value is 0, wait here till the
value increase to 
     * greater than 0 */
    if (sem_wait(semaphore) < 0) {
        printf("sem_wait(3) failed on
child");
        exit(EXIT_FAILURE);
    }
printf("PID %ld release semaphore\n", (long) getpid());
sem_unlink(SEM_NAME);
return;
}
Output:
Terminal 1: Start the process
neelkanth_surekha#./a.out 
Wed Dec 27 09:11:29 2017: PID 6330 trying to acquire semaphore
Wed Dec 27 09:11:29 2017: PID 6330 semaphore value: 0
Wed Dec 27 09:11:29 2017: PID 6330: Semaphore name: neel_semaphore
Sleep here till the semaphore countis increased to 1 
Wed Dec 27 09:11:42 2017: INSIDE signal handler
Wed Dec 27 09:11:42 2017: PID 6330 semaphore value before sem_post: 0
Wed Dec 27 09:11:42 2017: Sem_post done. i.e. semaphore count is incremented to 1
Wed Dec 27 09:11:42 2017: PID 6330 semaphore value after sem_post: 1
Wed Dec 27 09:11:42 2017: EXIT signal handler
Wed Dec 27 09:11:42 2017: PID 6330 release semaphore
Terminal 2: Give Kill -15 to process
neelkanth_surekha#ps -elf | grep a.out
0 S neelkan+  6330  5227  0  80   0
-  1632 futex_ 09:11 pts/1    00:00:00 ./a.out
0 S neelkan+  6333  6079  0  80   0
-  3556 pipe_w 09:11 pts/19   00:00:00 grep --color=auto a.out