예제 #1
0
gint
ide_vte_pty_create_slave (VtePty *pty)
{
  gint master_fd;
#ifdef HAVE_PTSNAME_R
  char name[PATH_MAX + 1];
#else
  const char *name;
#endif

  g_assert (VTE_IS_PTY (pty));

  if (-1 == (master_fd = vte_pty_get_fd (pty)))
    return -1;

  if (grantpt (master_fd) != 0)
    return -1;

  if (unlockpt (master_fd) != 0)
    return -1;

#ifdef HAVE_PTSNAME_R
  if (ptsname_r (master_fd, name, sizeof name - 1) != 0)
    return -1;
  name[sizeof name - 1] = '\0';
#else
  if (NULL == (name = ptsname (master_fd)))
    return -1;
#endif

  return open (name, O_RDWR | O_CLOEXEC);
}
예제 #2
0
파일: pty_open.c 프로젝트: GNOME/vinagre
static char *
_pty_ptsname(int master)
{
#if defined(HAVE_PTSNAME_R)
	gsize len = 1024;
	char *buf = NULL;
	int i;
	do {
		buf = g_malloc0(len);
		i = ptsname_r(master, buf, len - 1);
		switch (i) {
		case 0:
			/* Return the allocated buffer with the name in it. */
			return buf;
			break;
		default:
			g_free(buf);
			buf = NULL;
			break;
		}
		len *= 2;
	} while ((i != 0) && (errno == ERANGE));
#elif defined(HAVE_PTSNAME)
	char *p;
	if ((p = ptsname(master)) != NULL) {
		return g_strdup(p);
	}
#elif defined(TIOCGPTN)
	int pty = 0;
	if (ioctl(master, TIOCGPTN, &pty) == 0) {
		return g_strdup_printf("/dev/pts/%d", pty);
	}
#endif
	return NULL;
}
예제 #3
0
// We would like to use "openpty", but it isn't in libc on some systems.
static bool createPseudoTty(int& masterFd, int& slaveFd, char *ttyname)
{
    // try opening Unix98 pseudo tty
    if ((masterFd = ::open("/dev/ptmx", O_RDWR | O_NONBLOCK, 0)) >= 0) {
        if (grantpt(masterFd) == 0) {
            if (unlockpt(masterFd) == 0) {
                ptsname_r(masterFd, ttyname, BUFSIZ);
                if ((slaveFd = ::open(ttyname, O_RDWR | O_NOCTTY, 0)) >= 0)
                    return true;
            }
        }
        ::close(masterFd);
    }

    // opening Unix98 pseudo tty failed, fall back to BSD style pseudo tty
    static char const firstChars[]  = "pqrstuvwxyzabcde";
    static char const secondChars[] = "0123456789abcdef";
    const char *first;
    const char *second;
    char ptyname[16];
    for ( first = firstChars; *first != '\0'; ++first ) {
        for ( second = secondChars; *second != '\0'; ++second ) {
            sprintf( ptyname, "/dev/pty%c%c", *first, *second );
            sprintf( ttyname, "/dev/tty%c%c", *first, *second );
            if ( ( masterFd = ::open( ptyname, O_RDWR | O_NONBLOCK, 0 ) ) >= 0 ) {
                if ( ( slaveFd = ::open( ttyname, O_RDWR | O_NOCTTY, 0 ) )
                        >= 0 ) {
                    return true;
                }
                ::close( masterFd );
            }
        }
    }
    return false;
}
예제 #4
0
파일: trytty.c 프로젝트: Zex/trytty
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
}
예제 #5
0
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;
}
예제 #6
0
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;
}
static int create_subprocess(JNIEnv *env, const char *cmd, char *const argv[], char *const envp[], int masterFd)
{
    // same size as Android 1.6 libc/unistd/ptsname_r.c
    char devname[64];
    pid_t pid;

    fcntl(masterFd, F_SETFD, FD_CLOEXEC);

    // grantpt is unnecessary, because we already assume devpts by using /dev/ptmx
    if(unlockpt(masterFd)){
        throwIOException(env, errno, "trouble with /dev/ptmx");
        return -1;
    }
    memset(devname, 0, sizeof(devname));
    // Early (Android 1.6) bionic versions of ptsname_r had a bug where they returned the buffer
    // instead of 0 on success.  A compatible way of telling whether ptsname_r
    // succeeded is to zero out errno and check it after the call
    errno = 0;
    int ptsResult = ptsname_r(masterFd, devname, sizeof(devname));
    if (ptsResult && errno) {
        throwIOException(env, errno, "ptsname_r returned error");
        return -1;
    }

    pid = fork();
    if(pid < 0) {
        throwIOException(env, errno, "fork failed");
        return -1;
    }

    if(pid == 0){
        int pts;

        setsid();

        pts = open(devname, O_RDWR);
        if(pts < 0) exit(-1);

        ioctl(pts, TIOCSCTTY, 0);

        dup2(pts, 0);
        dup2(pts, 1);
        dup2(pts, 2);

        closeNonstandardFileDescriptors();

        if (envp) {
            for (; *envp; ++envp) {
                putenv(*envp);
            }
        }

        execv(cmd, argv);
        exit(-1);
    } else {
        return (int) pid;
    }
}
예제 #8
0
TEST(stdlib, ptsname_r_ERANGE) {
  int fd = getpt();
  ASSERT_NE(-1, fd);
  errno = 0;
  char buf[1];
  ASSERT_EQ(ERANGE, ptsname_r(fd, buf, sizeof(buf)));
  ASSERT_EQ(ERANGE, errno);
  close(fd);
}
예제 #9
0
TEST(stdlib, ptsname_r_EINVAL) {
  int fd = getpt();
  ASSERT_NE(-1, fd);
  errno = 0;
  char* buf = NULL;
  ASSERT_EQ(EINVAL, ptsname_r(fd, buf, 128));
  ASSERT_EQ(EINVAL, errno);
  close(fd);
}
예제 #10
0
파일: pty.c 프로젝트: gbl/vte
/*
 * _vte_pty_ptsname:
 * @master: file descriptor to the PTY master
 * @error: a location to store a #GError, or %NULL
 *
 * Returns: a newly allocated string containing the file name of the
 *   PTY slave device, or %NULL on failure with @error filled in
 */
