Index: /trunk/gui/scripts/visviewer.tcl
===================================================================
--- /trunk/gui/scripts/visviewer.tcl	(revision 4107)
+++ /trunk/gui/scripts/visviewer.tcl	(revision 4108)
@@ -283,16 +283,7 @@
         if { [gets $_sid data] <= 0 } {
             set _sid ""
-            puts stderr "reading from server"
+            puts stderr "reading from server data=($data)"
             RemoveServerFromList $_serverType $server
             continue
-        }
-        # The response should be in the form "serverName major.minor ...".
-        set pattern {^[A-Za-z][A-Za-z0-9_]* [0-9]+\.[0-9].*}
-
-        while { ![regexp $pattern $data match] } {
-            puts stderr "$data"
-            if { [gets $_sid data] <= 0 } {
-                exit -1
-            }
         }
         puts stderr "Render server is $data"
Index: /trunk/packages/vizservers/configure
===================================================================
--- /trunk/packages/vizservers/configure	(revision 4107)
+++ /trunk/packages/vizservers/configure	(revision 4108)
@@ -629,4 +629,5 @@
 SUBDIRS
 STATSDIR
+LOGDIR
 LD_RPATH
 CXXCPP
@@ -718,4 +719,5 @@
 with_tcllib
 with_statsdir
+with_logsdir
 with_python
 enable_64bit
@@ -1363,4 +1365,5 @@
                           [default=/usr/lib]
   --with-statsdir=DIR     Write statistics in DIR
+  --with-logsdir=DIR      Write log files in DIR
   --with-python=DIR       location of python [default=yes]
   --with-x                use the X Window System
@@ -2464,4 +2467,13 @@
 else
   STATSDIR="/var/tmp/visservers"
+fi
+
+
+
+# Check whether --with-logsdir was given.
+if test "${with_logsdir+set}" = set; then :
+  withval=$with_logsdir; LOGDIR=$withval
+else
+  LOGDIR="/tmp"
 fi
 
@@ -7829,6 +7841,18 @@
 done
 
+for ac_func in mkstemps
+do :
+  ac_fn_cxx_check_func "$LINENO" "mkstemps" "ac_cv_func_mkstemps"
+if test "x$ac_cv_func_mkstemps" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MKSTEMPS 1
+_ACEOF
+
+fi
+done
+
 
 SUBDIRS="nanoscale pymolproxy"
+
 
 
Index: /trunk/packages/vizservers/configure.in
===================================================================
--- /trunk/packages/vizservers/configure.in	(revision 4107)
+++ /trunk/packages/vizservers/configure.in	(revision 4108)
@@ -17,4 +17,11 @@
     [STATSDIR=$withval],
     [STATSDIR="/var/tmp/visservers"])
+
+AC_ARG_WITH(
+    [logsdir],
+    [AS_HELP_STRING([--with-logsdir=DIR],
+        [Write log files in DIR])],
+    [LOGDIR=$withval],
+    [LOGDIR="/tmp"])
 
 RP_LANG_PYTHON
@@ -106,8 +113,10 @@
 
 AC_CHECK_FUNCS([accept4])
+AC_CHECK_FUNCS([mkstemps])
 
 SUBDIRS="nanoscale pymolproxy"
 
 AC_SUBST(LD_RPATH)
+AC_SUBST(LOGDIR)
 AC_SUBST(STATSDIR)
 AC_SUBST(SUBDIRS)
Index: /trunk/packages/vizservers/nanoscale/Makefile.in
===================================================================
--- /trunk/packages/vizservers/nanoscale/Makefile.in	(revision 4107)
+++ /trunk/packages/vizservers/nanoscale/Makefile.in	(revision 4108)
@@ -30,6 +30,10 @@
 TCL_INC_SPEC    = @TCL_INC_SPEC@
 LD_RUN_PATH     = $(libdir)
+LOGDIR		= @LOGDIR@
+SVN_VERSION	= $(shell svnversion $(srcdir))
 
-DEFINES		= -DSERVERSFILE=\"$(libdir)/renderservers.tcl\"
+DEFINES =	-DSERVERSFILE=\"$(libdir)/renderservers.tcl\" \
+		-DSVN_VERSION=\"$(SVN_VERSION)\" \
+		-DLOGDIR=\"$(LOGDIR)\" 
 INCLUDES	= -I. $(TCL_INC_SPEC)
 LIBS		= $(TCL_LIB_SPEC) \
Index: /trunk/packages/vizservers/nanoscale/config.h.in
===================================================================
--- /trunk/packages/vizservers/nanoscale/config.h.in	(revision 4107)
+++ /trunk/packages/vizservers/nanoscale/config.h.in	(revision 4108)
@@ -16,4 +16,7 @@
 #undef HAVE_MEMORY_H
 
