Statistics
| Branch: | Revision:

root / src / xseg_posixfd.c @ a86ebfc3

History | View | Annotate | Download (10.8 kB)

1 8cbf5379 Filippos Giannakos
/*
2 8cbf5379 Filippos Giannakos
 * Copyright 2012 GRNET S.A. All rights reserved.
3 8cbf5379 Filippos Giannakos
 *
4 8cbf5379 Filippos Giannakos
 * Redistribution and use in source and binary forms, with or
5 8cbf5379 Filippos Giannakos
 * without modification, are permitted provided that the following
6 8cbf5379 Filippos Giannakos
 * conditions are met:
7 8cbf5379 Filippos Giannakos
 *
8 8cbf5379 Filippos Giannakos
 *   1. Redistributions of source code must retain the above
9 8cbf5379 Filippos Giannakos
 *      copyright notice, this list of conditions and the following
10 8cbf5379 Filippos Giannakos
 *      disclaimer.
11 8cbf5379 Filippos Giannakos
 *   2. Redistributions in binary form must reproduce the above
12 8cbf5379 Filippos Giannakos
 *      copyright notice, this list of conditions and the following
13 8cbf5379 Filippos Giannakos
 *      disclaimer in the documentation and/or other materials
14 8cbf5379 Filippos Giannakos
 *      provided with the distribution.
15 8cbf5379 Filippos Giannakos
 *
16 8cbf5379 Filippos Giannakos
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 8cbf5379 Filippos Giannakos
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 8cbf5379 Filippos Giannakos
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 8cbf5379 Filippos Giannakos
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 8cbf5379 Filippos Giannakos
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 8cbf5379 Filippos Giannakos
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 8cbf5379 Filippos Giannakos
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 8cbf5379 Filippos Giannakos
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 8cbf5379 Filippos Giannakos
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 8cbf5379 Filippos Giannakos
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 8cbf5379 Filippos Giannakos
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 8cbf5379 Filippos Giannakos
 * POSSIBILITY OF SUCH DAMAGE.
28 8cbf5379 Filippos Giannakos
 *
29 8cbf5379 Filippos Giannakos
 * The views and conclusions contained in the software and
30 8cbf5379 Filippos Giannakos
 * documentation are those of the authors and should not be
31 8cbf5379 Filippos Giannakos
 * interpreted as representing official policies, either expressed
32 8cbf5379 Filippos Giannakos
 * or implied, of GRNET S.A.
33 8cbf5379 Filippos Giannakos
 */
34 8cbf5379 Filippos Giannakos
35 8cbf5379 Filippos Giannakos
#define _GNU_SOURCE
36 8cbf5379 Filippos Giannakos
#include <stdio.h>
37 8cbf5379 Filippos Giannakos
#include <stdlib.h>
38 8cbf5379 Filippos Giannakos
#include <unistd.h>
39 8cbf5379 Filippos Giannakos
#include <sys/types.h>
40 8cbf5379 Filippos Giannakos
#include <sys/time.h>
41 8cbf5379 Filippos Giannakos
#include <sys/select.h>
42 8cbf5379 Filippos Giannakos
#include <sys/stat.h>
43 8cbf5379 Filippos Giannakos
#include <sys/mman.h>
44 8cbf5379 Filippos Giannakos
#include <sys/syscall.h>
45 8cbf5379 Filippos Giannakos
#include <fcntl.h>
46 8cbf5379 Filippos Giannakos
#include <errno.h>
47 8cbf5379 Filippos Giannakos
#include <string.h>
48 8cbf5379 Filippos Giannakos
#include <signal.h>
49 51eafc68 Filippos Giannakos
#include <xseg/util.h>
50 8cbf5379 Filippos Giannakos
#include <xseg/xseg.h>
51 51eafc68 Filippos Giannakos
#include <xseg/xobj.h>
52 51eafc68 Filippos Giannakos
#include <xseg_posixfd.h>
53 8cbf5379 Filippos Giannakos
#define ERRSIZE 512
54 8cbf5379 Filippos Giannakos
char errbuf[ERRSIZE];
55 8cbf5379 Filippos Giannakos
56 8cbf5379 Filippos Giannakos
static long posixfd_allocate(const char *name, uint64_t size)
57 8cbf5379 Filippos Giannakos
{
58 8cbf5379 Filippos Giannakos
        int fd, r;
59 e615a1d0 Filippos Giannakos
        off_t lr;
60 8cbf5379 Filippos Giannakos
        fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0770);