static char *
_vte_pty_ptsname(int master,
                 GError **error)
{
#if defined(HAVE_PTSNAME_R)
	gsize len = 1024;
	char *buf = NULL;
	int i, errsv;
	do {
		buf = g_malloc0(len);
		i = ptsname_r(master, buf, len - 1);
		switch (i) {
		case 0:
			/* Return the allocated buffer with the name in it. */
			_vte_debug_print(VTE_DEBUG_PTY,
					"PTY slave is `%s'.\n", buf);
			return buf;
			break;
		default:
                        errsv = errno;
			g_free(buf);
                        errno = errsv;
			buf = NULL;
			break;
		}
		len *= 2;
	} while ((i != 0) && (errno == ERANGE));

        g_set_error(error, VTE_PTY_ERROR, VTE_PTY_ERROR_PTY98_FAILED,
                    "%s failed: %s", "ptsname_r", g_strerror(errno));
        return NULL;
#elif defined(HAVE_PTSNAME)
	char *p;
	if ((p = ptsname(master)) != NULL) {
		_vte_debug_print(VTE_DEBUG_PTY, "PTY slave is `%s'.\n", p);
		return g_strdup(p);
	}

        g_set_error(error, VTE_PTY_ERROR, VTE_PTY_ERROR_PTY98_FAILED,
                    "%s failed: %s", "ptsname", g_strerror(errno));
        return NULL;
#elif defined(TIOCGPTN)
	int pty = 0;
	if (ioctl(master, TIOCGPTN, &pty) == 0) {
		_vte_debug_print(VTE_DEBUG_PTY,
				"PTY slave is `/dev/pts/%d'.\n", pty);
		return g_strdup_printf("/dev/pts/%d", pty);
	}

        g_set_error(error, VTE_PTY_ERROR, VTE_PTY_ERROR_PTY98_FAILED,
                    "%s failed: %s", "ioctl(TIOCGPTN)", g_strerror(errno));
        return NULL;
#else
#error no ptsname implementation for this platform
#endif
}
예제 #11
0
int FAST_FUNC xgetpty(char *line)
{
	int p;

#if ENABLE_FEATURE_DEVPTS
	p = open("/dev/ptmx", O_RDWR);
	if (p > 0) {
		grantpt(p); /* chmod+chown corresponding slave pty */
		unlockpt(p); /* (what does this do?) */
# ifndef HAVE_PTSNAME_R
		{
			const char *name;
			name = ptsname(p); /* find out the name of slave pty */
			if (!name) {
				bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)");
			}
			safe_strncpy(line, name, GETPTY_BUFSIZE);
		}
# else
		/* find out the name of slave pty */
		if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) {
			bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)");
		}
		line[GETPTY_BUFSIZE-1] = '\0';
# endif
		return p;
	}
#else
	struct stat stb;
	int i;
	int j;

	strcpy(line, "/dev/ptyXX");

	for (i = 0; i < 16; i++) {
		line[8] = "pqrstuvwxyzabcde"[i];
		line[9] = '0';
		if (stat(line, &stb) < 0) {
			continue;
		}
		for (j = 0; j < 16; j++) {
			line[9] = j < 10 ? j + '0' : j - 10 + 'a';
			if (DEBUG)
				fprintf(stderr, "Trying to open device: %s\n", line);
			p = open(line, O_RDWR | O_NOCTTY);
			if (p >= 0) {
				line[5] = 't';
				return p;
			}
		}
	}
