Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
main.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "duktape.h"

Go to the source code of this file.

Functions

void poll_register (duk_context *ctx)
 
void ncurses_register (duk_context *ctx)
 
void socket_register (duk_context *ctx)
 
void fileio_register (duk_context *ctx)
 
void eventloop_register (duk_context *ctx)
 
int eventloop_run (duk_context *ctx)
 
static void my_sighandler (int x)
 
static void set_sigint_handler (void)
 
static void print_error (duk_context *ctx, FILE *f)
 
int wrapped_compile_execute (duk_context *ctx)
 
int handle_fh (duk_context *ctx, FILE *f, const char *filename)
 
int handle_file (duk_context *ctx, const char *filename)
 
int handle_stdin (duk_context *ctx)
 
int main (int argc, char *argv[])
 

Variables

static int c_evloop = 0
 

Function Documentation

◆ eventloop_register()

void eventloop_register ( duk_context * ctx)
extern

Definition at line 601 of file duktape-1.5.2/examples/eventloop/c_eventloop.c.

601 {
602 memset((void *) timer_list, 0, MAX_TIMERS * sizeof(ev_timer));
603 memset((void *) &timer_expiring, 0, sizeof(ev_timer));
604 memset((void *) poll_list, 0, MAX_FDS * sizeof(struct pollfd));
605
606 /* Set global 'EventLoop'. */
608 duk_push_object(ctx);
610 duk_put_prop_string(ctx, -2, "EventLoop");
611 duk_pop(ctx);
612
613 /* Initialize global stash 'eventTimers'. */
615 duk_push_object(ctx);
616 duk_put_prop_string(ctx, -2, "eventTimers");
617 duk_pop(ctx);
618}
static struct pollfd poll_list[MAX_FDS]
static ev_timer timer_list[MAX_TIMERS]
static duk_function_list_entry eventloop_funcs[]
DUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key)
DUK_EXTERNAL duk_idx_t duk_push_object(duk_context *ctx)
DUK_EXTERNAL void duk_push_global_stash(duk_context *ctx)
DUK_EXTERNAL void duk_push_global_object(duk_context *ctx)
DUK_EXTERNAL void duk_put_function_list(duk_context *ctx, duk_idx_t obj_index, const duk_function_list_entry *funcs)
DUK_EXTERNAL void duk_pop(duk_context *ctx)

Referenced by main().

◆ eventloop_run()

int eventloop_run ( duk_context * ctx)
extern

Definition at line 257 of file duktape-1.5.2/examples/eventloop/c_eventloop.c.

