static void synch_print(const char *buf, int len, void *arg) { struct ttyrec_frame *nf; if (!(nf=malloc(sizeof(struct ttyrec_frame)))) return; if (!(nf->data=malloc(len))) { free(nf); return; } nf->len=len; memcpy(nf->data, buf, len); nf->t=tr->tev_tail->t; tadd(nf->t, tr->ndelay); tr->ndelay.tv_sec=tr->ndelay.tv_usec=0; nf->snapshot=0; nf->next=0; tr->tev_tail->next=nf; tr->tev_tail=nf; tty_write(tr->tev_vt, buf, len); if ((tr->nchunk+=len)>=SNAPSHOT_CHUNK) // do a snapshot every 64KB of data { nf->snapshot=tty_copy(tr->tev_vt); tr->nchunk=0; } }
int recinput(char *arqinput, char *argv[]) { int fdm, c; pid_t pid; struct termios orig_termios; struct winsize size; if (! isatty(0) || ! isatty(1)) { msg("stdin and stdout must be a terminal"); return ERRO; } input = criarq("", arqinput, ""); if (input == NULL) return ERRO; if (tty_save(STDIN_FILENO) == ERRO) return ERRO; pid = pty_fork2(&fdm, slave_name); if (pid < 0) { return ERRO; } else if (pid == 0) { /* child */ if (execv(argv[0], argv) < 0) { msg("can't execv: %s"); return ERRO; } } if (tty_raw(STDIN_FILENO) < 0) /* user's tty to raw mode */ { msg("tty_raw error"); return ERRO; } c = loop1(fdm); /* copies stdin -> ptym, ptym -> stdout */ waitpid(pid, NULL, 0); fclose(input); close(fdm); tty_copy(STDIN_FILENO); return c; }
pid_t pty_fork(int *ptrfdm, int pipe_out[], int pipe_err[]) { int fdm, fds, k; pid_t pid; char pts_name[20]; /*/ fdm = glob_fdm; // strcpy(pts_name, glob_name); */ if ( (fdm = ptym_open(pts_name)) < 0) { msg("can't open master pty"); return ERRO; } strcpy(slave_name, pts_name); /* return name of slave */ /* /printf("\npty_fork: %d %s", fdm, pts_name); */ pipe(pipe_out); pipe(pipe_err); if ( (pid = fork()) < 0) { msg("Can not fork"); return(ERRO); } else if (pid == 0) { /* child */ /* /sleep(30); */ if (setsid() < 0) { msg("setsid error"); exit(1); } /* SVR4 acquires controlling terminal on open() */ if ( (fds = ptys_open(fdm, pts_name)) < 0) { printf("%d %s" , fdm, pts_name); msg("can't open slave pty"); exit(1); } close(fdm); /* all done with master in child */ /* /printf("\nfdm: %d fds: %d\n", fdm, fds);fflush(stdin); */ #ifdef LINUX /* 44BSD way to acquire controlling terminal */ if (ioctl(fds, TIOCSCTTY, (char *) 0) < 0) { msg("TIOCSCTTY error"); return ERRO; } #endif if (tty_copy(fds) == ERRO) /* set slave terminal mode */ { msg("tty_copy error"); perror(" "); exit(1); } if (dup2(pipe_out[1], STDOUT_FILENO) != STDOUT_FILENO) { msg("dup2 error to stdout"); exit(1); } if (dup2(pipe_err[1], STDERR_FILENO) != STDERR_FILENO) { msg("dup2 error to stderr"); exit(1); } if (dup2(fds, STDIN_FILENO) != STDIN_FILENO) { msg("dup2 error to stdin"); exit(1); } if (pipe_out[1] > STDERR_FILENO) close(pipe_out[1]); if (pipe_err[1] > STDERR_FILENO) close(pipe_err[1]); if (fds > STDERR_FILENO) { close(fds); } close(pipe_out[0]); close(pipe_err[0]); return 0; /* child returns 0 just like fork() */ } else { /* parent */ *ptrfdm = fdm; /* return fd of master */ close(pipe_out[1]); close(pipe_err[1]); return(pid); /* parent returns pid of child */ } }
pid_t pty_fork2(int *ptrfdm, char *slave_name) { int fdm, fds; pid_t pid; char pts_name[20]; if ( (fdm = ptym_open(pts_name)) < 0) { msg("can't open master pty"); return ERRO; } strcpy(slave_name, pts_name); /* return name of slave */ /*/printf("\npty_fork2: %d %s", fdm, pts_name); */ if ( (pid = fork()) < 0) { msg("Can not fork"); return ERRO; } else if (pid == 0) { /* child */ /*/ sleep(30); */ if (setsid() < 0) { msg("setsid error"); exit(1); } /* SVR4 acquires controlling terminal on open() */ if ( (fds = ptys_open(fdm, pts_name)) < 0) { msg("can't open slave pty"); exit(1); } close(fdm); /* all done with master in child */ #ifdef LINUX /* 44BSD way to acquire controlling terminal */ if (ioctl(fds, TIOCSCTTY, (char *) 0) < 0) { msg("TIOCSCTTY error"); return ERRO; } #endif if (tty_copy(fds) == ERRO) exit(1); /* slave becomes stdin/stdout/stderr of child */ if (dup2(fds, STDOUT_FILENO) != STDOUT_FILENO || dup2(fds, STDERR_FILENO) != STDERR_FILENO || dup2(fds, STDIN_FILENO) != STDIN_FILENO ) { msg("dup2 error to slave"); exit(1); } if (fds > STDERR_FILENO) close(fds); return 0; /* child returns 0 just like fork() */ } else { /* parent */ *ptrfdm = fdm; /* return fd of master */ return(pid); /* parent returns pid of child */ } }