aboutsummaryrefslogtreecommitdiffstats
path: root/erts/etc/vxworks/vxcall.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/etc/vxworks/vxcall.c')
-rw-r--r--erts/etc/vxworks/vxcall.c145
1 files changed, 145 insertions, 0 deletions
diff --git a/erts/etc/vxworks/vxcall.c b/erts/etc/vxworks/vxcall.c
new file mode 100644
index 0000000000..3362d05fc5
--- /dev/null
+++ b/erts/etc/vxworks/vxcall.c
@@ -0,0 +1,145 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1997-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vxWorks.h>
+#include <symLib.h>
+#include <sysSymTbl.h>
+#include <a_out.h>
+
+extern char *malloc();
+static STATUS lookup();
+
+/*
+ Little utility to convert from Unix' argv,argv calling conventions to
+ VxWorks' arg0,arg1,arg2,...
+ Will do limited argument parsing - no parenthesis around nor commas
+ between the args, which may be "-enclosed strings (without \ escapes),
+ '-enclosed characters (also no \ escapes), integers, or symbols.
+*/
+
+int vxcall(argc, argv)
+int argc;
+char **argv;
+{
+ int vxarg[10]; /* Max 10 args can be passed */
+ FUNCPTR entry;
+ SYM_TYPE type;
+ int i, l;
+
+#ifdef DEBUG
+ fdprintf(2, "vxcall:");
+ for (i = 1; i < argc; i++)
+ fdprintf(2, " %s", argv[i]);
+ fdprintf(2, "\n");
+#endif
+ if (lookup(argv[1], N_EXT | N_TEXT, (char **)&entry) != OK)
+ return(ERROR);
+ /* Do limited "C" parsing of the args */
+ for (i = 0; i < 10; i++) {
+ if (i < argc - 2) {
+ switch (argv[i+2][0]) {
+ case '"':
+ l = strlen(argv[i+2]) - 1;
+ if (argv[i+2][l] != '"')
+ return(ERROR);
+ /* just strip the quotes - should do \escapes within... */
+ vxarg[i] = (int)&argv[i+2][1];
+ argv[i+2][l] = '\0';
+ break;
+ case '\'':
+ if (argv[i+2][2] != '\'')
+ return(ERROR);
+ vxarg[i] = argv[i+2][1]; /* should do \escapes... */
+ break;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ vxarg[i] = atoi(argv[i+2]); /* should do octal, hex, float.. */
+ break;
+ default:
+ if (lookup(argv[i+2], 0, (char **)&vxarg[i]) != OK)
+ return(ERROR);
+ }
+ } else
+ vxarg[i] = 0;
+ }
+#ifdef DEBUG
+ fdprintf(2, "calling 0x%x(0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x)\n",
+ entry, vxarg[0], vxarg[1], vxarg[2], vxarg[3], vxarg[4],
+ vxarg[5], vxarg[6], vxarg[7], vxarg[8], vxarg[9]);
+#endif
+ return((*entry)(vxarg[0], vxarg[1], vxarg[2], vxarg[3], vxarg[4],
+ vxarg[5], vxarg[6], vxarg[7], vxarg[8], vxarg[9]));
+}
+
+/* Entry point for unix:cmd in post-4.1 erlang - uses "sh -c 'cmd...'" */
+int sh(argc, argv)
+int argc;
+char **argv;
+{
+ int ll = strlen(argv[argc-1]) - 1;
+
+#ifdef DEBUG
+ int i;
+ fdprintf(2, "sh:");
+ for (i = 1; i < argc; i++)
+ fdprintf(2, " %s", argv[i]);
+ fdprintf(2, "\n");
+#endif
+ if (strcmp(argv[1], "-c") != 0 ||
+ argv[2][0] != '\'' || argv[argc-1][ll] != '\'')
+ return(ERROR);
+ argv[argc-1][ll] = '\0'; /* delete trailing ' */
+ argv[2]++; /* skip leading ' (*after* the above!) */
+ return(vxcall(argc-1, argv+1));
+}
+
+/* Lookup symbol; get address for text symbols, value (assuming int)
+ otherwise; return OK or ERROR on failure
+ Symbol name is null-terminated and without the leading '_' */
+STATUS
+lookup(sym, stype, value)
+char *sym, **value;
+int stype;
+{
+ char buf[256];
+ char *symname = buf;
+ int len, ret;
+ SYM_TYPE type;
+
+ len = strlen(sym);
+ if (len > 254 && (symname = malloc(len+2)) == NULL)
+ return(ERROR);
+#if defined _ARCH_PPC || defined SIMSPARCSOLARIS
+ /* GCC for PPC or SIMSPARC doesn't add a leading _ to symbols */
+ strcpy(symname, sym);
+#else
+ sprintf(symname, "_%s", sym);
+#endif
+ ret = (stype != 0) ?
+ symFindByNameAndType(sysSymTbl, symname, value, &type, stype, stype) :
+ symFindByName(sysSymTbl, symname, value, &type);
+ if (symname != buf)
+ free(symname);
+ if (ret == OK && (type & N_TEXT) == 0) /* get value */
+ *value = (char *)*((int *)*value);
+ return(ret);
+}