Commit | Line | Data |
---|---|---|
6f81b18a AW |
1 | /* Copyright (C) 2010 Free Software Foundation, Inc. |
2 | * | |
3 | * This library is free software; you can redistribute it and/or | |
4 | * modify it under the terms of the GNU Lesser General Public License | |
5 | * as published by the Free Software Foundation; either version 3 of | |
6 | * the License, or (at your option) any later version. | |
7 | * | |
8 | * This library is distributed in the hope that it will be useful, but | |
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
11 | * Lesser General Public License for more details. | |
12 | * | |
13 | * You should have received a copy of the GNU Lesser General Public | |
14 | * License along with this library; if not, write to the Free Software | |
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
16 | * 02110-1301 USA | |
17 | */ | |
18 | ||
19 | ||
20 | \f | |
21 | ||
22 | #define _GNU_SOURCE | |
23 | ||
24 | #ifdef HAVE_CONFIG_H | |
25 | # include <config.h> | |
26 | #endif | |
27 | ||
28 | #include "libguile/_scm.h" | |
29 | #include "libguile/bytevectors.h" | |
30 | #include "libguile/numbers.h" | |
31 | #include "libguile/error.h" | |
32 | #include "libguile/validate.h" | |
33 | ||
34 | #include "libguile/poll.h" | |
35 | ||
36 | \f | |
37 | #ifdef HAVE_POLL_H | |
38 | #include <poll.h> | |
39 | #endif | |
40 | ||
41 | \f | |
42 | ||
43 | /* {Poll} | |
44 | */ | |
45 | ||
46 | /* Poll a set of file descriptors, waiting until one or more of them is | |
47 | ready to perform input or output. | |
48 | ||
49 | This is a low-level interface. See the `(ice-9 poll)' module for a more | |
50 | usable wrapper. | |
51 | ||
52 | `pollfds' is expected to be a bytevector, laid out in contiguous blocks of 64 | |
53 | bits. Each block has the format of one `struct pollfd': a 32-bit int file | |
54 | descriptor, a 16-bit int events mask, and a 16-bit int revents mask. | |
55 | ||
56 | The number of pollfd structures in `pollfds' is specified in | |
57 | `nfds'. `pollfds' must be at least long enough to support that number of | |
58 | structures. It may be longer, in which case the trailing entries are left | |
59 | untouched. | |
60 | ||
61 | The pollfds bytevector is modified directly, setting the returned events in | |
62 | the final two bytes (the revents member). | |
63 | ||
64 | If timeout is given and is non-negative, the poll will return after that | |
65 | number of milliseconds if no fd became active. | |
66 | */ | |
67 | #ifdef HAVE_POLL | |
68 | static SCM | |
69 | scm_primitive_poll (SCM pollfds, SCM nfds, SCM timeout) | |
70 | #define FUNC_NAME "primitive-poll" | |
71 | { | |
72 | int rv; | |
73 | nfds_t c_nfds; | |
74 | int c_timeout; | |
75 | struct pollfd *fds; | |
76 | ||
77 | SCM_VALIDATE_BYTEVECTOR (SCM_ARG1, pollfds); | |
78 | c_nfds = scm_to_uint32 (nfds); | |
79 | c_timeout = scm_to_int (timeout); | |
80 | ||
81 | if (SCM_UNLIKELY (SCM_BYTEVECTOR_LENGTH (pollfds) | |
82 | < c_nfds * sizeof(struct pollfd))) | |
83 | SCM_OUT_OF_RANGE (SCM_ARG1, nfds); | |
84 | ||
85 | fds = (struct pollfd*)SCM_BYTEVECTOR_CONTENTS (pollfds); | |
86 | ||
87 | SCM_SYSCALL (rv = poll (fds, c_nfds, c_timeout)); | |
88 | ||
89 | if (rv == -1) | |
90 | SCM_SYSERROR; | |
91 | ||
92 | return scm_from_int (rv); | |
93 | } | |
94 | #undef FUNC_NAME | |
95 | #endif /* HAVE_POLL */ | |
96 | ||
97 | ||
98 | \f | |
99 | ||
100 | static void | |
101 | scm_init_poll (void) | |
102 | { | |
103 | #if HAVE_POLL | |
104 | scm_c_define_gsubr ("primitive-poll", 3, 0, 0, scm_primitive_poll); | |
105 | #else | |
106 | scm_misc_error ("%init-poll", "`poll' unavailable on this platform", SCM_EOL); | |
107 | #endif | |
108 | ||
109 | #ifdef POLLIN | |
110 | scm_c_define ("POLLIN", scm_from_int (POLLIN)); | |
111 | #endif | |
112 | #ifdef POLLPRI | |
113 | scm_c_define ("POLLPRI", scm_from_int (POLLPRI)); | |
114 | #endif | |
115 | #ifdef POLLOUT | |
116 | scm_c_define ("POLLOUT", scm_from_int (POLLOUT)); | |
117 | #endif | |
118 | #ifdef POLLRDHUP | |
119 | scm_c_define ("POLLRDHUP", scm_from_int (POLLRDHUP)); | |
120 | #endif | |
121 | #ifdef POLLERR | |
122 | scm_c_define ("POLLERR", scm_from_int (POLLERR)); | |
123 | #endif | |
124 | #ifdef POLLHUP | |
125 | scm_c_define ("POLLHUP", scm_from_int (POLLHUP)); | |
126 | #endif | |
127 | #ifdef POLLNVAL | |
128 | scm_c_define ("POLLNVAL", scm_from_int (POLLNVAL)); | |
129 | #endif | |
130 | ||
131 | } | |
132 | ||
133 | void | |
134 | scm_register_poll (void) | |
135 | { | |
136 | scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION, | |
137 | "scm_init_poll", | |
138 | (scm_t_extension_init_func) scm_init_poll, | |
139 | NULL); | |
140 | } | |
141 | ||
142 | /* | |
143 | Local Variables: | |
144 | c-file-style: "gnu" | |
145 | End: | |
146 | */ |