The problem was caused by procd not opening /dev/tty* (whichever was
specified for the ID field /etc/inittab), causing /proc/PID/fd to
point to /dev/console instead.
This is a rework of
e63051d9, which did not initialise the console
pointer and did not check the tty pointer in askconsole. askfirst
was not completely fixed as it expected the console parameter on
the commandline, which is no longer necessary because procd opens
the console prior to fork()-ing.
Signed-off-by: Michel Stam <m.stam@fugro.nl>
#define MAX_ARGS 8
struct init_action;
#define MAX_ARGS 8
struct init_action;
struct init_handler {
const char *name;
struct init_handler {
const char *name;
static LIST_HEAD(actions);
static LIST_HEAD(actions);
+static int dev_open(const char *dev)
+{
+ int fd = -1;
+
+ if (dev) {
+ chdir("/dev");
+ fd = open( dev, O_RDWR);
+ chdir("/");
+ }
+
+ return fd;
+}
+
+static int dev_exist(const char *dev)
+{
+ int res;
+
+ res = dev_open(dev);
+ if (res != -1) {
+ close(res);
+ }
+
+ return (res != -1);
+}
+
static void fork_worker(struct init_action *a)
{
static void fork_worker(struct init_action *a)
{
a->proc.pid = fork();
if (!a->proc.pid) {
a->proc.pid = fork();
if (!a->proc.pid) {
+ p = setsid( );
+ fd = dev_open(a->id);
+ if (fd != -1)
+ {
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ tcsetpgrp(fd, p);
+ close(fd);
+ }
execvp(a->argv[0], a->argv);
ERROR("Failed to execute %s\n", a->argv[0]);
exit(-1);
execvp(a->argv[0], a->argv);
ERROR("Failed to execute %s\n", a->argv[0]);
exit(-1);
static void askfirst(struct init_action *a)
{
static void askfirst(struct init_action *a)
{
- chdir("/dev");
- i = stat(a->id, &s);
- chdir("/");
- if (i || (console && !strcmp(console, a->id))) {
+ if (!dev_exist(a->id) || (console && !strcmp(console, a->id))) {
DEBUG(4, "Skipping %s\n", a->id);
return;
}
a->tout.cb = respawn;
DEBUG(4, "Skipping %s\n", a->id);
return;
}
a->tout.cb = respawn;
- for (i = MAX_ARGS - 2; i >= 2; i--)
- a->argv[i] = a->argv[i - 2];
+ for (i = MAX_ARGS - 1; i >= 1; i--)
+ a->argv[i] = a->argv[i - 1];
a->respawn = 500;
a->proc.cb = child_exit;
a->respawn = 500;
a->proc.cb = child_exit;
static void askconsole(struct init_action *a)
{
static void askconsole(struct init_action *a)
{
char line[256], *tty, *split;
int i;
tty = get_cmdline_val("console", line, sizeof(line));
char line[256], *tty, *split;
int i;
tty = get_cmdline_val("console", line, sizeof(line));
- split=strchr(tty, ',');
- if (split != NULL)
- split = '\0';
-
- chdir("/dev");
- i = stat(tty, &s);
- chdir("/");
- if (i) {
+ if (tty != NULL) {
+ split = strchr(tty, ',');
+ if (split != NULL)
+ *split = '\0';
+ }
+
+ if (!dev_exist(tty)) {
DEBUG(4, "skipping %s\n", tty);
return;
}
console = strdup(tty);
a->tout.cb = respawn;
DEBUG(4, "skipping %s\n", tty);
return;
}
console = strdup(tty);
a->tout.cb = respawn;
- for (i = MAX_ARGS - 2; i >= 2; i--)
- a->argv[i] = a->argv[i - 2];
+ for (i = MAX_ARGS - 1; i >= 1; i--)
+ a->argv[i] = a->argv[i - 1];
+ a->id = strdup(tty);
- a->argv[1] = strdup(tty);
a->respawn = 500;
a->proc.cb = child_exit;
a->respawn = 500;
a->proc.cb = child_exit;
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <fcntl.h>
-static int redirect_output(const char *dev)
-{
- pid_t p = setsid();
- int fd;
-
- chdir("/dev");
- fd = open(dev, O_RDWR);
- chdir("/");
-
- if (fd < 0)
- return -1;
-
- dup2(fd, STDIN_FILENO);
- dup2(fd, STDOUT_FILENO);
- dup2(fd, STDERR_FILENO);
- tcsetpgrp(fd, p);
- close(fd);
-
- return 0;
-}
-
int main(int argc, char **argv)
{
int c;
int main(int argc, char **argv)
{
int c;
- if (redirect_output(argv[1]))
- fprintf(stderr, "%s: Failed to open %s\n", argv[0], argv[1]);
-
printf("Please press Enter to activate this console.\n");
do {
c = getchar();
printf("Please press Enter to activate this console.\n");
do {
c = getchar();
- execvp(argv[2], &argv[2]);
- printf("%s: Failed to execute %s\n", argv[0], argv[2]);
+ execvp(argv[1], &argv[1]);
+ printf("Failed to execute %s\n", argv[0]);