257 {
258 ev_timer *t;
259 double now;
260 double diff;
261 int timeout;
262 int rc;
263 int i, n;
264 int idx_eventloop;
265 int idx_fd_handler;
266
267 /* The Ecmascript poll handler is passed through EventLoop.fdPollHandler
268 * which c_eventloop.js sets before we come here.
269 */
271 duk_get_prop_string(ctx, -1, "EventLoop");
272 duk_get_prop_string(ctx, -1, "fdPollHandler"); /* -> [ global EventLoop fdPollHandler ] */
273 idx_fd_handler = duk_get_top_index(ctx);
274 idx_eventloop = idx_fd_handler - 1;
275
276 for (;;) {
277 /*
278 * Expire timers.
279 */
280
281 expire_timers(ctx);
282
283 /*
284 * If exit requested, bail out as fast as possible.
285 */
286
287 if (exit_requested) {
288#if 0
289 fprintf(stderr, "exit requested, exiting event loop\n");
290 fflush(stderr);
291#endif
292 break;
293 }
294
295 /*
296 * Compact poll list by removing pollfds with fd == 0.
297 */
298
300
301 /*
302 * Determine poll() timeout (as close to poll() as possible as
303 * the wait is relative).
304 */
305
306 now = get_now();
307 t = find_nearest_timer();
308 if (t) {
309 diff = t->target - now;
310 if (diff < MIN_WAIT) {
311 diff = MIN_WAIT;
312 } else if (diff > MAX_WAIT) {
313 diff = MAX_WAIT;
314 }
315 timeout = (int) diff; /* clamping ensures that fits */
316 } else {
317 if (poll_count == 0) {
318#if 0
319 fprintf(stderr, "no timers and no sockets to poll, exiting\n");
320 fflush(stderr);
321#endif
322 break;
323 }
324 timeout = (int) MAX_WAIT;
325 }
326
327 /*
328 * Poll for activity or timeout.
329 */
330
331#if 0
332 fprintf(stderr, "going to poll, timeout %d ms, pollfd count %d\n", timeout, poll_count);
333 fflush(stderr);
334#endif
335
336 rc = poll(poll_list, poll_count, timeout);
337#if 0
338 fprintf(stderr, "poll rc: %d\n", rc);
339 fflush(stderr);
340#endif
341 if (rc < 0) {
342 /* error */
343 } else if (rc == 0) {
344 /* timeout */
345 } else {
346 /* 'rc' fds active */
347 }
348
349 /*
350 * Check socket activity, handle all sockets. Handling is offloaded to
351 * Ecmascript code (fd + revents).
352 *
353 * If FDs are removed from the poll list while we're processing callbacks,
354 * the entries are simply marked unused (fd set to 0) without actually
355 * removing them from the poll list. This ensures indices are not
356 * disturbed. The poll list is compacted before next poll().
357 */
358
359 n = (rc == 0 ? 0 : poll_count); /* if timeout, no need to check pollfd */
360 for (i = 0; i < n; i++) {
361 struct pollfd *pfd = poll_list + i;
362
363 if (pfd->fd == 0) {
364 /* deleted, perhaps by previous callback */
365 continue;
366 }
367
368 if (pfd->revents) {
369#if 0
370 fprintf(stderr, "fd %d has revents: %d\n", (int) pfd->fd, (int) pfd->revents);
371 fflush(stderr);
372#endif
373 duk_dup(ctx, idx_fd_handler);
374 duk_dup(ctx, idx_eventloop);
375 duk_push_int(ctx, pfd->fd);
376 duk_push_int(ctx, pfd->revents);
377 rc = duk_pcall_method(ctx, 2 /*nargs*/);
378 if (rc) {
379#if 0
380 fprintf(stderr, "fd callback failed for fd %d: %s\n", (int) pfd->fd, duk_to_string(ctx, -1));
381 fflush(stderr);
382#endif
383 }
384 duk_pop(ctx);
385
386 pfd->revents = 0;
387 }
388
389 }
390 }
391
392 duk_pop_n(ctx, 3);
393
394 return 0;
395}
static double get_now(void)
static void expire_timers(duk_context *ctx)
static void compact_poll_list(void)
static ev_timer * find_nearest_timer(void)
DUK_EXTERNAL void duk_push_int(duk_context *ctx, duk_int_t val)
DUK_EXTERNAL duk_idx_t duk_get_top_index(duk_context *ctx)
DUK_EXTERNAL void duk_dup(duk_context *ctx, duk_idx_t from_index)
DUK_EXTERNAL duk_int_t duk_pcall_method(duk_context *ctx, duk_idx_t nargs)
DUK_EXTERNAL duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_index, const char *key)
DUK_EXTERNAL void duk_pop_n(duk_context *ctx, duk_idx_t count)
DUK_EXTERNAL const char * duk_to_string(duk_context *ctx, duk_idx_t index)

Referenced by wrapped_compile_execute().

◆ fileio_register()

void fileio_register ( duk_context * ctx)
extern

Definition at line 62 of file duktape-1.5.2/examples/eventloop/fileio.c.

62 {
63 /* Set global 'FileIo'. */
65 duk_push_object(ctx);
67 duk_put_prop_string(ctx, -2, "FileIo");
68 duk_pop(ctx);
69}
static duk_function_list_entry fileio_funcs[]

Referenced by main().

◆ handle_fh()

int handle_fh ( duk_context * ctx,
FILE * f,
const char * filename )

Definition at line 101 of file vendor/civetweb/third_party/duktape-1.5.2/examples/eventloop/main.c.

