home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume27
/
ytalk-3.0
/
part01
/
exec.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-20
|
4KB
|
237 lines
/* exec.c -- run a command inside a window */
/* NOTICE
*
* Copyright (c) 1990,1992,1993 Britt Yenne. All rights reserved.
*
* This software is provided AS-IS. The author gives no warranty,
* real or assumed, and takes no responsibility whatsoever for any
* use or misuse of this software, or any damage created by its use
* or misuse.
*
* This software may be freely copied and distributed provided that
* no part of this NOTICE is deleted or edited in any manner.
*
*/
/* Mail comments or questions to ytalk@austin.eds.com */
#include "header.h"
#include <fcntl.h>
#include <signal.h>
#include <sys/wait.h>
#ifdef USE_SGTTY
# include <sys/ioctl.h>
# ifdef hpux
# include <sys/bsdtty.h>
# include <sgtty.h>
# endif
#endif
int running_process = 0; /* flag: is process running? */
static int pid; /* currently executing process id */
static int pfd; /* currently executing process fd */
static int prows, pcols; /* saved rows, cols */
/* ---- local functions ---- */
#ifdef USE_SGTTY
static int
setsid()
{
register int fd;
if((fd = open("/dev/tty", O_RDWR)) >= 0)
{
ioctl(fd, TIOCNOTTY);
close(fd);
}
return fd;
}
#endif
static int
getpty(name)
char *name;
{
register int pty, tty;
strcpy(name, "/dev/ptyp0");
while(access(name, 0) == 0)
{
if((pty = open(name, O_RDWR)) >= 0)
{
name[5] = 't';
if((tty = open(name, O_RDWR)) >= 0)
{
close(tty);
return pty;
}
name[5] = 'p';
close(pty);
}
/* get next pty name */
if(name[9] == 'f')
{
name[8]++;
name[9] = '0';
}
else if(name[9] == '9')
name[9] = 'a';
else
name[9]++;
}
errno = ENOENT;
return -1;
}
static void
exec_input(fd)
int fd;
{
register int rc;
static ychar buf[MAXBUF];
if((rc = read(fd, buf, MAXBUF)) <= 0)
{
kill_exec();
errno = 0;
show_error("command shell terminated");
return;
}
show_input(me, buf, rc);
send_users(buf, rc);
}
static void
calculate_size(rows, cols)
int *rows, *cols;
{
register yuser *u;
*rows = me->t_rows;
*cols = me->t_cols;
for(u = connect_list; u; u = u->next)
if(u->remote.vmajor > 2)
{
if(u->remote.my_rows > 1 && u->remote.my_rows < *rows)
*rows = u->remote.my_rows;
if(u->remote.my_cols > 1 && u->remote.my_cols < *cols)
*cols = u->remote.my_cols;
}
}
/* ---- global functions ---- */
/* Execute a command inside my window. If command is NULL, then execute
* a shell.
*/
void
execute(command)
char *command;
{
int fd;
char name[20], *shell;
if(me->flags & FL_LOCKED)
{
errno = 0;
show_error("alternate mode already running");
return;
}
if((fd = getpty(name)) < 0)
{
msg_term(me, "cannot get pseudo terminal");
return;
}
if((shell = getenv("SHELL")) == NULL)
shell = "/bin/sh";
calculate_size(&prows, &pcols);
if((pid = fork()) == 0)
{
close_all();
if(setsid() < 0)
exit(-1);
if((fd = open(name, O_RDWR)) < 0)
exit(-1);
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
/* set terminal characteristics */
set_terminal_flags(fd);
set_terminal_size(fd, prows, pcols);
#ifndef NeXT
putenv("TERM=vt100");
#endif
/* execute the command */
if(command)
execl(shell, shell, "-c", command, NULL);
else
execl(shell, shell, NULL);
perror("execl");
(void)exit(-1);
}
if(pid < 0)
{
show_error("fork() failed");
return;
}
set_win_region(me, prows, pcols);
sleep(1);
pfd = fd;
running_process = 1;
lock_flags(FL_RAW | FL_SCROLL);
add_fd(fd, exec_input);
}
/* Send input to the command shell.
*/
void
update_exec()
{
(void)write(pfd, io_ptr, io_len);
io_len = 0;
}
/* Kill the command shell.
*/
void
kill_exec()
{
if(!running_process)
return;
remove_fd(pfd);
close(pfd);
running_process = 0;
unlock_flags();
end_win_region(me);
}
/* Send a SIGWINCH to the process.
*/
void
winch_exec()
{
int rows, cols;
if(!running_process)
return;
calculate_size(&rows, &cols);
if(rows == prows && cols == pcols)
return;
prows = rows;
pcols = cols;
set_terminal_size(pfd, prows, pcols);
set_win_region(me, prows, pcols);
#ifdef SIGWINCH
kill(pid, SIGWINCH);
#endif
}