#endif /* FEATURE_DEVPTS */
	bb_error_msg_and_die("can't find free pty");
}
예제 #12
0
static int create_subproc_pty(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
{
    D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
#ifdef HAVE_WIN32_PROC
    fprintf(stderr, "error: create_subproc_pty not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
    return -1;
#else /* !HAVE_WIN32_PROC */
    int ptm;

    ptm = unix_open("/dev/ptmx", O_RDWR | O_CLOEXEC); // | O_NOCTTY);
    if(ptm < 0){
        printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
        return -1;
    }

    char devname[64];
    if(grantpt(ptm) || unlockpt(ptm) || ptsname_r(ptm, devname, sizeof(devname)) != 0) {
        printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
        adb_close(ptm);
        return -1;
    }

    *pid = fork();
    if(*pid < 0) {
        printf("- fork failed: %s -\n", strerror(errno));
        adb_close(ptm);
        return -1;
    }

    if (*pid == 0) {
        init_subproc_child();

        int pts = unix_open(devname, O_RDWR | O_CLOEXEC);
        if (pts < 0) {
            fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname);
            exit(-1);
        }

        dup2(pts, STDIN_FILENO);
        dup2(pts, STDOUT_FILENO);
        dup2(pts, STDERR_FILENO);

        adb_close(pts);
        adb_close(ptm);

        execl(cmd, cmd, arg0, arg1, NULL);
        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
                cmd, strerror(errno), errno);
        exit(-1);
    } else {
        return ptm;
    }
#endif /* !HAVE_WIN32_PROC */
}
예제 #13
0
extern "C" char *ptsname(int fd)
{
  /* No need to acquire Wrapper Protection lock since it will be done in ptsname_r */
  JTRACE("ptsname() promoted to ptsname_r()");
  static char tmpbuf[PATH_MAX];

  if (ptsname_r(fd, tmpbuf, sizeof(tmpbuf)) != 0)
  {
    return NULL;
  }

  return tmpbuf;
}
예제 #14
0
static int create_subprocess(
  const char* cmd, const char* arg0, const char* arg1, int* pProcessId) {
  char devname[32];
  int ptm;
  pid_t pid;

  ptm = open("/dev/ptmx", O_RDWR); // | O_NOCTTY);
  if(ptm < 0){
    LOG("[ cannot open /dev/ptmx - %s ]\n", strerror(errno));
    return -1;
  }
  fcntl(ptm, F_SETFD, FD_CLOEXEC);

  if(
#if !defined(ANDROID)
     /* this actually doesn't do anything on Android */
     grantpt(ptm) ||
#endif
     unlockpt(ptm) ||
     ptsname_r(ptm, devname, sizeof(devname))){
    LOG("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
    return -1;
  }

  pid = fork();
  if(pid < 0) {
    LOG("- fork failed: %s -\n", strerror(errno));
    return -1;
  }

  if(pid == 0){
    int pts;

    setsid();

    pts = open(devname, O_RDWR);
    if(pts < 0) exit(-1);

    dup2(pts, 0);
    dup2(pts, 1);
    dup2(pts, 2);

    close(ptm);

    execl(cmd, cmd, arg0, arg1, NULL);
    exit(-1);
  } else {
    *pProcessId = (int) pid;
    return ptm;
  }
}
예제 #15
0
int try_open_pty(int *master, int *slave)
{
	int lmaster, lslave;
	char path[512];	
	struct termios newtio;

	lmaster = open("/dev/ptmx", O_RDWR | O_NOCTTY);
	if(lmaster == -1) return -1;
	
	dprintf("master fd is %d", lmaster);

	if(grantpt(lmaster) == -1) {
		close(lmaster);
		return -1;
	}

	if(unlockpt(lmaster) == -1) {
		close(lmaster);
		return -1;
	}

	memset(path, 0, sizeof(path));
	if(ptsname_r(lmaster, path, sizeof(path)-2) == -1) {
		close(lmaster);
		return -1;
	}

	lslave = open(path, O_RDWR | O_NOCTTY);
	if(lslave == -1) {
		close(lmaster);
		return -1;
	}

	*master = lmaster;
	*slave = lslave;

	if(tcgetattr(lmaster, &newtio) == -1) 
		// oh well
		return 0;

	// man 3 termios for more information (under linux, at least).

	newtio.c_lflag |= (ISIG|ICANON);
	newtio.c_lflag &= ~ECHO;

	// can't do anything about it if it fails
	tcsetattr(lmaster, TCSANOW, &newtio);

	return 0;
}	
예제 #16
0
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);
}
예제 #17
0
파일: openpty.c 프로젝트: Boshin/workspace
/* Return the result of ptsname_r in the buffer pointed to by PTS,
   which should be of length BUF_LEN.  If it is too long to fit in
   this buffer, a sufficiently long buffer is allocated using malloc,
   and returned in PTS.  0 is returned upon success, -1 otherwise.  */