101 {
102 char *buf = NULL;
103 int len;
104 int got;
105 int rc;
106 int retval = -1;
107
108 if (fseek(f, 0, SEEK_END) < 0) {
109 goto error;
110 }
111 len = (int) ftell(f);
112 if (fseek(f, 0, SEEK_SET) < 0) {
113 goto error;
114 }
115 buf = (char *) malloc(len);
116 if (!buf) {
117 goto error;
118 }
119
120 got = fread((void *) buf, (size_t) 1, (size_t) len, f);
121
122 duk_push_lstring(ctx, buf, got);
123 duk_push_string(ctx, filename);
124
125 free(buf);
126 buf = NULL;
127
128 rc = duk_safe_call(ctx, wrapped_compile_execute, 2 /*nargs*/, 1 /*nret*/);
129 if (rc != DUK_EXEC_SUCCESS) {
130 print_error(ctx, stderr);
131 goto error;
132 } else {
133 duk_pop(ctx);
134 retval = 0;
135 }
136 /* fall thru */
137
138 error:
139 if (buf) {
140 free(buf);
141 }
142 return retval;
143}
#define free
Definition civetweb.c:1542
#define malloc
Definition civetweb.c:1539
DUK_EXTERNAL const char * duk_push_string(duk_context *ctx, const char *str)
DUK_EXTERNAL const char * duk_push_lstring(duk_context *ctx, const char *str, duk_size_t len)
DUK_EXTERNAL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, duk_idx_t nargs, duk_idx_t nrets)
#define NULL
Definition gmacros.h:924
static void error(LoadState *S, const char *why)
size_t fread(void *, size_t, size_t, FILE *)
static void print_error(duk_context *ctx, FILE *f)

References DUK_EXEC_SUCCESS, duk_pop(), duk_push_lstring(), duk_push_string(), duk_safe_call(), error(), fread(), free, malloc, NULL, print_error(), and wrapped_compile_execute().

Referenced by handle_file(), and handle_stdin().

◆ handle_file()

int handle_file ( duk_context * ctx,
const char * filename )

Definition at line 145 of file vendor/civetweb/third_party/duktape-1.5.2/examples/eventloop/main.c.

145 {
146 FILE *f = NULL;
147 int retval;
148
149 f = fopen(filename, "rb");
150 if (!f) {
151 fprintf(stderr, "failed to open source file: %s\n", filename);
152 fflush(stderr);
153 goto error;
154 }
155
156 retval = handle_fh(ctx, f, filename);
157
158 fclose(f);
159 return retval;
160
161 error:
162 return -1;
163}
int handle_fh(duk_context *ctx, FILE *f, const char *filename)

References error(), handle_fh(), and NULL.

Referenced by main().

◆ handle_stdin()

int handle_stdin ( duk_context * ctx)

Definition at line 165 of file vendor/civetweb/third_party/duktape-1.5.2/examples/eventloop/main.c.

165 {
166 int retval;
167
168 retval = handle_fh(ctx, stdin, "stdin");
169
170 return retval;
171}

References handle_fh().

Referenced by main().

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 173 of file vendor/civetweb/third_party/duktape-1.5.2/examples/eventloop/main.c.

