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:
Axel Dörfler
2005-07-06 03:30:19 +00:00
parent 0b4ce825fb
commit f87938dc2e
+83 -81
View File
@@ -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);
} }