static int
pts_name (int fd, char **pts, size_t buf_len)
{
  int rv;
  char *buf = *pts;

  for (;;)
    {
      char *new_buf;

      if (buf_len)
	{
	  rv = ptsname_r (fd, buf, buf_len);

	  if (rv != 0 || memchr (buf, '\0', buf_len))
	    /* We either got an error, or we succeeded and the
	       returned name fit in the buffer.  */
	    break;

	  /* Try again with a longer buffer.  */
	  buf_len += buf_len;	/* Double it */
	}
      else
	/* No initial buffer; start out by mallocing one.  */
	buf_len = 128;		/* First time guess.  */

      if (buf != *pts)
	/* We've already malloced another buffer at least once.  */
	new_buf = realloc (buf, buf_len);
      else
	new_buf = malloc (buf_len);
      if (! new_buf)
	{
	  rv = -1;
	  __set_errno (ENOMEM);
	  break;
	}
      buf = new_buf;
    }

  if (rv == 0)
    *pts = buf;		/* Return buffer to the user.  */
  else if (buf != *pts)
    free (buf);		/* Free what we malloced when returning an error.  */

  return rv;
}
예제 #18
0
파일: fdhelper.c 프로젝트: chdir/fdshare
// Fork and get ourselves a tty. Acquired tty will be new stdin,
// Standard output streams will be redirected to new_stdouterr.
// Returns control side tty file descriptor.
static int GetTTY() {
    int masterFd = open("/dev/ptmx", O_RDWR);
    if (masterFd < 0)
        DieWithError("failed to open /dev/ptmx");

    char devname[64];
    pid_t pid;

    if(unlockpt(masterFd)) // grantpt is unnecessary, because we already assume devpts by using /dev/ptmx
        DieWithError("trouble with /dev/ptmx");

    memset(devname, 0, sizeof(devname));

    // Early (Android 1.6) bionic versions of ptsname_r had a bug where they returned the buffer
    // instead of 0 on success.  A compatible way of telling whether ptsname_r
    // succeeded is to zero out errno and check it after the call
    errno = 0;
    int ptsResult = ptsname_r(masterFd, devname, sizeof(devname));
    if (ptsResult && errno)
        DieWithError("ptsname_r() returned error");

    pid = fork();
    if(pid < 0)
        DieWithError("fork() failed");

    if (pid) {
        // tell creator the PID of forked process
        printf("PID:%d", pid);
        exit(0);
    } else {
        int pts;

        setsid();

        pts = open(devname, O_RDWR);
        if(pts < 0)
            exit(-1);

        ioctl(pts, TIOCSCTTY, 0);

        dup2(pts, 0);
    }

    return masterFd;
}
int capture_std::get_pty(void)
{
	int iResult;


	/* Get an unused pseudo-terminal master device. */
	m_iFdPtyMaster = posix_openpt(O_RDWR);
	if( m_iFdPtyMaster<0 )
	{
		fprintf(stderr, "Failed to get PTY master: %d %s\n", errno, strerror(errno));
		iResult = -1;
	}
	else
	{
		printf("iFdPtyMaster = %d\n", m_iFdPtyMaster);
		iResult = grantpt(m_iFdPtyMaster);
		if( iResult!=0 )
		{
			fprintf(stderr, "grantpt failed: %d %s\n", errno, strerror(errno));
		}
		else
		{
			iResult = unlockpt(m_iFdPtyMaster);
			if( iResult!=0 )
			{
				fprintf(stderr, "unlockpt failed: %d %s\n", errno, strerror(errno));
			}
			else
			{
				/* Get the name of the pty. */
				iResult = ptsname_r(m_iFdPtyMaster, m_acPtsName, c_iMaxPtsName);
				if( iResult!=0 )
				{
					fprintf(stderr, "ptsname_r failed: %d %s\n", errno, strerror(errno));
				}
				else
				{
					printf("pts name: '%s'\n", m_acPtsName);
				}
			}
		}
	}

	return iResult;
}
/* find the first pty master device that available */
int ptym_open(char *pts_name)
{
	int fdm;
	int ret;

	if ((fdm = posix_openpt(O_RDWR)) < 0) {
		perror ("ut_wrapper : posix_openpt:");
		return -1;
	}

	ret =  ptsname_r(fdm, pts_name, PTSNAME_BUFLEN);
	if (ret) {
		perror ("ut_wrapper : ptsname");
		close(fdm);
		return -1;
	}

	printf("PTS %s\n", pts_name);
	fflush (stdout);
	return fdm;	
}
예제 #21
0
int main()
{
	int fd, ret;
	char *pts;
	char buf[BUFSIZ];
	size_t length = 0, bufsiz = BUFSIZ;
	BufferRec ptmxBuf;

	fd = open("/dev/ptmx",O_RDWR);

	if (grantpt(fd)) {
		fprintf(stderr, "grantpt failed: %s\n", strerror(errno));
		close(fd);
		exit(1);
	}
	if (unlockpt(fd)) {
		fprintf(stderr, "unlockpt failed: %s\n", strerror(errno));
		close(fd);
		exit(1);
	}
	ret = ptsname_r(fd, buf, sizeof(buf));
	if (ret) {
		fprintf(stderr, "ptsname failed: %s\n", strerror(errno));
		close(fd);
		exit(1);
	}
	printf("%s\n", buf);

	ptmxBuf.buf = buf;
	ptmxBuf.length = 0;
	ptmxBuf.capacity = BUFSIZ;
	registerFD(fd, ptmx_read, &ptmxBuf);

	dispatch();

	close(fd);

	return 0;
}
예제 #22
0
/* Return the pathname of the pseudo terminal slave associated with
   the master FD is open on, or NULL on errors.
   The returned storage is good until the next call to this function.  */
