[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RFE: indirection_level_string() preserves 'x' flag [PATCH]
From: |
John Reiser |
Subject: |
RFE: indirection_level_string() preserves 'x' flag [PATCH] |
Date: |
Thu, 08 Sep 2011 15:19:26 -0700 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.20) Gecko/20110831 Fedora/3.1.12-2.fc14 Thunderbird/3.1.12 |
Please enhance the function indirection_level_string() in print_cmd.c
so that the value of the 'x' flag is preserved over the call to
decode_prompt_string(). This will permit the use of function
indirection_level_string() as a tool to track usage of system calls
by shell scripts.
For example, this code prints the script location of every fork().
-----
// bash-syspose.c - interpose so that bash shell prints $PS4 upon syscall
// Copyright 2011 John Reiser, BitWagon Software LLC. All rights reserved.
// Licensed under GNU General Public License, version 3 (GPLv3).
//
// Requires: change indirection_level_string() in bash/print_cmd.c
// to preserve 'x' flag around decode_prompt_string():
/*
--- bash-4.2/print_cmd.c 2011-09-08 13:27:53.877244584 -0700
+++ new/print_cmd.c 2011-09-08 13:29:34.088991764 -0700
@@ -426,9 +426,9 @@
if (ps4 == 0 || *ps4 == '\0')
return (indirection_string);
- change_flag ('x', FLAG_OFF);
+ int const old = change_flag ('x', FLAG_OFF);
ps4 = decode_prompt_string (ps4);
- change_flag ('x', FLAG_ON);
+ if (old) change_flag ('x', FLAG_ON);
if (ps4 == 0 || *ps4 == '\0')
return (indirection_string);
*/
// Build: gcc -shared -o bash-syspose.so -g -O -fPIC bash-syspose.c
// Run: LD_PRELOAD=./bash-syspose.so bash ... # "unset LD_PRELOAD" ASAP!
// EXAMPLE: (insert near beginning of shell script)
// unset LD_PRELOAD
// export PS4=' ${FUNCNAME[0]}@$LINENO <
${BASH_SOURCE[1]##*/}:${BASH_LINENO[0]} :'
//
// Obviously other syscalls could be handled, too.
#define _GNU_SOURCE 1 /* need RTLD_NEXT from dlfcn.h */
#include <dlfcn.h>
#include <stdlib.h>
#include <string.h>
// weak: Test to prevent crash if no such function, such as when
// LD_PRELOAD remains set and a child process of bash invokes a
// random executable that does a fork().
extern char const *indirection_level_string(void) __attribute__((weak));
int fork(void)
{
static int (*real_fork)(void);
if (!real_fork)
real_fork = (int (*)(void)) dlsym(RTLD_NEXT, "fork");
// Avoid infinite recursion in case evaluating PS4 does a fork().
static int recur;
char const *ils = 0;
if (!recur++ && indirection_level_string) {
ils = indirection_level_string(); // evaluate $PS4
}
if (!--recur && ils) {
write(2, ils, strlen(ils));
write(2, "fork\n", 5);
}
// The child might want to remove us (bash-syspose) from LD_PRELOAD.
// But it is ugly, so rely on 'weak' for now.
return (*real_fork)();
}
// end-of-file bash-syspose.c
-----
--
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- RFE: indirection_level_string() preserves 'x' flag [PATCH],
John Reiser <=