Esempio n. 1
0
int createProcess(int *ppid)
{
	char *devname;
	int ptm, pts;
	pid_t pid;
	int res;

	LOG("createProcess");

	char *const argv[] = {
		"su",
		"-c",
		"/data/data/org.androix.nativenetbook/nativeinit /native",
		NULL
	};

	char *const envp[] = {
		/*"PATH=/system/bin:/data/data/org.androix.nativenetbook",*/
        "DISPLAY=:0",
		NULL
	};

	ptm = open("/dev/ptmx", O_RDWR);
	fcntl(ptm, F_SETFD, FD_CLOEXEC);

	if(grantpt(ptm) || unlockpt(ptm) || ((devname = (char*)ptsname(ptm)) == 0)) {
		return -1;
	}

	pid = fork();

	if (pid < 0) return -1;

	if (pid) {
		*ppid = pid;
        LOG("[native] parent returning");
		return ptm;
	} else {
		/* child */
		close(ptm);
		setsid();
		pts = open(devname, O_RDWR);
		if (pts < 0) exit(-1);
		dup2(pts, 0);
		dup2(pts, 1);
		dup2(pts, 2);
		//execl("/data/data/org.androix.nativenetbook/lib/init.so", "./init", "/native", NULL);
		//res = execve("/system/bin/su", "su");
		//res = execve("/bin/su", "su");

		printf("in child\n");
		//execlp("ls", "ls", "/", NULL);
		//execl("su", "-c", "./init", "/native", NULL);
		//execve("/system/bin/su", argv, envp);
		//execve("/bin/su", argv, envp);

//        execlp("su", "su", "-c", "/data/data/org.androix.nativenetbook/nativeinit /native", NULL);
//        execlp("su", "su", "-c", "ls /native", NULL);

        execve("/system/bin/su", argv, envp);
        execve("/system/xbin/su", argv, envp);
        execve("/bin/su", argv, envp);

        LOG("[native] child exiting this should not happen");
		exit(-1);
	};
};
Esempio n. 2
0
/* This function sets child_pid and masterfd */
void
exec_target(char* argv[])
{
  int fd;
  int pid;

  masterfd = open ("/dev/ptmx", O_RDWR);
  if (masterfd < 0)
    {
      perror("Cannot open pseudo tty");
      exit (1);
    }

  pid = fork ();
  if (pid < 0)
    {
      perror ("Failed to fork");
      return;
    }

  if (pid == 0)
    {
      int slave;

      setsid();

      /* this open raises console window on Windows 7 RC,
	 hide_console_window () hides it. */
      slave = open (ptsname (masterfd), O_RDWR);
      hide_console_window ();

      if (slave < 0)
	{
	  perror ("Failed to open slave fd");
	  exit (1);
	}

    for (fd = 0 ; fd < 3 ; fd++)
      {
	if (slave != fd)
	  {
	    if (dup2 (slave, fd) < 0)
	      {
		perror ("Failed to dup2");
		exit (1);
	      }
	  }
	fcntl (fd, F_SETFD, 0);
      }

    if (slave > 2) close (slave);

    execvp (argv[0], argv);

    fprintf (stderr, "Failed to execute \"%s\".", argv[0]);
    perror ("execvp");
    exit (1);
  }

  child_pid = pid;

  return;
}
Esempio n. 3
0
pid_t
forkpty(int *master, char *name, struct termios *tio, struct winsize *ws)
{
	int	slave = -1;
	char   *path;
	pid_t	pid;

	if ((*master = open("/dev/ptmx", O_RDWR|O_NOCTTY)) == -1)
		return (-1);
	if (grantpt(*master) != 0)
		goto out;
	if (unlockpt(*master) != 0)
		goto out;

	if ((path = ptsname(*master)) == NULL)
		goto out;
	if (name != NULL)
		strlcpy(name, path, TTY_NAME_MAX);
	if ((slave = open(path, O_RDWR|O_NOCTTY)) == -1)
		goto out;

	switch (pid = fork()) {
	case -1:
		goto out;
	case 0:
		close(*master);

		setsid();
#ifdef TIOCSCTTY
		if (ioctl(slave, TIOCSCTTY, NULL) == -1)
			fatal("ioctl failed");
#endif

		if (ioctl(slave, I_PUSH, "ptem") == -1)
			fatal("ioctl failed");
		if (ioctl(slave, I_PUSH, "ldterm") == -1)
			fatal("ioctl failed");

		if (tio != NULL && tcsetattr(slave, TCSAFLUSH, tio) == -1)
			fatal("tcsetattr failed");
		if (ioctl(slave, TIOCSWINSZ, ws) == -1)
			fatal("ioctl failed");

		dup2(slave, 0);
		dup2(slave, 1);
		dup2(slave, 2);
		if (slave > 2)
			close(slave);
		return (0);
	}

	close(slave);
	return (pid);

out:
	if (*master != -1)
		close(*master);
	if (slave != -1)
		close(slave);
	return (-1);
}
Esempio n. 4
0
/**
 * @brief       call ssh run shell command
 * @note        the code is copied form open program "sshpass"
 * @param       argc,the paragram number
 * @param       argv,the point of point of cmd
 * @returns     0 sucess ,other failed
 * @exception
 */
