forked from svaarala/duktape
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpoll.c
More file actions
111 lines (91 loc) · 2.51 KB
/
Copy pathpoll.c
File metadata and controls
111 lines (91 loc) · 2.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
* C wrapper for poll().
*/
#define _GNU_SOURCE
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <poll.h>
#include <time.h>
#include "duktape.h"
static int poll_poll(duk_context *ctx) {
int timeout = duk_to_int(ctx, 1);
int i, n, nchanged;
int fd, rc;
struct pollfd fds[20];
struct timespec ts;
memset(fds, 0, sizeof(fds));
n = 0;
duk_enum(ctx, 0, 0 /*enum_flags*/);
while (duk_next(ctx, -1, 0)) {
if ((size_t) n >= sizeof(fds) / sizeof(struct pollfd)) {
return -1;
}
/* [... enum key] */
duk_dup_top(ctx); /* -> [... enum key key] */
duk_get_prop(ctx, 0); /* -> [... enum key val] */
fd = duk_to_int(ctx, -2);
duk_push_string(ctx, "events");
duk_get_prop(ctx, -2); /* -> [... enum key val events] */
fds[n].fd = fd;
fds[n].events = duk_to_int(ctx, -1);
fds[n].revents = 0;
duk_pop_n(ctx, 3); /* -> [... enum] */
n++;
}
/* leave enum on stack */
memset(&ts, 0, sizeof(ts));
ts.tv_nsec = (timeout % 1000) * 1000000;
ts.tv_sec = timeout / 1000;
/*rc = ppoll(fds, n, &ts, NULL);*/
rc = poll(fds, n, timeout);
if (rc < 0) {
duk_error(ctx, DUK_ERR_ERROR, "%s (errno=%d)", strerror(errno), errno);
}
duk_push_array(ctx);
nchanged = 0;
for (i = 0; i < n; i++) {
/* update revents */
if (fds[i].revents) {
duk_push_int(ctx, fds[i].fd); /* -> [... retarr fd] */
duk_put_prop_index(ctx, -2, nchanged);
nchanged++;
}
duk_push_int(ctx, fds[i].fd); /* -> [... retarr key] */
duk_get_prop(ctx, 0); /* -> [... retarr val] */
duk_push_string(ctx, "revents");
duk_push_int(ctx, fds[i].revents); /* -> [... retarr val "revents" fds[i].revents] */
duk_put_prop(ctx, -3); /* -> [... retarr val] */
duk_pop(ctx);
}
/* [retarr] */
return 1;
}
static duk_function_list_entry poll_funcs[] = {
{ "poll", poll_poll, 2 },
{ NULL, NULL, 0 }
};
static duk_number_list_entry poll_consts[] = {
{ "POLLIN", (double) POLLIN },
{ "POLLPRI", (double) POLLPRI },
{ "POLLOUT", (double) POLLOUT },
#if 0
/* Linux 2.6.17 and upwards, requires _GNU_SOURCE etc, not added
* now because we don't use it.
*/
{ "POLLRDHUP", (double) POLLRDHUP },
#endif
{ "POLLERR", (double) POLLERR },
{ "POLLHUP", (double) POLLHUP },
{ "POLLNVAL", (double) POLLNVAL },
{ NULL, 0.0 }
};
void poll_register(duk_context *ctx) {
/* Set global 'Poll' with functions and constants. */
duk_push_global_object(ctx);
duk_push_object(ctx);
duk_put_function_list(ctx, -1, poll_funcs);
duk_put_number_list(ctx, -1, poll_consts);
duk_put_prop_string(ctx, -2, "Poll");
duk_pop(ctx);
}