#include    <stdio.h>
#include    <sys/types.h>
#include    <sys/ipc.h>
#include    <sys/sem.h>

int sem_get(char *path)
{
int     sid;
union semun{
    int     val;
    struct semid_ds *buf;
    ushort  *array;
}c_arg;

    /* セマフォセットの獲得 */
    if((sid=semget(ftok(path,0),1,0666|IPC_CREAT))== -1){
        perror("semget");
        return(-1);
    }
    if(semctl(sid,0,GETVAL,c_arg)==0){    /* セマフォの値取得 */
        c_arg.val=1;
        if(semctl(sid,0,SETVAL,c_arg)==-1){    /* セマフォの値セット */
            perror("semctl");
            return(-1);
        }
    }
    return(sid);
}

int sem_lock(int sid)
{
struct sembuf   sb;

    sb.sem_num=0;
    sb.sem_op=-1;
    sb.sem_flg=0;
    if(semop(sid,&sb,1)== -1){
        perror("semop");
        return(-1);
    }
    return(1);
}

int sem_unlock(int sid)
{
struct sembuf   sb;

    sb.sem_num=0;
    sb.sem_op=1;
    sb.sem_flg=0;
    if(semop(sid,&sb,1)== -1){
        perror("semop");
        return(-1);
    }
    return(1);
}

void main()
{
int     sid,ret;
char    buf[128];
union semun{
    int     val;
    struct semid_ds *buf;
    ushort  *array;
}c_arg;

    setbuf(stdout,NULL);
    /* セマフォセットの獲得 */
    if((sid=sem_get("/tmp/aaa"))==-1){
        exit(-1);
    }
    printf("sid=%d\n",sid);

    /* テストループ */
    while(1){
        ret=semctl(sid,0,GETVAL,c_arg);    /* セマフォの状態取得 */
        printf("<%d> [L]ock / [U]nlock : ",ret);
        fgets(buf,sizeof(buf)-1,stdin);
        if(tolower(buf[0])=='l'){
            ret=sem_lock(sid);    /* ロック */
            printf("sem_lock()=%d\n",ret);
        }
        else if(tolower(buf[0])=='u'){
            ret=sem_unlock(sid);    /* アンロック */
            printf("sem_unlock()=%d\n",ret);
        }
    }
}
