Forum OpenACS Development: Re: NaviServer on Windows: [ns_logroll] returns "Permission denied"

Hi,

We were just discussing this with Brian. Windows and its permissions policies are causing this issue, the issue is in the call to the C rename function. We patched our AOLServer for Windows long time ago by writing an ugly custom workaround that creates a custom Rename function.

The Ns_RollFile calls CustomRename defined below.

Here is our workaround if you find it useful: https://gist.github.com/anonymous/aa3cf1f864c96c252d650f40f80aa4db

Dear Enrique,

many thanks for sharing the code. ... which is somewhat weird, since the custom "rename" performs actually a copy operation. This indicates, that the actual user of NaviServer/AOLserver has "create" permissions but not "rename" permissions - which are under windows essentially "delete" permissions (as i found though googling).

Stupid question: if this is the case, isn't it easier to give the user the delete permissions for this folder instead of patching the code?

all the best
-g

Thanks for your reply Gustaf.

Back then, We tried all possible combinations of Windows permissions, including Full Admin/Full Control and even granted ownership. It never worked.

So, we decided to give 'CopyFile' a go and it worked. Our feeling was that there was some sort of lock that the standard 'rename'/'copy' didn't like and we didn't have the chance to do more investigation than just using what worked for us back then.

Super duper Enrique! TVM
Dear Enrique,
I have implemented the following changes into my Windows-OpenACS distribution:

static int
Rename(const char *from, const char *to)
{
int err;
Tcl_Obj *fromObj, *toObj;

NS_NONNULL_ASSERT(from != NULL);
NS_NONNULL_ASSERT(to != NULL);

fromObj = Tcl_NewStringObj(from, -1);
Tcl_IncrRefCount(fromObj);

toObj = Tcl_NewStringObj(to, -1);
Tcl_IncrRefCount(toObj);

#ifdef WIN32
err != CopyFile(from, to, FALSE);
if (err == 0) {
DeleteFile(from);
}
#else
err = Tcl_FSRenameFile(fromObj, toObj);
#endif
Tcl_DecrRefCount(fromObj);
Tcl_DecrRefCount(toObj);
if (err != 0) {
Ns_Log(Error, "rollfile: failed to rename file '%s' to '%s': '%s'",
from, to, strerror(Tcl_GetErrno()));
}

return err;
}

with this change the rolling of the log files works also on Windows.

Once again thank you,
Maurizio

I did find the following piece of text inside TCL's code:

"The many functions in this structure are broken down into three
categories: infrastructure functions (almost all of which must be
implemented), operational functions (which must be implemented if a
complete filesystem is provided), and efficiency functions (which need
only be implemented if they can be done so efficiently, or if they have
side-effects which are required by the filesystem; Tcl has less
efficient emulations it can fall back on). It is important to note
that, in the current version of Tcl, most of these fallbacks are only
used to handle commands initiated in Tcl, not in C. What this means is,
that if a "file rename" command is issued in Tcl, and the relevant
filesystem(s) do not implement their "Tcl_FSRenameFileProc", Tcl's
core will instead fallback on a combination of other filesystem
functions (it will use "Tcl_FSCopyFileProc" followed by
"Tcl_FSDeleteFileProc", and if "Tcl_FSCopyFileProc\"is not
implemented there is a further fallback). However, if a
"Tcl_FSRenameFileProc" command is issued at the C level, no such
fallbacks occur
.
[...]
"