Base: LCDproc 0.5.2
[lcdproc-de200c.git] / server / drivers / lcd_sem.c
blobcf424f89908ff61fff80fb2caf65b6af66b37b29
1 /*
2 * lcd_sem.c -- semaphore code written for lcdtime and meter to mediate
3 * access to the parallel port.
4 *
5 * Written by Benjamin Tse (blt@mundil.cs.mu.edu.au); August,October 1995
6 *
7 * Functions in this file:
8 * getkey returns the key for the semaphore
9 * sem_get create the semaphore (and initialise) if one doesn't exist
10 * otherwise return its key
11 * sem_wait wait on the semaphore
12 * sem_signal signal on the semaphore
13 * sem_remove remove the semaphore
15 * Legal stuff: At no stage was this program written, assembled or compiled on
16 * any computer at the University of Melbourne, Australia. This program is
17 * Copyright (C) 1995 Benjamin Tse (blt@mundil.cs.mu.oz.au) and covered by
18 * GNU's GPL. In particular, this program is free software and comes WITHOUT
19 * ANY WARRANTY.
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <sys/types.h> /* for semaphore functions */
27 #include <sys/ipc.h>
28 #include <sys/sem.h>
29 #include <errno.h>
31 #include "lcd_sem.h"
33 // according to X/OPEN we have to define it ourselves
34 //#ifdef _SEM_SEMUN_UNDEFINED
35 #ifndef HAVE_UNION_SEMUN
36 union semun {
37 int val; /* value for SETVAL */
38 struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
39 unsigned short int *array; /* array for GETALL, SETALL */
40 struct seminfo *__buf; /* buffer for IPC_INFO */
42 #endif
44 #define SEMAPHORE "portctrl"
45 #define SEMKEY 0x706f7274 /* semaphore key */
46 #define SEMCOUNT 1 /* number of semaphores to create */
47 #define WMODE 0660 /* access permissions */
49 #define SEM_SIGNAL 0,1,SEM_UNDO
50 #define SEM_WAIT 0,-1,SEM_UNDO
52 /* functions local to this file */
53 static key_t getkey (register char *p);
55 /* global variables */
56 static struct sembuf semaphore_wait = { SEM_WAIT };
57 static struct sembuf semaphore_signal = { SEM_SIGNAL };
60 * getkey returns the key for the semaphore
63 static key_t
64 getkey (register char *p)
66 return ((key_t) SEMKEY);
70 * create the semaphore if one doesn't exist and initialise it to 1, else
71 * return the semaphore set id
74 int
75 sem_get (void)
77 int semid;
78 union semun semval;
80 if ((semid = semget (getkey (SEMAPHORE), SEMCOUNT, IPC_CREAT | IPC_EXCL | WMODE)) < 0) {
81 switch (errno) {
82 case EEXIST:
83 /* semaphore set exists, get id and return it */
84 if ((semid = semget (getkey (SEMAPHORE), SEMCOUNT, IPC_EXCL | WMODE)) < 0) {
85 perror ("semget");
86 exit (1);
88 return semid;
89 break;
90 case EACCES:
91 /* don't have permissions for semaphore, need to change key */
92 perror ("semget, can't get permissions for semaphore");
93 exit (1);
94 break;
95 default:
96 perror ("semget");
97 exit (1);
98 break;
100 } else {
101 /* initialise semaphore to 1 */
102 semval.val = 1;
104 if (semctl (semid, 0, SETVAL, semval) < 0) {
105 perror ("setval, can't initialise semaphore");
106 exit (1);
110 return semid;
114 * wait on the semaphore
118 sem_wait (int sid)
120 if (semop (sid, &semaphore_wait, 1) < -1) {
121 perror (SEMAPHORE);
122 exit (1);
125 return 0;
129 * signal on the semaphore
133 sem_signal (int sid)
135 if (semop (sid, &semaphore_signal, 1) < -1) {
136 perror (SEMAPHORE);
137 exit (1);
140 return 0;
144 * remove the semaphore
148 sem_remove (int sid)
150 #ifdef EIDRM
151 int i;
152 union semun dummy;
154 if ((i = semctl (sid, 0, IPC_RMID, dummy)) < 0) {
155 switch (i) {
156 case EIDRM:
157 /* semaphore removed */
158 return 0;
159 break;
160 default:
161 perror ("semctl, removing semaphore");
162 exit (1);
166 #endif
167 return 0;