+/* Define to 1 if you have the `mkstemps' function. */
+#undef HAVE_MKSTEMPS
+
 /* Define to 1 if you have the <netdb.h> header file. */
 #undef HAVE_NETDB_H
@@ -21,4 +24,7 @@
 /* Define to 1 if you have the <netinet/in.h> header file. */
 #undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the <Python.h> header file. */
+#undef HAVE_PYTHON_H
 
 /* Define to 1 if you have the <stdint.h> header file. */
Index: /trunk/packages/vizservers/nanoscale/server.c
===================================================================
--- /trunk/packages/vizservers/nanoscale/server.c	(revision 4107)
+++ /trunk/packages/vizservers/nanoscale/server.c	(revision 4108)
@@ -26,4 +26,8 @@
 #ifndef SERVERSFILE
 #define SERVERSFILE  "/opt/hubzero/rappture/render/lib/renderservers.tcl"
+#endif
+
+#ifndef LOGDIR
+#define LOGDIR		"/tmp"
 #endif
 
@@ -418,6 +422,7 @@
 	    if (child == 0) {		/* Child process. */
 		int i;
-		int errFd;
-		
+		int newFd;
+		char tmpname[200];
+
 		umask(0);
 		if ((!debug) && (setsid() < 0)) {
@@ -431,29 +436,47 @@
 		    exit(1);
 		}
-
-		/* Dup the descriptors and start the server.  */
-
-		if (dup2(f, 0) < 0)  {	/* Stdin */
+		/* We could use the same log file for stdout and stderr. 
+		 * Right now they are separate files. */
+
+		/* Redirect child's stdout to a log file. */
+		sprintf(tmpname, "%s/%s-%d-stdout.XXXXXX", LOGDIR, 
+			serverPtr->name, getpid());
+		newFd = mkstemp(tmpname);
+		if (newFd < 0) { 
+		    ERROR("%s: can't open \"%s\": %s", serverPtr->name,
+			  tmpname, strerror(errno));
+		    exit(1);
+		} 
+		if (dup2(newFd, 1) < 0) { 
+		    ERROR("%s: can't dup stdout to \"%s\": %s", 
+			  serverPtr->name, tmpname, strerror(errno));
+		    exit(1);
+		}
+		/* Redirect child's stderr to a log file. */
+		sprintf(tmpname, "%s/%s-%d-stderr.XXXXXX", LOGDIR, 
+			serverPtr->name, getpid());
+		newFd = mkstemp(tmpname);
+		if (newFd < 0) { 
+		    ERROR("%s: can't open \"%s\": %s", serverPtr->name,
+			  tmpname, strerror(errno));
+		    exit(1);
+		} 
+		if (dup2(newFd, 2) < 0) {
+		    ERROR("%s: can't dup stderr to \"%s\": %s", 
+			  serverPtr->name, tmpname, strerror(errno));
+		    exit(1);
+		}
+		/* Dup the socket to descriptors 3 and 4 */
+		if (dup2(f, 3) < 0)  {	/* Stdin */
 		    ERROR("%s: can't dup stdin: %s", serverPtr->name, 
 			strerror(errno));
 		    exit(1);
 		}
-		if (dup2(f, 1) < 0) {	/* Stdout */
+		if (dup2(f, 4) < 0) {	/* Stdout */
 		    ERROR("%s: can't dup stdout: %s", serverPtr->name, 
 			  strerror(errno));
 		    exit(1);
 		}
-		errFd = open("/dev/null", O_WRONLY, 0600);
-		if (errFd < 0) {
-		    ERROR("%s: can't open /dev/null for read/write: %s", 
-			  serverPtr->name, strerror(errno));
-		    exit(1);
-		}
-		if (dup2(errFd, 2) < 0) { /* Stderr */
-		    ERROR("%s: can't dup stderr for \"%s\": %s", 
-			  serverPtr->name, strerror(errno));
-		    exit(1);
-		}
-		for(i = 3; i <= FD_SETSIZE; i++) {
+		for(i = 5; i <= FD_SETSIZE; i++) {
 		    close(i);		/* Close all the other descriptors. */
 		}
Index: /trunk/packages/vizservers/nanovis/Command.cpp
===================================================================
--- /trunk/packages/vizservers/nanovis/Command.cpp	(revision 4107)
+++ /trunk/packages/vizservers/nanovis/Command.cpp	(revision 4108)
@@ -2237,5 +2237,5 @@
                                          * available. */
     while (inBufPtr->isLineAvailable() || 
-           (select(1, &readFds, NULL, NULL, tvPtr) > 0)) {
+           (select(inBufPtr->file()+1, &readFds, NULL, NULL, tvPtr) > 0)) {
         size_t numBytes;
         unsigned char *buffer;
Index: /trunk/packages/vizservers/nanovis/nanovisServer.cpp
===================================================================
--- /trunk/packages/vizservers/nanovis/nanovisServer.cpp	(revision 4107)
+++ /trunk/packages/vizservers/nanovis/nanovisServer.cpp	(revision 4108)
@@ -46,6 +46,8 @@
 int nv::g_statsFile = -1; ///< Stats output file descriptor.
 
-int nv::g_fdIn = STDIN_FILENO;     ///< Input file descriptor
-int nv::g_fdOut = STDOUT_FILENO;   ///< Output file descriptor
+#define CLIENT_READ     (3)
+#define CLIENT_WRITE    (4)
+int nv::g_fdIn = CLIENT_READ;     ///< Input file descriptor
+int nv::g_fdOut = CLIENT_WRITE;   ///< Output file descriptor
 FILE *nv::g_fOut = NULL;           ///< Output file handle
 FILE *nv::g_fLog = NULL;           ///< Trace logging file handle
@@ -84,11 +86,11 @@
     std::ostringstream oss;
     oss << "nv>ok -token " << g_stats.nCommands <<  "\n";
-    int nBytes = oss.str().length();
+    size_t numBytes = oss.str().length();
 
     TRACE("Sending OK for commands through %lu", g_stats.nCommands);
 #ifdef USE_THREADS
-    queueResponse(oss.str().c_str(), nBytes, Response::VOLATILE, Response::OK);
+    queueResponse(oss.str().c_str(), numBytes, Response::VOLATILE, Response::OK);
 #else
-    if (write(g_fdOut, oss.str().c_str(), nBytes) < 0) {
+    if (write(g_fdOut, oss.str().c_str(), numBytes) < 0) {
         ERROR("write failed: %s", strerror(errno));
         return -1;
@@ -318,11 +320,13 @@
 initService()
 {
+    // Create a stream associated with the client read file descriptor.  If
+    // we're not using a socket (fdopen of descriptor 4 will return NULL),
+    // then use descriptor 1 and stdout respectively.
     g_fOut = fdopen(g_fdOut, "w");
     // If running without socket, use stdout for debugging
-    if (g_fOut == NULL && g_fdOut != STDOUT_FILENO) {
+    if (g_fOut == NULL) {
         g_fdOut = STDOUT_FILENO;
-        g_fOut = fdopen(g_fdOut, "w");
-    }
-
+        g_fOut = stdout;
+    }
     const char* user = getenv("USER");
     char* logName = NULL;
@@ -339,14 +343,7 @@
         strncat(logName, user, strlen(user));
     }
-
-    // open log and map stderr to log file
+    // Nanoscale automatically redirects stdout and stderr to log files.
     g_fLog = fopen(logName, "w");
     dup2(fileno(g_fLog), STDERR_FILENO);
-    // If we are writing to socket, map stdout to log
-    if (g_fdOut != STDOUT_FILENO) {
-        dup2(fileno(g_fLog), STDOUT_FILENO);
-    }
-
-    fflush(stdout);
 
     // clean up malloc'd memory
@@ -531,6 +528,15 @@
      * also be used to supply information about the server (version, memory
      * size, etc). */
-    fprintf(g_fOut, "NanoVis %s (build %s)\n", NANOVIS_VERSION_STRING, SVN_VERSION);
-    fflush(g_fOut);
+    char mesg[200];
+
+    sprintf(mesg, "NanoVis %s (build %s)\n", NANOVIS_VERSION_STRING, SVN_VERSION);
+    size_t numBytes;
+    ssize_t numWritten;
+
+    numBytes = strlen(mesg);
+    numWritten = write(g_fdOut, mesg, numBytes);
+    if ((ssize_t)numBytes != numWritten) {
+        ERROR("Short write in version string: %s", strerror(errno));
+    }
 
     g_inBufPtr = new ReadBuffer(g_fdIn, 1<<12);
Index: /trunk/packages/vizservers/pymolproxy/Makefile.in
===================================================================
--- /trunk/packages/vizservers/pymolproxy/Makefile.in	(revision 4107)
+++ /trunk/packages/vizservers/pymolproxy/Makefile.in	(revision 4108)
@@ -7,5 +7,6 @@
 DEFINES =	-DSTANDALONE \
 		-DSVN_VERSION=\"$(SVN_VERSION)\" \
-		-DSTATSDIR=\"$(STATSDIR)\"
+		-DSTATSDIR=\"$(STATSDIR)\" \
+		-DLOGDIR=\"$(LOGDIR)\" 
 EXTRA_CFLAGS =	-Wall 
 INCLUDES =	$(TCL_INC_SPEC) -I$(srcdir)
@@ -29,4 +30,5 @@
 SVN_VERSION	= $(shell svnversion $(srcdir))
 STATSDIR	= @STATSDIR@
+LOGDIR		= @LOGDIR@
 
 .PHONY: all install clean distclean
Index: /trunk/packages/vizservers/pymolproxy/pymolproxy2.c
===================================================================
--- /trunk/packages/vizservers/pymolproxy/pymolproxy2.c	(revision 4107)
+++ /trunk/packages/vizservers/pymolproxy/pymolproxy2.c	(revision 4108)
@@ -91,6 +91,4 @@
 
 static int debug = FALSE;
-static char stderrFile[200];
-static FILE *fdebug;
 static FILE *frecord;
 static int recording = FALSE;
@@ -115,4 +113,10 @@
 
 #define IO_TIMEOUT (30000)
+#define CLIENT_READ		(3)
+#define CLIENT_WRITE		(4)
+
+#ifndef LOGDIR
+#define LOGDIR		"/tmp"
+#endif	/* LOGDIR */
 
 #define CVT2SECS(x)  ((double)(x).tv_sec) + ((double)(x).tv_usec * 1.0e-6)
@@ -226,8 +230,8 @@
     
     format = TCL_VARARGS_START(const char *, arg1, args);
-    fprintf(fdebug, "pymolproxy: ");
-    vfprintf(fdebug, format, args);
-    fprintf(fdebug, "\n");
-    fflush(fdebug);
+    fprintf(stderr, "pymolproxy: ");
+    vfprintf(stderr, format, args);
+    fprintf(stderr, "\n");
+    fflush(stderr);
 }
 #endif
@@ -2097,5 +2101,5 @@
 
 static int
-InitProxy(PymolProxy *p, const char *fileName, char *const *argv)
+InitProxy(PymolProxy *p, char *const *argv)
 {
     int sin[2], sout[2];		/* Pipes to connect to server. */
@@ -2127,4 +2131,5 @@
     if (child == 0) {			/* Child process */
         int f;
+	char tmpname[200];
 
         /* 
@@ -2139,11 +2144,14 @@
         dup2(sin[0],  0);		/* Server standard input */
         dup2(sout[1], 1);		/* Server standard output */
-	f = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+
+	/* Redirect child's stdout to a log file. */
+	sprintf(tmpname, "%s/PYMOL-%d-stderr.XXXXXX", LOGDIR, getpid());
+	f = mkstemp(tmpname);
 	if (f < 0) {
-	    ERROR("can't open server error file `%s': %s", fileName, 
+	    ERROR("can't open file `%s' to capture pymol stderr: %s", tmpname, 
 		  strerror(errno));
 	    exit(1);
 	}
-        dup2(f, 2);			/* Redirect stderr to a file */
+        dup2(f, 2);			/* Redirect stderr to a log file */
         
 	/* Close all other descriptors  */        
@@ -2176,5 +2184,5 @@
     p->frame      = 1;
     p->pid      = child;
-    InitReadBuffer(&p->client, "client", p->cout, 1<<16);
+    InitReadBuffer(&p->client, "client", CLIENT_READ, 1<<16);
     InitReadBuffer(&p->server, "server", p->sout, 1<<18);
 
@@ -2256,5 +2264,4 @@
 	result = WEXITSTATUS(result);
     }
-    unlink(stderrFile);
     return result;
 }
@@ -2299,6 +2306,6 @@
 #endif
 		    break;		/* This was caused by a "imgflush"
-					 * command. Break out of the read loop
-					 * and allow a new image to be
+					 * command. Break out of the read
+					 * loop and allow a new image to be
 					 * rendered. */
 		}
@@ -2311,7 +2318,6 @@
 	    }
 	    tv.tv_sec = 0L;
-	    tv.tv_usec = 0L;	/* On successive reads, we break
-					 *  out * if no data is
-					 *  available. */
+	    tv.tv_usec = 0L;		/* On successive reads, we break
+					 * out if no data is available. */
 	    tvPtr = &tv;			
 	}
@@ -2405,12 +2411,10 @@
 		struct timeval tv;
 		fd_set writeFds;
-		int fd;
 
 		tv.tv_sec = tv.tv_usec = 0L;
 		FD_ZERO(&writeFds);
-		fd = fileno(stdout);
-		FD_SET(fd, &writeFds);
-		if (select(fd+1, NULL, &writeFds, NULL, &tv) > 0) {
-		    WriteImages(&list, fd);
+		FD_SET(CLIENT_WRITE, &writeFds);
+		if (select(CLIENT_WRITE+1, NULL, &writeFds, NULL, &tv) > 0) {
+		    WriteImages(&list, CLIENT_WRITE);
 		}
 	    }
@@ -2428,10 +2432,8 @@
     PymolProxy proxy;
     pthread_t thread1, thread2;
-
-    sprintf(stderrFile, "/tmp/pymol%d.stderr", getpid());
-    fdebug = stderr;
-    if (debug) {
-        fdebug = fopen("/tmp/pymolproxy.log", "w");
-    }    
+    char version[200];
+    ssize_t numWritten;
+    size_t numBytes;
+
     frecord = NULL;
     if (recording) {
@@ -2441,10 +2443,13 @@
         frecord = fopen(fileName, "w");
     }    
-    fprintf(stdout, "PyMol 1.0 (build %s)\n", SVN_VERSION);
-    fflush(stdout);
-
+    sprintf(version, "PyMol 1.0 (build %s)\n", SVN_VERSION);
+    numBytes = strlen(version);
+    numWritten = write(CLIENT_WRITE, version, numBytes);
+    if (numWritten < numBytes) {
+        ERROR("Short write on version string", strerror(errno));
+    }
     INFO("Starting pymolproxy (threaded version)");
 
-    InitProxy(&proxy, stderrFile, argv + 1);
+    InitProxy(&proxy, argv + 1);
     if (pthread_create(&thread1, NULL, &ClientToServer, &proxy) < 0) {
         ERROR("Can't create reader thread: %s", strerror(errno));
Index: /trunk/packages/vizservers/vtkvis/RenderServer.cpp
===================================================================
--- /trunk/packages/vizservers/vtkvis/RenderServer.cpp	(revision 4107)
+++ /trunk/packages/vizservers/vtkvis/RenderServer.cpp	(revision 4108)
@@ -43,6 +43,8 @@
 
 int VtkVis::g_statsFile = -1; ///< Stats output file descriptor.
-int VtkVis::g_fdIn = STDIN_FILENO; ///< Input file descriptor
-int VtkVis::g_fdOut = STDOUT_FILENO; ///< Output file descriptor
+#define CLIENT_READ     (3)
+#define CLIENT_WRITE    (4)
+int VtkVis::g_fdIn = CLIENT_READ; ///< Input file descriptor
+int VtkVis::g_fdOut = CLIENT_WRITE; ///< Output file descriptor
 FILE *VtkVis::g_fOut = NULL; ///< Output file handle
 FILE *VtkVis::g_fLog = NULL; ///< Trace logging file handle
@@ -407,9 +409,12 @@
 initService()
 {
+    // Create a stream associated with the client read file descriptor.  If
+    // we're not using a socket (fdopen of descriptor 4 will return NULL),
+    // then use descriptor 1 and stdout respectively.
     g_fOut = fdopen(g_fdOut, "w");
     // If running without socket, use stdout for debugging
     if (g_fOut == NULL && g_fdOut != STDOUT_FILENO) {
         g_fdOut = STDOUT_FILENO;
-        g_fOut = fdopen(g_fdOut, "w");
+        g_fOut = stdout;
     }
 
@@ -431,13 +436,8 @@
     }
 
+    // Nanoscale automatically redirects stdout and stderr to log files.
     // open log and map stderr to log file
     g_fLog = fopen(logName, "w");
     dup2(fileno(g_fLog), STDERR_FILENO);
-    // If we are writing to socket, map stdout to log
-    if (g_fdOut != STDOUT_FILENO) {
-        dup2(fileno(g_fLog), STDOUT_FILENO);
-    }
-
-    fflush(stdout);
 
     // clean up malloc'd memory
Index: /trunk/packages/vizservers/vtkvis/RendererCmd.cpp
===================================================================
--- /trunk/packages/vizservers/vtkvis/RendererCmd.cpp	(revision 4107)
+++ /trunk/packages/vizservers/vtkvis/RendererCmd.cpp	(revision 4108)
@@ -12920,5 +12920,5 @@
                                          * available. */
     while (inBufPtr->isLineAvailable() || 
-           (select(1, &readFds, NULL, NULL, tvPtr) > 0)) {
+           (select(inBufPtr->file()+1, &readFds, NULL, NULL, tvPtr) > 0)) {
         size_t numBytes;
         unsigned char *buffer;
