The previous gcov behavior was to always output errors on the stderr channel.
This is fine for most uses, but some programs will require stderr to be
silent for certain tests. This change allows configuring the gcov output by
an environment variable which will be used to open the appropriate file.
---
v0: Note, I do not have a signed FSF agreement at present. I do work at Red
Hat, but gcc is not my primary role. If this change requires paperwork, I can
sign and return asap.

 libgcc/libgcov-driver-system.c | 28 +++++++++++++++++++++++++++-
 libgcc/libgcov-driver.c        |  5 +++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index 4e3b244..09bb167 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -23,6 +23,8 @@ a copy of the GCC Runtime Library Exception along with this 
program;
 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 <http://www.gnu.org/licenses/>.  */
 
+static FILE *gcov_error_file;
+
 /* A utility function for outputing errors.  */
 
 static int __attribute__((format(printf, 1, 2)))
@@ -31,11 +33,35 @@ gcov_error (const char *fmt, ...)
   int ret;
   va_list argp;
   va_start (argp, fmt);
-  ret = vfprintf (stderr, fmt, argp);
+  ret = vfprintf (gcov_error_file, fmt, argp);
   va_end (argp);
   return ret;
 }
 
+static void
+gcov_error_exit(void)
+{
+  if (gcov_error_file != stderr)
+       {
+         fclose(gcov_error_file);
+       }
+}
+
+static void
+gcov_error_init(void)
+{
+  char *gcov_error_filename = getenv("GCOV_ERROR_FILE");
+  gcov_error_file = NULL;
+  if (gcov_error_filename)
+       {
+         FILE *openfile = fopen(gcov_error_filename, "w");
+         if (openfile)
+               gcov_error_file = openfile;
+       }
+  if (!gcov_error_file)
+       gcov_error_file = stderr;
+}
+
 /* Make sure path component of the given FILENAME exists, create
    missing directories. FILENAME must be writable.
    Returns zero on success, or -1 if an error occurred.  */
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 9c4eeca..082755a 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -45,6 +45,8 @@ void __gcov_init (struct gcov_info *p __attribute__ 
((unused))) {}
 
 /* A utility function for outputing errors.  */
 static int gcov_error (const char *, ...);
+static void gcov_error_init(void);
+static void gcov_error_exit(void);
 
 #include "gcov-io.c"
 
@@ -878,6 +880,8 @@ gcov_exit (void)
     __gcov_root.prev->next = __gcov_root.next;
   else
     __gcov_master.root = __gcov_root.next;
+
+  gcov_error_exit();
 }
 
 /* Add a new object file onto the bb chain.  Invoked automatically
@@ -900,6 +904,7 @@ __gcov_init (struct gcov_info *info)
                __gcov_master.root->prev = &__gcov_root;
              __gcov_master.root = &__gcov_root;
            }
+         gcov_error_init();
          atexit (gcov_exit);
        }
 
-- 
2.5.0

Reply via email to