poll<=select
[tedtools.git] / shmem.c
1 /*
2  * Copyright (c) 2004 Teodor Sigaev <teodor@sigaev.ru>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *        notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *        notice, this list of conditions and the following disclaimer in the
12  *        documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the author nor the names of any co-contributors
14  *        may be used to endorse or promote products derived from this software
15  *        without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
18  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/types.h> 
33 #include <sys/ipc.h>
34 #include <sys/sem.h>
35 #include <sys/shm.h>
36 #include <errno.h>
37
38 #include "tlog.h"
39 #include "shmem.h"
40
41 #define KEY 101
42 #define PATH    "/bin"
43
44 void *
45 attachSharedMemory(int key, char *path, int size, int rdonly) {
46         key_t shm_key;
47         int shm_id, flags=0;
48         void *shm;
49
50         if ( size>0 && rdonly )
51                 return NULL;
52
53         shm_key = ftok( (path) ? path : PATH, (key) ? key : KEY);    /* Get IPC key */
54         if ((int) shm_key == -1) 
55                 tlog(TL_CRIT|TL_EXIT, "Ftok error: %s", strerror(errno));
56
57         if (size > 0) 
58                 flags = IPC_CREAT | IPC_EXCL | 0644;
59
60         shm_id = shmget(shm_key, size, flags); /* Get SHM segment */
61         if (shm_id == -1) {
62                 if ( errno == EEXIST || errno == ENOENT )
63                         return NULL;
64                 else
65                          tlog(TL_CRIT|TL_EXIT, "shmget error: %s", strerror(errno));
66         }
67
68         flags = ( rdonly ) ? SHM_RDONLY : 0;
69
70         shm = shmat(shm_id, 0, flags);      /* Attach SHM segment */
71         if ( (int)shm == -1 )
72                 tlog(TL_CRIT|TL_EXIT, "shmat error: %s", strerror(errno));
73  
74         return shm;
75 }
76  
77 void 
78 detachSharedMemory(void *shm) {
79         if ( shmdt(shm) == -1 )
80                 tlog(TL_CRIT, "shmdt error: %s", strerror(errno));
81 }
82
83 int
84 attachSemaphore(int key, char *path) {
85         key_t shm_key;
86         int sem_id;
87
88         shm_key = ftok( (path) ? path : PATH, (key) ? key : KEY);    /* Get IPC key */
89         if ((int) shm_key == -1)
90                 tlog(TL_CRIT|TL_EXIT, "Ftok error: %s", strerror(errno));
91
92         sem_id = semget(shm_key, 1, 0);
93         if ( sem_id == -1 ) {
94                 if ( errno == ENOENT ) { /* not exists */
95                         sem_id = semget(shm_key, 1, IPC_CREAT | IPC_EXCL | 0644);
96                         if ( sem_id == -1 )
97                                 tlog(TL_CRIT|TL_EXIT, "semget error: %s", strerror(errno));
98                         if ( semctl( sem_id, 0, SETVAL, 1 ) == -1 )
99                                 tlog(TL_CRIT|TL_EXIT, "sysctl error: %s", strerror(errno));
100                 } else 
101                         tlog(TL_CRIT|TL_EXIT, "semget error: %s", strerror(errno));
102         }
103         return sem_id;
104 }
105
106 void releaseSemaphore(int sem_id) {
107         struct sembuf sem;
108
109         sem.sem_num = 0;
110         sem.sem_flg = 0;
111         sem.sem_op =  1;
112
113         if (semop(sem_id, &sem, 1) == -1) 
114                 tlog(TL_CRIT|TL_EXIT, "semop error: %s", strerror(errno));
115 }
116         
117 void lockSemaphore(int sem_id) {
118         struct sembuf sem;
119
120         sem.sem_num = 0;
121         sem.sem_flg = 0;
122         sem.sem_op = -1;
123
124         if (semop(sem_id, &sem, 1) == -1) 
125                 tlog(TL_CRIT|TL_EXIT, "semop error: %s", strerror(errno));
126 }
127         
128         
129