According the the vfsapi docs, r+ is not included among
the supported file open modes in a virtual filesystem.
But if [open <file> r+] is tried, instead of
generating an error, a+ is passed to the handler
routine as the file open mode.
to reproduce:
source templatevfs.tcl
::vfs::template::Mount C:/temp /template
cd /template
set f [open rplus.txt r+]
From a strictly Tcl standpoint, an error should be
generated because rplus.txt doesn't exist. From a
Tclvfs standpoint, an error should be generated because
the r+ mode isn't supported. But the open command
returns a normal channel handle. Debugging shows that
the handler routine receives a+ as the file open mode.
Logged In: YES
user_id=32170
Note that in Tcl itself, TclGetOpenMode() is used to parse
the string "r+" and convert it into an 'int mode' which is
passed to tclvfs (vfs.c)
This integer 'mode' is then converted back into a string by
VfsGetMode() (in vfs.c).
So, I'm assuming one or other of these is doing the wrong
thing -- most likely VfsGetMode().
Perhaps you can have a look at that and suggest a fix (it's
a very simple function):
static Tcl_Obj*
VfsGetMode(int mode) {
Tcl_Obj *ret = Tcl_NewObj();
if (mode & O_RDONLY) {
Tcl_AppendToObj(ret, "r", 1);
} else if (mode & O_WRONLY || mode & O_RDWR) {
if (mode & O_TRUNC) {
Tcl_AppendToObj(ret, "w", 1);
} else {
Tcl_AppendToObj(ret, "a", 1);
}
if (mode & O_RDWR) {
Tcl_AppendToObj(ret, "+", 1);
}
}
return ret;
}
Logged In: YES
user_id=128673
The mode needs to survive an AND with O_CREAT before "a" can
be appended to the mode string object, otherwise an error
should be thrown (I don't know how to code an error
exception appropriate for this instance).
static Tcl_Obj*
VfsGetMode(int mode) {
Tcl_Obj *ret = Tcl_NewObj();
if (mode & O_RDONLY) {
Tcl_AppendToObj(ret, "r", 1);
} else if (mode & O_WRONLY || mode & O_RDWR) {
if (mode & O_TRUNC) {
Tcl_AppendToObj(ret, "w", 1);
} else if (mode & O_CREAT) {
Tcl_AppendToObj(ret, "a", 1);
} else {
<throw an error because vfs doesn't support r+>
}
if (mode & O_RDWR) {
Tcl_AppendToObj(ret, "+", 1);
}
}
return ret;
}
Logged In: YES
user_id=32170
Surely the error should only be thrown if the file doesn't
exist?
Logged In: YES
user_id=32170
I guess I should be clearer. There's no intrinisc reason
the vfs can't support 'r+' is there? Obviously to some
extent that may depend on the nature of the memchan/rchan
stream being used, but there's nothing to stop r+ being
passed on to the tcl layer, I would think...
Logged In: YES
user_id=128673
<<There's no intrinsic reason the vfs can't support 'r+' is
there?>>
I suppose you're the only person who can decide that. My
goal was simply to create a full instantiation of the Tclvfs
API as documented, and the documentation states that r+ is
not supported. There's no problem from my standpoint in
adding r+ support to my handler routine.
Logged In: YES
user_id=32170
That's probably something more for Andreas to comment on. I
don't see why tclvfs shouldn't pass "r+" on to the Tcl layer
for it to deal with...