diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html
index f12f718a9..5bad5edd5 100644
--- a/documentation/RELEASE_NOTES.html
+++ b/documentation/RELEASE_NOTES.html
@@ -7,6 +7,18 @@
+EPICS Base Release 3.14.8
+?? ??Month?? 2005
+
+Changes since 3.14.7
+
+
+iocsh
+I/O redirection from vxWorks startup scripts now works.
+
+
+
+
EPICS Base Release 3.14.7
7 December 2004
diff --git a/src/iocsh/iocsh.cpp b/src/iocsh/iocsh.cpp
index e6601aacb..9497cb971 100644
--- a/src/iocsh/iocsh.cpp
+++ b/src/iocsh/iocsh.cpp
@@ -318,6 +318,13 @@ openRedirect(const char *filename, int lineno, struct iocshRedirect *redirect)
if (redirect->fp == NULL) {
showError(filename, lineno, "Can't open \"%s\": %s.",
redirect->name, strerror(errno));
+ while (i--) {
+ redirect--;
+ if (redirect->fp) {
+ fclose(redirect->fp);
+ redirect->fp = NULL;
+ }
+ }
return -1;
}
}
@@ -337,16 +344,16 @@ startRedirect(const char *filename, int lineno, struct iocshRedirect *redirect)
if (redirect->fp != NULL) {
switch(i) {
case 0:
- redirect->oldFp = epicsGetStdin();
- epicsSetStdin(redirect->fp);
+ redirect->oldFp = epicsGetThreadStdin();
+ epicsSetThreadStdin(redirect->fp);
break;
case 1:
- redirect->oldFp = epicsGetStdout();
- epicsSetStdout(redirect->fp);
+ redirect->oldFp = epicsGetThreadStdout();
+ epicsSetThreadStdout(redirect->fp);
break;
case 2:
- redirect->oldFp = epicsGetStderr();
- epicsSetStderr(redirect->fp);
+ redirect->oldFp = epicsGetThreadStderr();
+ epicsSetThreadStderr(redirect->fp);
break;
}
}
@@ -368,9 +375,9 @@ stopRedirect(const char *filename, int lineno, struct iocshRedirect *redirect)
redirect->name, strerror(errno));
redirect->fp = NULL;
switch(i) {
- case 0: epicsSetStdin(redirect->oldFp); break;
- case 1: epicsSetStdout(redirect->oldFp); break;
- case 2: epicsSetStderr(redirect->oldFp); break;
+ case 0: epicsSetThreadStdin(redirect->oldFp); break;
+ case 1: epicsSetThreadStdout(redirect->oldFp); break;
+ case 2: epicsSetThreadStderr(redirect->oldFp); break;
}
}
redirect->name = NULL;
@@ -504,6 +511,15 @@ iocshBody (const char *pathname, const char *commandLine)
}
}
+ /*
+ * Set up redirection
+ */
+ redirects = (struct iocshRedirect *)calloc(NREDIRECTS, sizeof *redirects);
+ if (redirects == NULL) {
+ printf ("Out of memory!\n");
+ return -1;
+ }
+
/*
* Read commands till EOF or exit
*/
@@ -511,19 +527,6 @@ iocshBody (const char *pathname, const char *commandLine)
wasOkToBlock = epicsThreadIsOkToBlock();
epicsThreadSetOkToBlock(1);
for (;;) {
-
- /*
- * Undo redirection
- */
- if (redirects == NULL) {
- redirects = (struct iocshRedirect *)calloc(NREDIRECTS, sizeof *redirects);
- if (redirects == NULL) {
- printf ("Out of memory!\n");
- break;
- }
- }
- stopRedirect(filename, lineno, redirects);
-
/*
* Read a line
*/
@@ -699,6 +702,7 @@ iocshBody (const char *pathname, const char *commandLine)
continue;
startRedirect(filename, lineno, redirects);
iocshBody(commandFile, NULL);
+ stopRedirect(filename, lineno, redirects);
continue;
}
if (openRedirect(filename, lineno, redirects) < 0)
@@ -734,6 +738,7 @@ iocshBody (const char *pathname, const char *commandLine)
if (iarg == piocshFuncDef->nargs) {
startRedirect(filename, lineno, redirects);
(*found->func)(argBuf);
+ stopRedirect(filename, lineno, redirects);
break;
}
if (iarg >= argBufCapacity) {
diff --git a/src/libCom/osi/epicsStdio.c b/src/libCom/osi/epicsStdio.c
index ffa57faf3..288683f7d 100644
--- a/src/libCom/osi/epicsStdio.c
+++ b/src/libCom/osi/epicsStdio.c
@@ -36,47 +36,56 @@ static void once(void *junk)
FILE * epicsShareAPI epicsGetStdin(void)
{
- FILE *fp;
-
- epicsThreadOnce(&onceId,once,0);
- fp = epicsThreadPrivateGet(stdinThreadPrivateId);
+ FILE *fp = epicsGetThreadStdin();
if(!fp) fp = stdin;
return fp;
}
-void epicsShareAPI epicsSetStdin(FILE *fp)
+FILE * epicsShareAPI epicsGetStdout(void)
+{
+ FILE *fp = epicsGetThreadStdout();
+ if(!fp) fp = stdout;
+ return fp;
+}
+
+FILE * epicsShareAPI epicsGetStderr(void)
+{
+ FILE *fp = epicsGetThreadStderr();
+ if(!fp) fp = stderr;
+ return fp;
+}
+
+FILE * epicsShareAPI epicsGetThreadStdin(void)
+{
+ epicsThreadOnce(&onceId,once,0);
+ return epicsThreadPrivateGet(stdinThreadPrivateId);
+}
+
+FILE * epicsShareAPI epicsGetThreadStdout(void)
+{
+ epicsThreadOnce(&onceId,once,0);
+ return epicsThreadPrivateGet(stdoutThreadPrivateId);
+}
+
+FILE * epicsShareAPI epicsGetThreadStderr(void)
+{
+ epicsThreadOnce(&onceId,once,0);
+ return epicsThreadPrivateGet(stderrThreadPrivateId);
+}
+
+void epicsShareAPI epicsSetThreadStdin(FILE *fp)
{
epicsThreadOnce(&onceId,once,0);
epicsThreadPrivateSet(stdinThreadPrivateId,fp);
}
-FILE * epicsShareAPI epicsGetStdout(void)
-{
- FILE *fp;
-
- epicsThreadOnce(&onceId,once,0);
- fp = epicsThreadPrivateGet(stdoutThreadPrivateId);
- if(!fp) fp = stdout;
- return fp;
-}
-
-void epicsShareAPI epicsSetStdout(FILE *fp)
+void epicsShareAPI epicsSetThreadStdout(FILE *fp)
{
epicsThreadOnce(&onceId,once,0);
epicsThreadPrivateSet(stdoutThreadPrivateId,fp);
}
-FILE * epicsShareAPI epicsGetStderr(void)
-{
- FILE *fp;
-
- epicsThreadOnce(&onceId,once,0);
- fp = epicsThreadPrivateGet(stderrThreadPrivateId);
- if(!fp) fp = stderr;
- return fp;
-}
-
-void epicsShareAPI epicsSetStderr(FILE *fp)
+void epicsShareAPI epicsSetThreadStderr(FILE *fp)
{
epicsThreadOnce(&onceId,once,0);
epicsThreadPrivateSet(stderrThreadPrivateId,fp);
diff --git a/src/libCom/osi/epicsStdio.h b/src/libCom/osi/epicsStdio.h
index 8a51bdddc..e0396dc39 100644
--- a/src/libCom/osi/epicsStdio.h
+++ b/src/libCom/osi/epicsStdio.h
@@ -43,13 +43,17 @@ epicsShareFunc FILE * epicsShareAPI epicsTempFile ();
enum TF_RETURN {TF_OK=0, TF_ERROR=1};
epicsShareFunc enum TF_RETURN epicsShareAPI truncateFile ( const char *pFileName, unsigned size );
-/*The followig are for redirecting stdin,stdout,stderr */
+/* The following are for redirecting stdin,stdout,stderr */
epicsShareFunc FILE * epicsShareAPI epicsGetStdin(void);
epicsShareFunc FILE * epicsShareAPI epicsGetStdout(void);
epicsShareFunc FILE * epicsShareAPI epicsGetStderr(void);
-epicsShareFunc void epicsShareAPI epicsSetStdin(FILE *);
-epicsShareFunc void epicsShareAPI epicsSetStdout(FILE *);
-epicsShareFunc void epicsShareAPI epicsSetStderr(FILE *);
+/* These are intended for iocsh only */
+epicsShareFunc FILE * epicsShareAPI epicsGetThreadStdin(void);
+epicsShareFunc FILE * epicsShareAPI epicsGetThreadStdout(void);
+epicsShareFunc FILE * epicsShareAPI epicsGetThreadStderr(void);
+epicsShareFunc void epicsShareAPI epicsSetThreadStdin(FILE *);
+epicsShareFunc void epicsShareAPI epicsSetThreadStdout(FILE *);
+epicsShareFunc void epicsShareAPI epicsSetThreadStderr(FILE *);
epicsShareFunc int epicsShareAPI epicsStdoutPrintf(
const char *pformat, ...) EPICS_PRINTF_STYLE(1,2);
diff --git a/src/libCom/test/epicsStdioTest.c b/src/libCom/test/epicsStdioTest.c
index b8096b417..1bf0d434a 100644
--- a/src/libCom/test/epicsStdioTest.c
+++ b/src/libCom/test/epicsStdioTest.c
@@ -66,7 +66,7 @@ int epicsStdioTest (const char *report)
memset(buffer,'*',sizeof(buffer)-1);
rtn = epicsSnprintf(buffer,size,"%d",value);
printf("size %d rtn %d value %d buffer |%s|\n",size,rtn,value,buffer);
- printf("\nTest epicsSetStdout/epicsGetStdout stdout %p epicsGetStdout %p\n",
+ printf("\nTest epicsSetThreadStdout/epicsGetStdout stdout %p epicsGetStdout %p\n",
stdout,epicsGetStdout());
if(report && strlen(report)>0) {
int fd;
@@ -82,8 +82,8 @@ int epicsStdioTest (const char *report)
fprintf(stderr,"%s could not be opened for output %s\n",
report,strerror(errno));
} else {
- epicsSetStdout(stream);
- printf("After epicsSetStdout stream %p epicsGetStdout %p\n",
+ epicsSetThreadStdout(stream);
+ printf("After epicsSetThreadStdout stream %p epicsGetStdout %p\n",
stream,epicsGetStdout());
}
}
@@ -92,7 +92,7 @@ int epicsStdioTest (const char *report)
printf("\nThis is second and last line of sample report\n");
errno = 0;
if(stream) {
- epicsSetStdout(0);
+ epicsSetThreadStdout(0);
if(fclose(stream)) {
fprintf(stderr,"fclose failed %s\n",strerror(errno));
}