1#include <stdio.h>
2#include <stdarg.h>
3#include <string.h>
4#include <sys/stat.h>
5#include <errno.h>
6#include <fcntl.h>
7#include <unistd.h>
8#include "semaphore_mfp.h"
9
10int semaphore_create()
11{
12	int flag_sem = O_CREAT|O_RDWR;
13	int init_value = 1;
14
15	semaphore_unlink(SEM_NAME);
16
17	if(semaphore_open(SEM_NAME, flag_sem, FILE_MODE, init_value) == -1)
18	{
19		perror("semaphore_create fail");
20		return -1;
21	}
22
23	return 0;
24}
25
26int semaphore_close()
27{
28	if (Semaphore.sem_magic != SEM_MAGIC)
29	{
30		errno = EINVAL;
31		return -1;
32	}
33
34	Semaphore.sem_magic = 0;	// in case caller tries to use it later
35	if (close(Semaphore.sem_fd[0]) == -1 || close(Semaphore.sem_fd[1]) == -1)
36	{
37		memset(&Semaphore, '\0', sizeof(semaphore_t));
38		return -1;
39	}
40
41	memset(&Semaphore, '\0', sizeof(semaphore_t));
42	return 0;
43}
44
45int semaphore_open(const char *pathname, int oflag, ... )
46{
47	int	i, flags, save_errno;
48	char	c;
49	mode_t	mode;
50	va_list	ap;
51	unsigned int	value = 0;
52
53	if (oflag & O_CREAT)
54	{
55		va_start(ap, oflag);			// init ap to final named argument
56		mode = va_arg(ap, mode_t);
57		value = va_arg(ap, unsigned int);
58		va_end(ap);
59
60		if (mkfifo(pathname, mode) < 0)
61		{
62			if (errno == EEXIST && (oflag & O_EXCL) == 0)
63				oflag &= ~O_CREAT;      // already exists, OK
64			else
65			{
66				perror("Sen_open: mkfifo fail");
67				return -1;
68			}
69		}
70	}
71
72	Semaphore.sem_fd[0] = Semaphore.sem_fd[1] = -1;
73
74	if ( (Semaphore.sem_fd[0] = open(pathname, O_RDONLY | O_NONBLOCK)) < 0)
75		goto error;
76	if ( (Semaphore.sem_fd[1] = open(pathname, O_WRONLY | O_NONBLOCK)) < 0)
77		goto error;
78	if ( (flags = fcntl(Semaphore.sem_fd[0], F_GETFL, 0)) < 0)
79		goto error;
80	flags &= ~O_NONBLOCK;
81	if (fcntl(Semaphore.sem_fd[0], F_SETFL, flags) < 0)
82		goto error;
83	if (oflag & O_CREAT)	// initialize semaphore
84	{
85		for (i = 0; i < value; i++)
86			if (write(Semaphore.sem_fd[1], &c, 1) != 1)
87				goto error;
88	}
89
90	Semaphore.sem_magic = SEM_MAGIC;
91	return 0;
92
93error:
94	save_errno = errno;
95	if (oflag & O_CREAT)
96		unlink(pathname);		// if we created FIFO
97	close(Semaphore.sem_fd[0]);		// ignore error
98	close(Semaphore.sem_fd[1]);		// ignore error
99
100	memset(&Semaphore, '\0',sizeof(semaphore_t));
101	errno = save_errno;
102	perror("semaphore_open error");
103
104	return -1;
105}
106
107int semaphore_unlink(const char *pathname)
108{
109	return unlink(pathname);
110}
111
112int semaphore_post()
113{
114	char	c;
115
116	if (Semaphore.sem_magic != SEM_MAGIC)
117	{
118		errno = EINVAL;
119		return -1;
120	}
121
122	if (write(Semaphore.sem_fd[1], &c, 1) == 1)
123		return 0;
124
125        return -1;
126}
127
128int semaphore_wait()
129{
130	char	c;
131
132	if (Semaphore.sem_magic != SEM_MAGIC)
133	{
134		errno = EINVAL;
135		return -1;
136	}
137
138	if (read(Semaphore.sem_fd[0], &c, 1) == 1)
139		return 0;
140
141        return -1;
142}
143