bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

PATCH: direct xtrace to a file descriptor


From: Brian J. Murrell
Subject: PATCH: direct xtrace to a file descriptor
Date: Fri, 28 Jul 2006 15:45:57 -0400

Please find below a patch to allow one to direct the xtrace output of a
shell to an alternate file descriptor.  It can be used as such:

$ XTRACE_FD=4 ./bash -x [script] 4>bash.debug

or in a script:

exec 4>bash.debug
XTRACE_FD=4
set -x
who

This is very useful for separating the stderr of the shell and it's
children from the shell's xtrace output.

Please advise if this patch is acceptable and if it will be merged or
whether it needs work or otherwise.

Thanx,
b.



diff -ur bash-3.1/externs.h bash-3.1-xtrace_hack/externs.h
--- bash-3.1/externs.h  2005-11-11 23:10:52.000000000 -0500
+++ bash-3.1-xtrace_hack/externs.h      2006-07-28 13:49:58.000000000 -0400
@@ -51,6 +51,7 @@
 #endif
 
 /* set -x support */
+extern void set_xtrace_stream __P((void));
 extern char *indirection_level_string __P((void));
 extern void xtrace_print_assignment __P((char *, char *, int, int));
 extern void xtrace_print_word_list __P((WORD_LIST *, int));
diff -ur bash-3.1/flags.c bash-3.1-xtrace_hack/flags.c
--- bash-3.1/flags.c    2004-07-16 21:19:42.000000000 -0400
+++ bash-3.1-xtrace_hack/flags.c        2006-07-28 14:41:41.000000000 -0400
@@ -287,6 +287,10 @@
       break;
 #endif
 
+    case 'x':
+      if (on_or_off == FLAG_ON)
+       set_xtrace_stream();
+      break;
     }
 
   return (old_value);
diff -ur bash-3.1/print_cmd.c bash-3.1-xtrace_hack/print_cmd.c
--- bash-3.1/print_cmd.c        2005-07-04 13:05:54.000000000 -0400
+++ bash-3.1-xtrace_hack/print_cmd.c    2006-07-28 15:11:43.000000000 -0400
@@ -51,6 +51,7 @@
 #endif
 
 extern int indirection_level;
+extern FILE *xtrace_stream;
 
 static int indentation;
 static int indentation_amount = 4;
@@ -116,6 +117,42 @@
 /* A buffer to indicate the indirection level (PS4) when set -x is enabled. */
 static char indirection_string[100];
 
+void
+set_xtrace_stream() {
+  static lastfd = -1;
+  SHELL_VAR *v = find_variable("XTRACE_FD");
+  char *c;
+  int fd;
+
+  if (!v)
+       {
+      xtrace_stream = stderr;
+      return;
+       }
+
+  c = v->value;
+  fd = atoi(c); 
+
+  if (fd < 0)
+    {
+      report_error (_("invalid descriptor in $XTRACE_FD, using stderr"));
+      xtrace_stream = stderr;
+      return;
+    }
+
+  if (fd == lastfd)
+      return;
+
+  if (!(xtrace_stream = fdopen(fd, "a")))
+    {
+      report_error (_("invalid file descriptor in $XTRACE_FD, using stderr"));
+      xtrace_stream = stderr;
+      return;
+    }
+
+  lastfd = fd;
+}
+
 /* Print COMMAND (a command tree) on standard output. */
 void
 print_command (command)
@@ -380,7 +417,7 @@
   char *nval;
 
   if (xflags)
-    fprintf (stderr, "%s", indirection_level_string ());
+    fprintf (xtrace_stream, "%s", indirection_level_string ());
 
   /* VALUE should not be NULL when this is called. */
   if (*value == '\0' || assign_list)
@@ -393,14 +430,14 @@
     nval = value;
 
   if (assign_list)
-    fprintf (stderr, "%s=(%s)\n", name, nval);
+    fprintf (xtrace_stream, "%s=(%s)\n", name, nval);
   else
-    fprintf (stderr, "%s=%s\n", name, nval);
+    fprintf (xtrace_stream, "%s=%s\n", name, nval);
 
   if (nval != value)
     FREE (nval);
 
-  fflush (stderr);
+  fflush (xtrace_stream);
 }
 
 /* A function to print the words of a simple command when set -x is on. */
@@ -413,29 +450,30 @@
   char *t, *x;
 
   if (xtflags)
-    fprintf (stderr, "%s", indirection_level_string ());
+    fprintf (xtrace_stream, "%s", indirection_level_string ());
 
   for (w = list; w; w = w->next)
     {
       t = w->word->word;
       if (t == 0 || *t == '\0')
-       fprintf (stderr, "''%s", w->next ? " " : "");
+       fprintf (xtrace_stream, "''%s", w->next ? " " : "");
       else if (sh_contains_shell_metas (t))
        {
          x = sh_single_quote (t);
-         fprintf (stderr, "%s%s", x, w->next ? " " : "");
+         fprintf (xtrace_stream, "%s%s", x, w->next ? " " : "");
          free (x);
        }
       else if (ansic_shouldquote (t))
        {
          x = ansic_quote (t, 0, (int *)0);
-         fprintf (stderr, "%s%s", x, w->next ? " " : "");
+         fprintf (xtrace_stream, "%s%s", x, w->next ? " " : "");
          free (x);
        }
       else
-       fprintf (stderr, "%s%s", t, w->next ? " " : "");
+       fprintf (xtrace_stream, "%s%s", t, w->next ? " " : "");
     }