61 8cbf5379 Filippos Giannakos
        if (fd < 0) {
62 8cbf5379 Filippos Giannakos
                XSEGLOG("Cannot create shared segment: %s\n",
63 8cbf5379 Filippos Giannakos
                        strerror_r(errno, errbuf, ERRSIZE));
64 8cbf5379 Filippos Giannakos
                return fd;
65 8cbf5379 Filippos Giannakos
        }
66 8cbf5379 Filippos Giannakos
67 e615a1d0 Filippos Giannakos
        lr = lseek(fd, size -1, SEEK_SET);
68 e615a1d0 Filippos Giannakos
        if (lr == (off_t)-1) {
69 8cbf5379 Filippos Giannakos
                close(fd);
70 8cbf5379 Filippos Giannakos
                XSEGLOG("Cannot seek into segment file: %s\n",
71 8cbf5379 Filippos Giannakos
                        strerror_r(errno, errbuf, ERRSIZE));
72 8cbf5379 Filippos Giannakos
                return r;
73 8cbf5379 Filippos Giannakos
        }
74 8cbf5379 Filippos Giannakos
75 8cbf5379 Filippos Giannakos
        errbuf[0] = 0;
76 8cbf5379 Filippos Giannakos
        r = write(fd, errbuf, 1);
77 8cbf5379 Filippos Giannakos
        if (r != 1) {
78 8cbf5379 Filippos Giannakos
                close(fd);
79 8cbf5379 Filippos Giannakos
                XSEGLOG("Failed to set segment size: %s\n",
80 8cbf5379 Filippos Giannakos
                        strerror_r(errno, errbuf, ERRSIZE));
81 8cbf5379 Filippos Giannakos
                return r;
82 8cbf5379 Filippos Giannakos
        }
83 8cbf5379 Filippos Giannakos
84 8cbf5379 Filippos Giannakos
        close(fd);
85 8cbf5379 Filippos Giannakos
        return 0;
86 8cbf5379 Filippos Giannakos
}
87 8cbf5379 Filippos Giannakos
88 8cbf5379 Filippos Giannakos
static long posixfd_deallocate(const char *name)
89 8cbf5379 Filippos Giannakos
{
90 8cbf5379 Filippos Giannakos
        return shm_unlink(name);
91 8cbf5379 Filippos Giannakos
}
92 8cbf5379 Filippos Giannakos
93 8cbf5379 Filippos Giannakos
static void *posixfd_map(const char *name, uint64_t size, struct xseg *seg)
94 8cbf5379 Filippos Giannakos
{
95 8cbf5379 Filippos Giannakos
        struct xseg *xseg;
96 8cbf5379 Filippos Giannakos
        int fd;
97 8cbf5379 Filippos Giannakos
98 8cbf5379 Filippos Giannakos
        fd = shm_open(name, O_RDWR, 0000);
99 8cbf5379 Filippos Giannakos
        if (fd < 0) {
100 8cbf5379 Filippos Giannakos
                XSEGLOG("Failed to open '%s' for mapping: %s\n",
101 8cbf5379 Filippos Giannakos
                        name, strerror_r(errno, errbuf, ERRSIZE));
102 8cbf5379 Filippos Giannakos
                return NULL;
103 8cbf5379 Filippos Giannakos
        }
104 8cbf5379 Filippos Giannakos
105 8cbf5379 Filippos Giannakos
        xseg = mmap (        XSEG_BASE_AS_PTR,
106 8cbf5379 Filippos Giannakos
                        size,
107 8cbf5379 Filippos Giannakos
                        PROT_READ | PROT_WRITE,
108 8cbf5379 Filippos Giannakos
                        MAP_SHARED | MAP_FIXED /* | MAP_LOCKED */,
109 8cbf5379 Filippos Giannakos
                        fd, 0        );
110 8cbf5379 Filippos Giannakos
111 8cbf5379 Filippos Giannakos
        if (xseg == MAP_FAILED) {
112 8cbf5379 Filippos Giannakos
                XSEGLOG("Could not map segment: %s\n",
113 8cbf5379 Filippos Giannakos
                        strerror_r(errno, errbuf, ERRSIZE));
114 8cbf5379 Filippos Giannakos
                return NULL;
115 8cbf5379 Filippos Giannakos
        }
116 8cbf5379 Filippos Giannakos
117 8cbf5379 Filippos Giannakos
        close(fd);
118 8cbf5379 Filippos Giannakos
        return xseg;
119 8cbf5379 Filippos Giannakos
}
120 8cbf5379 Filippos Giannakos
121 8cbf5379 Filippos Giannakos
static void posixfd_unmap(void *ptr, uint64_t size)
122 8cbf5379 Filippos Giannakos
{
123 8cbf5379 Filippos Giannakos
        struct xseg *xseg = ptr;
124 8cbf5379 Filippos Giannakos
        (void)munmap(xseg, xseg->segment_size);
125 8cbf5379 Filippos Giannakos
}
126 8cbf5379 Filippos Giannakos
127 8cbf5379 Filippos Giannakos
static struct posixfd_signal_desc * __get_signal_desc(struct xseg *xseg, xport portno)
128 8cbf5379 Filippos Giannakos
{
129 8cbf5379 Filippos Giannakos
        struct xseg_port *port = xseg_get_port(xseg, portno);
130 8cbf5379 Filippos Giannakos
        if (!port)
131 8cbf5379 Filippos Giannakos
                return NULL;
132 8cbf5379 Filippos Giannakos
        struct posixfd_signal_desc *psd = xseg_get_signal_desc(xseg, port);
133 8cbf5379 Filippos Giannakos
        if (!psd)
134 8cbf5379 Filippos Giannakos
                return NULL;
135 8cbf5379 Filippos Giannakos
        return psd;
136 8cbf5379 Filippos Giannakos
}
137 8cbf5379 Filippos Giannakos
138 8cbf5379 Filippos Giannakos
static void __get_filename(struct posixfd_signal_desc *psd, char *filename)
139 8cbf5379 Filippos Giannakos
{
140 8cbf5379 Filippos Giannakos
        int pos = 0;
141 8cbf5379 Filippos Giannakos
        strncpy(filename+pos, POSIXFD_DIR, POSIXFD_DIR_LEN);
142 8cbf5379 Filippos Giannakos
        pos += POSIXFD_DIR_LEN;
143 8cbf5379 Filippos Giannakos
        strncpy(filename + pos, psd->signal_file, POSIXFD_FILENAME_LEN);
144 8cbf5379 Filippos Giannakos
        pos += POSIXFD_FILENAME_LEN;
145 8cbf5379 Filippos Giannakos
        filename[pos] = 0;
146 8cbf5379 Filippos Giannakos
}
147 8cbf5379 Filippos Giannakos
148 8cbf5379 Filippos Giannakos
/*
149 8cbf5379 Filippos Giannakos
 * In order to be able to accept signals we must:
150 8cbf5379 Filippos Giannakos
 *
151 8cbf5379 Filippos Giannakos
 * a) Create the name piped for our signal descriptor.
152 8cbf5379 Filippos Giannakos
 * b) Open the named pipe and get an fd.
153 8cbf5379 Filippos Giannakos
 */
