From 6dba2ec1d7f600d66fddb6c30d0c3e5b6b3a8618 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 13 Feb 2020 12:08:51 +0000 Subject: [PATCH] caRepeater /dev/null --- documentation/RELEASE_NOTES.md | 13 +++++++ modules/ca/src/client/caRepeater.cpp | 55 +++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/documentation/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md index 2adeacf24..bdd246857 100644 --- a/documentation/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -12,6 +12,19 @@ The external PVA submodules each have their own separate set of release notes which should also be read to understand what has changed since an earlier release. +## EPICS Release 7.x.y.z + +### caRepeater /dev/null + +On *NIX targets caRepeater will now partially daemonize by redirecting +stdin/out/err with /dev/null. This prevents caRepeater from inheriting +the stdin/out of a process, like caget, which has spawned it in the +background. This has been known to cause problems in some cases when +caget is itself being run from a shell script. + +caRepeater will now understand the '-v' argument to retain stdin/out/err +which may be necessary to see any error messages it may emit. + ## EPICS Release 7.0.3.1 **IMPORTANT NOTE:** *Some record types in this release will not be compatible diff --git a/modules/ca/src/client/caRepeater.cpp b/modules/ca/src/client/caRepeater.cpp index 03cb8957d..2561223a5 100644 --- a/modules/ca/src/client/caRepeater.cpp +++ b/modules/ca/src/client/caRepeater.cpp @@ -31,12 +31,65 @@ #define epicsAssertAuthor "Jeff Hill johill@lanl.gov" +#include + +#if !defined(_WIN32) && !defined(__rtems__) && !defined(vxWorks) +# include +# include +# include +#define CAN_DETACH_STDINOUT +#endif + #include "epicsAssert.h" #include "osiUnistd.h" +#include "epicsGetopt.h" #include "udpiiu.h" -int main() +static void usage(char* argv[]) { + fprintf(stderr, "Usage: %s -hv\n" + "\n" + " -h - Print this message\n" + " -v - Do not replace stdin/out/err with /dev/null\n", + argv[0]); +} + +int main(int argc, char* argv[]) +{ + bool detachinout = true; + + int opt; + while ((opt = getopt(argc, argv, "hv")) != -1) { + switch (opt) { + default: + usage(argv); + fprintf(stderr, "\nUnknown argument '%c'\n", opt); + return 1; + case 'h': + usage(argv); + return 0; + case 'v': + detachinout = false; + break; + } + } + +#ifdef CAN_DETACH_STDINOUT + if(detachinout) { + int readfd = open("/dev/null", O_RDONLY); + int writefd = open("/dev/null", O_WRONLY); + + dup2(readfd, 0); + dup2(writefd, 1); + dup2(writefd, 2); + + close(readfd); + close(writefd); + } +#else + (void)detachinout; +#endif + chdir ( "/" ); ca_repeater (); return ( 0 );