int runprogram( int argc, char *argv[],char*result,int len)
{
    int ii = 0;

    struct winsize ttysize; // The size of our tty

    // We need to interrupt a select with a SIGCHLD. In order to do so, we need a SIGCHLD handler
    signal( SIGCHLD,sigchld_handler );

    // Create a pseudo terminal for our process
    masterpt=posix_openpt(O_RDWR);

    if( masterpt==-1 ) {
        perror("Failed to get a pseudo terminal");

        return RETURN_RUNTIME_ERROR;
    }

    fcntl(masterpt, F_SETFL, O_NONBLOCK);

    if( grantpt( masterpt )!=0 ) {
        perror("Failed to change pseudo terminal's permission");

        return RETURN_RUNTIME_ERROR;
    }
    if( unlockpt( masterpt )!=0 ) {
        perror("Failed to unlock pseudo terminal");

        return RETURN_RUNTIME_ERROR;
    }

    ourtty=open("/dev/tty", 0);
    if( ourtty!=-1 && ioctl( ourtty, TIOCGWINSZ, &ttysize )==0 ) {
        signal(SIGWINCH, window_resize_handler);

        ioctl( masterpt, TIOCSWINSZ, &ttysize );
    }

    const char *name=ptsname(masterpt);
    int slavept;
    /*
       Comment no. 3.14159

       This comment documents the history of code.

       We need to open the slavept inside the child process, after "setsid", so that it becomes the controlling
       TTY for the process. We do not, otherwise, need the file descriptor open. The original approach was to
       close the fd immediately after, as it is no longer needed.

       It turns out that (at least) the Linux kernel considers a master ptty fd that has no open slave fds
       to be unused, and causes "select" to return with "error on fd". The subsequent read would fail, causing us
       to go into an infinite loop. This is a bug in the kernel, as the fact that a master ptty fd has no slaves
       is not a permenant problem. As long as processes exist that have the slave end as their controlling TTYs,
       new slave fds can be created by opening /dev/tty, which is exactly what ssh is, in fact, doing.

       Our attempt at solving this problem, then, was to have the child process not close its end of the slave
       ptty fd. We do, essentially, leak this fd, but this was a small price to pay. This worked great up until
       openssh version 5.6.

       Openssh version 5.6 looks at all of its open file descriptors, and closes any that it does not know what
       they are for. While entirely within its prerogative, this breaks our fix, causing sshpass to either
       hang, or do the infinite loop again.

       Our solution is to keep the slave end open in both parent AND child, at least until the handshake is
       complete, at which point we no longer need to monitor the TTY anyways.
       */

    int childpid=fork();
    if( childpid==0 ) {
        // Child

        // Detach us from the current TTY
        setsid();
        // This line makes the ptty our controlling tty. We do not otherwise need it open
        slavept=open(name, O_RDWR );
        dup2(slavept,STDIN_FILENO);
        dup2(slavept,STDOUT_FILENO);
        dup2(slavept,STDERR_FILENO);

        close( masterpt );

        char **new_argv=(char**)malloc(sizeof(char *)*(argc+1));

        int i;

        for( i=0; i<argc; ++i ) {
            new_argv[i]=argv[i];
        }

        new_argv[i]=NULL;

        execvp( new_argv[0], new_argv );

        perror("sshpass: Failed to run command");

        close( slavept );
        exit(RETURN_RUNTIME_ERROR);
    } else if( childpid<0 ) {
        perror("sshpass: Failed to create child process");

        return RETURN_RUNTIME_ERROR;
    }

    // We are the parent
    //slavept=open(name, O_RDWR|O_NOCTTY );

    int status=0;
    int terminate=0;
    pid_t wait_id;
    sigset_t sigmask, sigmask_select;

    // Set the signal mask during the select
    sigemptyset(&sigmask_select);

    // And during the regular run
    sigemptyset(&sigmask);
    sigaddset(&sigmask, SIGCHLD);

    sigprocmask( SIG_SETMASK, &sigmask, NULL );

    do {
        if( !terminate ) {
            fd_set readfd;

            FD_ZERO(&readfd);
            FD_SET(masterpt, &readfd);

            int selret=pselect( masterpt+1, &readfd, NULL, NULL, NULL, &sigmask_select );

            if( selret>0 ) {
                if( FD_ISSET( masterpt, &readfd ) ) {
                    int ret;
                    if( (ret=handleoutput( masterpt,result,len)) ) {
                        // Authentication failed or any other error

                        // handleoutput returns positive error number in case of some error, and a negative value
                        // if all that happened is that the slave end of the pt is closed.
                        if( ret>0 ) {
                            close( masterpt ); // Signal ssh that it's controlling TTY is now closed
                        }

                        terminate=ret;

                        if( terminate ) {
                        }
                    }
                }
            }
            wait_id=waitpid( childpid, &status, WNOHANG );
        } else {
            wait_id=waitpid( childpid, &status, 0 );
        }
    } while( wait_id==0 || (!WIFEXITED( status ) && !WIFSIGNALED( status )) );

    if( terminate>0 )
        return terminate;
    else if( WIFEXITED( status ) )
        return WEXITSTATUS(status);
    else
        return 255;
}
Esempio n. 5
0
int getpty(int *ptynum)
{
#ifdef __osf__ /* XXX */
    int master;
    int slave;
    if(openpty(&master, &slave, line, 0, 0) == 0){
	close(slave);
	return master;
    }
    return -1;
#else
#ifdef HAVE__GETPTY
    int master, slave;
    char *p;
    p = _getpty(&master, O_RDWR, 0600, 1);
    if(p == NULL)
	return -1;
    strlcpy(line, p, sizeof(Xline));
    return master;
#else

    int p;
    char *cp, *p1, *p2;
    int i;
#if SunOS == 40
    int dummy;
#endif
#if __linux
    int master;
    int slave;
    if(openpty(&master, &slave, line, 0, 0) == 0){
	close(slave);
	return master;
    }
#else
#ifdef	STREAMSPTY
    char *clone[] = { "/dev/ptc", "/dev/ptmx", "/dev/ptm", 
		      "/dev/ptym/clone", 0 };

    char **q;
    for(q=clone; *q; q++){
	p=open(*q, O_RDWR);
	if(p >= 0){
#ifdef HAVE_GRANTPT
	    grantpt(p);
#endif
#ifdef HAVE_UNLOCKPT
	    unlockpt(p);
#endif
	    strlcpy(line, ptsname(p), sizeof(Xline));
	    really_stream = 1;
	    return p;
	}
    }
#endif /* STREAMSPTY */
#ifndef _CRAY

#ifndef	__hpux
    snprintf(line, sizeof(Xline), "/dev/ptyXX");
    p1 = &line[8];
    p2 = &line[9];
#else
    snprintf(line, sizeof(Xline), "/dev/ptym/ptyXX");
    p1 = &line[13];
    p2 = &line[14];
#endif

	
    for (cp = "pqrstuvwxyzPQRST"; *cp; cp++) {
	struct stat stb;

	*p1 = *cp;
	*p2 = '0';
	/*
	 * This stat() check is just to keep us from
	 * looping through all 256 combinations if there
	 * aren't that many ptys available.
	 */
	if (stat(line, &stb) < 0)
	    break;
	for (i = 0; i < 16; i++) {
	    *p2 = "0123456789abcdef"[i];
	    p = open(line, O_RDWR);
	    if (p > 0) {
#ifndef	__hpux
		line[5] = 't';
#else
		for (p1 = &line[8]; *p1; p1++)
		    *p1 = *(p1+1);
		line[9] = 't';
#endif
		chown(line, 0, 0);
		chmod(line, 0600);
#if SunOS == 40
		if (ioctl(p, TIOCGPGRP, &dummy) == 0
		    || errno != EIO) {
		    chmod(line, 0666);
		    close(p);
		    line[5] = 'p';
		} else
#endif /* SunOS == 40 */
		    return(p);
	    }
	}
    }
#else	/* CRAY */
    extern lowpty, highpty;
    struct stat sb;

    for (*ptynum = lowpty; *ptynum <= highpty; (*ptynum)++) {
	snprintf(myline, sizeof(myline), "/dev/pty/%03d", *ptynum);
	p = open(myline, 2);
	if (p < 0)
	    continue;
	snprintf(line, sizeof(Xline), "/dev/ttyp%03d", *ptynum);
	/*
	 * Here are some shenanigans to make sure that there
	 * are no listeners lurking on the line.
	 */
	if(stat(line, &sb) < 0) {
	    close(p);
	    continue;
	}
	if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
	    chown(line, 0, 0);
	    chmod(line, 0600);
	    close(p);
	    p = open(myline, 2);
	    if (p < 0)
		continue;
	}
	/*
	 * Now it should be safe...check for accessability.
	 */
	if (access(line, 6) == 0)
	    return(p);
	else {
	    /* no tty side to pty so skip it */
	    close(p);
	}
    }