154 8cbf5379 Filippos Giannakos
static int posixfd_local_signal_init(struct xseg *xseg, xport portno)
155 8cbf5379 Filippos Giannakos
{
156 8cbf5379 Filippos Giannakos
        /* create or truncate POSIXFD+portno file */
157 8cbf5379 Filippos Giannakos
        int r, fd;
158 8cbf5379 Filippos Giannakos
        char filename[POSIXFD_DIR_LEN + POSIXFD_FILENAME_LEN + 1];
159 8cbf5379 Filippos Giannakos
160 8cbf5379 Filippos Giannakos
        struct posixfd_signal_desc *psd = __get_signal_desc(xseg, portno);
161 8cbf5379 Filippos Giannakos
        if (!psd) {
162 8cbf5379 Filippos Giannakos
                return -1;
163 8cbf5379 Filippos Giannakos
        }
164 8cbf5379 Filippos Giannakos
        __get_filename(psd, filename);
165 8cbf5379 Filippos Giannakos
166 8cbf5379 Filippos Giannakos
retry:
167 8cbf5379 Filippos Giannakos
        r = mkfifo(filename, S_IRUSR|S_IWUSR);
168 8cbf5379 Filippos Giannakos
        if (r < 0) {
169 8cbf5379 Filippos Giannakos
                if (errno == EEXIST) {
170 8cbf5379 Filippos Giannakos
                        unlink(filename);
171 8cbf5379 Filippos Giannakos
                        goto retry;
172 8cbf5379 Filippos Giannakos
                }
173 8cbf5379 Filippos Giannakos
                return -1;
174 8cbf5379 Filippos Giannakos
        }
175 8cbf5379 Filippos Giannakos
176 8cbf5379 Filippos Giannakos
        fd = open(filename, O_RDONLY | O_NONBLOCK);
177 8cbf5379 Filippos Giannakos
        if (fd < 0) {
178 8cbf5379 Filippos Giannakos
                unlink(filename);
179 8cbf5379 Filippos Giannakos
                return -1;
180 8cbf5379 Filippos Giannakos
        }
181 8cbf5379 Filippos Giannakos
        psd->fd = fd;
182 8cbf5379 Filippos Giannakos
        open(filename, O_WRONLY | O_NONBLOCK);
183 8cbf5379 Filippos Giannakos
184 8cbf5379 Filippos Giannakos
        return 0;
185 8cbf5379 Filippos Giannakos
}
186 8cbf5379 Filippos Giannakos
187 8cbf5379 Filippos Giannakos
/*
188 8cbf5379 Filippos Giannakos
 * To clean up after our signal initialiazation, we should:
189 8cbf5379 Filippos Giannakos
 *
190 8cbf5379 Filippos Giannakos
 * a) close the open fd for our named pipe
191 8cbf5379 Filippos Giannakos
 * b) unlink the named pipe from the file system.
192 8cbf5379 Filippos Giannakos
 */
