Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Trouble porting an app from Linux to Solaris. *Please help in a terrible time crunch*

13 views
Skip to first unread message

Ron Stewart

unread,
Feb 28, 2002, 10:37:19 AM2/28/02
to
I find myself in a terrible time crunch while porting an app from
Linux to Solaris 2.6 (management set this up and made promises and
now I have to work a miracle to get it done by tomorrow). The problem
is that Solaris does not have a set controlling terminal option.

Any and all opinions and advice on how this can be rewritten to
fix this problem (or work around it) are greatly appreciated.

Help me Obi-Wan Kenobi. You're my only hope.


Ron Stewart
Software Engineer
Lockheed Martin Mission Systems

The relevant code follows:



shell = getenv("SHELL");
if (shell == NULL)
shell = _PATH_BSHELL;

getmaster();
fixtty();

(void) signal(SIGCHLD, finish);
child = fork();
if (child < 0) {
perror("fork");
fail();
}
if (child == 0) {
subchild = child = fork();
if (child < 0) {
perror("fork");
fail();
}
if (child)
dooutput();
else
doshell();
} else
(void) signal(SIGWINCH, resize);
doinput();

----------------------------------------------------------------------------------
void
getmaster() {
char *pty, *bank, *cp;
struct stat stb;

pty = &line[strlen("/dev/ptyp")];
for (bank = "pqrs"; *bank; bank++) {
line[strlen("/dev/pty")] = *bank;
*pty = '0';
if (stat(line, &stb) < 0)
break;
for (cp = "0123456789abcdef"; *cp; cp++) {
*pty = *cp;
master = open(line, O_RDWR);
if (master >= 0) {
char *tp = &line[strlen("/dev/")];
int ok;

/* verify slave side is usable */
*tp = 't';
ok = access(line, R_OK|W_OK) == 0;
*tp = 'p';
if (ok) {
(void) tcgetattr(0, &tt);
(void) ioctl(0, TIOCGWINSZ,
(char *)&win);
return;
}
(void) close(master);
}
}
}
fprintf(stderr, _("Out of pty's\n"));
fail();
}

void
getslave() {
line[strlen("/dev/")] = 't';
slave = open(line, O_RDWR);
if (slave < 0) {
perror(line);
fail();
}
(void) tcsetattr(slave, TCSAFLUSH, &tt);
(void) ioctl(slave, TIOCSWINSZ, (char *)&win);

(void) setsid();
/* (void) ioctl(slave, TIOCSCTTY, 0); Here's where it sets
the
slave to be the
controlling term
*/
}

void
doinput() {
register int cc;
char ibuf[BUFSIZ];

while ((cc = read(0, ibuf, BUFSIZ)) > 0)
(void) write(master, ibuf, cc);
done();
}

void
dooutput() {
register int cc;
time_t tvec;
char obuf[BUFSIZ];

(void) close(0);
tvec = time((time_t *)NULL);
for (;;) {
cc = read(master, obuf, sizeof (obuf));
if (cc <= 0)
break;
(void) write(1, obuf, cc);
}
done();
}

void
doshell() {
getslave();
(void) close(master);
(void) dup2(slave, 0);
(void) dup2(slave, 1);
(void) dup2(slave, 2);
(void) close(slave);
execl(shell, "sh", "-i", 0);
perror(shell);
fail();
}

void
fixtty() {
struct termios rtt;

rtt = tt;
/* cfmakeraw(&rtt); */

/* This section added since Solaris does not support cfmakeraw
RES */
rtt.c_iflag &=
~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
rtt.c_oflag &= ~OPOST;
rtt.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN|FLUSHO);
rtt.c_cflag &= ~(CSIZE|PARENB);
rtt.c_cflag |= CS8;

rtt.c_lflag &= ~ECHO;

(void) tcsetattr(0, TCSAFLUSH, &rtt);
}

Richard Masoner

unread,
Feb 28, 2002, 12:56:08 PM2/28/02
to
ronald....@kirtland.af.mil (Ron Stewart) wrote:

> The problem
> is that Solaris does not have a set controlling terminal option.


In System V, the controlling terminal is the first tty that's opened
that is not already associated with a session. If you don't want that
tty to be the controlling terminal, use the O_NOCTTY flag on open().

You don't need the TIOCSCTTY ioctl in SVR4 systems.

If you'll be doing much UNIX programming, Stevens' _Advanced UNIX
Programming_ is a must-buy.

Richard Masoner

0 new messages