Forum OpenACS Development: Re: Win32-OpenACS Version 1.8

Posted by Gustaf Neumann on
concerning db_load_sql_data:

Seems as if the following sequence leads to the problem

set fd [open "|[file join $env(ORACLE_HOME) bin sqlldr] userid=$user_pass control=$tmpnam" "r"]


close $fd

Do you have the sqlldr under [file join $env(ORACLE_HOME) bin sqlldr]?
Are the provded parameters ok (e.g. the $tmpnam)?

Concerning (d): You are using the head version of categories, where it seems, that the column "widget" was not added in the Oracle version. Although i hate add something to CVS, which i cannot test, i added the column in the Oracle creation procs. Please get the head version from CVS and test it with Oracle. If the error is gone, i will apply the same fix to the oacs-5-4 branch, which has apparently the same problem.

Posted by Maurizio Martignano on
Dear Gustaf,

1. The first problem was due to $tmpnam (which was wrong: in Vista you can't write files wherever you want).
To fix it I had to introduce the following change:

# set tmpnam [ns_tmpnam]
set tmpnam [ns_mktemp /tmp/ctl-XXXXXX]

2. Your correction to the categories Oracle creation procs worked.

Thanks a lot for your help!


Posted by Gustaf Neumann on
Dear Maurizio,

i count current 77 occurrences of ns_tmpnam in OpenACS and its packages. These places will have the same problem, so the fix is not sufficient in the general case. Since ns_tmpnam is implemented in C, it is most probably the best solution to address the problem in the aolserver implementation. Again, as i do not have a WIN32 environment, please test the following replacement of NsTclTmpNamObjCmd() in aolserver/nsd/tclfile.c. With this fix, set tmpnam [ns_tmpnam] should be ok again.

-gustaf neumann

NsTclTmpNamObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
#ifdef WIN32
The WIN32 implmentation of tmpnam() ignores the environment
variable TMP and generates filenames for the root
directory. Unfortunately, new WIN versions (Vista) don't allow
this. The suggested replacement is _tempnam().

The first argument of _tempnam() is the default directory, in case
the environment variable TMP is not set or points to a directory
that does not exist.
char *buf = _tempnam("/tmp", NULL);

if (buf == NULL) {
Tcl_SetResult(interp, "could not generate temporary filename.", TCL_STATIC);
return TCL_ERROR;
The documentation says that _tempnam() allocates memory via
malloc(); to be sure, that the "right" free() is used, we do
not use TCL_DYNAMIC but the TCL_VOLATILE followed by the manual
Tcl_SetResult(interp, buf, TCL_VOLATILE);
char buf[L_tmpnam];

if (tmpnam(buf) == NULL) {
Tcl_SetResult(interp, "could not generate temporary filename.", TCL_STATIC);
return TCL_ERROR;
Tcl_SetResult(interp, buf, TCL_VOLATILE);
return TCL_OK;