193 8cbf5379 Filippos Giannakos
static void posixfd_local_signal_quit(struct xseg *xseg, xport portno)
194 8cbf5379 Filippos Giannakos
{
195 8cbf5379 Filippos Giannakos
        char filename[POSIXFD_DIR_LEN + POSIXFD_FILENAME_LEN + 1];
196 8cbf5379 Filippos Giannakos
        struct posixfd_signal_desc *psd = __get_signal_desc(xseg, portno);
197 8cbf5379 Filippos Giannakos
        if (psd->fd >=0) {
198 8cbf5379 Filippos Giannakos
                close(psd->fd);
199 8cbf5379 Filippos Giannakos
                psd->fd = -1;
200 8cbf5379 Filippos Giannakos
        }
201 8cbf5379 Filippos Giannakos
        __get_filename(psd, filename);
202 8cbf5379 Filippos Giannakos
        unlink(filename);
203 8cbf5379 Filippos Giannakos
        return;
204 8cbf5379 Filippos Giannakos
}
205 8cbf5379 Filippos Giannakos
206 8cbf5379 Filippos Giannakos
/*
207 8cbf5379 Filippos Giannakos
 * When this peer type is initialized, we must make sure the directory where the
208 8cbf5379 Filippos Giannakos
 * named pipes will be created, exist.
209 8cbf5379 Filippos Giannakos
 */
210 8cbf5379 Filippos Giannakos
static int posixfd_remote_signal_init(void)
211 8cbf5379 Filippos Giannakos
{
212 8cbf5379 Filippos Giannakos
        int r;
213 8cbf5379 Filippos Giannakos
        r = mkdir(POSIXFD_DIR, 01755);
214 8cbf5379 Filippos Giannakos
215 8cbf5379 Filippos Giannakos
        if (r < 0) {
216 8cbf5379 Filippos Giannakos
                if (errno != EEXIST) // && isdir(POSIXFD_DIR)
217 8cbf5379 Filippos Giannakos
                        return -1;
218 8cbf5379 Filippos Giannakos
        }
219 8cbf5379 Filippos Giannakos
220 8cbf5379 Filippos Giannakos
        return 0;
221 8cbf5379 Filippos Giannakos
}
222 8cbf5379 Filippos Giannakos
223 8cbf5379 Filippos Giannakos
static void posixfd_remote_signal_quit(void)
224 8cbf5379 Filippos Giannakos
{
225 8cbf5379 Filippos Giannakos
        return;
226 8cbf5379 Filippos Giannakos
}
227 8cbf5379 Filippos Giannakos
228 8cbf5379 Filippos Giannakos
static int posixfd_prepare_wait(struct xseg *xseg, uint32_t portno)
229 8cbf5379 Filippos Giannakos
{
230 8cbf5379 Filippos Giannakos
        char buf[512];
231 8cbf5379 Filippos Giannakos
        int buf_size = 512;
232 8cbf5379 Filippos Giannakos
        struct posixfd_signal_desc *psd = __get_signal_desc(xseg, portno);
233 8cbf5379 Filippos Giannakos
        if (!psd)
234 8cbf5379 Filippos Giannakos
                return -1;
235 8cbf5379 Filippos Giannakos
        psd->flag = 1;
236 8cbf5379 Filippos Giannakos
        while (read(psd->fd, buf, buf_size) > 0);
237 8cbf5379 Filippos Giannakos
238 8cbf5379 Filippos Giannakos
        return 0;
239 8cbf5379 Filippos Giannakos
}
240 8cbf5379 Filippos Giannakos
241 8cbf5379 Filippos Giannakos
static int posixfd_cancel_wait(struct xseg *xseg, uint32_t portno)
242 8cbf5379 Filippos Giannakos
{
243 8cbf5379 Filippos Giannakos
        char buf[512];
244 8cbf5379 Filippos Giannakos
        int buf_size = 512;
245 8cbf5379 Filippos Giannakos
        struct posixfd_signal_desc *psd = __get_signal_desc(xseg, portno);
246 8cbf5379 Filippos Giannakos
        if (!psd)
247 8cbf5379 Filippos Giannakos
                return -1;
248 8cbf5379 Filippos Giannakos
        psd->flag = 0;
249 8cbf5379 Filippos Giannakos
        while (read(psd->fd, buf, buf_size) > 0);
250 8cbf5379 Filippos Giannakos
251 8cbf5379 Filippos Giannakos
        return 0;
252 8cbf5379 Filippos Giannakos
}
253 8cbf5379 Filippos Giannakos
254 8cbf5379 Filippos Giannakos
/*
255 8cbf5379 Filippos Giannakos
 * To wait a signal, the posixfd peer must use select on the fd of its named
256 8cbf5379 Filippos Giannakos
 * pipe.
257 8cbf5379 Filippos Giannakos
 *
258 8cbf5379 Filippos Giannakos
 * When the peer wakes up from the select, if it wasn't waked up because of a
259 8cbf5379 Filippos Giannakos
 * timeout, it should read as much as it can from the named pipe to clean it and
260 8cbf5379 Filippos Giannakos
 * prepare it for the next select.
261 8cbf5379 Filippos Giannakos
 */
