propagate env from stage1 further

This commit is contained in:
Sergey Bolshakov 2005-01-21 13:52:04 +00:00
parent 24782199d4
commit d62b45ce1a
5 changed files with 87 additions and 61 deletions

128
init.c
View File

@ -32,26 +32,25 @@
#endif
char * env[] = {
"PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sbin:/mnt/usr/sbin:/mnt/bin:/mnt/usr/bin",
"LD_LIBRARY_PATH=/lib:/usr/lib:/mnt/lib:/mnt/usr/lib:/usr/X11R6/lib:/mnt/usr/X11R6/lib",
"PATH=/usr/bin:/bin:/sbin:/usr/sbin:/usr/X11R6/bin",
"LD_LIBRARY_PATH=/lib:/usr/lib:/usr/X11R6/lib",
"HOME=/",
"TERM=linux",
"TERMINFO=/etc/terminfo",
NULL
};
char ** myenv = NULL;
/*
* this needs to handle the following cases:
*
* 1) run from a CD root filesystem
* 2) run from a read only nfs rooted filesystem
* 3) run from a floppy
* 4) run from a floppy that's been loaded into a ramdisk
*
* 1) run from a CD root filesystem
* 2) run from a read only nfs rooted filesystem
* 3) run from a floppy
* 4) run from a floppy that's been loaded into a ramdisk
*/
int testing = 0;
int klog_pid;
@ -107,8 +106,6 @@ void doklog()
{
int in, out, i;
int log;
int s;
int sock = -1;
char buf[1024];
/* open kernel message logger */
@ -154,6 +151,35 @@ void doklog()
}
}
void grab_env(int fd)
{
char buf[PIPE_BUF];
char *p = buf;
char **ep;
int i;
if ((i = read(fd, buf, sizeof(buf))) < 0) {
print_error("failed to read env from pipe");
myenv = env;
return;
}
close(fd);
buf[i] = '\0';
if ((ep = myenv = malloc(sizeof(char *) * 32)) == NULL) {
print_error("can't malloc env");
myenv = env;
return;
}
do {
*ep++ = p;
p += strlen(p);
} while(++p < buf+i);
*ep = NULL;
}
#define LOOP_CLR_FD 0x4C01
void del_loop(char *device)
@ -361,50 +387,26 @@ int main(int argc, char **argv)
char * stage2_argv[] = {STAGE2_BINNAME, NULL};
int wait_status;
int fd;
int fds[2];
int end_stage1 = 0;
/* getpid() != 1 should work, by linuxrc tends to get a larger pid */
/*testing = (getpid() > 50); */
if (!testing) {
/* turn off screen blanking */
printf("\033[9;0]");
printf("\033[8]");
}
else
printf("*** TESTING MODE ***\n");
// printf("\n\t\t\t\033[1;40mWelcome to \033[1;36mALT Linux\033[0;39m\n\n");
if (!testing) {
if (mount("/proc", "/proc", "proc", 0, NULL))
fatal_error("Unable to mount proc filesystem");
if (mount("/sysfs", "/sys", "sysfs", 0, NULL))
fatal_error("Unable to mount sysfs filesystem");
}
if (mount("/proc", "/proc", "proc", 0, NULL))
fatal_error("Unable to mount proc filesystem");
if (mount("/sysfs", "/sys", "sysfs", 0, NULL))
fatal_error("Unable to mount sysfs filesystem");
/* ignore Control-C and keyboard stop signals */
signal(SIGINT, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
if (!testing) {
fd = open("/dev/tty1", O_RDWR, 0);
if (fd < 0) {
perror("can't open /dev/tty1");
/* try with devfs */
fd = open("/dev/vc/1", O_RDWR, 0);
}
if (fd < 0)
fatal_error("failed to open /dev/tty1 and /dev/vc/1");
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
close(fd);
}
fd = open("/dev/console", O_RDWR, 0);
if (fd < 0)
fatal_error("failed to open /dev/console");
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
close(fd);
/* I set me up as session leader (probably not necessary?) */
setsid();
@ -413,16 +415,12 @@ int main(int argc, char **argv)
print_error("could not set new controlling tty");
}
if (!testing) {
char my_hostname[] = "localhost.localdomain";
sethostname(my_hostname, sizeof(my_hostname));
/* the default domainname (as of 2.0.35) is "(none)", which confuses
glibc */
setdomainname("", 0);
}
char my_hostname[] = "localhost.localdomain";
sethostname(my_hostname, sizeof(my_hostname));
/* the default domainname (as of 2.0.35) is "(none)", which confuses glibc */
setdomainname("", 0);
if (!testing)
doklog();
doklog();
/* Go into normal init mode - keep going, and then do a orderly shutdown
when:
@ -432,6 +430,11 @@ int main(int argc, char **argv)
*/
printf("Running stage1...\n");
/* create a pipe for env passing */
pipe(fds);
fcntl(fds[0], F_SETFD, 1);
fcntl(fds[1], F_SETFD, 0);
if (!(installpid = fork())) {
/* child */
@ -443,6 +446,8 @@ int main(int argc, char **argv)
return 0;
}
close(fds[1]);
while (!end_stage1) {
childpid = wait4(-1, &wait_status, 0, NULL);
if (childpid == installpid)
@ -457,9 +462,6 @@ int main(int argc, char **argv)
printf("-- received signal %d", WTERMSIG(wait_status));
printf("\n");
if (testing)
return 0;
sync(); sync();
printf("sending termination signals...");
@ -478,10 +480,13 @@ int main(int argc, char **argv)
while (1);
}
grab_env(fds[0]);
kill(klog_pid, 9);
waitpid(klog_pid, &wait_status, 0);
printf("Spawning init ...");
/* rest was seamlessy stolen from klibc */
/* First, change to the new root directory */
if (chdir(STAGE2_LOCATION))
@ -546,6 +551,7 @@ int main(int argc, char **argv)
if (stat(stage2_argv[0], &ist) || !S_ISREG(ist.st_mode))
fatal_error("can't find init on root fs");
execve(stage2_argv[0], stage2_argv, env);
execve(stage2_argv[0], stage2_argv, myenv);
fatal_error("stage2"); /* Failed to spawn init */
return 0;
}

