/* * Class: org_eclipse_cdt_utils_pty_PTY * Method: forkpty * Signature: ()I */ JNIEXPORT jstring JNICALL Java_org_eclipse_cdt_utils_pty_PTY_openMaster (JNIEnv *env, jobject jobj, jboolean console) { jfieldID fid; /* Store the field ID */ jstring jstr = NULL; int master = -1; char line[1024]; /* FIXME: Should be enough */ jclass cls; line[0] = '\0'; master = ptym_open(line); if (master >= 0) { if (console) { // turn off echo set_noecho(master); } /* Get a reference to the obj's class */ cls = (*env)->GetObjectClass(env, jobj); /* Set the master fd. */ fid = (*env)->GetFieldID(env, cls, "master", "I"); if (fid == NULL) { return NULL; } (*env)->SetIntField(env, jobj, fid, (jint)master); /* Create a new String for the slave. */ jstr = (*env)->NewStringUTF(env, line); } return jstr; }
int set_pty(char *pty_name) { int fd; if ((fd = open(pty_name, O_RDWR, 0)) == -1 || login_tty(fd) == -1) return (0); return (set_noecho(STDIN_FILENO)); }
/* * call-seq: * io.echo = flag * * Enables/disables echo back. * On some platforms, all combinations of this flags and raw/cooked * mode may not be valid. * * You must require 'io/console' to use this method. */ static VALUE console_set_echo(VALUE io, VALUE f) { conmode t; rb_io_t *fptr; int fd; GetOpenFile(io, fptr); fd = GetReadFD(fptr); if (!getattr(fd, &t)) rb_sys_fail(0); if (RTEST(f)) set_echo(&t, NULL); else set_noecho(&t, NULL); if (!setattr(fd, &t)) rb_sys_fail(0); return io; }
int set_pty(char *pty_name) { int fd; #if !defined(LISP_FEATURE_HPUX) && !defined(SVR4) fd = open("/dev/tty", O_RDWR, 0); if (fd >= 0) { ioctl(fd, TIOCNOTTY, 0); close(fd); } #endif if ((fd = open(pty_name, O_RDWR, 0)) == -1) return (-1); dup2(fd, 0); set_noecho(0); dup2(fd, 1); dup2(fd, 2); close(fd); return (0); }
int main(int argc, char *argv[]) { int fdm, c, ignoreeof, interactive, noecho, verbose; pid_t pid; char *driver, slave_name[20]; struct termios orig_termios; struct winsize size; interactive = isatty(STDIN_FILENO); ignoreeof = 0; noecho = 0; verbose = 0; driver = NULL; opterr = 0; /* don't want getopt() writing to stderr */ while ( (c = getopt(argc, argv, "d:einv")) != EOF) { switch (c) { case 'd': /* driver for stdin/stdout */ driver = optarg; break; case 'e': /* noecho for slave pty's line discipline */ noecho = 1; break; case 'i': /* ignore EOF on standard input */ ignoreeof = 1; break; case 'n': /* not interactive */ interactive = 0; break; case 'v': /* verbose */ verbose = 1; break; case '?': err_quit("unrecognized option: -%c", optopt); } } if (optind >= argc) err_quit("usage: pty [ -d driver -einv ] program [ arg ... ]"); if (interactive) { /* fetch current termios and window size */ if (tcgetattr(STDIN_FILENO, &orig_termios) < 0) err_sys("tcgetattr error on stdin"); if (ioctl(STDIN_FILENO, TIOCGWINSZ, (char *) &size) < 0) err_sys("TIOCGWINSZ error"); pid = pty_fork(&fdm, slave_name, &orig_termios, &size); } else pid = pty_fork(&fdm, slave_name, NULL, NULL); if (pid < 0) err_sys("fork error"); else if (pid == 0) { /* child */ if (noecho) set_noecho(STDIN_FILENO); /* stdin is slave pty */ if (execvp(argv[optind], &argv[optind]) < 0) err_sys("can't execute: %s", argv[optind]); } if (verbose) { fprintf(stderr, "slave name = %s\n", slave_name); if (driver != NULL) fprintf(stderr, "driver = %s\n", driver); } if (interactive && driver == NULL) { if (tty_raw(STDIN_FILENO) < 0) /* user's tty to raw mode */ err_sys("tty_raw error"); if (atexit(tty_atexit) < 0) /* reset user's tty on exit */ err_sys("atexit error"); } if (driver) do_driver(driver); /* changes our stdin/stdout */ loop(fdm, ignoreeof); /* copies stdin -> ptym, ptym -> stdout */ exit(0); }
pid_t exec_pty(const char *path, char *const argv[], char *const envp[], const char *dirpath, int channels[3], const char *pts_name, int fdm, int console) { int pipe2[2]; pid_t childpid; char *full_path; /* * We use pfind() to check that the program exists and is an executable. * If not pass the error up. Also execve() wants a full path. */ full_path = pfind(path, envp); if (full_path == NULL) { fprintf(stderr, "Unable to find full path for \"%s\"\n", (path) ? path : ""); return -1; } /* * Make sure we can create our pipes before forking. */ if (console && channels != NULL) { if (pipe(pipe2) < 0) { fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno)); free(full_path); return -1; } } childpid = fork(); if (childpid < 0) { fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno)); free(full_path); return -1; } else if (childpid == 0) { /* child */ chdir(dirpath); if (channels != NULL) { int fds; if (!console && setsid() < 0) { perror("setsid()"); return -1; } fds = ptys_open(fdm, pts_name); if (fds < 0) { fprintf(stderr, "%s(%d): returning due to error: %s\n", __FUNCTION__, __LINE__, strerror(errno)); return -1; } /* Close the read end of pipe2 */ if (console && close(pipe2[0]) == -1) { perror("close(pipe2[0]))"); } /* close the master, no need in the child */ close(fdm); if (console) { set_noecho(fds); if (setpgid(getpid(), getpid()) < 0) { perror("setpgid()"); return -1; } } /* redirections */ dup2(fds, STDIN_FILENO); /* dup stdin */ dup2(fds, STDOUT_FILENO); /* dup stdout */ if (console) { dup2(pipe2[1], STDERR_FILENO); /* dup stderr */ } else { dup2(fds, STDERR_FILENO); /* dup stderr */ } close(fds); /* done with fds. */ } /* Close all the fd's in the child */ { int fdlimit = sysconf(_SC_OPEN_MAX); int fd = 3; while (fd < fdlimit) close(fd++); } if (envp[0] == NULL) { execv(full_path, argv); } else { execve(full_path, argv, envp); } _exit(127); } else if (childpid != 0) { /* parent */ ioctl(fdm, I_PUSH, "ptem"); if (console) { set_noecho(fdm); } if (channels != NULL) { /* close the write end of pipe1 */ if (console && close(pipe2[1]) == -1) perror("close(pipe2[1])"); channels[0] = fdm; /* Input Stream. */ channels[1] = fdm; /* Output Stream. */ if (console) { /* stderr Stream. */ channels[2] = pipe2[0]; } else { channels[2] = fdm; } } free(full_path); return childpid; } free(full_path); return -1; /*NOT REACHED */ }
int main(int argc, char* argv[]) { int fdm, c, ignoreeof, interactive, noecho, verbose; pid_t pid; char* config; char slave_name[20]; struct termios orig_termios; struct winsize size; int flags; interactive = isatty(STDIN_FILENO); ignoreeof = 0; noecho = 0; verbose = 0; config = NULL; while ((c = getopt_long(argc, argv, "hVs:einv", long_options, NULL)) != EOF) { switch (c) { case 'h': printf("Usage: %s [options] config_file -- program [args ...]\n", argv[0]); printf("\t -h --help \t\tdisplay usage summary\n"); printf("\t -V --version \t\tdisplay version\n"); printf("\t -e --no-echo \t\tdisable echo\n"); printf("\t -i --ignore-eof \tignore EOF\n"); printf("\t -n --non-interactive \tforce non-interactive mode\n"); printf("\t -v --verbose \t\tverbose mode\n"); return EXIT_SUCCESS; case 'V': printf("irpty %s\n", VERSION); return EXIT_SUCCESS; case 'e': noecho = 1; break; case 'i': ignoreeof = 1; break; case 'n': interactive = 0; break; case 'v': verbose = 1; break; case '?': die("unrecognized option: -%c\n", optopt); } } if (optind + 1 >= argc) die("usage: irpty [ -s server -einv ] cfg program [ arg ... ]\n"); config = argv[optind++]; if ((lsock = lirc_init("irpty", 1)) == -1) exit(EXIT_FAILURE); flags = fcntl(lsock, F_GETFL, 0); if (flags != -1) fcntl(lsock, F_SETFL, flags | FASYNC | O_NONBLOCK); if (lirc_readconfig(config, &lconfig, NULL) != 0) exit(EXIT_FAILURE); if (interactive) { if (tcgetattr(STDIN_FILENO, &orig_termios) < 0) die("tcgetattr error on stdin\n"); if (ioctl(STDIN_FILENO, TIOCGWINSZ, (char*)&size) < 0) die("TIOCGWINSZ error\n"); pid = pty_fork(&fdm, slave_name, &orig_termios, &size); } else { pid = pty_fork(&fdm, slave_name, NULL, NULL); } if (pid < 0) { die("fork error\n"); } else if (!pid) { /* child */ if (noecho) set_noecho(STDIN_FILENO); /* stdin is slave pty */ if (execvp(argv[optind], &argv[optind]) < 0) die("can't execute: %s\n", argv[optind]); } if (verbose) { fprintf(stderr, "slave name = %s\n", slave_name); if (config) fprintf(stderr, "config file = %s\n", config); } if (interactive) { if (tty_raw(STDIN_FILENO) < 0) /* user's tty to raw mode */ die("tty_raw error"); if (atexit(tty_atexit) < 0) /* reset user's tty on exit */ die("atexit error"); } copy_loop(fdm, ignoreeof); exit(0); }
/* Open up UART port and begin redirect input/output from login shell. */ void *ttyS(char *port) { struct termios term,stdIn,stdOut; fd_set rset; int fd, maxfd,selectval,nbytes; int sd=STDIN_FILENO; char buf[TRANSFER_BUFFER_SIZE]; char devname[40]; int ch,lastchar; /* connect to tty device write port */ sprintf(devname,"/dev/tty%s",port); if( (fd=open(devname,O_RDWR | O_NOCTTY |O_NDELAY)) < 0 ){ fprintf(stderr,"can't open device %s\n",devname); return NULL; } #ifdef DEBUG fprintf(stderr,"%s opened, fd=%d\n",devname,fd); #endif hndl =fd; fcntl(fd,F_SETFL,O_NONBLOCK); /* set non-blocking mode */ if (tcgetattr(fd,&term) ){ fprintf(stderr,"Can't get device attr.\n"); close(fd); return NULL; } saved_termios = term; //save original termios if(signal(SIGINT,sig_catcher) == SIG_ERR) { fprintf(stderr,"Can't install signal SIGINT handler\n"); close(fd); return NULL; } if(signal(SIGTERM,sig_catcher) == SIG_ERR) { fprintf(stderr,"Can't install signal SIGTERM handler\n"); close(fd); return NULL; } if(signal(SIGHUP,sig_catcher) == SIG_ERR) { fprintf(stderr,"Can't install signal SIGHUP handler\n"); close(fd); return NULL; } /* make the following file descriptors raw */ if (isatty (0)) { tcgetattr(0, &original_stdin); tcgetattr(1, &original_stdout); tty_modified = 1; stdIn = original_stdin; stdOut = original_stdout; MAKE_TTY_RAW(0, original_stdin); MAKE_TTY_RAW(1, original_stdout); } cfmakeraw(&term); /* raw mode */ atexit(cleanup); cfsetispeed(&term,B115200); //B9600); cfsetospeed(&term,B115200); //B9600); tcsetattr(fd,TCSANOW,&term); #ifdef DEBUG if (!tcgetattr(fd,&term) ){ fprintf(stderr,"tty: ispeed=%d, ospeed = %d\n",\ cfgetispeed(&term),cfgetospeed(&term)); } #endif set_noecho(fd); set_noecho(STDOUT_FILENO); #ifdef DEBUG if (!tcgetattr(STDIN_FILENO,&stdIn) ){ fprintf(stderr,"STDIN: ispeed=%d, ospeed = %d\n",\ cfgetispeed(&stdIn),cfgetospeed(&stdIn)); } #endif tcflush(fd,TCIOFLUSH); maxfd = ((sd > fd) ? sd:fd)+1; /* * Loop to read/write between remote client and host until 'esc q' is received. */ for (;;) { FD_ZERO(&rset); FD_SET (STDIN_FILENO, &rset); FD_SET (fd, &rset); selectval = select (maxfd, &rset, NULL, NULL, NULL); if (selectval == -1) { syslog (LOG_ERR, "select(): %m"); break; } /* * if client is readable, read from client, write to destination */ if (FD_ISSET (STDIN_FILENO, &rset)) { ch = getch(); if ((lastchar==0x1b) && (ch=='q')) { #ifdef DEBUG fprintf(stderr,"Esc-q received\n"); #endif break; } write(fd,&ch,1); lastchar = ch; #ifdef DEBUG if(lastchar == 0x1b)fprintf(stderr,"0x1b char received\n"); #endif } /* * If destination is readable, read from destination, write to client. */ if (FD_ISSET (fd, &rset)) { nbytes = read(fd, &buf, TRANSFER_BUFFER_SIZE); if (nbytes <= 0) { fprintf(stderr,"server close connection\n"); break; } if (write (STDOUT_FILENO, &buf, nbytes) != nbytes) syslog(LOG_ERR, "Error on write %m"); nbytes -= nbytes; } } cleanup(); #ifdef DEBUG fprintf(stderr,"thread exit\n"); #endif tcsetattr(hndl,TCSANOW,&saved_termios); return NULL; }