aio recvfrom was not null terminating the result
[jimtcl.git] / jimsh.c
bloba688fd8d810ec8cda5e9c54ccd57cc6f1d30f9ef
2 /* Jimsh - An interactive shell for Jim
3 * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>
4 * Copyright 2009 Steve Bennett <steveb@workware.net.au>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * A copy of the license is also included in the source distribution
13 * of Jim, as a TXT file name called LICENSE.
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
26 #include "jim.h"
29 /* JimGetExePath try to get the absolute path of the directory
30 * of the jim binary, in order to add this path to the library path.
31 * Likely shipped libraries are in the same path too. */
32 #ifndef JIM_ANSIC
34 /* A bit complex on POSIX */
35 #include <unistd.h>
36 static Jim_Obj *JimGetExePath(Jim_Interp *interp, const char *argv0)
38 char path[JIM_PATH_LEN + 1];
40 /* Check if the executable was called with an absolute pathname */
41 if (argv0[0] == '/') {
42 char *p;
44 strncpy(path, argv0, JIM_PATH_LEN);
45 p = strrchr(path, '/');
46 *(p + 1) = '\0';
47 return Jim_NewStringObj(interp, path, -1);
49 else {
50 char cwd[JIM_PATH_LEN + 1];
51 char base[JIM_PATH_LEN + 1], *p;
52 int l;
54 strncpy(base, argv0, JIM_PATH_LEN);
55 if (getcwd(cwd, JIM_PATH_LEN) == NULL) {
56 return Jim_NewStringObj(interp, "/usr/local/lib/jim/", -1);
58 l = strlen(cwd);
59 if (l > 0 && cwd[l - 1] == '/')
60 cwd[l - 1] = '\0';
61 p = strrchr(base, '/');
62 if (p == NULL)
63 base[0] = '\0';
64 else if (p != base)
65 *p = '\0';
66 sprintf(path, "%s/%s", cwd, base);
67 l = strlen(path);
68 if (l > 2 && path[l - 2] == '/' && path[l - 1] == '.')
69 path[l - 1] = '\0';
70 return Jim_NewStringObj(interp, path, -1);
73 #else /* JIM_ANSIC */
75 /* ... and impossible with just ANSI C */
76 static Jim_Obj *JimGetExePath(Jim_Interp *interp, const char *argv0)
78 JIM_NOTUSED(argv0);
79 return Jim_NewStringObj(interp, "/usr/local/lib/jim/", -1);
81 #endif /* JIM_ANSIC */
83 static void JimLoadJimRc(Jim_Interp *interp)
85 const char *home;
86 char buf[JIM_PATH_LEN + 1];
87 const char *names[] = { ".jimrc", "jimrc.tcl", NULL };
88 int i;
89 FILE *fp;
91 if ((home = getenv("HOME")) == NULL)
92 return;
93 for (i = 0; names[i] != NULL; i++) {
94 if (strlen(home) + strlen(names[i]) + 1 > JIM_PATH_LEN)
95 continue;
96 sprintf(buf, "%s/%s", home, names[i]);
97 if ((fp = fopen(buf, "r")) != NULL) {
98 fclose(fp);
99 if (Jim_EvalFile(interp, buf) != JIM_OK) {
100 Jim_PrintErrorMessage(interp);
102 return;
107 static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[])
109 int n;
110 Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0);
112 /* Populate argv global var */
113 for (n = 0; n < argc; n++) {
114 Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1);
116 Jim_ListAppendElement(interp, listObj, obj);
119 Jim_SetVariableStr(interp, "argv", listObj);
122 int main(int argc, char *const argv[])
124 int retcode;
125 Jim_Interp *interp;
126 Jim_Obj *listObj;
128 /* Create and initialize the interpreter */
129 interp = Jim_CreateInterp();
130 Jim_RegisterCoreCommands(interp);
132 /* Register static extensions */
133 if (Jim_InitStaticExtensions(interp) != JIM_OK) {
134 Jim_PrintErrorMessage(interp);
137 /* Append the path where the executed Jim binary is contained
138 * in the jim_libpath list. */
139 listObj = Jim_GetVariableStr(interp, JIM_LIBPATH, JIM_NONE);
140 if (Jim_IsShared(listObj))
141 listObj = Jim_DuplicateObj(interp, listObj);
142 Jim_ListAppendElement(interp, listObj, JimGetExePath(interp, argv[0]));
143 Jim_SetVariableStr(interp, JIM_LIBPATH, listObj);
145 Jim_SetVariableStrWithStr(interp, "jim_argv0", argv[0]);
147 if (argc == 1) {
148 Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, "1");
149 JimSetArgv(interp, 0, NULL);
150 JimLoadJimRc(interp);
151 retcode = Jim_InteractivePrompt(interp);
153 else {
154 Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, "0");
155 if (argc > 2 && strcmp(argv[1], "-e") == 0) {
156 JimSetArgv(interp, argc - 3, argv + 3);
157 retcode = Jim_Eval(interp, argv[2]);
159 else {
160 Jim_SetVariableStr(interp, "argv0", Jim_NewStringObj(interp, argv[1], -1));
161 JimSetArgv(interp, argc - 2, argv + 2);
162 retcode = Jim_EvalFile(interp, argv[1]);
164 if (retcode == JIM_ERR) {
165 Jim_PrintErrorMessage(interp);
168 if (retcode == JIM_OK) {
169 retcode = 0;
171 else if (retcode == JIM_EXIT) {
172 retcode = interp->exitCode;
174 else {
175 retcode = 1;
177 Jim_FreeInterp(interp);
178 return retcode;