[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
signature.asc
Description: This is a digitally signed message part
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- PATCH: direct xtrace to a file descriptor,
Brian J. Murrell <=