Skip to content
Browse files

Fix aio close from non-global namespace

aio [open], as well as similar commands return the name of the
created command.  If this is done in the non-global namespace, the
returned name is implicitly scoped to the current namespace while
the actual command is created in the global namespace. Thus [close]
does not work when invoked in that namespace.

The solution is to return a fully qualified name, such as ::aio.handle3

Note that this may also be a problem for similar command such as
[proc] and [alias] that return command names.

Signed-off-by: Steve Bennett <steveb@workware.net.au>
  • Loading branch information...
1 parent 2448a20 commit dd213d13411bce204850d48669632bc57b242c7c @msteveb committed
Showing with 43 additions and 8 deletions.
  1. +5 −3 jim-aio.c
  2. +1 −1 jim-sdl.c
  3. +3 −1 jim-sqlite3.c
  4. +21 −0 jim.c
  5. +2 −3 jim.h
  6. +11 −0 tests/jim.test
View
8 jim-aio.c
@@ -667,8 +667,7 @@ static int aio_cmd_eof(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static int aio_cmd_close(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
- Jim_DeleteCommand(interp, Jim_String(argv[0]));
- return JIM_OK;
+ return Jim_DeleteCommand(interp, Jim_String(argv[0]));
}
static int aio_cmd_seek(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
@@ -1098,7 +1097,10 @@ static int JimMakeChannel(Jim_Interp *interp, FILE *fh, int fd, Jim_Obj *filenam
snprintf(buf, sizeof(buf), hdlfmt, Jim_GetId(interp));
Jim_CreateCommand(interp, buf, JimAioSubCmdProc, af, JimAioDelProc);
- Jim_SetResultString(interp, buf, -1);
+ /* Note that the command must use the global namespace, even if
+ * the current namespace is something different
+ */
+ Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1)));
return JIM_OK;
}
View
2 jim-sdl.c
@@ -228,7 +228,7 @@ static int JimSdlSurfaceCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar
jss->screen = screen;
sprintf(buf, "sdl.surface%ld", screenId);
Jim_CreateCommand(interp, buf, JimSdlHandlerCommand, jss, JimSdlDelProc);
- Jim_SetResultString(interp, buf, -1);
+ Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1)));
return JIM_OK;
}
View
4 jim-sqlite3.c
@@ -286,7 +286,9 @@ static int JimSqliteOpenCommand(Jim_Interp *interp, int argc, Jim_Obj *const *ar
sh->db = db;
snprintf(buf, sizeof(buf), "sqlite.handle%ld", Jim_GetId(interp));
Jim_CreateCommand(interp, buf, JimSqliteHandlerCommand, sh, JimSqliteDelProc);
- Jim_SetResultString(interp, buf, -1);
+
+ Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1)));
+
return JIM_OK;
}
View
21 jim.c
@@ -3775,6 +3775,22 @@ static Jim_Obj *JimQualifyNameObj(Jim_Interp *interp, Jim_Obj *nsObj)
return nsObj;
}
+Jim_Obj *Jim_MakeGlobalNamespaceName(Jim_Interp *interp, Jim_Obj *nameObjPtr)
+{
+ Jim_Obj *resultObj;
+
+ const char *name = Jim_String(nameObjPtr);
+ if (name[0] == ':' && name[1] == ':') {
+ return nameObjPtr;
+ }
+ Jim_IncrRefCount(nameObjPtr);
+ resultObj = Jim_NewStringObj(interp, "::", -1);
+ Jim_AppendObj(interp, resultObj, nameObjPtr);
+ Jim_DecrRefCount(interp, nameObjPtr);
+
+ return resultObj;
+}
+
/**
* An efficient version of JimQualifyNameObj() where the name is
* available (and needed) as a 'const char *'.
@@ -3807,6 +3823,11 @@ static const char *JimQualifyName(Jim_Interp *interp, const char *name, Jim_Obj
/* We can be more efficient in the no-namespace case */
#define JimQualifyName(INTERP, NAME, DUMMY) (((NAME)[0] == ':' && (NAME)[1] == ':') ? (NAME) + 2 : (NAME))
#define JimFreeQualifiedName(INTERP, DUMMY) (void)(DUMMY)
+
+Jim_Obj *Jim_MakeGlobalNamespaceName(Jim_Interp *interp, Jim_Obj *nameObjPtr)
+{
+ return nameObjPtr;
+}
#endif
static int JimCreateCommand(Jim_Interp *interp, const char *name, Jim_Cmd *cmd)
View
5 jim.h
@@ -760,9 +760,8 @@ JIM_EXPORT int Jim_SetVariableStrWithStr (Jim_Interp *interp,
JIM_EXPORT int Jim_SetVariableLink (Jim_Interp *interp,
Jim_Obj *nameObjPtr, Jim_Obj *targetNameObjPtr,
Jim_CallFrame *targetCallFrame);
-JIM_EXPORT int Jim_CreateNamespaceVariable(Jim_Interp *interp,
- Jim_Obj *varNameObj, Jim_Obj *targetNameObj);
-JIM_EXPORT int Jim_DiscardNamespaceVars(Jim_Interp *interp);
+JIM_EXPORT Jim_Obj * Jim_MakeGlobalNamespaceName(Jim_Interp *interp,
+ Jim_Obj *nameObjPtr);
JIM_EXPORT Jim_Obj * Jim_GetVariable (Jim_Interp *interp,
Jim_Obj *nameObjPtr, int flags);
JIM_EXPORT Jim_Obj * Jim_GetGlobalVariable (Jim_Interp *interp,
View
11 tests/jim.test
@@ -3486,5 +3486,16 @@ test regression-1.1 {lrange bug with negative indexes of type int} {
lrange {a b c} 0 [- 0 1]
} {}
+test regression-1.2 {open/close from non-global namespace} {
+ proc a::b {} {
+ set f [open $::argv0]
+ $f close
+ return $f
+ }
+ set f [a::b]
+ rename a::b ""
+ expr {$f in [info channels]}
+} {0}
+
testreport

0 comments on commit dd213d1

Please sign in to comment.
Something went wrong with that request. Please try again.