173 {
174 duk_context *ctx = NULL;
175 int retval = 0;
176 const char *filename = NULL;
177 int i;
178
179#ifndef NO_SIGNAL
181
182 /* This is useful at the global level; libraries should avoid SIGPIPE though */
183 /*signal(SIGPIPE, SIG_IGN);*/
184#endif
185
186 for (i = 1; i < argc; i++) {
187 char *arg = argv[i];
188 if (!arg) {
189 goto usage;
190 }
191 if (strcmp(arg, "-c") == 0) {
192 c_evloop = 1;
193 } else if (strlen(arg) > 1 && arg[0] == '-') {
194 goto usage;
195 } else {
196 if (filename) {
197 goto usage;
198 }
199 filename = arg;
200 }
201 }
202 if (!filename) {
203 goto usage;
204 }
205
207
208 poll_register(ctx);
209 ncurses_register(ctx);
210 socket_register(ctx);
211 fileio_register(ctx);
212
213 if (c_evloop) {
214 fprintf(stderr, "Using C based eventloop (omit -c to use Ecmascript based eventloop)\n");
215 fflush(stderr);
216
218 duk_eval_file(ctx, "c_eventloop.js");
219 } else {
220 fprintf(stderr, "Using Ecmascript based eventloop (give -c to use C based eventloop)\n");
221 fflush(stderr);
222
223 duk_eval_file(ctx, "ecma_eventloop.js");
224 }
225
226 fprintf(stderr, "Executing code from: '%s'\n", filename);
227 fflush(stderr);
228
229 if (strcmp(filename, "-") == 0) {
230 if (handle_stdin(ctx) != 0) {
231 retval = 1;
232 goto cleanup;
233 }
234 } else {
235 if (handle_file(ctx, filename) != 0) {
236 retval = 1;
237 goto cleanup;
238 }
239 }
240
241 cleanup:
242 if (ctx) {
243 duk_destroy_heap(ctx);
244 }
245
246 return retval;
247
248 usage:
249 fprintf(stderr, "Usage: evloop [-c] <filename>\n");
250 fprintf(stderr, "\n");
251 fprintf(stderr, "Uses an Ecmascript based eventloop (ecma_eventloop.js) by default.\n");
252 fprintf(stderr, "If -c option given, uses a C based eventloop (c_eventloop.{c,js}).\n");
253 fprintf(stderr, "If <filename> is '-', the entire STDIN executed.\n");
254 fflush(stderr);
255 exit(1);
256}
CURL_EXTERN int void * arg
Definition curl.h:2622
DUK_EXTERNAL void duk_destroy_heap(duk_context *ctx)
#define duk_eval_file(ctx, path)
#define duk_create_heap_default()
static void usage(const char *message)
void fileio_register(duk_context *ctx)
int handle_file(duk_context *ctx, const char *filename)
void socket_register(duk_context *ctx)
void poll_register(duk_context *ctx)
void eventloop_register(duk_context *ctx)
void ncurses_register(duk_context *ctx)

References arg, c_evloop, duk_create_heap_default, duk_destroy_heap(), duk_eval_file, eventloop_register(), fileio_register(), handle_file(), handle_stdin(), ncurses_register(), NULL, poll_register(), set_sigint_handler(), socket_register(), and usage().

◆ my_sighandler()

static void my_sighandler ( int x)
static

Definition at line 27 of file vendor/civetweb/third_party/duktape-1.5.2/examples/eventloop/main.c.

27 {
28 fprintf(stderr, "Got signal %d\n", x);
29 fflush(stderr);
30}

Referenced by set_sigint_handler().

◆ ncurses_register()

void ncurses_register ( duk_context * ctx)
extern

Definition at line 98 of file duktape-1.5.2/examples/eventloop/ncurses.c.

98 {
99 /* Set global 'Ncurses'. */
101 duk_push_object(ctx);
103 duk_put_prop_string(ctx, -2, "Ncurses");
104 duk_pop(ctx);
105}
static duk_function_list_entry ncurses_funcs[]

References duk_pop(), duk_push_global_object(), duk_push_object(), duk_put_function_list(), duk_put_prop_string(), and ncurses_funcs.

Referenced by main().

◆ poll_register()

void poll_register ( duk_context * ctx)
extern

Definition at line 103 of file duktape-1.5.2/examples/eventloop/poll.c.

103 {
104 /* Set global 'Poll' with functions and constants. */
106 duk_push_object(ctx);
109 duk_put_prop_string(ctx, -2, "Poll");
110 duk_pop(ctx);
111}
static duk_function_list_entry poll_funcs[]
static duk_number_list_entry poll_consts[]
DUK_EXTERNAL void duk_put_number_list(duk_context *ctx, duk_idx_t obj_index, const duk_number_list_entry *numbers)

References duk_pop(), duk_push_global_object(), duk_push_object(), duk_put_function_list(), duk_put_number_list(), duk_put_prop_string(), poll_consts, and poll_funcs.

Referenced by main().

◆ print_error()

static void print_error ( duk_context * ctx,
FILE * f )
static

Definition at line 37 of file vendor/civetweb/third_party/duktape-1.5.2/examples/eventloop/main.c.

