Skip to content

Commit

Permalink
Special-case bash to export variables properly.
Browse files Browse the repository at this point in the history
  • Loading branch information
geofft committed Sep 22, 2013
1 parent 10b63eb commit 31fecf2
Showing 1 changed file with 32 additions and 8 deletions.
40 changes: 32 additions & 8 deletions enviable.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,38 @@ static int (*real___libc_current_sigrtmin)(void) = NULL;

static char *watchfile = "/tmp/vars";

/* The following definitions are stolen from bash-4.2 */
__attribute__((weak))
extern int do_assignment_no_expand(char *);
__attribute__((weak))
extern void set_var_attribute(char *, int, int);
#define att_exported 1

int
__libc_current_sigrtmin(void)
{
return real___libc_current_sigrtmin() + 1;
}

static void
enviable_setenv(char *line)
{
char *eq = strchr(line, '=');
if (do_assignment_no_expand && set_var_attribute) {
/* We're running inside bash. Since bash maintains its
* own idea of the environment (shell variables marked
* exported), we need to go through that for child
* processes to see changes. */
do_assignment_no_expand(line);
*eq = '\0';
set_var_attribute(line, att_exported, 0);
} else {
/* Unknown host process -- fall back to libc. */
*eq = '\0';
setenv(line, eq + 1, 1);
}
}

static void
enviable_callback(int signum, siginfo_t *si, void *context)
{
Expand All @@ -64,21 +90,19 @@ enviable_callback(int signum, siginfo_t *si, void *context)
if (!fd) {
return;
}
char *buf = NULL;
char *line = NULL;
size_t n = 0;
ssize_t len;
while ((len = getline(&buf, &n, fd)) > 0) {
if (buf[len - 1] == '\n') {
buf[len - 1] = '\0';
while ((len = getline(&line, &n, fd)) > 0) {
if (line[len - 1] == '\n') {
line[len - 1] = '\0';
} else {
/* Conservatively reject partial lines. */
continue;
}
char *eq = strchr(buf, '=');
*eq = '\0';
setenv(buf, eq + 1, 1);
enviable_setenv(line);
}
free(buf);
free(line);
fclose(fd);
}

Expand Down

0 comments on commit 31fecf2

Please sign in to comment.