#endif	/* CRAY */
#endif	/* STREAMSPTY */
#endif /* OPENPTY */
    return(-1);
#endif
}
Esempio n. 6
0
bool KPty::open()
{
  Q_D(KPty);

  if (d->masterFd >= 0)
    return true;

  QByteArray ptyName;

  // Find a master pty that we can open ////////////////////////////////

  // Because not all the pty animals are created equal, they want to
  // be opened by several different methods.

  // We try, as we know them, one by one.

#ifdef HAVE_OPENPTY

  char ptsn[PATH_MAX];
  if (::openpty( &d->masterFd, &d->slaveFd, ptsn, 0, 0))
  {
    d->masterFd = -1;
    d->slaveFd = -1;
    kWarning(175) << "Can't open a pseudo teletype";
    return false;
  }
  d->ttyName = ptsn;

#else

#ifdef HAVE__GETPTY // irix

  char *ptsn = _getpty(&d->masterFd, O_RDWR|O_NOCTTY, S_IRUSR|S_IWUSR, 0);
  if (ptsn) {
    d->ttyName = ptsn;
    goto grantedpt;
  }

#elif defined(HAVE_PTSNAME) || defined(TIOCGPTN)

//#ifdef HAVE_POSIX_OPENPT
  d->masterFd = ::posix_openpt(O_RDWR|O_NOCTTY);
//#elif defined(HAVE_GETPT)
 // d->masterFd = ::getpt();
//#elif defined(PTM_DEVICE)
 // d->masterFd = ::open(PTM_DEVICE, O_RDWR|O_NOCTTY);
//#else
//;//# error No method to open a PTY master detected.
//#endif

  if (d->masterFd >= 0)
  {
 
#ifdef HAVE_PTSNAME
    char *ptsn = ptsname(d->masterFd);
    if (ptsn) {
        d->ttyName = ptsn;
#else
    int ptyno;
    if (!ioctl(d->masterFd, TIOCGPTN, &ptyno)) {
        d->ttyName = QByteArray("/dev/pts/") + QByteArray::number(ptyno);
#endif
#ifdef HAVE_GRANTPT
        if (!grantpt(d->masterFd))
           goto grantedpt;
#else

        goto gotpty;
#endif
    }
    ::close(d->masterFd);
    d->masterFd = -1;
  }
#endif // HAVE_PTSNAME || TIOCGPTN

  // Linux device names, FIXME: Trouble on other systems?
  for (const char* s3 = "pqrstuvwxyzabcde"; *s3; s3++)
  {
    for (const char* s4 = "0123456789abcdef"; *s4; s4++)
    {
      ptyName = QString().sprintf("/dev/pty%c%c", *s3, *s4).toAscii();
      d->ttyName = QString().sprintf("/dev/tty%c%c", *s3, *s4).toAscii();

      d->masterFd = ::open(ptyName.data(), O_RDWR);
      if (d->masterFd >= 0)
      {
#ifdef Q_OS_SOLARIS
        /* Need to check the process group of the pty.
         * If it exists, then the slave pty is in use,
         * and we need to get another one.
         */
        int pgrp_rtn;
        if (ioctl(d->masterFd, TIOCGPGRP, &pgrp_rtn) == 0 || errno != EIO) {
          ::close(d->masterFd);
          d->masterFd = -1;
          continue;
        }
#endif /* Q_OS_SOLARIS */
        if (!access(d->ttyName.data(),R_OK|W_OK)) // checks availability based on permission bits
        {
          if (!geteuid())
          {
            struct group* p = getgrnam(TTY_GROUP);
            if (!p)
              p = getgrnam("wheel");
            gid_t gid = p ? p->gr_gid : getgid ();

            chown(d->ttyName.data(), getuid(), gid);
            chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP);
          }
          goto gotpty;
        }
        ::close(d->masterFd);
        d->masterFd = -1;
      }
    }
  }

  qWarning() << "Can't open a pseudo teletype";
  return false;

 gotpty:
  struct stat st;
  if (stat(d->ttyName.data(), &st)) {
    return false; // this just cannot happen ... *cough*  Yeah right, I just
                  // had it happen when pty #349 was allocated.  I guess
                  // there was some sort of leak?  I only had a few open.
    }
  if (((st.st_uid != getuid()) ||
       (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) &&
      !d->chownpty(true))
  {
    qWarning()
      << "chownpty failed for device " << ptyName << "::" << d->ttyName
      << "\nThis means the communication can be eavesdropped." << endl;
  }

#if defined (HAVE__GETPTY) || defined (HAVE_GRANTPT)
 grantedpt:
#endif 

#ifdef HAVE_REVOKE
  revoke(d->ttyName.data());
#endif

#ifdef HAVE_UNLOCKPT
  unlockpt(d->masterFd);
#elif defined(TIOCSPTLCK)
  int flag = 0;
  ioctl(d->masterFd, TIOCSPTLCK, &flag);
#endif

  d->slaveFd = ::open(d->ttyName.data(), O_RDWR | O_NOCTTY);
  if (d->slaveFd < 0)
  {
    qWarning() << "Can't open slave pseudo teletype";
    ::close(d->masterFd);
    d->masterFd = -1;
    return false;
  }

#if (defined(__svr4__) || defined(__sgi__))
  // Solaris
  ioctl(d->slaveFd, I_PUSH, "ptem");
  ioctl(d->slaveFd, I_PUSH, "ldterm");
#endif

#endif /* HAVE_OPENPTY */

  fcntl(d->masterFd, F_SETFD, FD_CLOEXEC);
  fcntl(d->slaveFd, F_SETFD, FD_CLOEXEC);

  return true;
}

void KPty::closeSlave()
{
    Q_D(KPty);

    if (d->slaveFd < 0)
        return;
    ::close(d->slaveFd);
    d->slaveFd = -1;
}
Esempio n. 7
0
int slirp_openpty(int *amaster, int *aslave)
{
	register int master, slave;

#ifdef HAVE_GRANTPT
	char *ptr;
	
	if ((master = open("/dev/ptmx", O_RDWR)) < 0 ||
	    grantpt(master) < 0 ||
	    unlockpt(master) < 0 ||
	    (ptr = ptsname(master)) == NULL)  {
		close(master);
		return -1;
	}
	
	if ((slave = open(ptr, O_RDWR)) < 0 ||
	    ioctl(slave, I_PUSH, "ptem") < 0 ||
	    ioctl(slave, I_PUSH, "ldterm") < 0 ||
	    ioctl(slave, I_PUSH, "ttcompat") < 0) {
		close(master);
		close(slave);
		return -1;
	}
	
	*amaster = master;
	*aslave = slave;
	return 0;
	
#else
	
	static char line[] = "/dev/ptyXX";
	register const char *cp1, *cp2;
	
	for (cp1 = "pqrsPQRS"; *cp1; cp1++) {
		line[8] = *cp1;
		for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) {
			line[9] = *cp2;
			if ((master = open(line, O_RDWR, 0)) == -1) {
				if (errno == ENOENT)
				   return (-1);    /* out of ptys */
			} else {
				line[5] = 't';
				/* These will fail */
				(void) chown(line, getuid(), 0);
				(void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
#ifdef HAVE_REVOKE
				(void) revoke(line);
#endif
				if ((slave = open(line, O_RDWR, 0)) != -1) {
					*amaster = master;
					*aslave = slave;
					return 0;
				}
				(void) close(master);
				line[5] = 'p';
			}
		}
	}
	errno = ENOENT; /* out of ptys */
	return (-1);
#endif
}
Esempio n. 8
0
void ps_program_exec(int fd_master, char *arguments)
{
    struct winsize windowsize;
    char *argv[64];
    char *p;
    int i, n, fd_slave;

    if (setsid() == -1)
        ps_log(EXIT_FAILURE, LOG_ERROR("setsid failed - error [%s]"), strerror(errno));

    fd_slave=open(ptsname(fd_master), O_RDWR);

    if (fd_slave == -1)
        ps_log(EXIT_FAILURE, LOG_ERROR("unable to open slave with name [%s] - error [%s]"), ptsname(fd_master), strerror(errno));

    ps_log(0, LOG_INFO("fd_master [%d] fd_slave [%d] ptsname [%s]"), fd_master, fd_slave, ptsname(fd_master));

    if (dup2(fd_slave, STDIN_FILENO) != STDIN_FILENO)
        ps_log(EXIT_FAILURE, LOG_ERROR("failed to set STDIN_FILENO - error [%s]"), strerror(errno));

    if (dup2(fd_slave, STDOUT_FILENO) != STDOUT_FILENO)
        ps_log(EXIT_FAILURE, LOG_ERROR("failed to set STDOUT_FILENO - error [%s]"), strerror(errno));

    if (dup2(fd_slave, STDERR_FILENO) != STDERR_FILENO)
        ps_log(EXIT_FAILURE, LOG_ERROR("failed to set STDERR_FILENO - error [%s]"), strerror(errno));

    if (fd_slave > STDERR_FILENO)
        close(fd_slave);

    close(fd_master);

    // get terminal columns and rows

    memset(&windowsize, 0, sizeof(windowsize));

    p=arguments;
    windowsize.ws_col=atoi(p);
    p+=strlen(p)+1;
    windowsize.ws_row=atoi(p);
    p+=strlen(p)+1;

    if (ioctl(STDOUT_FILENO, TIOCSWINSZ, &windowsize) == -1)
        ps_log(0, LOG_INFO("failed to set window size to w [%d] h [%d] - error [%s]"), windowsize.ws_col, windowsize.ws_row, strerror(errno));

    // program arguments

    n=atoi(p);
    p+=strlen(p)+1;

    for (i=0; i < n; i++)
    {
        argv[i]=p;
        p+=strlen(p)+1;
    }

    argv[i]=0;
    execvp(argv[0], argv);

    // this code only executes if execvp failes
    ps_log(EXIT_FAILURE, LOG_ERROR("failed to run program [%s] - error [%s]"), argv[0], strerror(errno));
}
Esempio n. 9
0
/* lpty_new
 *
 * create a new lpty object, initialize it, put it into a userdata and
 * return it to the user.
 *
 * Arguments:
 *	L	Lua State
 *
 * Lua Stack:
 *	-
 *
 * Lua Returns:
 *	+1	the lpty userdata
 */
static int lpty_new(lua_State *L)
{
	/* create pty master side */
	int mfd = posix_openpt(O_RDWR);
	int sfd = -1;
	int failed = (mfd < 0);
	int throwe = 0;	/* throw errors, default = no */
	int usep = 1;	/* use path, default = yes */
	int nle = 0;	/* no local echo, default = no */
	int rawm = 0;	/* raw mode, default = no */
	int sepse = 0;	/* separate stderr, default = no */
	
	/* check for options */
	if (lua_gettop(L) > 0) {
		luaL_checktype(L, 1, LUA_TTABLE);
		
		lua_pushnil(L);
		while (lua_next(L, 1) != 0) {
			const char* k = lua_tostring(L, -2);
			if (!strcmp(k, "throw_errors"))
				throwe = lua_toboolean(L, -1);
			else if (!strcmp(k, "no_local_echo"))
				nle = lua_toboolean(L, -1);
			else if (!strcmp(k, "raw_mode"))
				rawm = lua_toboolean(L, -1);
			else if (!strcmp(k, "use_path"))
				usep = lua_toboolean(L, -1);
			else if (!strcmp(k, "separate_stderr")) {
				sepse = lua_toboolean(L, -1);
			} else
				return _lpty_error(L, 1, "invalid configuration option: %s", k);
			
			lua_pop(L, 1);
		}
	}
	
	if (mfd > 0) {
		/* setup parent side of pty. BEWARE:
		 * behaviour of grantpt is undefined if a SIGCHLD handler is active */
		_lpty_set_sigchld_handler(SIG_DFL);
		failed = grantpt(mfd);
		_lpty_set_sigchld_handler(_lpty_sigchld_handler);

		failed = failed || unlockpt(mfd);

		/* open slave side of pty */
		if (!failed) {
			char *ttyn = ptsname(mfd);
			if (ttyn) {
				sfd = open(ttyn, O_RDWR);
				failed = (sfd < 0);
			} else
				failed = 1;
		}

		/* cleanup if anything went wrong */
		if (failed) {
			close(mfd);
			mfd = -1;
		}
	}
	if (failed)
		return _lpty_error(L, throwe, "pty initialisation failed: %s", strerror(errno));

	lPty *pty = lpty_pushLPty(L);
	pty->m_fd = mfd;
	pty->s_fd = sfd;
	pty->child = -1;
	pty->flags.throwerrors = throwe;
	pty->flags.nolocalecho = nle;
	pty->flags.rawmode = rawm;
	pty->flags.usepath = usep;
	pty->e_mfd = -1;
	pty->e_sfd = -1;
	/* get original tty flags */
	tcgetattr(sfd, &pty->otios);
	
	if (!_lpty_separate_stderr(pty, sepse))
		return _lpty_error(L, throwe, "pty initialisation failed: %s", strerror(errno));

	return 1;
}
Esempio n. 10
0
File: tty00.c Progetto: OSLL/pmover
int main(int argc, char ** argv)
{
	int fdm, fds, status;
	char *slavename;
	pid_t pid;

	test_init(argc, argv);

	fdm = open("/dev/ptmx", O_RDWR);
	if (fdm == -1) {
		err("Can't open a master pseudoterminal");
		return 1;
	}

	grantpt(fdm);
	unlockpt(fdm);
	slavename = ptsname(fdm);

	pid = test_fork();
	if (pid < 0) {
		err("fork() failed");
		return 1;
	}

	if (pid == 0) {
		close(fdm);
		signal(SIGHUP, sighup_handler);

		if (setsid() == -1)
			return 1;

		/* set up a controlling terminal */
		fds = open(slavename, O_RDWR);
		if (fds == -1) {
			err("Can't open a slave pseudoterminal %s", slavename);
			return 1;
		}

		if (ioctl(fdm, TIOCSCTTY, 1) < 0) {
			err("Can't setup a controlling terminal");
			return 1;
		}
		close(fds);

		test_waitsig();
		if (sighup)
			return 0;
		return 1;
	}


	test_daemon();

	test_waitsig();

	close(fdm);

	if (kill(pid, SIGTERM) == -1) {
		err("kill failed");
		return 1;
	}

	pid = waitpid(pid, &status, 0);
	if (pid < 0)
		return 1;

	if (WIFEXITED(status)) {
		if (WEXITSTATUS(status)) {
			fail("The child returned %d", WEXITSTATUS(status));
			return 1;
		}
	} else
		err("The child has been killed by %d", WTERMSIG(status));

	pass();

	return 0;
}
Esempio n. 11
0
int
openpty(int *amaster, int *aslave, char *name, struct termios *termp,
   struct winsize *winp)
{
#if defined(HAVE__GETPTY)
	/*
	 * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
	 * pty's automagically when needed
	 */
	char *slave;

	if ((slave = _getpty(amaster, O_RDWR, 0622, 0)) == NULL)
		return (-1);

	/* Open the slave side. */
	if ((*aslave = open(slave, O_RDWR | O_NOCTTY)) == -1) {
		close(*amaster);
		return (-1);
	}
	return (0);

#elif defined(HAVE_DEV_PTMX)
	/*
	 * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
	 * also has bsd-style ptys, but they simply do not work.)
	 */
	int ptm;
	char *pts;
	mysig_t old_signal;

	if ((ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1)
		return (-1);

	/* XXX: need to close ptm on error? */
	old_signal = signal(SIGCHLD, SIG_DFL);
	if (grantpt(ptm) < 0)
		return (-1);
	signal(SIGCHLD, old_signal);

	if (unlockpt(ptm) < 0)
		return (-1);

	if ((pts = ptsname(ptm)) == NULL)
		return (-1);
	*amaster = ptm;

	/* Open the slave side. */
	if ((*aslave = open(pts, O_RDWR | O_NOCTTY)) == -1) {
		close(*amaster);
		return (-1);
	}

	/*
	 * Try to push the appropriate streams modules, as described 
	 * in Solaris pts(7).
	 */
	ioctl(*aslave, I_PUSH, "ptem");
	ioctl(*aslave, I_PUSH, "ldterm");
# ifndef __hpux
	ioctl(*aslave, I_PUSH, "ttcompat");
# endif /* __hpux */

	return (0);

#elif defined(HAVE_DEV_PTS_AND_PTC)
	/* AIX-style pty code. */
	const char *ttname;

	if ((*amaster = open("/dev/ptc", O_RDWR | O_NOCTTY)) == -1)
		return (-1);
	if ((ttname = ttyname(*amaster)) == NULL)
		return (-1);
	if ((*aslave = open(ttname, O_RDWR | O_NOCTTY)) == -1) {
		close(*amaster);
		return (-1);
	}
	return (0);

#elif defined(_UNICOS)
	char ptbuf[64], ttbuf[64];
	int i;
	int highpty;

	highpty = 128;
#ifdef _SC_CRAY_NPTY
	if ((highpty = sysconf(_SC_CRAY_NPTY)) == -1)
		highpty = 128;
#endif /* _SC_CRAY_NPTY */

	for (i = 0; i < highpty; i++) {
		snprintf(ptbuf, sizeof(ptbuf), "/dev/pty/%03d", i);
		snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%03d", i);
		if ((*amaster = open(ptbuf, O_RDWR|O_NOCTTY)) == -1)
			continue;
		/* Open the slave side. */
		if ((*aslave = open(ttbuf, O_RDWR|O_NOCTTY)) == -1) {
			close(*amaster);
			return (-1);
		}
		return (0);
	}
	return (-1);

#else
	/* BSD-style pty code. */
	char ptbuf[64], ttbuf[64];
	int i;
	const char *ptymajors = "pqrstuvwxyzabcdefghijklmno"
	    "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	const char *ptyminors = "0123456789abcdef";
	int num_minors = strlen(ptyminors);
	int num_ptys = strlen(ptymajors) * num_minors;
	struct termios tio;

	for (i = 0; i < num_ptys; i++) {
		snprintf(ptbuf, sizeof(ptbuf), "/dev/pty%c%c", 
		    ptymajors[i / num_minors], ptyminors[i % num_minors]);
		snprintf(ttbuf, sizeof(ttbuf), "/dev/tty%c%c",
		    ptymajors[i / num_minors], ptyminors[i % num_minors]);

		if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1) {
			/* Try SCO style naming */
			snprintf(ptbuf, sizeof(ptbuf), "/dev/ptyp%d", i);
			snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%d", i);
			if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1)
				continue;
		}

		/* Open the slave side. */
		if ((*aslave = open(ttbuf, O_RDWR | O_NOCTTY)) == -1) {
			close(*amaster);
			return (-1);
		}
		/* set tty modes to a sane state for broken clients */
		if (tcgetattr(*amaster, &tio) != -1) {
			tio.c_lflag |= (ECHO | ISIG | ICANON);
			tio.c_oflag |= (OPOST | ONLCR);
			tio.c_iflag |= ICRNL;
			tcsetattr(*amaster, TCSANOW, &tio);
		}

		return (0);
	}
	return (-1);
#endif
}