It's now using setenv() under Haiku instead of its own stuff - and that will
now mimic setenv() instead of some strangely different thing :) Rearranged and corrected the code that opens the PTY, and TTY. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13478 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -67,27 +67,33 @@ Check \"Shell\" in preferance panel.' "\
|
|||||||
* Set environment varriable.
|
* Set environment varriable.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
#ifndef __HAIKU__
|
||||||
Setenv (const char *var, const char *value)
|
int
|
||||||
|
setenv(const char *var, const char *value, bool overwrite)
|
||||||
{
|
{
|
||||||
int envindex = 0;
|
int envindex = 0;
|
||||||
const int len = strlen(var);
|
const int len = strlen(var);
|
||||||
const int val_len = strlen (value);
|
const int val_len = strlen (value);
|
||||||
|
|
||||||
while (environ [envindex] != NULL) {
|
while (environ[envindex] != NULL) {
|
||||||
if (strncmp (environ [envindex], var, len) == 0) {
|
if (!strncmp(environ[envindex], var, len)) {
|
||||||
/* found it */
|
/* found it */
|
||||||
environ[envindex] = (char *)malloc ((unsigned)len + val_len + 1);
|
if (overwrite) {
|
||||||
sprintf (environ [envindex], "%s%s", var, value);
|
environ[envindex] = (char *)malloc((unsigned)len + val_len + 2);
|
||||||
return;
|
sprintf(environ[envindex], "%s=%s", var, value);
|
||||||
}
|
}
|
||||||
envindex ++;
|
return 0;
|
||||||
|
}
|
||||||
|
envindex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
environ [envindex] = (char *) malloc ((unsigned)len + val_len + 1);
|
environ[envindex] = (char *)malloc((unsigned)len + val_len + 2);
|
||||||
sprintf (environ [envindex], "%s%s", var, value);
|
sprintf(environ[envindex], "%s=%s", var, value);
|
||||||
environ [++envindex] = NULL;
|
environ[++envindex] = NULL;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* reapchild. Child process is out there, let's catch its terminaltion.
|
* reapchild. Child process is out there, let's catch its terminaltion.
|
||||||
@@ -122,13 +128,14 @@ typedef struct
|
|||||||
pid_t sh_pid;
|
pid_t sh_pid;
|
||||||
char tty_name[B_PATH_NAME_LENGTH];
|
char tty_name[B_PATH_NAME_LENGTH];
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
spawn_shell (int row, int col, const char *command, const char *coding)
|
spawn_shell(int row, int col, const char *command, const char *coding)
|
||||||
{
|
{
|
||||||
int done = 0;
|
int done = 0;
|
||||||
pid_t pgrp;
|
pid_t pgrp;
|
||||||
|
|
||||||
int master = 0;
|
int master = -1;
|
||||||
int slave;
|
int slave;
|
||||||
struct termios tio;
|
struct termios tio;
|
||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
@@ -154,44 +161,46 @@ spawn_shell (int row, int col, const char *command, const char *coding)
|
|||||||
* which is already in use, so we simply go until the open succeeds.
|
* which is already in use, so we simply go until the open succeeds.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DIR *dir;
|
DIR *dir = opendir("/dev/pt/");
|
||||||
dir = opendir("/dev/pt/");
|
if (dir != NULL) {
|
||||||
|
struct dirent *dirEntry;
|
||||||
struct dirent *dir_entry;
|
while ((dirEntry = readdir(dir)) != NULL) {
|
||||||
char pty_name[B_PATH_NAME_LENGTH];
|
// skip '.' and '..'
|
||||||
while(NULL != (dir_entry = readdir(dir)))
|
if (dirEntry->d_name[0] == '.')
|
||||||
{
|
|
||||||
if (dir_entry->d_name[0] == '.') // skip . and ..
|
|
||||||
continue;
|
continue;
|
||||||
sprintf(pty_name, "/dev/pt/%s", dir_entry->d_name);
|
|
||||||
printf("%s\n", pty_name);
|
char ptyName[B_PATH_NAME_LENGTH];
|
||||||
master = open(pty_name, O_RDWR);
|
sprintf(ptyName, "/dev/pt/%s", dirEntry->d_name);
|
||||||
if (master >= 0)
|
|
||||||
|
master = open(ptyName, O_RDWR);
|
||||||
|
if (master >= 0) {
|
||||||
|
// Set the tty that corresponds to the pty we found
|
||||||
|
sprintf(tty_name, "/dev/tt/%s", dirEntry->d_name);
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "could not open %s: %s\n", ptyName, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If master is still < 0 then we haven't found a tty we can use
|
// If master is still < 0 then we haven't found a tty we can use
|
||||||
if (master < 0)
|
if (master < 0) {
|
||||||
{
|
|
||||||
printf("didn't find any available pesudo ttys.");
|
printf("didn't find any available pesudo ttys.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the tty that corresponds to the pty we found
|
|
||||||
sprintf (tty_name, "/dev/tt/%s", dir_entry->d_name);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the modes of the current terminal. We will duplicates these
|
* Get the modes of the current terminal. We will duplicates these
|
||||||
* on the pseudo terminal.
|
* on the pseudo terminal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Create pipe that be use to handshake */
|
/* Create pipe that be use to handshake */
|
||||||
if ( pipe (pc_pipe) || pipe (cp_pipe)) {
|
if (pipe(pc_pipe) || pipe(cp_pipe)) {
|
||||||
printf ("Could not create handshake pipe.");
|
printf ("Could not create handshake pipe.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Fork a child process. */
|
/* Fork a child process. */
|
||||||
if ((sh_pid = fork()) < 0) {
|
if ((sh_pid = fork()) < 0) {
|
||||||
close(master);
|
close(master);
|
||||||
@@ -199,15 +208,14 @@ spawn_shell (int row, int col, const char *command, const char *coding)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sh_pid == 0) {
|
if (sh_pid == 0) {
|
||||||
/*
|
// Now in child process.
|
||||||
* Now in child process.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make our controlling tty the pseudo tty. This hapens because
|
* Make our controlling tty the pseudo tty. This hapens because
|
||||||
* we cleared our original controlling terminal above.
|
* we cleared our original controlling terminal above.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// ToDo: why two of them in the first place?
|
||||||
close(cp_pipe[0]);
|
close(cp_pipe[0]);
|
||||||
close(pc_pipe[1]);
|
close(pc_pipe[1]);
|
||||||
|
|
||||||
@@ -220,34 +228,33 @@ spawn_shell (int row, int col, const char *command, const char *coding)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* change pty owner and asscess mode. */
|
/* change pty owner and asscess mode. */
|
||||||
chown (tty_name, getuid(), getgid());
|
chown(tty_name, getuid(), getgid());
|
||||||
chmod (tty_name, S_IRUSR | S_IWUSR);
|
chmod(tty_name, S_IRUSR | S_IWUSR);
|
||||||
|
|
||||||
/* open slave pty */
|
/* open slave pty */
|
||||||
if ((slave = open (tty_name, O_RDWR)) < 0) {
|
if ((slave = open(tty_name, O_RDWR)) < 0) {
|
||||||
handshake.status = PTY_NG;
|
handshake.status = PTY_NG;
|
||||||
sprintf (handshake.msg, "can't open tty (%s).", tty_name);
|
sprintf(handshake.msg, "can't open tty (%s).", tty_name);
|
||||||
write (cp_pipe[1], (char *)&handshake, sizeof (handshake));
|
write(cp_pipe[1], (char *)&handshake, sizeof (handshake));
|
||||||
exit (1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get tty termios (don't necessary). */
|
/* get tty termios (don't necessary). */
|
||||||
tcgetattr (slave, &tio);
|
tcgetattr(slave, &tio);
|
||||||
|
|
||||||
/* set signal default */
|
/* set signal default */
|
||||||
signal (SIGCHLD, SIG_DFL);
|
signal(SIGCHLD, SIG_DFL);
|
||||||
signal (SIGHUP, SIG_DFL);
|
signal(SIGHUP, SIG_DFL);
|
||||||
signal (SIGQUIT, SIG_DFL);
|
signal(SIGQUIT, SIG_DFL);
|
||||||
signal (SIGTERM, SIG_DFL);
|
signal(SIGTERM, SIG_DFL);
|
||||||
signal (SIGINT, SIG_DFL);
|
signal(SIGINT, SIG_DFL);
|
||||||
signal (SIGTTOU, SIG_DFL);
|
signal(SIGTTOU, SIG_DFL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set Terminal interface.
|
* Set Terminal interface.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tio.c_line = 0;
|
tio.c_line = 0;
|
||||||
|
|
||||||
tio.c_lflag |= ECHOE;
|
tio.c_lflag |= ECHOE;
|
||||||
|
|
||||||
/* input: nl->nl, cr->nl */
|
/* input: nl->nl, cr->nl */
|
||||||
@@ -260,7 +267,6 @@ spawn_shell (int row, int col, const char *command, const char *coding)
|
|||||||
tio.c_oflag |= ONLCR;
|
tio.c_oflag |= ONLCR;
|
||||||
tio.c_oflag |= OPOST;
|
tio.c_oflag |= OPOST;
|
||||||
|
|
||||||
|
|
||||||
/* baud rate is 19200 (equal beterm) */
|
/* baud rate is 19200 (equal beterm) */
|
||||||
tio.c_cflag &= ~(CBAUD);
|
tio.c_cflag &= ~(CBAUD);
|
||||||
tio.c_cflag |= B19200;
|
tio.c_cflag |= B19200;
|
||||||
@@ -276,10 +282,7 @@ spawn_shell (int row, int col, const char *command, const char *coding)
|
|||||||
* enable signals, canonical processing (erase, kill, etc), echo.
|
* enable signals, canonical processing (erase, kill, etc), echo.
|
||||||
*/
|
*/
|
||||||
tio.c_lflag |= ISIG|ICANON|ECHO|ECHOE|ECHONL;
|
tio.c_lflag |= ISIG|ICANON|ECHO|ECHOE|ECHONL;
|
||||||
tio.c_lflag &= ~ECHOK;
|
tio.c_lflag &= ~(ECHOK | IEXTEN);
|
||||||
|
|
||||||
tio.c_lflag &= ~IEXTEN;
|
|
||||||
|
|
||||||
|
|
||||||
/* set control charactors. */
|
/* set control charactors. */
|
||||||
tio.c_cc[VINTR] = 'C' & 0x1f; /* '^C' */
|
tio.c_cc[VINTR] = 'C' & 0x1f; /* '^C' */
|
||||||
@@ -300,22 +303,22 @@ spawn_shell (int row, int col, const char *command, const char *coding)
|
|||||||
* change control tty.
|
* change control tty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dup2 (slave, 0);
|
dup2(slave, 0);
|
||||||
dup2 (slave, 1);
|
dup2(slave, 1);
|
||||||
dup2 (slave, 2);
|
dup2(slave, 2);
|
||||||
|
|
||||||
/* close old slave fd. */
|
/* close old slave fd. */
|
||||||
if (slave > 2)
|
if (slave > 2)
|
||||||
close (slave);
|
close(slave);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set terminal interface.
|
* set terminal interface.
|
||||||
*/
|
*/
|
||||||
if (tcsetattr (0, TCSANOW, &tio) == -1) {
|
if (tcsetattr (0, TCSANOW, &tio) == -1) {
|
||||||
handshake.status = PTY_NG;
|
handshake.status = PTY_NG;
|
||||||
sprintf (handshake.msg, "failed set terminal interface (TERMIOS).");
|
sprintf(handshake.msg, "failed set terminal interface (TERMIOS).");
|
||||||
write (cp_pipe[1], (char *)&handshake, sizeof (handshake));
|
write(cp_pipe[1], (char *)&handshake, sizeof (handshake));
|
||||||
exit (1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -323,20 +326,20 @@ spawn_shell (int row, int col, const char *command, const char *coding)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
handshake.status = PTY_WS;
|
handshake.status = PTY_WS;
|
||||||
write (cp_pipe[1], (char *)&handshake, sizeof (handshake));
|
write(cp_pipe[1], (char *)&handshake, sizeof (handshake));
|
||||||
read (pc_pipe[0], (char *)&handshake, sizeof (handshake));
|
read(pc_pipe[0], (char *)&handshake, sizeof (handshake));
|
||||||
|
|
||||||
if (handshake.status != PTY_WS) {
|
if (handshake.status != PTY_WS) {
|
||||||
handshake.status = PTY_NG;
|
handshake.status = PTY_NG;
|
||||||
sprintf (handshake.msg, "missmatch handshake.");
|
sprintf(handshake.msg, "missmatch handshake.");
|
||||||
write (cp_pipe[1], (char *)&handshake, sizeof (handshake));
|
write(cp_pipe[1], (char *)&handshake, sizeof (handshake));
|
||||||
exit (1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ws.ws_row = handshake.row;
|
ws.ws_row = handshake.row;
|
||||||
ws.ws_col = handshake.col;
|
ws.ws_col = handshake.col;
|
||||||
|
|
||||||
ioctl (0, TIOCSWINSZ, &ws);
|
ioctl(0, TIOCSWINSZ, &ws);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set process group ID to process, and Terminal Process group ID
|
* Set process group ID to process, and Terminal Process group ID
|
||||||
@@ -348,26 +351,25 @@ spawn_shell (int row, int col, const char *command, const char *coding)
|
|||||||
tcsetpgrp(0, pgrp);
|
tcsetpgrp(0, pgrp);
|
||||||
|
|
||||||
/* mark the pipes as close on exec */
|
/* mark the pipes as close on exec */
|
||||||
fcntl( cp_pipe[1], F_SETFD, 1);
|
fcntl(cp_pipe[1], F_SETFD, 1);
|
||||||
fcntl( pc_pipe[0], F_SETFD, 1);
|
fcntl(pc_pipe[0], F_SETFD, 1);
|
||||||
|
|
||||||
/* pty open and set termios successful. */
|
/* pty open and set termios successful. */
|
||||||
handshake.status = PTY_OK;
|
handshake.status = PTY_OK;
|
||||||
write (cp_pipe[1], (char *)&handshake, sizeof (handshake));
|
write(cp_pipe[1], (char *)&handshake, sizeof (handshake));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* setenv TERM and TTY.
|
* setenv TERM and TTY.
|
||||||
*/
|
*/
|
||||||
Setenv ("TERM=", "xterm");
|
setenv("TERM", "xterm", true);
|
||||||
Setenv ("TTY=",tty_name);
|
setenv("TTY", tty_name, true);
|
||||||
Setenv ("TTYPE=", coding);
|
setenv("TTYPE", coding, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If don't set command args, exec SHELL_COMMAND.
|
* If don't set command args, exec SHELL_COMMAND.
|
||||||
*/
|
*/
|
||||||
if (command == NULL) {
|
if (command == NULL)
|
||||||
command = SHELL_COMMAND;
|
command = SHELL_COMMAND;
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (com_line, command, 256);
|
memcpy (com_line, command, 256);
|
||||||
ptr = com_line;
|
ptr = com_line;
|
||||||
@@ -389,7 +391,7 @@ spawn_shell (int row, int col, const char *command, const char *coding)
|
|||||||
|
|
||||||
args[i] = NULL;
|
args[i] = NULL;
|
||||||
|
|
||||||
Setenv ("SHELL=", *args);
|
setenv("SHELL", *args, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print Welcome Message.
|
* Print Welcome Message.
|
||||||
@@ -406,16 +408,16 @@ spawn_shell (int row, int col, const char *command, const char *coding)
|
|||||||
now_hour = 2;
|
now_hour = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
execve (*args, args, environ);
|
execve(*args, args, environ);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exec failed.
|
* Exec failed.
|
||||||
*/
|
*/
|
||||||
sleep (1);
|
sleep(1);
|
||||||
sprintf (err_msg, spawn_alert_msg, com_line);
|
sprintf(err_msg, spawn_alert_msg, com_line);
|
||||||
|
|
||||||
if (system (err_msg) == 0)
|
if (system(err_msg) == 0)
|
||||||
execl ("/bin/sh", "/bin/sh", "-login", NULL);
|
execl("/bin/sh", "/bin/sh", "-login", NULL);
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user