View File

@ -679,6 +679,9 @@ enum return_type nfs_prepare(void)
#endif
method_name = strdup("nfs");
add_to_env("METHOD", method_name);
add_to_env("HOST", answers[0]);
add_to_env("PREFIX", answers[1]);
return RETURN_OK;
}
@ -758,6 +761,7 @@ enum return_type ftp_prepare(void)
return results;
method_name = strdup("ftp");
add_to_env("METHOD", method_name);
add_to_env("HOST", answers[0]);
add_to_env("PREFIX", answers[1]);
if (strcmp(answers[2], "")) {
@ -822,6 +826,7 @@ enum return_type http_prepare(void)
return RETURN_ERROR;
method_name = strdup("http");
add_to_env("METHOD", method_name);
sprintf(location_full, "http://%s/%s", answers[0], answers[1]);
add_to_env("URLPREFIX", location_full);
}

View File

@ -424,5 +424,7 @@ int main(int argc, char **argv, char **env)
if (shell_pid != 0)
kill(shell_pid, 9);
pass_env(4);
return 0; /* shut up compiler (we can't get here anyway!) */
}

12
tools.c
View File

@ -414,6 +414,18 @@ void add_to_env(char * name, char * value)
my_env[env_size] = NULL;
}
void pass_env(int fd)
{
char ** ptr = my_env;
char *s;
while (ptr && *ptr) {
s = *ptr;
while(*s++);
write(fd, *ptr, s - *ptr);
ptr++;
}
}
char ** list_directory(char * direct)
{

View File

@ -38,6 +38,7 @@ void * memdup(void *src, size_t size);
void add_to_env(char * name, char * value);
void handle_env(char ** env);
char ** grab_env(void);
void pass_env(int);
char ** list_directory(char * direct);
int string_array_length(char ** a);
int do_losetup(char * device, char * target);