37 {
38 if (duk_is_object(ctx, -1) && duk_has_prop_string(ctx, -1, "stack")) {
39 /* XXX: print error objects specially */
40 /* XXX: pcall the string coercion */
41 duk_get_prop_string(ctx, -1, "stack");
42 if (duk_is_string(ctx, -1)) {
43 fprintf(f, "%s\n", duk_get_string(ctx, -1));
44 fflush(f);
45 duk_pop_2(ctx);
46 return;
47 } else {
48 duk_pop(ctx);
49 }
50 }
51 duk_to_string(ctx, -1);
52 fprintf(f, "%s\n", duk_get_string(ctx, -1));
53 fflush(f);
54 duk_pop(ctx);
55}
DUK_EXTERNAL void duk_pop_2(duk_context *ctx)
DUK_EXTERNAL duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_index, const char *key)
DUK_EXTERNAL const char * duk_get_string(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL duk_bool_t duk_is_object(duk_context *ctx, duk_idx_t index)
DUK_EXTERNAL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t index)

References duk_get_prop_string(), duk_get_string(), duk_has_prop_string(), duk_is_object(), duk_is_string(), duk_pop(), duk_pop_2(), and duk_to_string().

Referenced by handle_fh().

◆ set_sigint_handler()

static void set_sigint_handler ( void )
static

Definition at line 31 of file vendor/civetweb/third_party/duktape-1.5.2/examples/eventloop/main.c.

31 {
32 (void) signal(SIGINT, my_sighandler);
33}

References my_sighandler().

Referenced by main().

◆ socket_register()

void socket_register ( duk_context * ctx)
extern

Definition at line 279 of file duktape-1.5.2/examples/eventloop/socket.c.

279 {
280 /* Set global 'Socket'. */
282 duk_push_object(ctx);
284 duk_put_prop_string(ctx, -2, "Socket");
285 duk_pop(ctx);
286}
static duk_function_list_entry socket_funcs[]

References duk_pop(), duk_push_global_object(), duk_push_object(), duk_put_function_list(), duk_put_prop_string(), and socket_funcs.

Referenced by main().

◆ wrapped_compile_execute()

int wrapped_compile_execute ( duk_context * ctx)

Definition at line 57 of file vendor/civetweb/third_party/duktape-1.5.2/examples/eventloop/main.c.

57 {
58 int comp_flags = 0;
59 int rc;
60
61 /* Compile input and place it into global _USERCODE */
62 duk_compile(ctx, comp_flags);
64 duk_insert(ctx, -2); /* [ ... global func ] */
65 duk_put_prop_string(ctx, -2, "_USERCODE");
66 duk_pop(ctx);
67#if 0
68 printf("compiled usercode\n");
69#endif
70
71 /* Start a zero timer which will call _USERCODE from within
72 * the event loop.
73 */
74 fprintf(stderr, "set _USERCODE timer\n");
75 fflush(stderr);
76 duk_eval_string(ctx, "setTimeout(function() { _USERCODE(); }, 0);");
77 duk_pop(ctx);
78
79 /* Finally, launch eventloop. This call only returns after the
80 * eventloop terminates.
81 */
82 if (c_evloop) {
83 fprintf(stderr, "calling eventloop_run()\n");
84 fflush(stderr);
85 rc = duk_safe_call(ctx, eventloop_run, 0 /*nargs*/, 1 /*nrets*/);
86 if (rc != 0) {
87 fprintf(stderr, "eventloop_run() failed: %s\n", duk_to_string(ctx, -1));
88 fflush(stderr);
89 }
90 duk_pop(ctx);
91 } else {
92 fprintf(stderr, "calling EventLoop.run()\n");
93 fflush(stderr);
94 duk_eval_string(ctx, "EventLoop.run();");
95 duk_pop(ctx);
96 }
97
98 return 0;
99}
DUK_EXTERNAL void duk_insert(duk_context *ctx, duk_idx_t to_index)
#define duk_eval_string(ctx, src)
#define duk_compile(ctx, flags)
#define printf
int eventloop_run(duk_context *ctx)

References c_evloop, duk_compile, duk_eval_string, duk_insert(), duk_pop(), duk_push_global_object(), duk_put_prop_string(), duk_safe_call(), duk_to_string(), eventloop_run(), and printf.

Referenced by handle_fh().

Variable Documentation

◆ c_evloop

int c_evloop = 0
static