--- /dev/null
+/* $Id: js_errno.c,v 1.1 2005/07/14 00:55:06 mmondor Exp $ */
+
+/*
+ * Copyright (c) 2005, Matthew Mondor
+ * ALL RIGHTS RESERVED.
+ */
+
+/*
+ * Basic UNIX errno services for ECMAScript
+ */
+
+
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <jsapi.h>
+
+#include <js_file.h>
+
+
+
+/* Utility macros */
+#define QUEUE_EXCEPTION(s) do { \
+ JS_SetPendingException(cx, \
+ STRING_TO_JSVAL(JS_NewStringCopyZ(cx, (s)))); \
+} while (/* CONSTCOND */0)
+
+
+
+/* Prototypes */
+static JSBool errno_static_getProperty(JSContext *, JSObject *, jsval,
+ jsval *);
+
+static JSBool errno_sm_strerror(JSContext *, JSObject *, uintN, jsval *,
+ jsval *);
+
+
+
+/* Actual class parameters */
+static JSClass errno_class = {
+ "Errno", 0, JS_PropertyStub, JS_PropertyStub,
+ JS_PropertyStub, JS_PropertyStub, JS_EnumerateStub,
+ JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
+};
+
+/* Provided static methods */
+static JSFunctionSpec errno_smethods[] = {
+ { "strerror", errno_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 errno_sprops {
+ ERRNO_SP_EPERM,
+ ERRNO_SP_ENOENT,
+ ERRNO_SP_EINTR,
+ ERRNO_SP_EIO,
+ ERRNO_SP_ENXIO,
+ ERRNO_SP_EBADF,
+ ERRNO_SP_EACCES,
+ ERRNO_SP_ENOTBLK,
+ ERRNO_SP_EBUSY,
+ ERRNO_SP_EEXIST,
+ ERRNO_SP_EXDEV,
+ ERRNO_SP_ENODEV,
+ ERRNO_SP_ENOTDIR,
+ ERRNO_SP_EISDIR,
+ ERRNO_SP_EINVAL,
+ ERRNO_SP_ENFILE,
+ ERRNO_SP_EMFILE,
+ ERRNO_SP_ENOTTY,
+ ERRNO_SP_ETXTBSY,
+ ERRNO_SP_EFBIG,
+ ERRNO_SP_ENOSPC,
+ ERRNO_SP_ESPIPE,
+ ERRNO_SP_EROFS,
+ ERRNO_SP_EMLINK,
+ ERRNO_SP_EPIPE,
+ ERRNO_SP_EAGAIN,
+ ERRNO_SP_EINPROGRESS,
+ ERRNO_SP_EALREADY,
+ ERRNO_SP_ENOTSOCK,
+ ERRNO_SP_EDESTADDRREQ,
+ ERRNO_SP_EMSGSIZE,
+ ERRNO_SP_EPROTOTYPE,
+ ERRNO_SP_EPROTONOSUPPORT,
+ ERRNO_SP_EOPNOTSUPP,
+ ERRNO_SP_EPFNOSUPPORT,
+ ERRNO_SP_EAFNOSUPPORT,
+ ERRNO_SP_EADDRINUSE,
+ ERRNO_SP_EADDRNOTAVAIL,
+ ERRNO_SP_ENETDOWN,
+ ERRNO_SP_ENETUNREACH,
+ ERRNO_SP_ENETRESET,
+ ERRNO_SP_ECONNABORTED,
+ ERRNO_SP_ECONNRESET,
+ ERRNO_SP_ENOBUFS,
+ ERRNO_SP_EISCONN,
+ ERRNO_SP_ENOTCONN,
+ ERRNO_SP_ESHUTDOWN,
+ ERRNO_SP_ETIMEDOUT,
+ ERRNO_SP_ECONNREFUSED,
+ ERRNO_SP_ELOOP,
+ ERRNO_SP_ENAMETOOLONG,
+ ERRNO_SP_EHOSTDOWN,
+ ERRNO_SP_EHOSTUNREACH,
+ ERRNO_SP_ENOTEMPTY,
+ ERRNO_SP_EDQUOT,
+ ERRNO_SP_ESTALE,
+ ERRNO_SP_ENOLCK,
+ ERRNO_SP_ENOSYS,
+ ERRNO_SP_EFTYPE,
+ ERRNO_SP_ENOMSG,
+ ERRNO_SP_ENOTSUP,
+ ERRNO_SP_ECANCELED,
+ ERRNO_SP_EBADMSG,
+ ERRNO_SP_ENODATA,
+ ERRNO_SP_ETIME,
+
+ ERRNO_SP_MAX
+};
+
+#define JSP_STATPROP \
+ (JSPROP_ENUMERATE | JSPROP_SHARED | JSPROP_READONLY | JSPROP_PERMANENT)
+#define JSP_STATPROPFS \
+ errno_static_getProperty, NULL
+
+static JSPropertySpec errno_sproperties[ERRNO_SP_MAX + 1] = {
+ { "EPERM", ERRNO_SP_EPERM, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENOENT", ERRNO_SP_ENOENT, JSP_STATPROP, JSP_STATPROPFS },
+ { "EINTR", ERRNO_SP_EINTR, JSP_STATPROP, JSP_STATPROPFS },
+ { "EIO", ERRNO_SP_EIO, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENXIO", ERRNO_SP_ENXIO, JSP_STATPROP, JSP_STATPROPFS },
+ { "EBADF", ERRNO_SP_EBADF, JSP_STATPROP, JSP_STATPROPFS },
+ { "EACCES", ERRNO_SP_EACCES, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENOTBLK", ERRNO_SP_ENOTBLK, JSP_STATPROP, JSP_STATPROPFS },
+ { "EBUSY", ERRNO_SP_EBUSY, JSP_STATPROP, JSP_STATPROPFS },
+ { "EEXIST", ERRNO_SP_EEXIST, JSP_STATPROP, JSP_STATPROPFS },
+ { "EXDEV", ERRNO_SP_EXDEV, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENODEV", ERRNO_SP_ENODEV, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENOTDIR", ERRNO_SP_ENOTDIR, JSP_STATPROP, JSP_STATPROPFS },
+ { "EISDIR", ERRNO_SP_EISDIR, JSP_STATPROP, JSP_STATPROPFS },
+ { "EINVAL", ERRNO_SP_EINVAL, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENFILE", ERRNO_SP_ENFILE, JSP_STATPROP, JSP_STATPROPFS },
+ { "EMFILE", ERRNO_SP_EMFILE, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENOTTY", ERRNO_SP_ENOTTY, JSP_STATPROP, JSP_STATPROPFS },
+ { "ETXTBSY", ERRNO_SP_ETXTBSY, JSP_STATPROP, JSP_STATPROPFS },
+ { "EFBIG", ERRNO_SP_EFBIG, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENOSPC", ERRNO_SP_ENOSPC, JSP_STATPROP, JSP_STATPROPFS },
+ { "ESPIPE", ERRNO_SP_ESPIPE, JSP_STATPROP, JSP_STATPROPFS },
+ { "EROFS", ERRNO_SP_EROFS, JSP_STATPROP, JSP_STATPROPFS },
+ { "EMLINK", ERRNO_SP_EMLINK, JSP_STATPROP, JSP_STATPROPFS },
+ { "EPIPE", ERRNO_SP_EPIPE, JSP_STATPROP, JSP_STATPROPFS },
+ { "EAGAIN", ERRNO_SP_EAGAIN, JSP_STATPROP, JSP_STATPROPFS },
+ { "EINPROGRESS", ERRNO_SP_EINPROGRESS, JSP_STATPROP, JSP_STATPROPFS },
+ { "EALREADY", ERRNO_SP_EALREADY, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENOTSOCK", ERRNO_SP_ENOTSOCK, JSP_STATPROP, JSP_STATPROPFS },
+ { "EDESTADDRREQ", ERRNO_SP_EDESTADDRREQ, JSP_STATPROP,
+ JSP_STATPROPFS },
+ { "EMSGSIZE", ERRNO_SP_EMSGSIZE, JSP_STATPROP, JSP_STATPROPFS },
+ { "EPROTOTYPE", ERRNO_SP_EPROTOTYPE, JSP_STATPROP, JSP_STATPROPFS },
+ { "EPROTONOSUPPORT", ERRNO_SP_EPROTONOSUPPORT, JSP_STATPROP,
+ JSP_STATPROPFS },
+ { "EOPNOTSUPP", ERRNO_SP_EOPNOTSUPP, JSP_STATPROP, JSP_STATPROPFS },
+ { "EPFNOSUPPORT", ERRNO_SP_EPFNOSUPPORT, JSP_STATPROP,
+ JSP_STATPROPFS },
+ { "EAFNOSUPPORT", ERRNO_SP_EAFNOSUPPORT, JSP_STATPROP,
+ JSP_STATPROPFS },
+ { "EADDRINUSE", ERRNO_SP_EADDRINUSE, JSP_STATPROP, JSP_STATPROPFS },
+ { "EADDRNOTAVAIL", ERRNO_SP_EADDRNOTAVAIL, JSP_STATPROP,
+ JSP_STATPROPFS },
+ { "ENETDOWN", ERRNO_SP_ENETDOWN, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENETUNREACH", ERRNO_SP_ENETUNREACH, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENETRESET", ERRNO_SP_ENETRESET, JSP_STATPROP, JSP_STATPROPFS },
+ { "ECONNABORTED", ERRNO_SP_ECONNABORTED, JSP_STATPROP,
+ JSP_STATPROPFS },
+ { "ECONNRESET", ERRNO_SP_ECONNRESET, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENOBUFS", ERRNO_SP_ENOBUFS, JSP_STATPROP, JSP_STATPROPFS },
+ { "EISCONN", ERRNO_SP_EISCONN, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENOTCONN", ERRNO_SP_ENOTCONN, JSP_STATPROP, JSP_STATPROPFS },
+ { "ESHUTDOWN", ERRNO_SP_ESHUTDOWN, JSP_STATPROP, JSP_STATPROPFS },
+ { "ETIMEDOUT", ERRNO_SP_ETIMEDOUT, JSP_STATPROP, JSP_STATPROPFS },
+ { "ECONNREFUSED", ERRNO_SP_ECONNREFUSED, JSP_STATPROP,
+ JSP_STATPROPFS },
+ { "ELOOP", ERRNO_SP_ELOOP, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENAMETOOLONG", ERRNO_SP_ENAMETOOLONG, JSP_STATPROP,
+ JSP_STATPROPFS },
+ { "EHOSTDOWN", ERRNO_SP_EHOSTDOWN, JSP_STATPROP, JSP_STATPROPFS },
+ { "EHOSTUNREACH", ERRNO_SP_EHOSTUNREACH, JSP_STATPROP,
+ JSP_STATPROPFS },
+ { "ENOTEMPTY", ERRNO_SP_ENOTEMPTY, JSP_STATPROP, JSP_STATPROPFS },
+ { "EDQUOT", ERRNO_SP_EDQUOT, JSP_STATPROP, JSP_STATPROPFS },
+ { "ESTALE", ERRNO_SP_ESTALE, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENOLCK", ERRNO_SP_ENOLCK, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENOSYS", ERRNO_SP_ENOSYS, JSP_STATPROP, JSP_STATPROPFS },
+ { "EFTYPE", ERRNO_SP_EFTYPE, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENOMSG", ERRNO_SP_ENOMSG, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENOTSUP", ERRNO_SP_ENOTSUP, JSP_STATPROP, JSP_STATPROPFS },
+ { "ECANCELED", ERRNO_SP_ECANCELED, JSP_STATPROP, JSP_STATPROPFS },
+ { "EBADMSG", ERRNO_SP_EBADMSG, JSP_STATPROP, JSP_STATPROPFS },
+ { "ENODATA", ERRNO_SP_ENODATA, JSP_STATPROP, JSP_STATPROPFS },
+ { "ETIME", ERRNO_SP_ETIME, 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 errno_sprops_data[ERRNO_SP_MAX] = {
+ EPERM,
+ ENOENT,
+ EINTR,
+ EIO,
+ ENXIO,
+ EBADF,
+ EACCES,
+ ENOTBLK,
+ EBUSY,
+ EEXIST,
+ EXDEV,
+ ENODEV,
+ ENOTDIR,
+ EISDIR,
+ EINVAL,
+ ENFILE,
+ EMFILE,
+ ENOTTY,
+ ETXTBSY,
+ EFBIG,
+ ENOSPC,
+ ESPIPE,
+ EROFS,
+ EMLINK,
+ EPIPE,
+ EAGAIN,
+ EINPROGRESS,
+ EALREADY,
+ ENOTSOCK,
+ EDESTADDRREQ,
+ EMSGSIZE,
+ EPROTOTYPE,
+ EPROTONOSUPPORT,
+ EOPNOTSUPP,
+ EPFNOSUPPORT,
+ EAFNOSUPPORT,
+ EADDRINUSE,
+ EADDRNOTAVAIL,
+ ENETDOWN,
+ ENETUNREACH,
+ ENETRESET,
+ ECONNABORTED,
+ ECONNRESET,
+ ENOBUFS,
+ EISCONN,
+ ENOTCONN,
+ ESHUTDOWN,
+ ETIMEDOUT,
+ ECONNREFUSED,
+ ELOOP,
+ ENAMETOOLONG,
+ EHOSTDOWN,
+ EHOSTUNREACH,
+ ENOTEMPTY,
+ EDQUOT,
+ ESTALE,
+ ENOLCK,
+ ENOSYS,
+ EFTYPE,
+ ENOMSG,
+ ENOTSUP,
+ ECANCELED,
+ EBADMSG,
+ ENODATA,
+ ETIME
+};
+
+
+
+/*
+ * Class control functions
+ */
+
+JSObject *
+js_InitErrnoClass(JSContext *cx, JSObject *obj)
+{
+ JSObject *class;
+
+ if ((class = JS_InitClass(cx, obj, NULL, &errno_class, NULL,
+ 0, NULL, NULL, errno_sproperties, errno_smethods)) == NULL) {
+ (void) fprintf(stderr, "Error initializing Errno class\n");
+ return NULL;
+ }
+
+ return class;
+}
+
+
+
+/*
+ * Static properties functions
+ */
+
+static JSBool
+errno_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 >= ERRNO_SP_MAX)
+ return JS_TRUE;
+
+ *vp = INT_TO_JSVAL(errno_sprops_data[
+ (int)errno_sproperties[p].tinyid]);
+
+ return JS_TRUE;
+}
+
+
+
+/*
+ * Static methods
+ */
+
+static JSBool
+errno_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, strerror(error))) == NULL) {
+ QUEUE_EXCEPTION("Out of memory");
+ return JS_FALSE;
+ }
+
+ *rval = STRING_TO_JSVAL(string);
+
+ return JS_TRUE;
+}