static pid_t frkpty(int *masterin, char *slavename) { int master, slave; pid_t chldp; if (openpty(&master, &slave, slavename, NULL, NULL) < 0) { _exit(1); } chldp=fork(); if (chldp == -1) { _exit(1); } else if (chldp == 0) { close(master); setsid(); if (ioctl(slave, TIOCSCTTY) < 0) { /*_exit(1);*/ } /* dont really care what fails here */ dup2(slave, 0); dup2(slave, 1); dup2(slave, 2); return 0; } else { *masterin=master; close(slave); return chldp; } exit(1); }
static int open_device(uart_ctx_t* ctx, char* name) { int flags; int fd; #ifdef HAVE_PTY if (strcmp(name, "pty") == 0) { int fd1; char slave_name[UART_MAX_DEVICE_NAME]; if (openpty(&fd,&fd1,slave_name,NULL,NULL) < 0) return -1; INFOF("slave name = %s", slave_name); strcpy(name, slave_name); // close(fd1); // ??? } else #endif { if ((fd = open(name, O_RDWR|O_NDELAY|O_NOCTTY)) < 0) return -1; } flags = fcntl(fd, F_GETFL, 0); fcntl(fd, F_SETFL, flags | O_NONBLOCK); // non-blocking!!! tcflush(fd, TCOFLUSH); tcflush(fd, TCIFLUSH); ctx->fd = fd; DEBUGF("open_device: %d", ctx->fd); return fd; }
/* * Get device node names for the master and slave end of a free pseudo * terminal. We don't want to replicate the entire openpty(3) logic here, so * start by letting openpty(3) do the work for us. We make the assumption that * nobody snatches the pair while we are running. */ static void get_names(char pname[PATH_MAX], char tname[PATH_MAX]) { int len, masterfd, slavefd; if (openpty(&masterfd, &slavefd, tname, NULL, NULL) < 0) e(300); /* * openpty(3) gives us only the slave name, but we also need the master * name. */ strlcpy(pname, tname, PATH_MAX); len = strlen(_PATH_DEV); if (strncmp(pname, _PATH_DEV, len)) e(301); /* If this fails, this test needs to be updated. */ if (pname[len] != 't') e(302); pname[len] = 'p'; test_comm(masterfd, slavefd); if (close(masterfd) < 0) e(303); if (close(slavefd) < 0) e(304); }
int forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp) { int master, slave, pid; if (openpty(&master, &slave, name, termp, winp) == -1) return (-1); switch (pid = fork()) { case -1: return (-1); case 0: /* * child */ (void) close(master); login_tty(slave); return (0); } /* * parent */ *amaster = master; (void) close(slave); return (pid); }
int forkpty (int *amaster, char *name, const struct termios *termp, const struct winsize *winp) { int master, slave, pid; if (openpty (&master, &slave, name, termp, winp) == -1) return -1; switch (pid = fork ()) { case -1: close (master); close (slave); return -1; case 0: /* Child. */ close (master); if (login_tty (slave)) _exit (1); return 0; default: /* Parent. */ *amaster = master; close (slave); return pid; } }
/* * For some reason, openpty() in glibc sometimes doesn't * work at boot-time. It must be a bug with old-style pty * names, as new-style (/dev/pts) is not available at that * point. So, we find a pty/tty pair ourself if openpty() * fails for whatever reason. */ int findpty(int *master, int *slave, char *name) { char pty[16]; char tty[16]; int i, j; int found; if (openpty(master, slave, name, NULL, NULL) >= 0) return 0; found = 0; for (i = 'p'; i <= 'z'; i++) { for (j = '0'; j <= 'f'; j++) { if (j == '9' + 1) j = 'a'; sprintf(pty, "/dev/pty%c%c", i, j); sprintf(tty, "/dev/tty%c%c", i, j); if ((*master = open(pty, O_RDWR|O_NOCTTY)) >= 0) { *slave = open(tty, O_RDWR|O_NOCTTY); if (*slave >= 0) { found = 1; break; } } } if (found) break; } if (!found) return -1; if (name) strcpy(name, tty); return 0; }
static gboolean create_tty(const char *modem_path) { int master, slave; char pty_name[256]; GIOChannel *server_io; if (modem_path == NULL) return FALSE; if (openpty(&master, &slave, pty_name, NULL, NULL) < 0) return FALSE; set_raw_mode(slave); g_print("new pty is created at %s\n", pty_name); server_io = g_io_channel_unix_new(master); server = g_at_server_new(server_io); if (server == NULL) { g_io_channel_shutdown(server_io, FALSE, NULL); g_io_channel_unref(server_io); return FALSE; } g_io_channel_unref(server_io); return TRUE; }
PRIVATE static bool Pic::prepare_irq(int sockets[2]) { struct termios tt; if (openpty(&sockets[0], &sockets[1], NULL, NULL, NULL)) { perror("openpty"); return false; } if (tcgetattr(sockets[0], &tt) < 0) { perror("tcgetattr"); return false; } cfmakeraw(&tt); if (tcsetattr(sockets[0], TCSADRAIN, &tt) < 0) { perror("tcsetattr"); return false; } fflush(NULL); return true; }
int allocate_pty(int *master, int *slave) { #if defined(HAVE_OPENPTY) || (defined(HAVE_DECL_OPENPTY) && HAVE_DECL_OPENPTY != 0) if(openpty(master, slave, NULL, NULL, NULL)) return -1; #else /* STREAMS... sigh */ char *slavename; extern char *ptsname(); *master = open("/dev/ptmx", O_RDWR); /* open master */ if(*master < 0) return -1; grantpt(*master); /* change permission of slave */ unlockpt(*master); /* unlock slave */ slavename = ptsname(*master); /* get name of slave */ *slave = open(slavename, O_RDWR); /* open slave */ if(*slave < 0) { close(*master); *master = -1; return -1; } /* This is a bit backwards as we using the PTY backwards. * We want to make the master a tty instead of the slave... odd, I know. */ ioctl(*master, I_PUSH, "ptem"); /* push ptem */ ioctl(*master, I_PUSH, "ldterm"); /* push ldterm*/ #endif if(eventer_set_fd_nonblocking(*master)) return -1; noitL(noit_debug, "allocate_pty -> %d,%d\n", *master, *slave); return 0; }
explicit GnuplotPty(bool debug_messages) : pty_fn(), pty_fh(NULL), master_fd(-1), slave_fd(-1) { // adapted from http://www.gnuplot.info/files/gpReadMouseTest.c if(0 > openpty(&master_fd, &slave_fd, NULL, NULL, NULL)) { perror("openpty"); throw std::runtime_error("openpty failed"); } char pty_fn_buf[1024]; if(ttyname_r(slave_fd, pty_fn_buf, 1024)) { perror("ttyname_r"); throw std::runtime_error("ttyname failed"); } pty_fn = std::string(pty_fn_buf); if(debug_messages) { std::cerr << "fn=" << pty_fn << std::endl; } // disable echo struct termios tios; if(tcgetattr(slave_fd, &tios) < 0) { perror("tcgetattr"); throw std::runtime_error("tcgetattr failed"); } tios.c_lflag &= ~(ECHO | ECHONL); if(tcsetattr(slave_fd, TCSAFLUSH, &tios) < 0) { perror("tcsetattr"); throw std::runtime_error("tcsetattr failed"); } pty_fh = fdopen(master_fd, "r"); if(!pty_fh) throw std::runtime_error("fdopen failed"); }
int qemu_openpty_raw(int *aslave, char *pty_name) { #ifndef __ANDROID__ int amaster; struct termios tty; #endif #if defined(__OpenBSD__) || defined(__DragonFly__) char pty_buf[PATH_MAX]; #define q_ptsname(x) pty_buf #elif defined(__ANDROID__) #else char *pty_buf = NULL; #define q_ptsname(x) ptsname(x) #endif #ifdef __ANDROID__ return -1; #else if (openpty(&amaster, aslave, pty_buf, NULL, NULL) < 0) { return -1; } /* Set raw attributes on the pty. */ tcgetattr(*aslave, &tty); cfmakeraw(&tty); tcsetattr(*aslave, TCSAFLUSH, &tty); if (pty_name) { strcpy(pty_name, q_ptsname(amaster)); } return amaster; #endif //__ANDROID__ }
static UInt OpenPty( int *pty, int *tty ) { #if HAVE_OPENPTY /* openpty is available on OpenBSD, NetBSD and FreeBSD, Mac OS X, Cygwin, Interix, OSF/1 4 and 5, and glibc (since 1998), and hence on most modern Linux systems. See also: http://www.gnu.org/software/gnulib/manual/html_node/openpty.html */ return (openpty(pty, tty, NULL, NULL, NULL) < 0); #else Char ttyname[32]; Char ptyname[32]; /* construct the name of the pseudo terminal */ strcpy( ttyname, SYS_TTYDEV ); strcpy( ptyname, SYS_PTYDEV ); if ( GetMasterPty(pty, ttyname, ptyname) ) { Pr( "open master failed\n", 0L, 0L ); return 1; } *tty = open( ttyname, O_RDWR, 0 ); if ( *tty < 0 ) { Pr( "open slave failed\n", 0L, 0L ); close(*pty); return 1; } return 0; #endif }
int make_new_session(int new_sock_fd) { int ret, sv[2], use_socket_pair=1; set_useful_sock_opt(new_sock_fd); snd_iac(new_sock_fd,DONT, TELOPT_ECHO); snd_iac(new_sock_fd,DO, TELOPT_LFLOW); snd_iac(new_sock_fd,WILL, TELOPT_ECHO); snd_iac(new_sock_fd,WILL, TELOPT_SGA); if (use_socket_pair) { ret=socketpair(AF_UNIX, SOCK_STREAM, 0, sv); } else { ret=openpty(&(sv[0]), &(sv[1]), NULL, NULL, NULL); tty_cfg(fd_pty_slave); } if (ret<0) { return ret; } fd_conn = new_sock_fd; set_fd_nonblock(fd_conn); fd_pty_master = sv[0]; fd_pty_slave = sv[1]; shell_thread_should_exit = 0; pthread_create(&the_shell_thread, NULL, the_shell_thread_func, NULL); return 0; }
wxString wxTerminal::StartTTY() { m_process = NULL; char __name[128]; memset(__name, 0, sizeof(__name)); int master(-1); m_slave = -1; if(openpty(&master, &m_slave, __name, NULL, NULL) != 0) return wxT(""); // disable ECHO struct termios termio; tcgetattr(master, &termio); termio.c_lflag = ICANON; termio.c_oflag = ONOCR | ONLRET; tcsetattr(master, TCSANOW, &termio); m_tty = wxString(__name, wxConvUTF8); m_tty = ptsname(master); // Start a listener on the tty m_dummyProcess = new UnixProcessImpl(this); static_cast<UnixProcessImpl*>(m_dummyProcess)->SetReadHandle (master); static_cast<UnixProcessImpl*>(m_dummyProcess)->SetWriteHandler(master); static_cast<UnixProcessImpl*>(m_dummyProcess)->SetPid(wxNOT_FOUND); static_cast<UnixProcessImpl*>(m_dummyProcess)->StartReaderThread(); return m_tty; }
/* Create a pseudo terminal for other process to use (as this program is using up the actual TTY) */ int create_pseudo_tty() { int amaster, aslave; int flags; if (openpty(&amaster, &aslave, NULL, NULL, NULL) == -1) { errlog("Error: Openpty failed - %m\n"); return -1; } /* Set to non blocking mode */ flags = fcntl(amaster, F_GETFL); flags |= O_NONBLOCK; fcntl(amaster, F_SETFL, flags); FILE *pseudo_save_file = fopen(pseudo_tty_save_file, "w+"); if (!pseudo_save_file) { errlog("Error: Unable to open the pseudo info file - %m\n"); return -1; } /* Save the name of the created pseudo tty in a text file for other processes to use */ if (fprintf(pseudo_save_file, "%s\n", ttyname(aslave)) == -1) { errlog("Error writing to the pseudo info file\n"); fclose(pseudo_save_file); return -1; } fclose(pseudo_save_file); if (set_tty(aslave) == -1) { errlog("Error: Slave TTY not set properly\n"); return -1; } return amaster; }
//------------pseudoPTY()--------------------------// //Create a psuedo terminal // //Return the path and name of the PTY port // //Returns a file descriptor for the pseudo terminal// //-------------------------------------------------// int pseudoTY(char** PTY) { //char *letters; int master; int slave; pid_t pid = openpty(&master,&slave,NULL,NULL,NULL);//Create a pseudo terminal //Use ttyname() on the file descriptor to find the name of the terminal //That is: slave name = ttyname(slave); if(pid == -1){//Openpty() failed perror("Openpty() Failed! :"); return pid; } if(pid == 0){//Openpty() successful (*PTY) = ttyname(slave); // Ensure that the echo is switched off struct termios orig_termios; if (tcgetattr (master, &orig_termios) < 0) { perror ("ERROR getting current terminal's attributes"); return -1; } orig_termios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); orig_termios.c_oflag &= ~(ONLCR); if (tcsetattr (master, TCSANOW, &orig_termios) < 0) { perror ("ERROR setting current terminal's attributes"); return -1; } return master; //Return the file descriptor } }
int open_master( char **rtn_name) /* RETURN name of slave pts */ { int master; int slave; static char slave_name[PTY_SIZE]; int status = openpty(&master, &slave, slave_name, 0, 0); if (status < 0) { log_err(errno, "open_master", "failed in openpty()"); return(-1); } close(slave); /* open_master has no way to return this, must return slave_name instead */ *rtn_name = slave_name; return(master); } /* END open_master() */
void try_tty() { int master, slave; char name[128] = "123"; struct termios *term; struct winsize *win; if ( ! openpty( &master, &slave, name, term, win ) ) { printf( "name: %s\n", name ); printf( "master: %d\n", master ); printf( "slave: %d\n", slave ); printf( "window row: %u\n", win->ws_row ); printf( "window column: %u\n", win->ws_col ); printf( "window xpixel: %u\n", win->ws_xpixel ); printf( "window ypixel: %u\n", win->ws_ypixel ); // getchar(); } ELSE_PRINT_ERROR int fd_pt; char buf[128]; if ( 0 < ( fd_pt = getpt() ) ) { grantpt( fd_pt ); printf( "ptsname==>name: %s\n", ptsname( fd_pt ) ); ptsname_r( fd_pt, buf, sizeof(buf) ); printf( "ptsname_r==>name: %s\n", buf ); write( fd_pt, "Hello tty !!", 13 ); // getchar(); } ELSE_PRINT_ERROR }
int forkpty(int* master, char* name, const termios* t, const winsize* ws) { int slave; if (openpty(master, &slave, name, t, ws) == -1) { return -1; } pid_t pid = fork(); if (pid == -1) { close(*master); close(slave); return -1; } if (pid == 0) { // Child. close(*master); if (login_tty(slave) == -1) { _exit(1); } return 0; } // Parent. close(slave); return pid; }
int do_pty(void) { struct kevent ev[4]; struct termios tt; int kq, massa, slave; char buf[1024]; tcgetattr(STDIN_FILENO, &tt); cfmakeraw(&tt); tt.c_lflag &= ~ECHO; if (openpty(&massa, &slave, NULL, &tt, NULL) < 0) err(1, "openpty"); if (fcntl(massa, F_SETFL, O_NONBLOCK) < 0) err(1, "massa: fcntl"); if (fcntl(slave, F_SETFL, O_NONBLOCK) < 0) err(1, "massa: fcntl"); if ((kq = kqueue()) == -1) err(1, "kqueue"); /* test the read from the slave works */ EV_SET(&ev[0], massa, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, NULL); EV_SET(&ev[1], massa, EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, NULL); EV_SET(&ev[2], slave, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, NULL); EV_SET(&ev[3], slave, EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, NULL); if (kevent(kq, ev, 4, NULL, 0, NULL) < 0) err(1, "slave: kevent add"); memset(buf, 0, sizeof buf); if (write(massa, " ", 1) != 1) err(1, "massa: write"); if (pty_check(kq, ev, 4, -massa, slave, massa, slave)) return (1); read(slave, buf, sizeof(buf)); if (pty_check(kq, ev, 4, -massa, -slave, massa, slave)) return (1); while (write(massa, buf, sizeof(buf)) > 0) continue; if (pty_check(kq, ev, 4, -massa, slave, -massa, slave)) return (1); read(slave, buf, 1); if (pty_check(kq, ev, 4, -massa, slave, massa, slave)) return (1); while (read(slave, buf, sizeof(buf)) > 0) continue; if (pty_check(kq, ev, 4, -massa, -slave, massa, slave)) return (1); return (0); }
int rpl_openpty (int *amaster, int *aslave, char *name, struct termios const *termp, struct winsize const *winp) { /* Cast away const, for implementations with weaker prototypes. */ return openpty (amaster, aslave, name, (struct termios *) termp, (struct winsize *) winp); }
int getpty(void) { int masterfd; if (openpty(&masterfd, &ptyslavefd, line, NULL, NULL)) { return -1; } return masterfd; }
static char *openmaster(int *master, int *slave) { int m, s; static char path[1024]; if (openpty(&m, &s, path, NULL, NULL) < 0) return NULL; *master = m; *slave = s; return path; }
static ERL_NIF_TERM allocate_pty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int master; int slave; char* name; openpty(&master, &slave, NULL, NULL, NULL); name = ttyname(slave); return enif_make_tuple2(env, enif_make_int(env, master), enif_make_string(env, name, ERL_NIF_LATIN1)); }
TEST(pty, bug_28979140) { // This test is to test a kernel bug, which uses a lock free ring-buffer to // pass data through a raw pty, but missing necessary memory barriers. cpu_set_t cpus; ASSERT_EQ(0, sched_getaffinity(0, sizeof(cpu_set_t), &cpus)); if (CPU_COUNT(&cpus) < 2) { GTEST_LOG_(INFO) << "This test tests bug happens only on multiprocessors."; return; } constexpr uint32_t TEST_DATA_COUNT = 200000; // 1. Open raw pty. int master; int slave; ASSERT_EQ(0, openpty(&master, &slave, nullptr, nullptr, nullptr)); termios tattr; ASSERT_EQ(0, tcgetattr(slave, &tattr)); cfmakeraw(&tattr); ASSERT_EQ(0, tcsetattr(slave, TCSADRAIN, &tattr)); // 2. Make master thread and slave thread running on different cpus: // master thread uses first available cpu, and slave thread uses other cpus. PtyReader_28979140_Arg arg; arg.main_cpu_id = -1; for (int i = 0; i < CPU_SETSIZE; i++) { if (CPU_ISSET(i, &cpus)) { arg.main_cpu_id = i; break; } } ASSERT_GE(arg.main_cpu_id, 0); // 3. Create thread for slave reader. pthread_t thread; arg.slave_fd = slave; arg.data_count = TEST_DATA_COUNT; arg.matched = true; ASSERT_EQ(0, pthread_create(&thread, nullptr, reinterpret_cast<void*(*)(void*)>(PtyReader_28979140), &arg)); CPU_ZERO(&cpus); CPU_SET(arg.main_cpu_id, &cpus); ASSERT_EQ(0, sched_setaffinity(0, sizeof(cpu_set_t), &cpus)); // 4. Send data to slave. uint32_t counter = 0; while (counter <= TEST_DATA_COUNT) { ASSERT_TRUE(android::base::WriteFully(master, &counter, sizeof(counter))); ASSERT_TRUE(arg.matched) << "failed at count = " << counter; counter++; } ASSERT_EQ(0, pthread_join(thread, nullptr)); ASSERT_TRUE(arg.finished); ASSERT_TRUE(arg.matched); close(master); }
int run_console (void) { int slave; int rc; rc = openpty (&master, &slave, pty_name, 0,0); printf ("pty name: %s\n", pty_name); close (slave); return master; }
/* c_openpty: unit -> (int * Unix.file_descr) */ CAMLprim value c_openpty() { int master,slave; value pair; if (openpty(&master,&slave,NULL,NULL,NULL) < 0) uerror("openpty", (value) 0); pair = alloc_tuple(2); Store_field(pair,0,Val_int(master)); Store_field(pair,1,Val_int(slave)); return pair; }
int GUCEF_pty_open(int *fdm, int *fds) { if ( -1 == openpty( fdm, fds, NULL, NULL, NULL ) ) { /* something went wrong, no pseudo terminals available? */ return 1; } return 0; }
static unsigned char *getpty(int *ptyfd) { static unsigned char name[32]; int ttyfd; if (openpty(ptyfd, &ttyfd, (char *)name, NULL, NULL) == 0) return(name); else return (NULL); }
void ezioDevice300::CreatePort(int &fd_master, int &fd_slave) { #if 0 struct termios tio; switch (baud_rate) { case 2400: cfsetospeed(&tio, B2400); cfsetispeed(&tio, B2400); break; default: throw ezioException(EZIOEX_INVALID_BAUD); } // Set input modes tio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | INPCK | ISTRIP | INLCR | IGNCR | ICRNL | IUCLC | IXON | IXANY | IXOFF | IMAXBEL); tio.c_iflag |= IGNPAR; // Set output modes tio.c_oflag &= ~(OPOST | OLCUC | ONLCR | OCRNL | ONOCR | ONLRET | OFILL | OFDEL | NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY); tio.c_oflag |= NL0 | CR0 | TAB0 | BS0 | VT0 | FF0; // Set control modes tio.c_cflag &= ~(CSIZE | PARENB | CRTSCTS | PARODD | HUPCL); tio.c_cflag |= CREAD | CS8 | CSTOPB | CLOCAL; // Set local modes tio.c_lflag &= ~(ISIG | ICANON | IEXTEN | ECHO | FLUSHO | PENDIN); tio.c_lflag |= NOFLSH; if (openpty(&fd_master, &fd_slave, tty, &tio, NULL) < 0) #endif char tty[1024]; if (openpty(&fd_master, &fd_slave, tty, NULL, NULL) < 0) throw ezioException(EZIOEX_EMUL_OPENPTY); printf("%s: created port: %s\n", name.c_str(), tty); }