*** empty log message ***
authorMatthew Mondor <mmondor@pulsar-zone.net>
Tue, 19 Jul 2005 19:27:28 +0000 (19:27 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Tue, 19 Jul 2005 19:27:28 +0000 (19:27 +0000)
tests/js-test/js/httpd/httpd.js
tests/js-test/src/GNUmakefile
tests/js-test/src/classes/js_errno.h
tests/js-test/src/classes/js_fd.h
tests/js-test/src/classes/js_signal.c [new file with mode: 0644]
tests/js-test/src/classes/js_signal.h [new file with mode: 0644]
tests/js-test/src/js-server.c

index 3d5fbf4..cfe2f4f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: httpd.js,v 1.68 2005/07/19 04:05:26 mmondor Exp $ */
+/* $Id: httpd.js,v 1.69 2005/07/19 19:25:44 mmondor Exp $ */
 
 /*
  * Copyright (c) 2005, Matthew Mondor
@@ -59,7 +59,7 @@
  * Server identification
  */
 SERVER_VERSION                 = 'mmondor_js_httpd/0.0.1 (NetBSD)';
-SERVER_CVSID   = '$Id: httpd.js,v 1.68 2005/07/19 04:05:26 mmondor Exp $';
+SERVER_CVSID   = '$Id: httpd.js,v 1.69 2005/07/19 19:25:44 mmondor Exp $';
 
 
 
@@ -1632,6 +1632,11 @@ function main() {
                                close = true;
                        else if ((e[i].revents & (FD.POLLIN | FD.POLLOUT))
                            != 0) {
+                               /*
+                                * Flush output queue if any and possible,
+                                * since we're in non-blocking mode writes
+                                * can yield short counts.
+                                */
                                var o = e[i].bwrite_flush();
 
                                if (o.close == true)
index fa33637..f7297a2 100644 (file)
@@ -1,9 +1,9 @@
-# $Id: GNUmakefile,v 1.5 2005/07/15 21:57:06 mmondor Exp $
+# $Id: GNUmakefile,v 1.6 2005/07/19 19:25:44 mmondor Exp $
 
 JS_CFLAGS := $(shell spidermonkey-config -dc)
 JS_LDFLAGS := $(shell spidermonkey-config -dl)
 
-OBJS := $(addprefix classes/,js_fd.o js_errno.o)
+OBJS := $(addprefix classes/,js_fd.o js_errno.o js_signal.o)
 OBJS += js-server.o
 
 CFLAGS += $(JS_CFLAGS) -Iclasses -Wall
index 4dcb90c..22b69bb 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: js_errno.h,v 1.1 2005/07/14 00:55:06 mmondor Exp $ */
+/* $Id: js_errno.h,v 1.2 2005/07/19 19:25:44 mmondor Exp $ */
 
 /*
- * Copyright (c) 2004, Matthew Mondor
+ * Copyright (c) 2005, Matthew Mondor
  * ALL RIGHTS RESERVED.
  */
 
index 9a7f9e5..5d268b4 100644 (file)
@@ -1,7 +1,7 @@
-/* $Id: js_fd.h,v 1.2 2005/07/14 00:55:06 mmondor Exp $ */
+/* $Id: js_fd.h,v 1.3 2005/07/19 19:25:44 mmondor Exp $ */
 
 /*
- * Copyright (c) 2004, Matthew Mondor
+ * Copyright (c) 2005, Matthew Mondor
  * ALL RIGHTS RESERVED.
  */
 
diff --git a/tests/js-test/src/classes/js_signal.c b/tests/js-test/src/classes/js_signal.c
new file mode 100644 (file)
index 0000000..13115d6
--- /dev/null
@@ -0,0 +1,273 @@
+/* $Id: js_signal.c,v 1.1 2005/07/19 19:27:28 mmondor Exp $ */
+
+/*
+ * Copyright (c) 2005, Matthew Mondor
+ * ALL RIGHTS RESERVED.
+ */
+
+/*
+ * Basic UNIX signal services for ECMAScript
+ *
+ * XXX
+ * I have to see what interface I want to export. There are several
+ * possibilities we could use:
+ * - Have the shell register signal handlers fore interesting events at
+ *   startup and allow scripts to provide a handler function, which if
+ *   exists upon reception of a signal, gets executed.  We might then
+ *   need to add extra custom checks in the shell for special signals
+ *   which if the script doesn't end, might still end the process
+ *   i.e. function would be expected to cause the script to exit upon
+ *   reception of a SIGTERM signal...
+ * - Provide a sigaction-style interface so that the script would be
+ *   able to define functions to execute upon reception of certain
+ *   signals, or null or such for the signal to be ignored.
+ *   This solution might allow better application customization.
+ *   If assuming this interface, the following would be exported:
+ *   - Signal class, through which static signal properties could be
+ *     accessed for signal numbers I.E. Signal.SIGTERM.
+ *   - A static method to create/set/unset/ignore a signal/handler
+ *     Signal.sigaction()?
+ *     It could be provided with the parameters:
+ *     Signal.sigaction(FD.SIG*, obj);
+ *      Where obj would contain fields sa_handler, sa_mask, sa_flags?
+ *     Signal.kill(pid, sig);
+ *     Signal.sigaltstack(...) ?
+ *     Signal.sigprocmask(...)
+ *     Signal.sigsuspend(mask)
+ *    And maybe provide the sigsetops(3)?  We possibly could just allow an
+ *    array or such instead of sigset_t though if wanted.
+ *    I'm not sure I want to provide sigsetjmp()/siglongjmp(). JavaScript has
+ *    exceptions anyways.  If allowing sigaltstack(), C would need to allocate
+ *    the stacks, so a stack object would need to be exported or such.  I
+ *    don't think I want to support this as it's probably not needed by any of
+ *    the applications I'll write, I don't want to write a threading library
+ *    in JS.
+ */
+
+
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <jsapi.h>
+
+
+
+/* Utility macros */
+#define QUEUE_EXCEPTION(s)     do {                                    \
+       JS_SetPendingException(cx,                                      \
+           STRING_TO_JSVAL(JS_NewStringCopyZ(cx, (s))));               \
+} while (/* CONSTCOND */0)
+
+
+
+/* Prototypes */
+static JSBool  signal_static_getProperty(JSContext *, JSObject *, jsval,
+                   jsval *);
+
+static JSBool  signal_sm_strerror(JSContext *, JSObject *, uintN, jsval *,
+                   jsval *);
+
+
+
+/* Actual class parameters */
+static JSClass signal_class = {
+       "Signal", 0, JS_PropertyStub, JS_PropertyStub,
+       JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
+       JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
+};
+
+/* Provided static methods */
+static JSFunctionSpec signal_smethods[] = {
+       { "strerror", signal_sm_strerror, 1, 0, 0 },
+       { NULL, NULL, 0, 0, 0 }
+};
+
+/*
+ * Provided static properties.
+ * We use these to provide ECMAScript with the ability to use system-specific
+ * standard C constant macros without us having to tidiously map them
+ * individually, or to require other scripts to be used as headers to define
+ * them.  Another possibility would have been to supply these parameters as
+ * string, but this would have required even slower remapping because of the
+ * parsing and string comparisions.
+ * We only include those which we consider necessary for now, others may be
+ * added easily as needed, provided that they are added in all three maps.
+ * I might perhaps develop macros and/or functions to map all these easily
+ * from a single map.
+ */
+enum signal_sprops {
+       SIGNAL_SP_SIGHUP,
+       SIGNAL_SP_SIGINT,
+       SIGNAL_SP_SIGQUIT,
+       SIGNAL_SP_SIGILL,
+       SIGNAL_SP_SIGTRAP,
+       SIGNAL_SP_SIGABRT,
+       SIGNAL_SP_SIGEMT,
+       SIGNAL_SP_SIGFPE,
+       SIGNAL_SP_SIGKILL,
+       SIGNAL_SP_SIGBUS,
+       SIGNAL_SP_SIGSEGV,
+       SIGNAL_SP_SIGSYS,
+       SIGNAL_SP_SIGPIPE,
+       SIGNAL_SP_SIGALRM,
+       SIGNAL_SP_SIGTERM,
+       SIGNAL_SP_SIGURG,
+       SIGNAL_SP_SIGSTOP,
+       SIGNAL_SP_SIGTSTP,
+       SIGNAL_SP_SIGCONT,
+       SIGNAL_SP_SIGCHLD,
+       SIGNAL_SP_SIGTTIN,
+       SIGNAL_SP_SIGTTOU,
+       SIGNAL_SP_SIGIO,
+       SIGNAL_SP_SIGXCPU,
+       SIGNAL_SP_SIGXFSZ,
+       SIGNAL_SP_SIGVTALRM,
+       SIGNAL_SP_SIGPROF,
+       SIGNAL_SP_SIGWINCH,
+       SIGNAL_SP_SIGINFO,
+       SIGNAL_SP_SIGUSR1,
+       SIGNAL_SP_SIGUSR2,
+       SIGNAL_SP_SIGPWR,
+
+       SIGNAL_SP_MAX
+};
+
+#define JSP_STATPROP \
+   (JSPROP_ENUMERATE | JSPROP_SHARED | JSPROP_READONLY | JSPROP_PERMANENT)
+#define JSP_STATPROPFS \
+   signal_static_getProperty, NULL
+
+static JSPropertySpec signal_sproperties[SIGNAL_SP_MAX + 1] = {
+       { "SIGHUP", SIGNAL_SP_SIGHUP, JSP_STATPROP, JSP_STATPROPFS },
+
+       { NULL, 0, 0, NULL, NULL }
+};
+
+#undef JSPROP_STATPROP
+#undef JSPROP_STATPROPFS
+
+/*
+ * The following array is necessary since we can only store unique tiny IDs,
+ * while some of our values may be duplicated.  So let tinyid be unique (and
+ * limited to 8-bit), but map them to integers.
+ */
+
+static int signal_sprops_data[SIGNAL_SP_MAX] = {
+       SIGHUP,
+       SIGINT,
+       SIGQUIT,
+       SIGILL,
+       SIGTRAP,
+       SIGABRT,
+       SIGEMT,
+       SIGFPE,
+       SIGKILL,
+       SIGBUS,
+       SIGSEGV,
+       SIGSYS,
+       SIGPIPE,
+       SIGALRM,
+       SIGTERM,
+       SIGURG,
+       SIGSTOP,
+       SIGTSTP,
+       SIGCONT,
+       SIGCHLD,
+       SIGTTIN,
+       SIGTTOU,
+       SIGIO,
+       SIGXCPU,
+       SIGXFSZ,
+       SIGVTALRM,
+       SIGPROF,
+       SIGWINCH,
+       SIGINFO,
+       SIGUSR1,
+       SIGUSR2,
+       SIGPWR
+};
+
+
+
+/*
+ * Class control functions
+ */
+
+JSObject *
+js_InitSignalClass(JSContext *cx, JSObject *obj)
+{
+       JSObject *class;
+
+       if ((class = JS_InitClass(cx, obj, NULL, &signal_class, NULL,
+           0, NULL, NULL, signal_sproperties, signal_smethods)) == NULL) {
+               (void) fprintf(stderr, "Error initializing Signal class\n");
+               return NULL;
+       }
+
+       return class;
+}
+
+
+
+/*
+ * Static properties functions
+ */
+
+static JSBool
+signal_static_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+       jsint   p;
+
+       if (!JSVAL_IS_INT(id))
+               return JS_TRUE;
+
+       p = (int)JSVAL_TO_INT(id);
+       if (p < 0 || p >= SIGNAL_SP_MAX)
+               return JS_TRUE;
+
+       *vp = INT_TO_JSVAL(signal_sprops_data[
+           (int)signal_sproperties[p].tinyid]);
+
+       return JS_TRUE;
+}
+
+
+
+/*
+ * Static methods
+ */
+
+static JSBool
+signal_sm_strerror(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
+    jsval *rval)
+{
+       int             error;
+       JSString        *string;
+
+       *rval = OBJECT_TO_JSVAL(NULL);
+
+       if (argc != 1) {
+               QUEUE_EXCEPTION("Wrong number of arguments");
+               return JS_FALSE;
+       }
+       if (!JSVAL_IS_INT(*argv)) {
+               QUEUE_EXCEPTION("Argument not an integer");
+               return JS_FALSE;
+       }
+       error = (int)JSVAL_TO_INT(*argv);
+
+       if ((string = JS_NewStringCopyZ(cx, "testXXX")) == NULL) {
+               QUEUE_EXCEPTION("Out of memory");
+               return JS_FALSE;
+       }
+
+       *rval = STRING_TO_JSVAL(string);
+
+       return JS_TRUE;
+}
diff --git a/tests/js-test/src/classes/js_signal.h b/tests/js-test/src/classes/js_signal.h
new file mode 100644 (file)
index 0000000..3690d12
--- /dev/null
@@ -0,0 +1,13 @@
+/* $Id: js_signal.h,v 1.1 2005/07/19 19:27:28 mmondor Exp $ */
+
+/*
+ * Copyright (c) 2005, Matthew Mondor
+ * ALL RIGHTS RESERVED.
+ */
+
+#ifndef JSSIGNAL_H
+#define JSSIGNAL_H
+
+extern JSObject        *js_InitSignalClass(JSContext *, JSObject *);
+
+#endif
index fcaab86..a2c1f08 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: js-server.c,v 1.3 2005/07/15 22:08:35 mmondor Exp $ */
+/* $Id: js-server.c,v 1.4 2005/07/19 19:25:44 mmondor Exp $ */
 
 /*
  * Copyright (c) 2004-2005, Matthew Mondor
@@ -37,6 +37,7 @@
 
 #include <js_fd.h>
 #include <js_errno.h>
+#include <js_signal.h>
 
 
 
@@ -59,7 +60,7 @@
 typedef struct {
        JSRuntime       *rt;
        JSContext       *ctx;
-       JSObject        *global, *class_fd, *class_errno;
+       JSObject        *global, *class_fd, *class_errno, *class_signal;
 } js_context_t;
 
 /*
@@ -240,6 +241,8 @@ js_context_init(size_t gc_size, size_t stack_size)
            (cctx->class_fd = js_InitFDClass(cctx->ctx, cctx->global))
                == NULL ||
            (cctx->class_errno = js_InitErrnoClass(cctx->ctx, cctx->global))
+               == NULL ||
+           (cctx->class_signal = js_InitSignalClass(cctx->ctx, cctx->global))
                == NULL) {
                /* An error, free any partially allocated resources */
                if (cctx != NULL)