262 8cbf5379 Filippos Giannakos
static int posixfd_wait_signal(struct xseg *xseg, void *sd, uint32_t usec_timeout)
263 8cbf5379 Filippos Giannakos
{
264 8cbf5379 Filippos Giannakos
        int r;
265 8cbf5379 Filippos Giannakos
        struct timeval tv;
266 8cbf5379 Filippos Giannakos
        char buf[512];
267 8cbf5379 Filippos Giannakos
        int buf_size = 512;
268 8cbf5379 Filippos Giannakos
        fd_set fds;
269 8cbf5379 Filippos Giannakos
270 8cbf5379 Filippos Giannakos
        struct posixfd_signal_desc *psd = (struct posixfd_signal_desc *)sd;
271 8cbf5379 Filippos Giannakos
        if (!psd)
272 8cbf5379 Filippos Giannakos
                return -1;
273 8cbf5379 Filippos Giannakos
274 8cbf5379 Filippos Giannakos
        tv.tv_sec = usec_timeout / 1000000;
275 8cbf5379 Filippos Giannakos
        tv.tv_usec = usec_timeout - tv.tv_sec * 1000000;
276 8cbf5379 Filippos Giannakos
277 8cbf5379 Filippos Giannakos
        FD_ZERO(&fds);
278 8cbf5379 Filippos Giannakos
        FD_SET(psd->fd, &fds);
279 8cbf5379 Filippos Giannakos
280 8cbf5379 Filippos Giannakos
        r = select(psd->fd + 1, &fds, NULL, NULL, &tv);
281 8cbf5379 Filippos Giannakos
        //XSEGLOG("Tv sec: %ld, tv_usec: %ld", tv.tv_sec, tv.tv_usec);
282 8cbf5379 Filippos Giannakos
283 8cbf5379 Filippos Giannakos
        if (r < 0) {
284 8cbf5379 Filippos Giannakos
                if (errno != EINTR) {
285 8cbf5379 Filippos Giannakos
                        return -1;
286 8cbf5379 Filippos Giannakos
                } else {
287 8cbf5379 Filippos Giannakos
                        return 0;
288 8cbf5379 Filippos Giannakos
                }
289 8cbf5379 Filippos Giannakos
        }
290 8cbf5379 Filippos Giannakos
291 8cbf5379 Filippos Giannakos
        if (r != 0) {
292 8cbf5379 Filippos Giannakos
                /* clean up pipe */
293 8cbf5379 Filippos Giannakos
                while (read(psd->fd, buf, buf_size) > 0);
294 8cbf5379 Filippos Giannakos
        }
295 8cbf5379 Filippos Giannakos
296 8cbf5379 Filippos Giannakos
        return 0;
297 8cbf5379 Filippos Giannakos
}
298 8cbf5379 Filippos Giannakos
299 8cbf5379 Filippos Giannakos
/*
300 8cbf5379 Filippos Giannakos
 * To signal a posixfd peer, we must:
301 8cbf5379 Filippos Giannakos
 *
302 8cbf5379 Filippos Giannakos
 * a) Check if the peer wants to be signaled.
303 8cbf5379 Filippos Giannakos
 * b) Open the named pipe, it provides.
304 8cbf5379 Filippos Giannakos
 * c) Write some data to the named pipe, so the peer's fd will be selectable for
305 8cbf5379 Filippos Giannakos
 *    writing.
306 8cbf5379 Filippos Giannakos
 * d) Close the named pipe.
307 8cbf5379 Filippos Giannakos
 */