-  fprintf (stderr, "\n");
+  fprintf (xtrace_stream, "\n");
+  fflush (xtrace_stream);
 }
 
 static void
@@ -458,8 +496,8 @@
 xtrace_print_for_command_head (for_command)
      FOR_COM *for_command;
 {
-  fprintf (stderr, "%s", indirection_level_string ());
-  fprintf (stderr, "for %s in ", for_command->name->word);
+  fprintf (xtrace_stream, "%s", indirection_level_string ());
+  fprintf (xtrace_stream, "for %s in ", for_command->name->word);
   xtrace_print_word_list (for_command->map_list, 0);
 }
 
@@ -512,8 +550,8 @@
 xtrace_print_select_command_head (select_command)
      SELECT_COM *select_command;
 {
-  fprintf (stderr, "%s", indirection_level_string ());
-  fprintf (stderr, "select %s in ", select_command->name->word);
+  fprintf (xtrace_stream, "%s", indirection_level_string ());
+  fprintf (xtrace_stream, "select %s in ", select_command->name->word);
   xtrace_print_word_list (select_command->map_list, 0);
 }
 
@@ -581,8 +619,9 @@
 xtrace_print_case_command_head (case_command)
      CASE_COM *case_command;
 {
-  fprintf (stderr, "%s", indirection_level_string ());
-  fprintf (stderr, "case %s in\n", case_command->word->word);
+  fprintf (xtrace_stream, "%s", indirection_level_string ());
+  fprintf (xtrace_stream, "case %s in\n", case_command->word->word);
+  fflush (xtrace_stream);
 }
 
 static void
@@ -756,24 +795,25 @@
      char *arg1, *arg2;
 {
   command_string_index = 0;
-  fprintf (stderr, "%s", indirection_level_string ());
-  fprintf (stderr, "[[ ");
+  fprintf (xtrace_stream, "%s", indirection_level_string ());
+  fprintf (xtrace_stream, "[[ ");
   if (invert)
-    fprintf (stderr, "! ");
+    fprintf (xtrace_stream, "! ");
 
   if (type == COND_UNARY)
     {
-      fprintf (stderr, "%s ", op->word);
-      fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
+      fprintf (xtrace_stream, "%s ", op->word);
+      fprintf (xtrace_stream, "%s", (arg1 && *arg1) ? arg1 : "''");
     }
   else if (type == COND_BINARY)
     {
-      fprintf (stderr, "%s", (arg1 && *arg1) ? arg1 : "''");
-      fprintf (stderr, " %s ", op->word);
-      fprintf (stderr, "%s", (arg2 && *arg2) ? arg2 : "''");
+      fprintf (xtrace_stream, "%s", (arg1 && *arg1) ? arg1 : "''");
+      fprintf (xtrace_stream, " %s ", op->word);
+      fprintf (xtrace_stream, "%s", (arg2 && *arg2) ? arg2 : "''");
     }
 
-  fprintf (stderr, " ]]\n");
+  fprintf (xtrace_stream, " ]]\n");
+  fflush (xtrace_stream);
 }        
 #endif /* COND_COMMAND */
 
@@ -785,11 +825,12 @@
 {
   WORD_LIST *w;
 
-  fprintf (stderr, "%s", indirection_level_string ());
-  fprintf (stderr, "(( ");
+  fprintf (xtrace_stream, "%s", indirection_level_string ());
+  fprintf (xtrace_stream, "(( ");
   for (w = list; w; w = w->next)
-    fprintf (stderr, "%s%s", w->word->word, w->next ? " " : "");
-  fprintf (stderr, " ))\n");
+    fprintf (xtrace_stream, "%s%s", w->word->word, w->next ? " " : "");
+  fprintf (xtrace_stream, " ))\n");
+  fflush (xtrace_stream);
 }
 #endif
 
diff -ur bash-3.1/shell.c bash-3.1-xtrace_hack/shell.c
--- bash-3.1/shell.c    2005-09-04 22:32:08.000000000 -0400
+++ bash-3.1-xtrace_hack/shell.c        2006-07-28 13:49:29.000000000 -0400
@@ -163,6 +163,9 @@
 /* Non-zero is the recursion depth for commands. */
 int indirection_level = 0;
 
+/* the file descriptor to print xtrace info to. */
+FILE *xtrace_stream = (FILE *)NULL;
+
 /* The name of this shell, as taken from argv[0]. */
 char *shell_name = (char *)NULL;
 

-- 
My other computer is your Microsoft Windows server.

Brian J. Murrell

Attachment: signature.asc
Description: This is a digitally signed message part


reply via email to

[Prev in Thread] Current Thread [Next in Thread]