char *
ptsname (int fd)
{
  return ptsname_r (fd, buffer, sizeof (buffer)) != 0 ? NULL : buffer;
}
예제 #23
0
파일: pty.c 프로젝트: milisarge/termrec
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;
    }
}
예제 #24
0
파일: pty.c 프로젝트: myra/kmscon
static void setup_child(int master, struct winsize *ws)
{
	int ret;
	sigset_t sigset;
	pid_t pid;
	char slave_name[128];
	int slave = -1;

	/* The child should not inherit our signal mask. */
	sigemptyset(&sigset);
	ret = pthread_sigmask(SIG_SETMASK, &sigset, NULL);
	if (ret)
		log_warn("cannot reset blocked signals: %m");

	ret = grantpt(master);
	if (ret < 0) {
		log_err("grantpt failed: %m");
		goto err_out;
	}

	ret = unlockpt(master);
	if (ret < 0) {
		log_err("cannot unlock pty: %m");
		goto err_out;
	}

	ret = ptsname_r(master, slave_name, sizeof(slave_name));
	if (ret) {
		log_err("cannot find slave name: %m");
		goto err_out;
	}

	/* This also loses our controlling tty. */
	pid = setsid();
	if (pid < 0) {
		log_err("cannot start a new session: %m");
		goto err_out;
	}

	/* And the slave pty becomes our controlling tty. */
	slave = open(slave_name, O_RDWR | O_CLOEXEC);
	if (slave < 0) {
		log_err("cannot open slave: %m");
		goto err_out;
	}

	if (ws) {
		ret = ioctl(slave, TIOCSWINSZ, ws);
		if (ret)
			log_warn("cannot set slave window size: %m");
	}

	if (dup2(slave, STDIN_FILENO) != STDIN_FILENO ||
			dup2(slave, STDOUT_FILENO) != STDOUT_FILENO ||
			dup2(slave, STDERR_FILENO) != STDERR_FILENO) {
		log_err("cannot duplicate slave: %m");
		goto err_out;
	}

	close(master);
	close(slave);
	return;

err_out:
	ret = -errno;
	if (slave >= 0)
		close(slave);
	close(master);
	exit(EXIT_FAILURE);
}
예제 #25
0
파일: iostream.c 프로젝트: YurieCo/gap
static UInt GetMasterPty ( int *pty, Char *nametty, Char *namepty )
{
#if HAVE_POSIX_OPENPT && HAVE_PTSNAME
    /* Attempt to use POSIX 98 pseudo ttys. Opening a master tty is done
       via posix_openpt, which is available on virtually every current
       UNIX system; indeed, according to gnulib, it is available on at
       least the following systems:
         - glibc >= 2.2.1 (released January 2001; but is a stub on GNU/Hurd),
         - Mac OS X >= 10.4 (released April 2005),
         - FreeBSD >= 5.1 (released June 2003),
         - NetBSD >= 3.0 (released December 2005),
         - AIX >= 5.2 (released October 2002),
         - HP-UX >= 11.31 (released February 2007),
         - Solaris >= 10 (released January 2005),
         - Cygwin >= 1.7 (released December 2009).
       Systems lacking posix_openpt (in addition to older versions of
       the systems listed above) include:
         - OpenBSD
         - Minix 3.1.8
         - IRIX 6.5
         - OSF/1 5.1
         - mingw
         - MSVC 9
         - Interix 3.5
         - BeOS
       */
    *pty = posix_openpt( O_RDWR | O_NOCTTY );
    if (*pty > 0) {
        if (grantpt(*pty) || unlockpt(*pty)) {
            close(*pty);
            return 1;
        }
        strxcpy(nametty, ptsname(*pty), 32);
        return 0;
    }
    return 1;

#elif HAVE_GETPT && HAVE_PTSNAME_R
    /* Attempt to use glibc specific APIs, for compatibility with older
       glibc versions (before 2.2.1, release January 2001). */
    *pty = getpt();
    if (*pty > 0) {
        if (grantpt(*pty) || unlockpt(*pty)) {
            close(*pty);
            return 1;
        }
        ptsname_r(*pty, nametty, 32); 
        return 0;
    }
    return 1;

#elif HAVE_PTSNAME
    /* Attempt to use Sys V pseudo ttys on systems that don't have posix_openpt,
       getpt or openpty, but do have ptsname.
       Platforms *missing* ptsname include:
       Mac OS X 10.3, OpenBSD 3.8, Minix 3.1.8, mingw, MSVC 9, BeOS. */
    *pty = open( "/dev/ptmx", O_RDWR );
    if ( *pty < 0 )
        return 1;
    strxcpy(nametty, ptsname(*pty), 32);
    return 0;

#elif HAVE_GETPSEUDOTTY
    /* TODO: From which system(s) does getpseudotty originate? */
    *pty = getpseudotty( nametty, namepty );
    return *pty < 0 ? 1 : 0;

#elif HAVE__GETPTY
    /* Available on SGI IRIX >= 4.0 (released September 1991).
       See also http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?cmd=getdoc&coll=0530&db=man&fname=7%20pty */
    char  * line;
    line = _getpty(pty, O_RDWR|O_NDELAY, 0600, 0) ;
    if (0 == line)
        return 1;
    strcpy( nametty, line );
    return 0;

#else
    /* fallback to old-style BSD pseudoterminals, doing a brute force
       search over all pty device files. */
    int devindex;
    int letter;
    int ttylen, ptylen;

    ttylen = strlen(nametty);
    ptylen = strlen(namepty);

    for ( letter = 0; SYS_PTYCHAR1[letter]; ++letter ) {
        nametty[ttylen-2] = SYS_PTYCHAR1[letter];
        namepty[ptylen-2] = SYS_PTYCHAR1[letter];

        for ( devindex = 0; SYS_PTYCHAR2[devindex]; ++devindex ) {
            nametty[ttylen-1] = SYS_PTYCHAR2[devindex];
            namepty[ptylen-1] = SYS_PTYCHAR2[devindex];
                    
            *pty = open( namepty, O_RDWR );
            if ( *pty >= 0 ) {
                int slave = open( nametty, O_RDWR );
                if ( slave >= 0 ) {
                    close(slave);
                    return 0;
                }
                close(*pty);
            } 
        }
    }
    return 1;
#endif
}
예제 #26
0
mexp_h *
mexp_spawnvf (unsigned flags, const char *file, char **argv)
{
  mexp_h *h = NULL;
  int fd = -1;
  int err;
  char slave[1024];
  pid_t pid = 0;

  fd = posix_openpt (O_RDWR|O_NOCTTY);
  if (fd == -1)
    goto error;

  if (grantpt (fd) == -1)
    goto error;

  if (unlockpt (fd) == -1)
    goto error;

  /* Get the slave pty name now, but don't open it in the parent. */
  if (ptsname_r (fd, slave, sizeof slave) != 0)
    goto error;

  /* Create the handle last before we fork. */
  h = create_handle ();
  if (h == NULL)
    goto error;

  pid = fork ();
  if (pid == -1)
    goto error;

  if (pid == 0) {               /* Child. */
    int slave_fd;

    if (!(flags & MEXP_SPAWN_KEEP_SIGNALS)) {
      struct sigaction sa;
      int i;

      /* Remove all signal handlers.  See the justification here:
       * https://www.redhat.com/archives/libvir-list/2008-August/msg00303.html
       * We don't mask signal handlers yet, so this isn't completely
       * race-free, but better than not doing it at all.
       */
      memset (&sa, 0, sizeof sa);
      sa.sa_handler = SIG_DFL;
      sa.sa_flags = 0;
      sigemptyset (&sa.sa_mask);
      for (i = 1; i < NSIG; ++i)
        sigaction (i, &sa, NULL);
    }

    setsid ();

    /* Open the slave side of the pty.  We must do this in the child
     * after setsid so it becomes our controlling tty.
     */
    slave_fd = open (slave, O_RDWR);
    if (slave_fd == -1)
      goto error;

    if (!(flags & MEXP_SPAWN_COOKED_MODE)) {
      struct termios termios;

      /* Set raw mode. */
      tcgetattr (slave_fd, &termios);
      cfmakeraw (&termios);
      tcsetattr (slave_fd, TCSANOW, &termios);
    }

    /* Set up stdin, stdout, stderr to point to the pty. */
    dup2 (slave_fd, 0);
    dup2 (slave_fd, 1);
    dup2 (slave_fd, 2);
    close (slave_fd);

    /* Close the master side of the pty - do this late to avoid a
     * kernel bug, see sshpass source code.
     */
    close (fd);

    if (!(flags & MEXP_SPAWN_KEEP_FDS)) {
      int i, max_fd;

      /* Close all other file descriptors.  This ensures that we don't
       * hold open (eg) pipes from the parent process.
       */
      max_fd = sysconf (_SC_OPEN_MAX);
      if (max_fd == -1)
        max_fd = 1024;
      if (max_fd > 65536)
        max_fd = 65536;      /* bound the amount of work we do here */
      for (i = 3; i < max_fd; ++i)
        close (i);
    }

    /* Run the subprocess. */
    execvp (file, argv);
    perror (file);
    _exit (EXIT_FAILURE);
  }

  /* Parent. */

  h->fd = fd;
  h->pid = pid;
  return h;

 error:
  err = errno;
  if (fd >= 0)
    close (fd);
  if (pid > 0)
    waitpid (pid, NULL, 0);
  if (h != NULL)
    mexp_close (h);
  errno = err;
  return NULL;
}
예제 #27
0
파일: master.c 프로젝트: mocidis/riuc4-emu
void *master_thread(void *p_data) {
    int cnt, cnt1;
    int fdm;
    int rc;
    int n;
    char buffer[10];
    int *f_quit = 0;
    fd_set readset;
    fd_set writeset;
    struct timeval timeout;
    char pts_name[50];
    int len;
    char cmd[10];

    fdm = posix_openpt(O_RDWR);
    ANSI_EXIT_IF_TRUE(fdm < 0, "Cannot create pseudo-terminal master\n");

    rc = grantpt(fdm);
    ANSI_EXIT_IF_TRUE(rc != 0, "Cannot grantpt (change access right)\n");

    rc = unlockpt(fdm);
    ANSI_EXIT_IF_TRUE(rc != 0, "Cannot unlockpt (unlock slave side)\n");

    bzero(pts_name, sizeof(pts_name));
    len = ptsname_r(fdm, pts_name, sizeof(pts_name));
    printf("Pseudo terminal file: %s\n", pts_name);
    //printf("Pseudo terminal file: %s\n", ptsname(fdm));

    f_quit = p_data;
    timeout.tv_sec = 0;
    timeout.tv_usec = 10*1000;
    while(!(*f_quit)) {
        FD_ZERO(&readset);
        FD_SET(fdm, &readset);
        FD_ZERO(&writeset);
        FD_SET(fdm, &writeset);
        rc = select(fdm + 1, &readset, &writeset, NULL, &timeout);
        if( rc > 0 ) {
            if(FD_ISSET(fdm, &readset)) {
                n = read(fdm, buffer, sizeof(buffer) - 1);
                if( n > 0 ) {
                    buffer[n] = '\0'; 
                    fprintf(stdout, "1-%d\n", cnt);fflush(stdout);
                    cnt = 0;
                    //len = strlen(buffer);
                    printf("Received command: = %s\n",buffer);
                    sscanf(buffer,"%s", cmd);
                    len = strlen(cmd);
                    if (isdigit(buffer[len-1])) {
                        port_number = buffer[len-1] - '0';
                        printf("Port number = %d\n", port_number);
                        buffer[len-1] = '\0';
                        switch(port_number) {
                            case 1:
                                riuc4_change_status(&riuc1, buffer);
                                break;
                            case 2:
                                riuc4_change_status(&riuc2, buffer);
                                break;
                            case 3:
                                riuc4_change_status(&riuc3, buffer);			
                                break;
                            case 4:
                                riuc4_change_status(&riuc4, buffer);		
                                break;

                            default:
                                riuc4_change_status(&riuc, "err");
                                printf("Received: %d", port_number);				
                                break;
                        }
                    }
                    else {
                        riuc4_change_status(&riuc, "err");
                        printf("Received (wrong port): %s\n", buffer);
                    }
                }
                else ANSI_EXIT_IF_TRUE_V2(n < 0);
            }
            if(FD_ISSET(fdm, &writeset)) {
                if (port_number == 1){ 	
                    if (riuc1.is_pending) {
                        if (riuc1.is_reset) {
                            write(fdm, "ready\n",6);
                            riuc1.is_reset = 0;
                        }
                        else {	
                            riuc4_gen_status(riuc1, port_number, fdm);
                        }
                        riuc1.is_pending = 0;
                    }
                }
                else if (port_number == 2){
                    if (riuc2.is_pending) {
                        if (riuc2.is_reset) {
                            write(fdm, "ready\n",6);
                            riuc2.is_reset = 0;
                        }
                        else {	
                            riuc4_gen_status(riuc2, port_number, fdm);
                        }
                        riuc2.is_pending = 0;
                    }
                }	
                else if (port_number == 3){			

                    if (riuc3.is_pending) {
                        if (riuc3.is_reset) {
                            write(fdm, "ready\n",6);
                            riuc3.is_reset = 0;
                        }
                        else {	
                            riuc4_gen_status(riuc3, port_number, fdm);
                        }
                        riuc3.is_pending = 0;
                    }
                }
                else if (port_number == 4){
                    if (riuc4.is_pending) {
                        if (riuc4.is_reset) {
                            write(fdm, "ready\n",6);
                            riuc4.is_reset = 0;
                        }
                        else {	
                            riuc4_gen_status(riuc4, port_number, fdm);
                        }
                        riuc4.is_pending = 0;
                    }
                }
                else {
                    if (riuc.is_pending) {
                        if (riuc.is_reset) {
                            write(fdm, "ready\n",6);
                            riuc.is_reset = 0;
                        }
                        else {	
                            riuc4_gen_status(riuc, port_number, fdm);
                        }
                        riuc.is_pending = 0;
                    }

                }
            }
        }
        usleep(100*1000);
    }
    printf("main thread end\n");
    return NULL;
}
예제 #28
0
파일: osic.c 프로젝트: SQ6NTI/dxlAPRS
int osic_getptsname(int fd, char *name, int len)
{
	return ptsname_r(fd, name, len);
}
예제 #29
0
static int create_subproc_pty(const char *cmd, const char *arg0, const char *arg1, pid_t *pid)
{
    D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1);
