add (ice-9 poll), a poll wrapper
[bpt/guile.git] / libguile / poll.c
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 */