308 8cbf5379 Filippos Giannakos
static int posixfd_signal(struct xseg *xseg, uint32_t portno)
309 8cbf5379 Filippos Giannakos
{
310 8cbf5379 Filippos Giannakos
        int r, fd;
311 8cbf5379 Filippos Giannakos
        /* NULL terminated */
312 8cbf5379 Filippos Giannakos
        char filename[POSIXFD_DIR_LEN + POSIXFD_FILENAME_LEN + 1] = POSIXFD_DIR;
313 8cbf5379 Filippos Giannakos
314 8cbf5379 Filippos Giannakos
        struct posixfd_signal_desc *psd = __get_signal_desc(xseg, portno);
315 8cbf5379 Filippos Giannakos
        if (!psd)
316 8cbf5379 Filippos Giannakos
                return -1;
317 8cbf5379 Filippos Giannakos
318 8cbf5379 Filippos Giannakos
        if (!psd->flag) {
319 8cbf5379 Filippos Giannakos
                /* If the peer advises not to signal, we respect it. */
320 8cbf5379 Filippos Giannakos
                return 0;
321 8cbf5379 Filippos Giannakos
        }
322 8cbf5379 Filippos Giannakos
        __get_filename(psd, filename);
323 8cbf5379 Filippos Giannakos
324 8cbf5379 Filippos Giannakos
        fd = open(filename, O_WRONLY|O_NONBLOCK);
325 8cbf5379 Filippos Giannakos
        if (fd < 0) {
326 8cbf5379 Filippos Giannakos
                return -1;
327 8cbf5379 Filippos Giannakos
        }
328 8cbf5379 Filippos Giannakos
        r = write(fd, "a", 1);
329 8cbf5379 Filippos Giannakos
        if (r < 0) {
330 8cbf5379 Filippos Giannakos
                close(fd);
331 8cbf5379 Filippos Giannakos
                return -1;
332 8cbf5379 Filippos Giannakos
        }
333 8cbf5379 Filippos Giannakos
        /* FIXME what here? */
334 8cbf5379 Filippos Giannakos
        r = close(fd);
335 8cbf5379 Filippos Giannakos
336 8cbf5379 Filippos Giannakos
        return 0;
337 8cbf5379 Filippos Giannakos
}
338 8cbf5379 Filippos Giannakos
339 8cbf5379 Filippos Giannakos
static void *posixfd_malloc(uint64_t size)
340 8cbf5379 Filippos Giannakos
{
341 8cbf5379 Filippos Giannakos
        return malloc((size_t)size);
342 8cbf5379 Filippos Giannakos
}
343 8cbf5379 Filippos Giannakos
344 8cbf5379 Filippos Giannakos
static void *posixfd_realloc(void *mem, uint64_t size)
345 8cbf5379 Filippos Giannakos
{
346 8cbf5379 Filippos Giannakos
        return realloc(mem, (size_t)size);
347 8cbf5379 Filippos Giannakos
}
348 8cbf5379 Filippos Giannakos
349 8cbf5379 Filippos Giannakos
static void posixfd_mfree(void *mem)
350 8cbf5379 Filippos Giannakos
{
351 8cbf5379 Filippos Giannakos
        free(mem);
352 8cbf5379 Filippos Giannakos
}
353 8cbf5379 Filippos Giannakos
354 8cbf5379 Filippos Giannakos
/* taken from user/hash.c */
355 8cbf5379 Filippos Giannakos
static char get_hex(unsigned int h)
356 8cbf5379 Filippos Giannakos
{
357 8cbf5379 Filippos Giannakos
        switch (h)
358 8cbf5379 Filippos Giannakos
        {
359 8cbf5379 Filippos Giannakos
                case 0:
360 8cbf5379 Filippos Giannakos
                case 1:
361 8cbf5379 Filippos Giannakos
                case 2:
362 8cbf5379 Filippos Giannakos
                case 3:
363 8cbf5379 Filippos Giannakos
                case 4:
364 8cbf5379 Filippos Giannakos
                case 5:
365 8cbf5379 Filippos Giannakos
                case 6:
366 8cbf5379 Filippos Giannakos
                case 7:
367 8cbf5379 Filippos Giannakos
                case 8:
368 8cbf5379 Filippos Giannakos
                case 9:
369 8cbf5379 Filippos Giannakos
                        return h + '0';
370 8cbf5379 Filippos Giannakos
                case 10:
371 8cbf5379 Filippos Giannakos
                        return 'a';
372 8cbf5379 Filippos Giannakos
                case 11:
373 8cbf5379 Filippos Giannakos
                        return 'b';
374 8cbf5379 Filippos Giannakos
                case 12:
375 8cbf5379 Filippos Giannakos
                        return 'c';
376 8cbf5379 Filippos Giannakos
                case 13:
377 8cbf5379 Filippos Giannakos
                        return 'd';
378 8cbf5379 Filippos Giannakos
                case 14:
379 8cbf5379 Filippos Giannakos
                        return 'e';
380 8cbf5379 Filippos Giannakos
                case 15:
381 8cbf5379 Filippos Giannakos
                        return 'f';
382 8cbf5379 Filippos Giannakos
        }
383 8cbf5379 Filippos Giannakos
        /* not reachable */
384 8cbf5379 Filippos Giannakos
        return '0';
385 8cbf5379 Filippos Giannakos
}
386 8cbf5379 Filippos Giannakos
387 8cbf5379 Filippos Giannakos
static void hexlify(unsigned char *data, long datalen, char *hex)
388 8cbf5379 Filippos Giannakos
{
389 8cbf5379 Filippos Giannakos
        long i;
390 8cbf5379 Filippos Giannakos
        for (i=0; i<datalen; i++){
391 8cbf5379 Filippos Giannakos
                hex[2*i] = get_hex((data[i] & 0xF0) >> 4);
392 8cbf5379 Filippos Giannakos
                hex[2*i + 1] = get_hex(data[i] & 0x0F);
393 8cbf5379 Filippos Giannakos
        }
394 8cbf5379 Filippos Giannakos
}
395 8cbf5379 Filippos Giannakos
396 8cbf5379 Filippos Giannakos
397 8cbf5379 Filippos Giannakos
398 8cbf5379 Filippos Giannakos
int posixfd_init_signal_desc(struct xseg *xseg, void *sd)
399 8cbf5379 Filippos Giannakos
{
400 8cbf5379 Filippos Giannakos
        struct posixfd_signal_desc *psd = sd;
401 8cbf5379 Filippos Giannakos
        if (!psd)
402 8cbf5379 Filippos Giannakos
                return -1;
403 8cbf5379 Filippos Giannakos
        psd->flag = 0;
404 8cbf5379 Filippos Giannakos
        psd->signal_file[0] = 0;
405 8cbf5379 Filippos Giannakos
        hexlify(&sd, POSIXFD_FILENAME_LEN, psd->signal_file);
406 8cbf5379 Filippos Giannakos
        psd->fd = -1;
407 8cbf5379 Filippos Giannakos
408 8cbf5379 Filippos Giannakos
        return 0;
409 8cbf5379 Filippos Giannakos
}
410 8cbf5379 Filippos Giannakos
411 8cbf5379 Filippos Giannakos
void posixfd_quit_signal_desc(struct xseg *xseg, void *sd)
412 8cbf5379 Filippos Giannakos
{
413 8cbf5379 Filippos Giannakos
        return;
414 8cbf5379 Filippos Giannakos
}
415 8cbf5379 Filippos Giannakos
416 8cbf5379 Filippos Giannakos
void * posixfd_alloc_data(struct xseg *xseg)
417 8cbf5379 Filippos Giannakos
{
418 8cbf5379 Filippos Giannakos
        struct xobject_h *sd_h = xseg_get_objh(xseg, MAGIC_POSIX_SD,
419 8cbf5379 Filippos Giannakos
                        sizeof(struct posixfd_signal_desc));
420 8cbf5379 Filippos Giannakos
        return sd_h;
421 8cbf5379 Filippos Giannakos
}
422 8cbf5379 Filippos Giannakos
423 8cbf5379 Filippos Giannakos
void posixfd_free_data(struct xseg *xseg, void *data)
424 8cbf5379 Filippos Giannakos
{
425 8cbf5379 Filippos Giannakos
        if (data)
426 8cbf5379 Filippos Giannakos
                xseg_put_objh(xseg, (struct xobject_h *)data);
427 8cbf5379 Filippos Giannakos
}
428 8cbf5379 Filippos Giannakos
429 8cbf5379 Filippos Giannakos
void *posixfd_alloc_signal_desc(struct xseg *xseg, void *data)
430 8cbf5379 Filippos Giannakos
{
431 8cbf5379 Filippos Giannakos
        struct xobject_h *sd_h = (struct xobject_h *) data;
432 8cbf5379 Filippos Giannakos
        if (!sd_h)
433 8cbf5379 Filippos Giannakos
                return NULL;
434 8cbf5379 Filippos Giannakos
        struct posixfd_signal_desc *psd = xobj_get_obj(sd_h, X_ALLOC);
435 8cbf5379 Filippos Giannakos
        if (!psd)
436 8cbf5379 Filippos Giannakos
                return NULL;
437 8cbf5379 Filippos Giannakos
        return psd;
438 8cbf5379 Filippos Giannakos
439 8cbf5379 Filippos Giannakos
}
440 8cbf5379 Filippos Giannakos
441 8cbf5379 Filippos Giannakos
void posixfd_free_signal_desc(struct xseg *xseg, void *data, void *sd)
442 8cbf5379 Filippos Giannakos
{
443 8cbf5379 Filippos Giannakos
        struct xobject_h *sd_h = (struct xobject_h *) data;
444 8cbf5379 Filippos Giannakos
        if (!sd_h)
445 8cbf5379 Filippos Giannakos
                return;
446 8cbf5379 Filippos Giannakos
        if (sd)
447 8cbf5379 Filippos Giannakos
                xobj_put_obj(sd_h, sd);
448 8cbf5379 Filippos Giannakos
        return;
449 8cbf5379 Filippos Giannakos
}
450 8cbf5379 Filippos Giannakos
451 8cbf5379 Filippos Giannakos
static struct xseg_type xseg_posixfd = {
452 8cbf5379 Filippos Giannakos
        /* xseg_operations */
453 8cbf5379 Filippos Giannakos
        {
454 8cbf5379 Filippos Giannakos
                .mfree                = posixfd_mfree,
455 8cbf5379 Filippos Giannakos
                .allocate        = posixfd_allocate,
456 8cbf5379 Filippos Giannakos
                .deallocate        = posixfd_deallocate,
457 8cbf5379 Filippos Giannakos
                .map                = posixfd_map,
458 8cbf5379 Filippos Giannakos
                .unmap                = posixfd_unmap,
459 8cbf5379 Filippos Giannakos
        },
460 8cbf5379 Filippos Giannakos
        /* name */
461 8cbf5379 Filippos Giannakos
        "posixfd"
462 8cbf5379 Filippos Giannakos
};
463 8cbf5379 Filippos Giannakos
464 8cbf5379 Filippos Giannakos
static struct xseg_peer xseg_peer_posixfd = {
465 8cbf5379 Filippos Giannakos
        /* xseg_peer_operations */
466 8cbf5379 Filippos Giannakos
        {
467 8cbf5379 Filippos Giannakos
                .init_signal_desc   = posixfd_init_signal_desc,
468 8cbf5379 Filippos Giannakos
                .quit_signal_desc   = posixfd_quit_signal_desc,
469 8cbf5379 Filippos Giannakos
                .alloc_data         = posixfd_alloc_data,
470 8cbf5379 Filippos Giannakos
                .free_data          = posixfd_free_data,
471 8cbf5379 Filippos Giannakos
                .alloc_signal_desc  = posixfd_alloc_signal_desc,
472 8cbf5379 Filippos Giannakos
                .free_signal_desc   = posixfd_free_signal_desc,
473 8cbf5379 Filippos Giannakos
                .local_signal_init  = posixfd_local_signal_init,
474 8cbf5379 Filippos Giannakos
                .local_signal_quit  = posixfd_local_signal_quit,
475 8cbf5379 Filippos Giannakos
                .remote_signal_init = posixfd_remote_signal_init,
476 8cbf5379 Filippos Giannakos
                .remote_signal_quit = posixfd_remote_signal_quit,
477 8cbf5379 Filippos Giannakos
                .prepare_wait            = posixfd_prepare_wait,
478 8cbf5379 Filippos Giannakos
                .cancel_wait            = posixfd_cancel_wait,
479 8cbf5379 Filippos Giannakos
                .wait_signal            = posixfd_wait_signal,
480 8cbf5379 Filippos Giannakos
                .signal                    = posixfd_signal,
481 8cbf5379 Filippos Giannakos
                .malloc                    = posixfd_malloc,
482 8cbf5379 Filippos Giannakos
                .realloc             = posixfd_realloc,
483 8cbf5379 Filippos Giannakos
                .mfree                    = posixfd_mfree,
484 8cbf5379 Filippos Giannakos
        },
485 8cbf5379 Filippos Giannakos
        /* name */
486 8cbf5379 Filippos Giannakos
        "posixfd"
487 8cbf5379 Filippos Giannakos
};
488 8cbf5379 Filippos Giannakos
489 8cbf5379 Filippos Giannakos
void xseg_posixfd_init(void)
490 8cbf5379 Filippos Giannakos
{
491 8cbf5379 Filippos Giannakos
        xseg_register_type(&xseg_posixfd);
492 8cbf5379 Filippos Giannakos
        xseg_register_peer(&xseg_peer_posixfd);
493 8cbf5379 Filippos Giannakos
}