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