version 1.16, 1997/08/06 06:43:40 |
version 1.17, 1997/08/31 18:00:43 |
|
|
one = 1; |
one = 1; |
host = user = NULL; |
host = user = NULL; |
|
|
if (p = strrchr(argv[0], '/')) |
if ((p = strrchr(argv[0], '/'))) |
++p; |
++p; |
else |
else |
p = argv[0]; |
p = argv[0]; |
|
|
/*NOTREACHED*/ |
/*NOTREACHED*/ |
} |
} |
|
|
int child; |
pid_t child; |
|
|
void |
void |
doit(omask) |
doit(omask) |
int omask; |
int omask; |
{ |
{ |
|
struct sigaction sa; |
|
|
(void)signal(SIGINT, SIG_IGN); |
(void)signal(SIGINT, SIG_IGN); |
setsignal(SIGHUP); |
setsignal(SIGHUP); |
|
|
done(1); |
done(1); |
} |
} |
if (child == 0) { |
if (child == 0) { |
|
(void)signal(SIGCHLD, SIG_DFL); |
if (reader(omask) == 0) { |
if (reader(omask) == 0) { |
msg("connection closed."); |
msg("connection closed."); |
exit(0); |
exit(0); |
} |
} |
sleep(1); |
sleep(1); |
|
|
|
/* |
|
* Use sigaction() instead of signal() to avoid getting SIGCHLDs |
|
* for stopped children. |
|
*/ |
|
sigemptyset(&sa.sa_mask); |
|
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; |
|
sa.sa_handler = catch_child; |
|
(void)sigaction(SIGCHLD, &sa, NULL); |
|
|
msg("\aconnection closed."); |
msg("\aconnection closed."); |
exit(1); |
exit(1); |
} |
} |
|
|
* that were set above. |
* that were set above. |
*/ |
*/ |
(void)sigsetmask(omask); |
(void)sigsetmask(omask); |
(void)signal(SIGCHLD, catch_child); |
|
writer(); |
writer(); |
msg("closed connection."); |
msg("closed connection."); |
done(0); |
done(0); |
|
|
/* make sure catch_child does not snap it up */ |
/* make sure catch_child does not snap it up */ |
(void)signal(SIGCHLD, SIG_DFL); |
(void)signal(SIGCHLD, SIG_DFL); |
if (kill(child, SIGKILL) >= 0) |
if (kill(child, SIGKILL) >= 0) |
while ((w = wait(&wstatus)) > 0 && w != child); |
while ((w = wait(&wstatus)) > 0 && w != child) |
|
; |
} |
} |
exit(status); |
exit(status); |
} |
} |
|
|
catch_child(signo) |
catch_child(signo) |
int signo; |
int signo; |
{ |
{ |
union wait status; |
|
int save_errno = errno; |
int save_errno = errno; |
int pid; |
int status; |
|
pid_t pid; |
|
|
for (;;) { |
for (;;) { |
pid = wait3((int *)&status, WNOHANG|WUNTRACED, NULL); |
pid = wait3(&status, WNOHANG, NULL); |
if (pid == 0) |
if (pid == 0) |
break; |
break; |
/* if the child (reader) dies, just quit */ |
/* if the child (reader) dies, just quit */ |
if (pid < 0 || (pid == child && !WIFSTOPPED(status))) |
if (pid == child && !WIFSTOPPED(status)) { |
done((int)(status.w_termsig | status.w_retcode)); |
child = -1; |
|
if (WIFEXITED(status)) |
|
done(WEXITSTATUS(status)); |
|
done(WTERMSIG(status)); |
|
} |
} |
} |
errno = save_errno; |
errno = save_errno; |
} |
} |
|
|
int all; |
int all; |
{ |
{ |
mode(0); |
mode(0); |
(void)signal(SIGCHLD, SIG_IGN); |
|
(void)kill(all ? 0 : getpid(), SIGTSTP); |
(void)kill(all ? 0 : getpid(), SIGTSTP); |
(void)signal(SIGCHLD, catch_child); |
|
mode(1); |
mode(1); |
sigwinch(0); /* check for size changes */ |
sigwinch(0); /* check for size changes */ |
} |
} |
|
|
#define WRITING 2 |
#define WRITING 2 |
|
|
jmp_buf rcvtop; |
jmp_buf rcvtop; |
int ppid, rcvcnt, rcvstate; |
pid_t ppid; |
|
int rcvcnt, rcvstate; |
char rcvbuf[8 * 1024]; |
char rcvbuf[8 * 1024]; |
|
|
void |
void |
|
|
reader(omask) |
reader(omask) |
int omask; |
int omask; |
{ |
{ |
int pid, n, remaining; |
pid_t pid; |
|
int n, remaining; |
char *bufp; |
char *bufp; |
|
|
#if BSD >= 43 || defined(SUNOS4) |
#if BSD >= 43 || defined(SUNOS4) |