mirror of
https://github.com/IanDarwin/OpenLookCDROM.git
synced 2026-02-13 03:24:52 +00:00
230 lines
6.1 KiB
C
230 lines
6.1 KiB
C
/*
|
|
* This file is a product of Sun Microsystems, Inc. and is provided for
|
|
* unrestricted use provided that this legend is included on all tape
|
|
* media and as a part of the software program in whole or part.
|
|
* Users may copy, modify or distribute this file at will.
|
|
*
|
|
* THIS FILE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
|
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
|
*
|
|
* This file is provided with no support and without any obligation on the
|
|
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
|
* modification or enhancement.
|
|
*
|
|
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
|
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS FILE
|
|
* OR ANY PART THEREOF.
|
|
*
|
|
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
|
* or profits or other special, indirect and consequential damages, even
|
|
* if Sun has been advised of the possibility of such damages.
|
|
*
|
|
* Sun Microsystems, Inc.
|
|
* 2550 Garcia Avenue
|
|
* Mountain View, California 94043
|
|
*
|
|
* Modifications to the original Sun Microsystems, Inc. source code
|
|
* made by the Grasshopper Group are in the Public Domain.
|
|
*
|
|
* Extensions to this file by Eric Messick of the Grasshopper Group.
|
|
*
|
|
* Grasshopper Group
|
|
* 212 Clayton St
|
|
* San Francisco, CA 94117
|
|
*
|
|
*/
|
|
|
|
#ifndef lint
|
|
static char sccsid[] = "@(#)slave.c 9.6 88/01/19 Copyright 1985 Sun Micro";
|
|
static char RCSid[] = "@(#)$Header: /it/grass/gterm/RCS/slave.c,v 2.7 1991/04/23 06:52:01 hugh Grass2 $";
|
|
#endif
|
|
|
|
|
|
/*
|
|
* Copyright (c) 1985 by Sun Microsystems, Inc.
|
|
*/
|
|
|
|
/*-
|
|
slave.c
|
|
|
|
slave.c, Tue Apr 1 09:17:08 1986
|
|
|
|
David Rosenthal,
|
|
Sun Microsystems
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <sys/types.h>
|
|
#ifdef REF
|
|
#include <ref/config.h>
|
|
#endif
|
|
#include <signal.h>
|
|
|
|
#ifdef HAVE_VFORK_H
|
|
#include <vfork.h>
|
|
#endif
|
|
|
|
/*#define DEBUG*/
|
|
#ifdef DEBUG
|
|
#define err0(A) fprintf(fdd,A);fflush(fdd)
|
|
#define err1(A,B) fprintf(fdd,A,B);fflush(fdd)
|
|
#define err2(A,B,C) fprintf(fdd,A,B,C);fflush(fdd)
|
|
#define err3(A,B,C,D) fprintf(fdd,A,B,C,D);fflush(fdd)
|
|
#else
|
|
#define err0(A)
|
|
#define err1(A,B)
|
|
#define err2(A,B,C)
|
|
#define err3(A,B,C,D)
|
|
#endif
|
|
|
|
extern void exit();
|
|
extern unsigned sleep();
|
|
extern void perror();
|
|
|
|
#ifndef HAVE_VFORK
|
|
#define vfork() fork()
|
|
#endif
|
|
|
|
#ifdef SYSVREF
|
|
/* Micom-Interlan software installs some non-streams based pty's on 'p' */
|
|
#ifdef INTERLANTCP
|
|
#define PTYNAME "qrst"
|
|
#else
|
|
#define PTYNAME "pqrst"
|
|
#endif
|
|
#else
|
|
#define PTYNAME "pqrst"
|
|
#endif
|
|
|
|
int Mfd, /* the /dev/ptyX, this is what gterm reads from */
|
|
Sfd; /* the /dev/ttyX, this is what the spawned procces sees */
|
|
/* XXX - there should be a library routine to get a pty */
|
|
char ptcname[] = "/dev/ptyXX";
|
|
char ptsname[] = "/dev/ttyXX";
|
|
int pgrp;
|
|
extern int errno;
|
|
|
|
FILE *
|
|
spawn_slave(name, args)
|
|
char *name, **args;
|
|
{
|
|
FILE *Master; /* What gterm reads from to display on screen */
|
|
int i, pid, uid, gid, retval;
|
|
extern int BackGround;
|
|
unsigned delay = 2 ;
|
|
#define MAXDELAY 120
|
|
char *gp, *tp;
|
|
|
|
#ifdef DEBUG
|
|
FILE *fdd;
|
|
|
|
fdd = fopen("/dev/console", "r+");
|
|
#endif /* DEBUG */
|
|
|
|
GetTTYDefaults();
|
|
/* Search through the ptys looking for an open one */
|
|
for (gp = PTYNAME; *gp; gp++)
|
|
for (tp = "0123456789abcdef"; *tp; tp++) {
|
|
ptcname[sizeof ("/dev/pty")-1] = *gp;
|
|
ptcname[sizeof ("/dev/ptyX")-1] = *tp;
|
|
if ((Mfd = open(ptcname, 2)) < 0)
|
|
continue;
|
|
ptsname[sizeof ("/dev/tty")-1] = *gp;
|
|
ptsname[sizeof ("/dev/ttyX")-1] = *tp;
|
|
if ((Sfd = open(ptsname, 2)) >= 0)
|
|
goto done;
|
|
close(Mfd);
|
|
}
|
|
done:
|
|
if (Mfd < 0 || Sfd < 0) return (NULL);
|
|
uid = getuid(), gid = getgid();
|
|
(void) chown(ptsname, uid, gid); /* set tty ownership */
|
|
(void) chmod(ptsname, 0622); /* set tty protection */
|
|
/*
|
|
* Establish tty state.
|
|
*/
|
|
SetTTYState(Sfd);
|
|
signal(SIGWINCH, SIG_IGN);
|
|
/*
|
|
* If we're to operate in the background, fork
|
|
* to return control to the shell and disassociate
|
|
* ourselves from the tty. The caller closes
|
|
* file descriptors so that, for example, rsh
|
|
* will not be kept around.
|
|
*/
|
|
if (BackGround) {
|
|
err0("\n\nPreFork\n");
|
|
retval = fork();
|
|
if (retval > 0) {
|
|
err1("gterm: Parent exiting, child=%d\n", retval);
|
|
exit(0);
|
|
} else if (retval == -1) {
|
|
fprintf(stderr, "gterm: backgrouding fork failed.\n\t");
|
|
perror("system error");
|
|
}
|
|
/* Else fork==0 and we are the child process! */
|
|
(void) setpgrp(0, getpid());
|
|
#ifdef HAVE_JCSETPGRP
|
|
if (jcsetpgrp(getpid()) == -1) {
|
|
perror("gterm: failed setpgrp()");
|
|
}
|
|
#endif
|
|
DisAssociateTTY();
|
|
} else
|
|
AssociateTTY();
|
|
err0("TTYStuff\n");
|
|
Master = fdopen(Mfd, "r+");
|
|
err2("Master = 0x%x, errno = %d\n", Master, errno);
|
|
while ((pid = vfork()) < 0 && errno == EAGAIN) {
|
|
sleep(delay);
|
|
if ((delay <<= 1) > MAXDELAY) {
|
|
close (Mfd); close (Sfd);
|
|
err0("Return NULL\n");
|
|
err3("delay %d, MAXDELAY %d, errno %d\n", delay, MAXDELAY, errno);
|
|
return (NULL);
|
|
}
|
|
}
|
|
|
|
err1("Post Forks, pid == %d\n", pid);
|
|
if (pid == 0) {
|
|
/*
|
|
* Setup controlling tty. Sfd == stdin, stdout & stderr
|
|
*/
|
|
for (i = 0; i < 3; i++)
|
|
if (dup2(Sfd, i) == -1) {
|
|
err1("bad dup2 on %d\n\t", i);
|
|
perror("gterm: Standard I/O dup2() failure");
|
|
}
|
|
if (Sfd > 2) (void)close(Sfd);
|
|
DisAssociateTTY(); /* Fixes -fg not working under SunOS 4.x */
|
|
addut(uid, ptsname);
|
|
for (i = getdtablesize(); i > 2; i--)
|
|
(void) close(i);
|
|
SetupControllingTTY(ptsname);
|
|
(void) setuid(uid), (void) setgid(gid);
|
|
/* restore various signals from SIG_IGN to their defaults */
|
|
signal (SIGINT, SIG_DFL);
|
|
signal (SIGQUIT, SIG_DFL);
|
|
signal (SIGTERM, SIG_DFL);
|
|
signal(SIGWINCH, SIG_DFL);
|
|
execvp(name, args);
|
|
fprintf(stderr, "gterm: spawning failure for:\n\t");
|
|
perror(name);
|
|
sleep(20); /* Let error message reach user */
|
|
_exit(errno);
|
|
}
|
|
pgrp = pid;
|
|
close(Sfd);
|
|
return (Master);
|
|
}
|
|
|
|
CleanupPty()
|
|
{
|
|
|
|
rmut();
|
|
(void) chown(ptsname, 0, 0); /* revoke ownership */
|
|
(void) chmod(ptsname, 0666); /* revoke protection */
|
|
}
|