bool start() { fdMaster = getpt(); if (fdMaster < 0) { LOGE("Error %d on getpt()", errno); return false; } if (unlockpt(fdMaster) != 0) { LOGE("Error %d on unlockpt()", errno); return false; } pid = fork(); if (pid < 0) { LOGE("fork failed for pty, error %d", errno); close(fdMaster); pid = 0; return false; } else if (pid) { // child started, now someone needs to periodically read from fdMaster // and write it to the terminal // this currently works through gui.cpp calling terminal_pty_read below g_pty_fd = fdMaster; return true; } else { int fdSlave = open(ptsname(fdMaster), O_RDWR); close(fdMaster); runSlave(fdSlave); } // we can't get here LOGE("impossible error in pty"); return false; }
static int pty_open_master (char *pty_name) { char *slave_name; int pty_master; #ifdef HAVE_POSIX_OPENPT pty_master = posix_openpt (O_RDWR); #elif HAVE_GETPT /* getpt () is a GNU extension (glibc 2.1.x) */ pty_master = getpt (); #elif IS_AIX strcpy (pty_name, "/dev/ptc"); pty_master = open (pty_name, O_RDWR); #else strcpy (pty_name, "/dev/ptmx"); pty_master = open (pty_name, O_RDWR); #endif if (pty_master == -1) return -1; if (grantpt (pty_master) == -1 /* Grant access to slave */ || unlockpt (pty_master) == -1 /* Clear slave's lock flag */ || !(slave_name = ptsname (pty_master))) /* Get slave's name */ { close (pty_master); return -1; } strcpy (pty_name, slave_name); return pty_master; }
int openpty(int* master, int* slave, char* name, const termios* t, const winsize* ws) { *master = getpt(); if (*master == -1) { return -1; } if (grantpt(*master) == -1 || unlockpt(*master) == -1) { close(*master); return -1; } char buf[32]; if (name == NULL) { name = buf; } if (ptsname_r(*master, name, sizeof(buf)) != 0) { close(*master); return -1; } *slave = open(name, O_RDWR|O_NOCTTY); if (*slave == -1) { close(*master); return -1; } if (t != NULL) { tcsetattr(*slave, TCSAFLUSH, t); } if (ws != NULL) { ioctl(*slave, TIOCSWINSZ, ws); } return 0; }
void pagemouse(Page *p, Point xy, int but) { Box *b; p = pagewhich(p, xy); if(p == nil) return; if(pagerefresh(p)) return; if(p->lay == nil) return; if(ptinrect(xy, p->vscrollr)){ pagescroll(p, but, FALSE); return; } if(ptinrect(xy, p->hscrollr)){ pagescroll(p, but, TRUE); return; } xy = getpt(p, xy); b = boxwhich(p->lay, xy); if(b && b->mouse) b->mouse(b, p, but); else if(but == 1) pageselect(p); }
int get_pty(Term *term) { /* do we need this here? */ /* extern char *ptsname(); */ int fd; char *ptydev; if((fd = getpt()) >= 0) { if(grantpt(fd) == 0 && unlockpt(fd) == 0) { ptydev = ptsname(fd); if((term->slave.sys = open(ptydev, O_RDWR | O_NOCTTY)) < 0) { fprintf(stderr, "Error opening slave pty: %m\n"); return -1; } fcntl(fd, F_SETFL, O_NDELAY); return fd; } close(fd); } fprintf(stderr, "Can't open a pseudo-tty\n"); return -1; }
int open_pty_pair(int *masterp, int *slavep) { int master, slave; char name[1024]; master = getpt(); if (master < 0) { return 0; } if (grantpt(master) < 0 || unlockpt(master) < 0) { close(master); return 0; } if (ptsname_r(master, name, sizeof(name)) < 0) { close(master); return 0; } slave = open(name, O_RDWR); if (slave < 0) { close(master); return 0; } *masterp = master; *slavep = slave; return 1; }
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 }
void testValues() { f = 2; int result = getpt(); //@ assert result >= -1; //@ assert f == 2; //@ assert vacuous: \false; }
TEST(stdlib, ttyname_r_ERANGE) { int fd = getpt(); ASSERT_NE(-1, fd); errno = 0; char buf[1]; ASSERT_EQ(ERANGE, ttyname_r(fd, buf, sizeof(buf))); ASSERT_EQ(ERANGE, errno); close(fd); }
TEST(stdlib, ttyname_r_EINVAL) { int fd = getpt(); ASSERT_NE(-1, fd); errno = 0; char* buf = NULL; ASSERT_EQ(EINVAL, ttyname_r(fd, buf, 128)); ASSERT_EQ(EINVAL, errno); close(fd); }
char *open_ptm(int *ptm) { if ((*ptm = getpt()) == -1) return NULL; if (grantpt(*ptm) == -1) return NULL; if (unlockpt(*ptm) == -1) return NULL; return ptsname(*ptm); }
TEST(stdlib, ttyname_r) { int fd = getpt(); ASSERT_NE(-1, fd); // ttyname_r returns "/dev/ptmx" for a pty. char name_r[128]; ASSERT_EQ(0, ttyname_r(fd, name_r, sizeof(name_r))); ASSERT_STREQ("/dev/ptmx", name_r); close(fd); }
/* Create pseudo tty master slave pair and set terminal attributes according to TERMP and WINP. Return handles for both ends in AMASTER and ASLAVE, and return the name of the slave end in NAME. */ int openpty (int *amaster, int *aslave, char *name, const struct termios *termp, const struct winsize *winp) { #ifdef PATH_MAX char _buf[PATH_MAX]; #else char _buf[512]; #endif char *buf = _buf; int master, slave; master = getpt (); if (master == -1) return -1; if (grantpt (master)) goto fail; if (unlockpt (master)) goto fail; if (pts_name (master, &buf, sizeof (_buf))) goto fail; slave = open (buf, O_RDWR | O_NOCTTY); if (slave == -1) { if (buf != _buf) free (buf); goto fail; } /* XXX Should we ignore errors here? */ if(termp) tcsetattr (slave, TCSAFLUSH, termp); if (winp) ioctl (slave, TIOCSWINSZ, winp); *amaster = master; *aslave = slave; if (name != NULL) strcpy (name, buf); if (buf != _buf) free (buf); return 0; fail: close (master); return -1; }
static void pageselect1(Page *p) /* when called, button 1 is down */ { Point mp, npos, opos; int b, scrled, x, y; b = mouse->buttons; mp = mousectl->xy; opos = getpt(p, mp); do{ x = y = 0; if(mp.x < p->r.min.x) x -= p->r.min.x-mp.x; else if(mp.x > p->r.max.x) x += mp.x-p->r.max.x; if(mp.y < p->r.min.y) y -= (p->r.min.y-mp.y)*Panspeed; else if(mp.y > p->r.max.y) y += (mp.y-p->r.max.y)*Panspeed; scrled = pagescrollxy(p, x, y); npos = getpt(p, mp); if(opos.y < npos.y){ p->top = opos; p->bot = npos; }else{ p->top = npos; p->bot = opos; } pageredraw(p); if(scrled == TRUE) scrsleep(100); else readmouse(mousectl); mp = mousectl->xy; }while(mousectl->buttons == b); }
static int alloc_func_pty(struct ptydev *pty) { FILE *master, *slave; int master_fd, slave_fd; #if defined(HAVE_OPENPTY) || defined(HAVE_UNIX98_FUNCS) #if defined(HAVE_UNIX98_FUNCS) char *pts_name; #endif int ret = 1; #endif #if defined(HAVE_OPENPTY) || defined(HAVE_UNIX98_FUNCS) # if defined(HAVE_UNIX98_FUNCS) # if defined(HAVE_POSIX_OPENPT) master_fd = posix_openpt(O_RDWR|O_NOCTTY); if(master_fd == -1) SYS_ERR("posix_openpt", NULL, error); # elif defined(HAVE_GETPT) master_fd = getpt(); if(master_fd == -1) SYS_ERR("getpt", NULL, error); # else master_fd = open("/dev/ptmx", O_RDWR|O_NOCTTY); if(master_fd == -1) SYS_ERR("open", "/dev/ptmx", error); # endif if(grantpt(master_fd) == -1) SYS_ERR("grantpt", NULL, error); if(unlockpt(master_fd) == -1) SYS_ERR("unlockpt", NULL, error); pts_name = ptsname(master_fd); if(!pts_name) SYS_ERR("ptsname", NULL, error); slave_fd = open(pts_name, O_RDWR|O_NOCTTY); if(slave_fd == -1) SYS_ERR("open", pts_name, error); # else if(openpty(&master_fd, &slave_fd, NULL, NULL, NULL) == -1) SYS_ERR("openpty", NULL, error); # endif master = fdopen(master_fd, "r+"); if(!master) SYS_ERR("fdopen", "fdopening master_fd", error); slave = fdopen(slave_fd, "r+"); if(!slave) SYS_ERR("fdopen", "fdopening slave_fd", error); pty->type = FUNC_PTY; pty->master = master; pty->slave = slave; error: return ret; #else return 0; #endif }
/* * _vte_pty_getpt: * @error: a location to store a #GError, or %NULL * * Opens a file descriptor for the next available PTY master. * Sets the descriptor to blocking mode! * * Returns: a new file descriptor, or %-1 on failure */ static int _vte_pty_getpt(GError **error) { int fd, flags, rv; #if defined(HAVE_POSIX_OPENPT) fd = posix_openpt(O_RDWR | O_NOCTTY); #elif defined(HAVE_GETPT) /* Call the system's function for allocating a pty. */ fd = getpt(); #else /* Try to allocate a pty by accessing the pty master multiplex. */ fd = open("/dev/ptmx", O_RDWR | O_NOCTTY); if ((fd == -1) && (errno == ENOENT)) { fd = open("/dev/ptc", O_RDWR | O_NOCTTY); /* AIX */ } #endif if (fd == -1) { g_set_error (error, VTE_PTY_ERROR, VTE_PTY_ERROR_PTY98_FAILED, "%s failed: %s", "getpt", g_strerror(errno)); return -1; } rv = fcntl(fd, F_GETFL, 0); if (rv < 0) { int errsv = errno; g_set_error(error, VTE_PTY_ERROR, VTE_PTY_ERROR_PTY98_FAILED, "%s failed: %s", "fcntl(F_GETFL)", g_strerror(errno)); close(fd); errno = errsv; return -1; } /* Set it to blocking. */ /* FIXMEchpe: why?? vte_terminal_set_pty does the inverse... */ flags = rv & ~(O_NONBLOCK); rv = fcntl(fd, F_SETFL, flags); if (rv < 0) { int errsv = errno; g_set_error(error, VTE_PTY_ERROR, VTE_PTY_ERROR_PTY98_FAILED, "%s failed: %s", "fcntl(F_SETFL)", g_strerror(errno)); close(fd); errno = errsv; return -1; } return fd; }
int main() { char buffer[200]; int devfilefd, fd, i; float elevation, azimuth; readconfig(); /* open the pseudo terminal device */ fd=getpt(); if (fd<0) { fprintf(stderr, "Unable to open serial line!\n"); return -1; } unlockpt(fd); /* write the device file */ devfilefd = open(PSEUDODEVICEFILE, O_WRONLY|O_CREAT, 0666); write(devfilefd, (char*)ptsname(fd), strlen((char*)ptsname(fd))); close(devfilefd); /* open the fodtrack device */ openfodtrack(fodtrackdev); /* print informations about the devices */ printf("Using %s as pseudo terminal device.\n", ptsname(fd)); printf("Using %s as port for the fodtrack device.\n", fodtrackdev); /* going for the background */ daemon(0,0); /* Main loop - reads from the device, and sets the antenna on the output */ for(;;) { usleep(100); i=read(fd, buffer, 199); if(i>0) { sscanf(buffer, "AZ%f EL%f", &azimuth, &elevation); /*printf("New Data:\nElevation: %f\nAzimuth: %f\n\n", elevation, azimuth);*/ setElevation(elevation); setAzimuth(azimuth); } } }
void CPseudoTerminal::CreatePTY() { #if defined(HAVE_GETPT) && defined(HAVE_PTSNAME) // 1: UNIX98: preferred way int pt = getpt(); if (pt == -1) throw Exceptions::CExOpenTerm(errno); m_iPTYFD = pt; m_TTYName = ptsname(m_iPTYFD); return; #elif defined(HAVE_OPENPTY) // 2: BSD interface // More preferred than the linux hacks char name[30]; int master_fd, slave_fd; if (openpty(&master_fd, &slave_fd, name, 0L, 0L) != -1) { m_TTYName = name; name[5]='p'; close(slave_fd); // We don't need this yet // Yes, we do. m_iPTYFD = master_fd; return; } throw Exceptions::CExOpenTerm(errno); #else // 4: Open terminal device directly // 4.1: Try /dev/ptmx first. (Linux w/ Unix98 PTYs, Solaris) m_iPTYFD = open("/dev/ptmx", O_RDWR); if (m_iPTYFD >= 0) { #ifdef HAVE_PTSNAME m_TTYName = ::ptsname(m_iPTYFD); return; #elif defined (TIOCGPTN) int ptyno; if (ioctl(m_iPTYFD, TIOCGPTN, &ptyno) == 0) { m_TTYName = "/dev/pts/" + ptyno); return; }
TEST(stdlib, pty_smoke) { // getpt returns a pty with O_RDWR|O_NOCTTY. int fd = getpt(); ASSERT_NE(-1, fd); // grantpt is a no-op. ASSERT_EQ(0, grantpt(fd)); // ptsname_r should start "/dev/pts/". char name_r[128]; ASSERT_EQ(0, ptsname_r(fd, name_r, sizeof(name_r))); name_r[9] = 0; ASSERT_STREQ("/dev/pts/", name_r); close(fd); }
int tty_master(struct lt_config_app *cfg) { int mfd; if ((mfd = getpt()) < 0) { perror("getpt failed"); return -1; } if (unlockpt(mfd)) { perror("unlockpt failed"); return -1; } PRINT_VERBOSE(cfg, 1, "pty master opened succesfully\n"); return mfd; }
/* * Allocate pseudo tty, returns master side fd. * Stores slave name in the first arg(must be large enough). */ int pty_open(char *sl_name) { int mr_fd; #if defined (HAVE_GETPT) && defined (HAVE_GRANTPT) && defined (HAVE_UNLOCKPT) && defined (HAVE_PTSNAME) char *ptyname; if((mr_fd=getpt()) < 0) return -1; if(grantpt(mr_fd) != 0) return -1; if(unlockpt(mr_fd) != 0) return -1; if ((ptyname = (char*)ptsname(mr_fd)) == NULL) return -1; strcpy(sl_name, ptyname); return mr_fd; #else char ptyname[] = "/dev/ptyXY"; char ch[] = "pqrstuvwxyz"; char digit[] = "0123456789abcdefghijklmnopqrstuv"; int l, m; /* This algorithm should work for almost all standard Unices */ for(l=0; ch[l]; l++ ) { for(m=0; digit[m]; m++ ) { ptyname[8] = ch[l]; ptyname[9] = digit[m]; /* Open the master */ if( (mr_fd=open(ptyname, O_RDWR)) < 0 ) continue; /* Check the slave */ ptyname[5] = 't'; if( (access(ptyname, R_OK | W_OK)) < 0 ){ close(mr_fd); ptyname[5] = 'p'; continue; } strcpy(sl_name,ptyname); return mr_fd; } } return -1; #endif }
static int getpty(char *line) { int p; p = getpt(); if (p < 0) { DEBUG_OUT("getpty(): couldn't get pty\n"); close(p); return -1; } if (grantpt(p)<0 || unlockpt(p)<0) { DEBUG_OUT("getpty(): couldn't grant and unlock pty\n"); close(p); return -1; } DEBUG_OUT("getpty(): got pty %s\n",ptsname(p)); strcpy(line, (const char*)ptsname(p)); return(p); }
void pagedoubleclick(Page *p) { Point xy; Line *l; Box *b; xy = getpt(p, mouse->xy); l = linewhich(p->lay, xy); if(l==nil || l->hastext==FALSE) return; if(xy.x<l->boxes->r.min.x && hasbrk(l->state)){ /* beginning of line? */ p->top = l->boxes->r.min; if(l->next && !hasbrk(l->next->state)){ for(l=l->next; l->next!=nil; l=l->next) if(hasbrk(l->next->state)) break; } p->bot = l->lastbox->r.max;; }else if(xy.x>l->lastbox->r.max.x && hasbrk(l->next->state)){ /* end of line? */ p->bot = l->lastbox->r.max; if(!hasbrk(l->state) && l->prev!=nil){ for(l=l->prev; l->prev!=nil; l=l->prev) if(hasbrk(l->state)) break; } p->top = l->boxes->r.min; }else{ b = pttobox(l, xy); if(b!=nil && b->i->tag==Itexttag){ p->top = b->r.min; p->bot = b->r.max; } } p->top.y += 2; p->bot.y -= 2; pageredraw(p); }
static int _pty_getpt(void) { int fd, flags; #ifdef HAVE_GETPT /* Call the system's function for allocating a pty. */ fd = getpt(); #elif defined(HAVE_POSIX_OPENPT) fd = posix_openpt(O_RDWR | O_NOCTTY); #else /* Try to allocate a pty by accessing the pty master multiplex. */ fd = open("/dev/ptmx", O_RDWR | O_NOCTTY); if ((fd == -1) && (errno == ENOENT)) { fd = open("/dev/ptc", O_RDWR | O_NOCTTY); /* AIX */ } #endif /* Set it to blocking. */ flags = fcntl(fd, F_GETFL); flags &= ~(O_NONBLOCK); fcntl(fd, F_SETFL, flags); return fd; }
JNIEXPORT jint JNICALL Java_link_kjr_SimpleTerminal_MainActivity_get_1pts(JNIEnv *env, jclass type) { master_terminal_fd = getpt(); __android_log_print(ANDROID_LOG_INFO,APPNAME,"running"); __android_log_print(ANDROID_LOG_INFO,APPNAME,"ptsname:%s, pt:%d",ptsname(master_terminal_fd), master_terminal_fd); pid_t pid=fork(); __android_log_print(ANDROID_LOG_INFO,APPNAME,"pid:%d",pid); if(pid<0){ __android_log_print(ANDROID_LOG_INFO,APPNAME,"could not fork"); } if(pid==0){ setsid(); unlockpt(master_terminal_fd); grantpt(master_terminal_fd); int slave_terminal=open(ptsname(master_terminal_fd),O_RDWR); ioctl(slave_terminal, TIOCSCTTY, 0); dup2(slave_terminal, 0); dup2(slave_terminal, 1); dup2(slave_terminal, 2); __android_log_print(ANDROID_LOG_INFO,APPNAME,"will now start shell"); int ret=execl(strdup("/system/bin/sh"),strdup("/system/bin/sh"),(char*)0); __android_log_print(ANDROID_LOG_INFO,APPNAME,"this code should not be reached, ret:%d errno:%s",ret,strerror(errno)); exit(-1); } else { /* sleep(5); unsigned char h[500]; char* msg=strdup("ps\nls\n");write(master_terminal_fd,msg,strlen(msg)); /**/ } }
int OpenPTY(char **ttyn) { register int f; char *m, *ptsname(); int unlockpt (int), grantpt (int); #if defined(HAVE_GETPT) && defined(linux) int getpt (void); #endif void (*sigcld)(int); strncpy(PtyName, "/dev/ptmx", 32); #if defined(HAVE_GETPT) && defined(linux) if ((f = getpt()) == -1) #else if ((f = open(PtyName, O_RDWR | O_NOCTTY)) == -1) #endif return -1; /* * SIGCHLD set to SIG_DFL for grantpt() because it fork()s and * exec()s pt_chmod */ sigcld = signal(SIGCHLD, SIG_DFL); if ((m = ptsname(f)) == NULL || grantpt(f) || unlockpt(f)) { signal(SIGCHLD, sigcld); close(f); return -1; } signal(SIGCHLD, sigcld); strncpy(TtyName, m, sizeof(TtyName)); initmaster(f); *ttyn = TtyName; return f; }
void pagetype(Page *p, Rune r, Point xy) { Box *b; int x, y; p = pagewhich(p, xy); if(p == nil) return; if(pagerefresh(p)) return; if(p->lay == nil) return; /* text field? */ xy = getpt(p, xy); b = boxwhich(p->lay, xy); if(b && b->key){ b->key(b, p, r); return; } /* ^H: same as 'Back' */ if(r == 0x08){ wingohist(p->w, FALSE); return; } x = 0; y = 0; switch(r){ case Kleft: x -= Dx(p->r)/2; break; case Kright: x += Dx(p->r)/2; break; case Kdown: case Kscrollonedown: y += Dy(p->r)/2; break; case Kpgdown: y += Dy(p->r); break; case Kup: case Kscrolloneup: y -= Dy(p->r)/2; break; case Kpgup: y -= Dy(p->r); break; case Khome: y -= Dy(p->lay->r); /* force p->pos.y = 0 */ break; case Kend: y = Dy(p->lay->r) - Dy(p->r); break; default: return; } if(pagescrollxy(p, x, y)) pageredraw(p); }
/* Changed the argv0 and execlp stuff similar to rxvt-2.18. * Command is ignored as parameter. Matthias */ int run_command(unsigned char *command,unsigned char **argv) { int ptyfd=-1; int uid, gid; int grantpty=1; unsigned char *s3, *s4; int i; int width, height; #ifndef SVR4 static char ptyc3[] = "pqrstuvwxyz"; static char ptyc4[] = "0123456789abcdef"; #endif /* First find a master pty that we can open. */ #if __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1 ptyfd = getpt(); if (ptyfd < 0) { error("Can't open a pseudo teletype"); return(-1); } if (grantpt(ptyfd) < 0 || unlockpt(ptyfd) < 0) { close(ptyfd); error("Can't grantpt/unlockpt a pseudo teletype"); return(-1); } ttynam = ptsname(ptyfd); if (ttynam == 0) { close(ptyfd); error("Pseudo teletype has no name"); return(-1); } fcntl(ptyfd,F_SETFL,O_NDELAY); grantpty = 0; #else #ifdef TIOCGPTN strcpy(ptynam,"/dev/ptmx"); strcpy(ttynam,"/dev/pts/"); ptyfd = open(ptynam,O_RDWR); if (ptyfd >= 0) // got the master pty { int ptyno; if (ioctl(ptyfd, TIOCGPTN, &ptyno) == 0) { struct stat sbuf; sprintf(ttynam,"/dev/pts/%d",ptyno); if (stat(ttynam,&sbuf) == 0 && S_ISCHR(sbuf.st_mode)) grantpty = 0; else { close(ptyfd); ptyfd = -1; } } else { close(ptyfd); ptyfd = -1; } } #endif if (ptyfd < 0) { #ifdef SVR4 ptyfd = open("/dev/ptmx",O_RDWR); if (ptyfd < 0) { error("Can't open a pseudo teletype"); return(-1); } grantpt(ptyfd); unlockpt(ptyfd); fcntl(ptyfd,F_SETFL,O_NDELAY); ttynam=ptsname(ptyfd); #else strcpy(ptynam, "/dev/ptyxx"); strcpy(ttynam, "/dev/ttyxx"); ptyfd = -1; for (s3 = ptyc3; *s3 != 0; s3++) { for (s4 = ptyc4; *s4 != 0; s4++) { ptynam[8] = ttynam[8] = *s3; ptynam[9] = ttynam[9] = *s4; if ((ptyfd = open(ptynam,O_RDWR)) >= 0) { if (geteuid() == 0 || access(ttynam,R_OK|W_OK) == 0) break; else { close(ptyfd); ptyfd = -1; } } } if (ptyfd >= 0) break; } if (ptyfd < 0) { error("Can't open a pseudo teletype"); return(-1); } fcntl(ptyfd,F_SETFL,O_NDELAY); #endif } #endif /* GLIBC */ for (i = 1; i <= 15; i++) signal(i,catch_sig); signal(SIGCHLD,catch_child); lstat(ttynam,&ttyfd_stat); utime(ttynam,NULL); makeutent(&ttynam[5]); /* stamp /etc/utmp */ comm_pid = fork(); if (comm_pid < 0) { error("Can't fork"); return(-1); } if (comm_pid == 0) { struct group *gr; if ((ttyfd = open(ttynam,O_RDWR)) < 0) { error("could not open slave tty %s",ttynam); clean_exit(1); } #ifdef SVR4 ioctl(ttyfd,I_PUSH,"ptem"); ioctl(ttyfd,I_PUSH,"ldterm"); #endif uid = getuid(); #ifndef SVR4 if ((gr = getgrnam("tty")) != NULL) gid = gr->gr_gid; else gid = -1; if (grantpty) { // regain root privileges seteuid(0); fchown(ttyfd,uid,gid); fchmod(ttyfd,0600); // drop root privileges again seteuid(getuid()); } #endif #ifdef TIOCCONS if (console) { int on = 1; if (ioctl (ttyfd, TIOCCONS, (unsigned char *)&on) == -1) fprintf(stderr, "kvt: cannot open console\n"); } #endif /* TIOCCONS */ #if defined(_HPUX_SOURCE) || defined (__Lynx__) for (i = 0; i < sysconf(_SC_OPEN_MAX); i++) if (i != ttyfd) close(i); #else for (i = 0; i < getdtablesize(); i++) if (i != ttyfd) close(i); #endif dup(ttyfd); dup(ttyfd); dup(ttyfd); if (ttyfd > 2) close(ttyfd); if (setsid() < 0) perror("failed to set process group"); #if defined(TIOCSCTTY) ioctl(0, TIOCSCTTY, 0) ; #endif { int pgrp = getpid(); ioctl(0, TIOCSPGRP, (char *)&pgrp); setpgid(0,0); close(open(ttynam, O_WRONLY, 0)); setpgid(0,0); } /* init of termios structure */ #if defined (__FreeBSD__) || (__NetBSD__) || defined(__bsdi__) ioctl(0,TIOCGETA,(char *)&ttmode); #else # if defined (_HPUX_SOURCE) || defined(__Lynx__) tcgetattr(0, &ttmode); # else ioctl(0,TCGETS,(char *)&ttmode); # endif #endif #if defined(_HPUX_SOURCE) || defined(__Lynx__) ttmode.c_iflag = BRKINT | IGNPAR | ICRNL| IXON; ttmode.c_lflag = ISIG|IEXTEN|ICANON|ECHO|ECHOE|ECHOK; #else ttmode.c_iflag = BRKINT | IGNPAR | ICRNL| IXON | IMAXBEL; ttmode.c_lflag = ISIG|IEXTEN|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE; #endif ttmode.c_oflag = OPOST | ONLCR ; ttmode.c_cflag = B9600 | CS8 | CREAD; ttmode.c_cc[VEOF] = CEOF; #ifdef ALPHA (unsigned) ttmode.c_cc[VEOL] = CEOL; #else ttmode.c_cc[VEOL] = CEOL; #endif ttmode.c_cc[VINTR] = CINTR; ttmode.c_cc[VQUIT] = CQUIT; ttmode.c_cc[VERASE] = CERASE; ttmode.c_cc[VKILL] = CKILL; #if defined(_HPUX_SOURCE) || defined(__Lynx__) ttmode.c_cc[VSUSP] = CSWTCH; #else ttmode.c_cc[VSUSP] = CSUSP; #endif #ifdef VDSUSP ttmode.c_cc[VDSUSP] = CDSUSP; #endif ttmode.c_cc[VSTART] = CSTART; ttmode.c_cc[VSTOP] = CSTOP; #ifdef VREPRINT ttmode.c_cc[VREPRINT] = CRPRNT; #endif #ifdef VDISCARD ttmode.c_cc[VDISCARD] = CFLUSH; #endif #ifdef VWERASE ttmode.c_cc[VWERASE] = CWERASE; #endif #ifdef VLNEXT ttmode.c_cc[VLNEXT] = CLNEXT; #endif #ifdef VSWTC ttmode.c_cc[VSWTC] = 0; #endif #ifdef VSWTCH ttmode.c_cc[VSWTCH] = 0; #endif #if VMIN != VEOF ttmode.c_cc[VMIN] = 1; #endif #if VTIME != VEOL ttmode.c_cc[VTIME] = 0; #endif if(mask == 0x7f) ttmode.c_cflag = B9600 | PARENB | CS7 | CREAD; #if defined (__FreeBSD__) || (__NetBSD__) || defined(__bsdi__) ioctl(0,TIOCSETA,(char *)&ttmode); #else # ifdef _HPUX_SOURCE tcsetattr(0, TCSANOW, &ttmode); # else ioctl(0,TCSETS,(char *)&ttmode); # endif #endif scr_get_size(&width,&height); tty_set_size(0,width,height); /* the stuff inspired from rxvt-2.18: */ /* command interpreter path */ if (argv != NULL) { setgid(getgid()); setuid(uid); execvp (argv [0], (char **) argv); error ("can't execute \"%s\"", argv [0]); clean_exit(1); } else { const char *argv0, *shell; char* base; if ((shell = getenv ("SHELL")) == NULL || *shell == '\0') shell = "/bin/sh"; base = strrchr (shell, '/'); argv0 = (base ? base + 1 : shell); if (login_shell) { char * p = (char*) safemalloc((strlen (argv0)+2)*sizeof(char), argv0); p [0] = '-'; strcpy (&p [1], argv0); argv0 = p; } setgid(getgid()); setuid(uid); execlp (shell, argv0, NULL); error ("can't execute \"%s\"", shell); clean_exit(1); } /* originally rvxt-2.08: (Matthias) */ /* if(login_shell) */ /* { */ /* char *tmp; */ /* strcpy(argv0,"-"); */ /* if ((tmp = strrchr(argv[0], '/')) == NULL) */ /* tmp = argv[0]; */ /* else */ /* tmp++; */ /* strcat(argv0,tmp); */ /* argv[0] = argv0; */ /* } */ /* setgid(getgid()); */ /* setuid(uid); */ /* execvp(command,(char **)argv); */ /* error("Couldn't execute %s",command); */ /* clean_exit(1); */ } return(ptyfd); }
int forkpty(int *amaster,char *dummy,struct termios *termp, struct winsize *wp) { int master,slave; int pid; #ifdef HAVE__GETPTY int filedes[2]; char *line; line = _getpty(&filedes[0], O_RDWR|O_NDELAY, 0600, 0); if (0 == line) return -1; if (0 > (filedes[1] = open(line, O_RDWR))) { close(filedes[0]); return -1; } master=filedes[0]; slave=filedes[1]; #elif defined(HAVE_GRANTPT) && (defined(HAVE_GETPT) || defined(HAVE_DEV_PTMX) || defined(HAVE_POSIX_OPENPT)) # ifdef HAVE_PTSNAME char *name; # else char name[80]; # endif # ifdef HAVE_GETPT master=getpt(); # elif HAVE_POSIX_OPENPT master=posix_openpt(O_RDWR); # else master=open("/dev/ptmx", O_RDWR); # endif if (master<0) return -1; if (grantpt(master)<0||unlockpt(master)<0) goto close_master; # ifdef HAVE_PTSNAME if (!(name=ptsname(master))) goto close_master; # else if (ptsname_r(master,name,80)) goto close_master; # endif slave=open(name,O_RDWR); if (slave==-1) goto close_master; # ifdef HAVE_STROPTS_H if (isastream(slave)) if (ioctl(slave, I_PUSH, "ptem")<0 ||ioctl(slave, I_PUSH, "ldterm")<0) goto close_slave; # endif goto ok; //close_slave: close (slave); close_master: close (master); return -1; ok: #else char *p, *q, *l, *d; char PtyName[32], TtyName[32]; strcpy(PtyName, PtyProto); strcpy(TtyName, TtyProto); for (p = PtyName; *p != 'X'; p++) ; for (q = TtyName; *q != 'X'; q++) ; for (l = PTYRANGE0; (*p = *l) != '\0'; l++) { for (d = PTYRANGE1; (p[1] = *d) != '\0'; d++) { // tintin_printf(0,"OpenPTY tries '%s'", PtyName); if ((master = open(PtyName, O_RDWR | O_NOCTTY)) == -1) continue; q[0] = *l; q[1] = *d; if (access(TtyName, R_OK | W_OK)) { close(master); continue; } if ((slave=open(TtyName, O_RDWR|O_NOCTTY))==-1) { close(master); continue; } goto ok; } } return -1; ok: #endif if (termp) tcsetattr(master, TCSANOW, termp); if (wp) ioctl(master,TIOCSWINSZ,wp); // let's ignore errors on this ioctl silently pid=fork(); switch (pid) { case -1: close(master); close(slave); return -1; case 0: close(master); setsid(); dup2(slave,0); dup2(slave,1); dup2(slave,2); close(slave); return 0; default: close(slave); *amaster=master; return pid; } }
int main() { return getpt() ; }