#ifdef HAVE_WIN32_PROC
    fprintf(stderr, "error: create_subproc_pty not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1);
    return -1;
#else /* !HAVE_WIN32_PROC */
    int ptm;

    ptm = unix_open("/dev/ptmx", O_RDWR | O_CLOEXEC); // | O_NOCTTY);
    if(ptm < 0){
        printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno));
        return -1;
    }

    char devname[64];
    if(grantpt(ptm) || unlockpt(ptm) || ptsname_r(ptm, devname, sizeof(devname)) != 0) {
        printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno));
        adb_close(ptm);
        return -1;
    }

    *pid = fork();
    if(*pid < 0) {
        printf("- fork failed: %s -\n", strerror(errno));
        XLOGW("- fork failed: pid(%d) %s -\n", *pid, strerror(errno));
        adb_close(ptm);
        return -1;
    }

    if (*pid == 0) {
        init_subproc_child();

        int pts = unix_open(devname, O_RDWR | O_CLOEXEC);
        if (pts < 0) {
            fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname);
            exit(-1);
        }

        dup2(pts, STDIN_FILENO);
        dup2(pts, STDOUT_FILENO);
        dup2(pts, STDERR_FILENO);

        adb_close(pts);
        adb_close(ptm);

        timer_t timerid;
        struct sigevent sev;
        /* Create the timer */
        sev.sigev_notify = SIGEV_SIGNAL;
        sev.sigev_signo = SIGALRM;
        sev.sigev_value.sival_ptr = &timerid;
        if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1)
        {
            D("adb: Call timer_create failed!\n");
            XLOGV("adb: Call timer_create failed!\n");
            exit(-1);
        }

        struct itimerspec its;
        /* Start the timer */
        its.it_value.tv_sec = 1;
        its.it_value.tv_nsec = 0;
        its.it_interval.tv_sec = 3;
        its.it_interval.tv_nsec = 0;

        if (timer_settime(timerid, 0, &its, NULL) == -1)
        {
            D("adb: Call timer_settime failed!\n");
            XLOGV("adb: Call timer_settime failed!\n");
            exit(-1);
        }

        sigset_t mask;
        struct sigaction sa;
        /* Establish handler for timer signal */
        sa.sa_flags = SA_SIGINFO;
        sa.sa_sigaction = catcher;
        sigemptyset(&sa.sa_mask);
        if (sigaction(SIGALRM, &sa, NULL) == -1)
        {
            D("adb: Call sigaction failed!\n");
            XLOGV("adb: Call sigaction failed!\n");
            exit(-1);
        }

        int nRet = execl(cmd, cmd, arg0, arg1, NULL);
        fprintf(stderr, "- exec '%s' failed: %s (%d) -\n",
                cmd, strerror(errno), errno);
        XLOGV("- exec '%s' failed: %s (%d) nRet(%d) -\n",
                cmd, strerror(errno), errno, nRet);
        exit(-1);
    } else {
        return ptm;
    }
#endif /* !HAVE_WIN32_PROC */
}
예제 #30
0
char* ptsname(int fd) {
  static char buf[32];
  return ptsname_r(fd, buf, sizeof(buf)) == 0 ? buf : NULL;
}