Beispiel #1
0
/*
 * Open the specified slave side of the pty,
 * making sure that we have a clean tty.
 */
static int cleanopen(char *lyne) {
    register int t;

    /*
     * Make sure that other people can't open the
     * slave side of the connection.
     */
    chown(lyne, 0, 0);
    chmod(lyne, 0600);

#ifndef NO_REVOKE
    revoke(lyne);
#endif

    t = open(lyne, O_RDWR|O_NOCTTY);
    if (t < 0) return(-1);

    /*
     * Hangup anybody else using this ttyp, then reopen it for
     * ourselves.
     */
# if !defined(__linux__)
    /* this looks buggy to me, our ctty is really a pty at this point */
    signal(SIGHUP, SIG_IGN);
    vhangup();
    signal(SIGHUP, SIG_DFL);
    t = open(lyne, O_RDWR|O_NOCTTY);
    if (t < 0) return(-1);
# endif
    return(t);
}
Beispiel #2
0
int
start_session(int vty, int argc, char **argv)
{
    int fd;
    char *t;

    close(0);
    close(1);
    close(2);
    revoke(ttys[vty].tty);
    fd=open(ttys[vty].tty,O_RDWR);
    dup2(fd,0);
    dup2(fd,1);
    dup2(fd,2);
    if(fd>2) close(fd);
    login_tty(fd);
    setpgid(0,getpid());
    putenv("TERM=xterm");
    putenv("HOME=/");
    putenv("PATH=/stand:/bin:/usr/bin:/sbin:.");
    signal(SIGHUP,SIG_DFL);
    signal(SIGINT,SIG_DFL);
    signal(SIGQUIT,SIG_DFL);
    signal(SIGTERM,SIG_DFL);
    chdir("/");
    t=(char *)(rindex(ttys[vty].tty,'/')+1);
    printf("\n\n\nStarting session on %s.\n",t);
    ttys[vty].func(argc,argv);
    _exit(0);
}
Beispiel #3
0
/*
 * Start a session and allocate a controlling terminal.
 * Only called by children of init after forking.
 */
static void
open_console(void)
{
	int fd;

	/*
	 * Try to open /dev/console.  Open the device with O_NONBLOCK to
	 * prevent potential blocking on a carrier.
	 */
	revoke(_PATH_CONSOLE);
	if ((fd = open(_PATH_CONSOLE, O_RDWR | O_NONBLOCK)) != -1) {
		(void)fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK);
		if (login_tty(fd) == 0)
			return;
		close(fd);
	}

	/* No luck.  Log output to file if possible. */
	if ((fd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
		stall("cannot open null device.");
		_exit(1);
	}
	if (fd != STDIN_FILENO) {
		dup2(fd, STDIN_FILENO);
		close(fd);
	}
	fd = open(_PATH_INITLOG, O_WRONLY | O_APPEND | O_CREAT, 0644);
	if (fd == -1)
		dup2(STDIN_FILENO, STDOUT_FILENO);
	else if (fd != STDOUT_FILENO) {
		dup2(fd, STDOUT_FILENO);
		close(fd);
	}
	dup2(STDOUT_FILENO, STDERR_FILENO);
}
Beispiel #4
0
int cleanopen(char *line)
{
    int t;

    if (ptyslavefd != -1)
	return ptyslavefd;

#ifdef STREAMSPTY
    if (!really_stream)
#endif
	{
	    /*
	     * Make sure that other people can't open the
	     * slave side of the connection.
	     */
	    chown(line, 0, 0);
	    chmod(line, 0600);
	}

#ifdef HAVE_REVOKE
    revoke(line);
#endif

    t = open(line, O_RDWR|O_NOCTTY);

    if (t < 0)
	return(-1);

    /*
     * Hangup anybody else using this ttyp, then reopen it for
     * ourselves.
     */
# if !(defined(_CRAY) || defined(__hpux)) && (BSD <= 43) && !defined(STREAMSPTY)
    signal(SIGHUP, SIG_IGN);
#ifdef HAVE_VHANGUP
    vhangup();
#else
#endif
    signal(SIGHUP, SIG_DFL);
    t = open(line, O_RDWR|O_NOCTTY);
    if (t < 0)
	return(-1);
# endif
# if	defined(_CRAY) && defined(TCVHUP)
    {
	int i;
	signal(SIGHUP, SIG_IGN);
	ioctl(t, TCVHUP, (char *)0);
	signal(SIGHUP, SIG_DFL);

	i = open(line, O_RDWR);

	if (i < 0)
	    return(-1);
	close(t);
	t = i;
    }
# endif	/* defined(CRAY) && defined(TCVHUP) */
    return(t);
}
Beispiel #5
0
void BiasedLocking::revoke(GrowableArray<Handle>* objs) {
  assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
  if (objs->length() == 0) {
    return;
  }
  VM_RevokeBias revoke(objs, JavaThread::current());
  VMThread::execute(&revoke);
}
Beispiel #6
0
/* Unlock the slave pseudo terminal associated with the master pseudo
   terminal specified by FD.  */
int
unlockpt (int fd)
{
  char buf[sizeof (_PATH_TTY) + 2];

  /* BSD doesn't have a lock, but it does have `revoke'.  */
  if (__ptsname_r (fd, buf, sizeof (buf)))
    return -1;
  return revoke (buf);
}
Beispiel #7
0
Boolean ssh_pty_internal_allocate(int *ptyfd, int *ttyfd, char *namebuf)
{
  char buf[64];
  int i;
#ifdef __FreeBSD__
  const char *ptymajors = "pqrsPQRS";
  const char *ptyminors = "0123456789abcdefghijklmnopqrstuv";
#else
  const char *ptymajors = 
    "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
  const char *ptyminors = "0123456789abcdef";
#endif
  int num_minors = strlen(ptyminors);
  int num_ptys = strlen(ptymajors) * num_minors;

  for (i = 0; i < num_ptys; i++)
    {
      snprintf(buf, sizeof(buf), "/dev/pty%c%c", ptymajors[i / num_minors], 
	      ptyminors[i % num_minors]);
      *ptyfd = open(buf, O_RDWR|O_NOCTTY);
      if (*ptyfd < 0)
	continue;
      snprintf(namebuf, SSH_PTY_NAME_SIZE,
	       "/dev/tty%c%c", ptymajors[i / num_minors], 
	       ptyminors[i % num_minors]);

#ifdef HAVE_REVOKE
      if (revoke(namebuf) == -1)
 	ssh_warning("pty_allocate: revoke failed for %.100s", namebuf);
#endif

      /* Open the slave side. */
      *ttyfd = open(namebuf, O_RDWR|O_NOCTTY);
      if (*ttyfd < 0)
	{
	  ssh_warning("%.100s: %.100s", namebuf, strerror(errno));
	  close(*ptyfd);
	  /* Try with another pty. */
	  continue;
	}

#if defined(ultrix) || defined(NeXT)
      (void) signal(SIGTTOU, SIG_IGN);  /* corey via nancy */
#endif /* ultrix or NeXT */
      
      return TRUE;
    }
  ssh_warning("Failed to allocate pty.");
  return FALSE;
}
Beispiel #8
0
/*
 * Start a session and allocate a controlling terminal.
 * Only called by children of init after forking.
 */
static void
setctty(const char *name)
{
	int fd;

	revoke(name);
	if ((fd = open(name, O_RDWR)) == -1) {
		stall("can't open %s: %m", name);
		_exit(1);
	}
	if (login_tty(fd) == -1) {
		stall("can't get %s for controlling terminal: %m", name);
		_exit(1);
	}
}
Beispiel #9
0
static int
setctty(const char *name)
{
	int fd;

	revoke(name);
	if ((fd = open(name, O_RDWR)) == -1) {
		exit(1);
	}

	if (login_tty(fd) == -1) {
		exit(1);
	}

	return fd;
}
Beispiel #10
0
int
main(int argc, char *argv[])
{
	char **d;
	int error = 0;

	if (argc == 1)
		usage();

	for (d = &argv[1]; *d != NULL; d++) {
		if (revoke(*d) != 0) {
			perror(*d);
			error = 1;
		}
	}

	return (error);
}
Beispiel #11
0
int
unlockpt (int fd)
{
  /* Platforms which have the TIOCSPTLCK ioctl (Linux) already have the
     unlockpt function.  */
#if HAVE_REVOKE
  /* Mac OS X 10.3, OpenBSD 3.8 do not have the unlockpt function, but they
     have revoke().  */
  char *name = ptsname (fd);
  if (name == NULL)
    return -1;
  return revoke (name);
#else
  /* Assume that the slave side of a pseudo-terminal is already unlocked
     by default.  */
  if (fcntl (fd, F_GETFD) < 0)
    return -1;
  return 0;
#endif
}
Beispiel #12
0
bool
get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
{
    char *bank, *cp;
    struct group *gr;
    gid_t ttygid = -1;
    bool rval = false;
    debug_decl(get_pty, SUDO_DEBUG_PTY)

    if ((gr = getgrnam("tty")) != NULL)
	ttygid = gr->gr_gid;

    for (bank = "pqrs"; *bank != '\0'; bank++) {
	line[sizeof("/dev/ptyX") - 2] = *bank;
	for (cp = "0123456789abcdef"; *cp != '\0'; cp++) {
	    line[sizeof("/dev/ptyXX") - 2] = *cp;
	    *master = open(line, O_RDWR|O_NOCTTY, 0);
	    if (*master == -1) {
		if (errno == ENOENT)
		    goto done; /* out of ptys */
		continue; /* already in use */
	    }
	    line[sizeof("/dev/p") - 2] = 't';
	    (void) chown(line, ttyuid, ttygid);
	    (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
# ifdef HAVE_REVOKE
	    (void) revoke(line);
# endif
	    *slave = open(line, O_RDWR|O_NOCTTY, 0);
	    if (*slave != -1) {
		    strlcpy(name, line, namesz);
		    rval = true; /* success */
		    goto done;
	    }
	    (void) close(*master);
	}
    }
done:
    debug_return_bool(rval);
}
Beispiel #13
0
int
main(int argc, char *argv[])
{
	extern	char **environ;
	int first_sleep = 1, first_time = 1;
	struct rlimit limit;
	int rval;

	signal(SIGINT, SIG_IGN);
	signal(SIGQUIT, SIG_IGN);

	openlog("getty", LOG_ODELAY|LOG_CONS|LOG_PID, LOG_AUTH);
	gethostname(hostname, sizeof(hostname) - 1);
	hostname[sizeof(hostname) - 1] = '\0';
	if (hostname[0] == '\0')
		strcpy(hostname, "Amnesiac");

	/*
	 * Limit running time to deal with broken or dead lines.
	 */
	(void)signal(SIGXCPU, timeoverrun);
	limit.rlim_max = RLIM_INFINITY;
	limit.rlim_cur = GETTY_TIMEOUT;
	(void)setrlimit(RLIMIT_CPU, &limit);

	gettable("default", defent);
	gendefaults();
	tname = "default";
	if (argc > 1)
		tname = argv[1];

	/*
	 * The following is a work around for vhangup interactions
	 * which cause great problems getting window systems started.
	 * If the tty line is "-", we do the old style getty presuming
	 * that the file descriptors are already set up for us.
	 * J. Gettys - MIT Project Athena.
	 */
	if (argc <= 2 || strcmp(argv[2], "-") == 0)
	    strcpy(ttyn, ttyname(STDIN_FILENO));
	else {
	    strcpy(ttyn, dev);
	    strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev));
	    if (strcmp(argv[0], "+") != 0) {
		chown(ttyn, 0, 0);
		chmod(ttyn, 0600);
		revoke(ttyn);

		/*
		 * Do the first scan through gettytab.
		 * Terminal mode parameters will be wrong until
		 * defttymode() called, but they're irrelevant for
		 * the initial setup of the terminal device.
		 */
		dogettytab();

		/*
		 * Init or answer modem sequence has been specified.
		 */
		if (IC || AC) {
			if (!opentty(ttyn, O_RDWR|O_NONBLOCK))
				exit(1);
			defttymode();
			setttymode(1);
		}

		if (IC) {
			if (getty_chat(IC, CT, DC) > 0) {
				syslog(LOG_ERR, "modem init problem on %s", ttyn);
				(void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
				exit(1);
			}
		}

		if (AC) {
			int i, rfds;
			struct timeval to;

        		rfds = 1 << 0;	/* FD_SET */
        		to.tv_sec = RT;
        		to.tv_usec = 0;
        		i = select(32, (fd_set*)&rfds, (fd_set*)NULL,
        			       (fd_set*)NULL, RT ? &to : NULL);
        		if (i < 0) {
				syslog(LOG_ERR, "select %s: %m", ttyn);
			} else if (i == 0) {
				syslog(LOG_NOTICE, "recycle tty %s", ttyn);
				(void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
				exit(0);  /* recycle for init */
			}
			i = getty_chat(AC, CT, DC);
			if (i > 0) {
				syslog(LOG_ERR, "modem answer problem on %s", ttyn);
				(void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
				exit(1);
			}
		} else { /* maybe blocking open */
			if (!opentty(ttyn, O_RDWR | (NC ? O_NONBLOCK : 0 )))
				exit(1);
		}
	    }
	}

	defttymode();
	for (;;) {

		/*
		 * if a delay was specified then sleep for that 
		 * number of seconds before writing the initial prompt
		 */
		if (first_sleep && DE) {
		    sleep(DE);
		    /* remove any noise */
		    (void)tcflush(STDIN_FILENO, TCIOFLUSH);
		}
		first_sleep = 0;

		setttymode(0);
		if (AB) {
			tname = autobaud();
			dogettytab();
			continue;
		}
		if (PS) {
			tname = portselector();
			dogettytab();
			continue;
		}
		if (CL && *CL)
			putpad(CL);
		edithost(HE);

		/* if this is the first time through this, and an
		   issue file has been given, then send it */
		if (first_time && IF) {
			int fd;

			if ((fd = open(IF, O_RDONLY)) != -1) {
				char * cp;

				while ((cp = getline(fd)) != NULL) {
					  putf(cp);
				}
				close(fd);
			}
		}
		first_time = 0;

		if (IM && *IM && !(PL && PP))
			putf(IM);
		if (setjmp(timeout)) {
			cfsetispeed(&tmode, B0);
			cfsetospeed(&tmode, B0);
			(void)tcsetattr(STDIN_FILENO, TCSANOW, &tmode);
			exit(1);
		}
		if (TO) {
			signal(SIGALRM, dingdong);
			alarm(TO);
		}

		rval = 0;
		if (AL) {
			const char *p = AL;
			char *q = name;

			while (*p && q < &name[sizeof name - 1]) {
				if (isupper(*p))
					upper = 1;
				else if (islower(*p))
					lower = 1;
				else if (isdigit(*p))
					digit = 1;
				*q++ = *p++;
			}
		} else if (!(PL && PP))
			rval = getname();
		if (rval == 2 || (PL && PP)) {
			oflush();
			alarm(0);
			limit.rlim_max = RLIM_INFINITY;
			limit.rlim_cur = RLIM_INFINITY;
			(void)setrlimit(RLIMIT_CPU, &limit);
			execle(PP, "ppplogin", ttyn, (char *) 0, env);
			syslog(LOG_ERR, "%s: %m", PP);
			exit(1);
		} else if (rval || AL) {
			int i;

			oflush();
			alarm(0);
			signal(SIGALRM, SIG_DFL);
			if (name[0] == '\0')
				continue;
			if (name[0] == '-') {
				puts("user names may not start with '-'.");
				continue;
			}
			if (!(upper || lower || digit)) {
				if (AL) {
					syslog(LOG_ERR,
					    "invalid auto-login name: %s", AL);
					exit(1);
				} else
					continue;
			}
			set_flags(2);
			if (crmod) {
				tmode.c_iflag |= ICRNL;
				tmode.c_oflag |= ONLCR;
			}
#if REALLY_OLD_TTYS
			if (upper || UC)
				tmode.sg_flags |= LCASE;
			if (lower || LC)
				tmode.sg_flags &= ~LCASE;
#endif
			if (tcsetattr(STDIN_FILENO, TCSANOW, &tmode) < 0) {
				syslog(LOG_ERR, "tcsetattr %s: %m", ttyn);
				exit(1);
			}
			signal(SIGINT, SIG_DFL);
			for (i = 0; environ[i] != (char *)0; i++)
				env[i] = environ[i];
			makeenv(&env[i]);

			limit.rlim_max = RLIM_INFINITY;
			limit.rlim_cur = RLIM_INFINITY;
			(void)setrlimit(RLIMIT_CPU, &limit);
			execle(LO, "login", AL ? "-fp" : "-p", name,
			    (char *) 0, env);
			syslog(LOG_ERR, "%s: %m", LO);
			exit(1);
		}
		alarm(0);
		signal(SIGALRM, SIG_DFL);
		signal(SIGINT, SIG_IGN);
		if (NX && *NX) {
			tname = NX;
			dogettytab();
		}
	}
}
Beispiel #14
0
/*
 * Threaded process initialization.
 *
 * This is only called under two conditions:
 *
 *   1) Some thread routines have detected that the library hasn't yet
 *      been initialized (_thr_initial == NULL && curthread == NULL), or
 *
 *   2) An explicit call to reinitialize after a fork (indicated
 *      by curthread != NULL)
 */
void
_libpthread_init(struct pthread *curthread)
{
	int fd, first = 0;
	sigset_t sigset, oldset;

	/* Check if this function has already been called: */
	if ((_thr_initial != NULL) && (curthread == NULL))
		/* Only initialize the threaded application once. */
		return;

	/*
	 * Check for the special case of this process running as
	 * or in place of init as pid = 1:
	 */
	if ((_thr_pid = getpid()) == 1) {
		/*
		 * Setup a new session for this process which is
		 * assumed to be running as root.
		 */
		if (setsid() == -1)
			PANIC("Can't set session ID");
		if (revoke(_PATH_CONSOLE) != 0)
			PANIC("Can't revoke console");
		if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
			PANIC("Can't open console");
		if (setlogin("root") == -1)
			PANIC("Can't set login to root");
		if (__sys_ioctl(fd, TIOCSCTTY, NULL) == -1)
			PANIC("Can't set controlling terminal");
	}

	/* Initialize pthread private data. */
	init_private();

	/* Set the initial thread. */
	if (curthread == NULL) {
		first = 1;
		/* Create and initialize the initial thread. */
		curthread = _thr_alloc(NULL);
		if (curthread == NULL)
			PANIC("Can't allocate initial thread");
		init_main_thread(curthread);
	}
	/*
	 * Add the thread to the thread list queue.
	 */
	THR_LIST_ADD(curthread);
	_thread_active_threads = 1;

	/* Setup the thread specific data */
	tls_set_tcb(curthread->tcb);

	if (first) {
		SIGFILLSET(sigset);
		__sys_sigprocmask(SIG_SETMASK, &sigset, &oldset);
		_thr_signal_init();
		_thr_initial = curthread;
		SIGDELSET(oldset, SIGCANCEL);
		__sys_sigprocmask(SIG_SETMASK, &oldset, NULL);
		if (td_eventismember(&_thread_event_mask, TD_CREATE))
			_thr_report_creation(curthread, curthread);
	}
}
Beispiel #15
0
int
openpty(int *amaster, int *aslave, char *name, struct termios *term,
	struct winsize *winp)
{
	char line[] = "/dev/XtyXX";
	const char *cp1, *cp2, *cp, *linep;
	int master, slave;
	gid_t ttygid;
	mode_t mode;
	struct group grs, *grp;
	char grbuf[1024];

	_DIAGASSERT(amaster != NULL);
	_DIAGASSERT(aslave != NULL);
	/* name may be NULL */
	/* term may be NULL */
	/* winp may be NULL */

#if !defined(__minix)
	if ((master = open("/dev/ptm", O_RDWR)) != -1) {
		struct ptmget pt;
		if (ioctl(master, TIOCPTMGET, &pt) != -1) {
			(void)close(master);
			master = pt.cfd;
			slave = pt.sfd;
			linep = pt.sn;
			goto gotit;
		}
		(void)close(master);
	}
#endif /* !defined(__minix) */

	(void)getgrnam_r("tty", &grs, grbuf, sizeof(grbuf), &grp);
	if (grp != NULL) {
		ttygid = grp->gr_gid;
		mode = S_IRUSR|S_IWUSR|S_IWGRP;
	} else {
		ttygid = getgid();
		mode = S_IRUSR|S_IWUSR;
	}

	for (cp1 = TTY_LETTERS; *cp1; cp1++) {
		line[8] = *cp1;
		for (cp = cp2 = TTY_OLD_SUFFIX TTY_NEW_SUFFIX; *cp2; cp2++) {
			line[5] = 'p';
			line[9] = *cp2;
#ifdef __minix
			if ((master = open(line, O_RDWR | O_NOCTTY, 0)) == -1) {
#else
			if ((master = open(line, O_RDWR, 0)) == -1) {
#endif
				if (errno != ENOENT)
					continue;	/* busy */
				if ((size_t)(cp2 - cp + 1) < sizeof(TTY_OLD_SUFFIX))
					return -1; /* out of ptys */
				else	
					break;	/* out of ptys in this group */
			}
			line[5] = 't';
			linep = line;
			if (chown(line, getuid(), ttygid) == 0 &&
			    chmod(line, mode) == 0 &&
#if !defined(__minix)
			    revoke(line) == 0 &&
#endif /* !defined(__minix) */
#ifdef __minix
			(slave = open(line, O_RDWR | O_NOCTTY, 0)) != -1) {
#else
			    (slave = open(line, O_RDWR, 0)) != -1) {
#endif
#if !defined(__minix)
gotit:
#endif /* !defined(__minix) */
				*amaster = master;
				*aslave = slave;
				if (name)
					(void)strcpy(name, linep);
				if (term)
					(void)tcsetattr(slave, TCSAFLUSH, term);
				if (winp)
					(void)ioctl(slave, TIOCSWINSZ, winp);
				return 0;
			}
			(void)close(master);
		}
	}
	errno = ENOENT;	/* out of ptys */
	return -1;
}

pid_t
forkpty(int *amaster, char *name, struct termios *term, struct winsize *winp)
{
	int master, slave;
	pid_t pid;

	_DIAGASSERT(amaster != NULL);
	/* name may be NULL */
	/* term may be NULL */
	/* winp may be NULL */

	if (openpty(&master, &slave, name, term, 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;
}
SubRegionMemory::~SubRegionMemory()
{
    revoke();
}
Beispiel #17
0
bool KPty::open()
{
    Q_D(KPty);

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

    d->ownMaster = 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;
        qWarning(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).toLatin1();
            d->ttyName = QString().sprintf("/dev/tty%c%c", *s3, *s4).toLatin1();

            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 ();

                        if (!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;
}

bool KPty::open(int fd)
{
#if !defined(HAVE_PTSNAME) && !defined(TIOCGPTN)
     qWarning() << "Unsupported attempt to open pty with fd" << fd;
     return false;
#else
    Q_D(KPty);

    if (d->masterFd >= 0) {
        qWarning() << "Attempting to open an already open pty";
         return false;
    }

    d->ownMaster = false;

# ifdef HAVE_PTSNAME
    char *ptsn = ptsname(fd);
    if (ptsn) {
        d->ttyName = ptsn;
# else
    int ptyno;
    if (!ioctl(fd, TIOCGPTN, &ptyno)) {
        char buf[32];
        sprintf(buf, "/dev/pts/%d", ptyno);
        d->ttyName = buf;
# endif
    } else {
        qWarning() << "Failed to determine pty slave device for fd" << fd;
        return false;
    }

    d->masterFd = fd;
    if (!openSlave()) {

        d->masterFd = -1;
        return false;
    }

    return true;
#endif
}

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

    if (d->slaveFd < 0) {
        return;
    }
    ::close(d->slaveFd);
    d->slaveFd = -1;
}
Beispiel #18
0
int
main(int argc, char *argv[])
{
	extern char **environ;
	char *tname;
	int repcnt = 0, failopenlogged = 0;
	struct rlimit limit;
	int rval;

	signal(SIGINT, SIG_IGN);
/*
	signal(SIGQUIT, SIG_DFL);
*/
	openlog("getty", LOG_ODELAY|LOG_CONS|LOG_PID, LOG_AUTH);
	gethostname(hostname, sizeof(hostname));
	if (hostname[0] == '\0')
		strlcpy(hostname, "Amnesiac", sizeof hostname);
	uname(&kerninfo);

	/*
	 * Limit running time to deal with broken or dead lines.
	 */
	(void)signal(SIGXCPU, timeoverrun);
	limit.rlim_max = RLIM_INFINITY;
	limit.rlim_cur = GETTY_TIMEOUT;
	(void)setrlimit(RLIMIT_CPU, &limit);

	/*
	 * The following is a work around for vhangup interactions
	 * which cause great problems getting window systems started.
	 * If the tty line is "-", we do the old style getty presuming
	 * that the file descriptors are already set up for us.
	 * J. Gettys - MIT Project Athena.
	 */
	if (argc <= 2 || strcmp(argv[2], "-") == 0) {
		snprintf(ttyn, sizeof ttyn, "%s", ttyname(0));
	} else {
		int i;

		snprintf(ttyn, sizeof ttyn, "%s%s", dev, argv[2]);
		if (strcmp(argv[0], "+") != 0) {
			chown(ttyn, 0, 0);
			chmod(ttyn, 0600);
			revoke(ttyn);
			/*
			 * Delay the open so DTR stays down long enough to be detected.
			 */
			sleep(2);
			while ((i = open(ttyn, O_RDWR)) == -1) {
				if ((repcnt % 10 == 0) &&
				    (errno != ENXIO || !failopenlogged)) {
					syslog(LOG_ERR, "%s: %m", ttyn);
					closelog();
					failopenlogged = 1;
				}
				repcnt++;
				sleep(60);
			}
			login_tty(i);
		}
	}

	/* Start with default tty settings */
	if (tcgetattr(0, &tmode) < 0) {
		syslog(LOG_ERR, "%s: %m", ttyn);
		exit(1);
	}
	omode = tmode;

	gettable("default", defent);
	gendefaults();
	tname = "default";
	if (argc > 1)
		tname = argv[1];
	for (;;) {
		int off;

		gettable(tname, tabent);
		if (OPset || EPset || APset)
			APset++, OPset++, EPset++;
		setdefaults();
		off = 0;
		(void)tcflush(0, TCIOFLUSH);	/* clear out the crap */
		ioctl(0, FIONBIO, &off);	/* turn off non-blocking mode */
		ioctl(0, FIOASYNC, &off);	/* ditto for async mode */

		if (IS)
			cfsetispeed(&tmode, IS);
		else if (SP)
			cfsetispeed(&tmode, SP);
		if (OS)
			cfsetospeed(&tmode, OS);
		else if (SP)
			cfsetospeed(&tmode, SP);
		setflags(0);
		setchars();
		if (tcsetattr(0, TCSANOW, &tmode) < 0) {
			syslog(LOG_ERR, "%s: %m", ttyn);
			exit(1);
		}
		if (AB) {
			tname = autobaud();
			continue;
		}
		if (PS) {
			tname = portselector();
			continue;
		}
		if (CL && *CL)
			putpad(CL);
		edithost(HE);
		if (IM && *IM)
			putf(IM);
		if (TO) {
			signal(SIGALRM, dingdong);
			alarm(TO);
		}
		if ((rval = getname()) == 2) {
			oflush();
			alarm(0);
			signal(SIGALRM, SIG_DFL);
			execle(PP, "ppplogin", ttyn, (char *) 0, env);
			syslog(LOG_ERR, "%s: %m", PP);
			exit(1);
		} else if (rval) {
			int i;

			oflush();
			alarm(0);
			signal(SIGALRM, SIG_DFL);
			if (name[0] == '-') {
				xputs("user names may not start with '-'.");
				continue;
			}
			if (!(upper || lower || digit))
				continue;
			setflags(2);
			if (crmod) {
				tmode.c_iflag |= ICRNL;
				tmode.c_oflag |= ONLCR;
			}
			if (upper || UC) {
				tmode.c_iflag |= IUCLC;
				tmode.c_oflag |= OLCUC;
				tmode.c_lflag |= XCASE;
			}
			if (lower || LC) {
				tmode.c_iflag &= ~IUCLC;
				tmode.c_oflag &= ~OLCUC;
				tmode.c_lflag &= ~XCASE;
			}
			if (tcsetattr(0, TCSANOW, &tmode) < 0) {
				syslog(LOG_ERR, "%s: %m", ttyn);
				exit(1);
			}
			signal(SIGINT, SIG_DFL);
			for (i = 0; environ[i] != (char *)0; i++)
				env[i] = environ[i];
			makeenv(&env[i]);

			limit.rlim_max = RLIM_INFINITY;
			limit.rlim_cur = RLIM_INFINITY;
			(void)setrlimit(RLIMIT_CPU, &limit);
			execle(LO, "login", "-p", "--", name, (char *)0, env);
			syslog(LOG_ERR, "%s: %m", LO);
			exit(1);
		}
		alarm(0);
		signal(SIGALRM, SIG_DFL);
		signal(SIGINT, SIG_IGN);
		if (NX && *NX)
			tname = NX;
	}
}
Beispiel #19
0
int
main(int argc, char *argv[])
{
    long retval;
    int status;
    char buf[4];
    int n;

    prog = argv[0];

    printf("parent: pid=%ld\n", (long)getpid());

    retval = ptyint_getpty_ext(&masterfd, slave, sizeof(slave), 0);

    if (retval) {
	com_err(prog, retval, "open master");
	exit(1);
    }
#if 0
    chown(slave, 1, -1);
#endif
    printf("parent: master opened; slave=%s\n", slave);
    fflush(stdout);

#if defined(HAVE_GRANTPT) && defined(HAVE_STREAMS)
#ifdef O_NOCTTY
    printf("parent: attempting to open slave before unlockpt\n");
    fflush(stdout);
    slavefd = open(slave, O_RDWR|O_NONBLOCK|O_NOCTTY);
    if (slavefd < 0) {
	printf("parent: failed slave open before unlockpt errno=%ld (%s)\n",
	       (long)errno, strerror(errno));
    } else {
	printf("parent: WARNING: "
	       "succeeded in opening slave before unlockpt\n");
    }
    close(slavefd);
#endif
    if (grantpt(masterfd) < 0) {
	perror("parent: grantpt");
	exit(1);
    }
    if (unlockpt(masterfd) < 0) {
	perror("parent: unlockpt");
	exit(1);
    }
#endif /* HAVE_GRANTPT && HAVE_STREAMS */

    if (pipe(pp1) < 0) {
	perror("pipe parent->child1");
	exit(1);
    }
    if (pipe(p1p) < 0) {
	perror("pipe child1->parent");
	exit(1);
    }

    pid1 = fork();
    if (!pid1) {
	child1();
    } else if (pid1 == -1) {
	perror("fork of child1");
	exit(1);
    }
    printf("parent: forked child1=%ld\n", (long)pid1);
    fflush(stdout);
    if (waitpid(pid1, &status1, 0) < 0) {
	perror("waitpid for child1");
	exit(1);
    }
    printf("parent: child1 exited, status=%d\n", status1);
    if (status1)
	exit(status1);

    wrsync(pp1[1], 0, "[01] parent->child2");
    rdsync(p1p[0], &status, "[02] child3->parent");
    if (status) {
	fprintf(stderr, "child2 or child3 got an error\n");
	exit(1);
    }

    printf("parent: closing master\n");
    fflush(stdout);
    close(masterfd);
    chmod(slave, 0666);
    printf("parent: closed master\n");
    wrsync(pp1[1], 0, "[03] parent->child3");

    rdsync(p1p[0], &status, "[04] child3->parent");
    switch (status) {
    case 1:
	break;
    case 0:
	exit(0);
    default:
	fprintf(stderr, "child3 got an error\n");
	fflush(stdout);
	exit(1);
    }

    retval = pty_getpty(&masterfd, slave2, sizeof(slave2));
    printf("parent: new master opened; slave=%s\n", slave2);
#if 0
#ifdef HAVE_REVOKE
    printf("parent: revoking\n");
    revoke(slave2);
#endif
#endif
    fflush(stdout);
    wrsync(pp1[1], 0, "[05] parent->child3");
    rdsync(p1p[0], NULL, "[06] child3->parent");

    n = read(masterfd, buf, 4);
    if (n < 0) {
	perror("parent: reading from master");
    } else {
	printf("parent: read %d bytes (%.*s) from master\n", n, n, buf);
	fflush(stdout);
    }
    chmod(slave2, 0666);
    close(masterfd);
    wrsync(pp1[1], 0, "[07] parent->child3");
    rdsync(p1p[0], NULL, "[08] child3->parent");
    fflush(stdout);
    exit(0);
}
Beispiel #20
0
/*
 * Threaded process initialization.
 *
 * This is only called under two conditions:
 *
 *   1) Some thread routines have detected that the library hasn't yet
 *      been initialized (_thr_initial == NULL && curthread == NULL), or
 *
 *   2) An explicit call to reinitialize after a fork (indicated
 *      by curthread != NULL)
 */
void
_libpthread_init(struct pthread *curthread)
{
	int fd, first = 0;

	/* Check if this function has already been called: */
	if ((_thr_initial != NULL) && (curthread == NULL))
		/* Only initialize the threaded application once. */
		return;

	/*
	 * Check the size of the jump table to make sure it is preset
	 * with the correct number of entries.
	 */
	if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2))
		PANIC("Thread jump table not properly initialized");
	memcpy(__thr_jtable, jmp_table, sizeof(jmp_table));

	/*
	 * Check for the special case of this process running as
	 * or in place of init as pid = 1:
	 */
	if ((_thr_pid = getpid()) == 1) {
		/*
		 * Setup a new session for this process which is
		 * assumed to be running as root.
		 */
		if (setsid() == -1)
			PANIC("Can't set session ID");
		if (revoke(_PATH_CONSOLE) != 0)
			PANIC("Can't revoke console");
		if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
			PANIC("Can't open console");
		if (setlogin("root") == -1)
			PANIC("Can't set login to root");
		if (_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1)
			PANIC("Can't set controlling terminal");
	}

	/* Initialize pthread private data. */
	init_private();

	/* Set the initial thread. */
	if (curthread == NULL) {
		first = 1;
		/* Create and initialize the initial thread. */
		curthread = _thr_alloc(NULL);
		if (curthread == NULL)
			PANIC("Can't allocate initial thread");
		init_main_thread(curthread);
	}
	/*
	 * Add the thread to the thread list queue.
	 */
	THR_LIST_ADD(curthread);
	_thread_active_threads = 1;

	/* Setup the thread specific data */
	_tcb_set(curthread->tcb);

	if (first) {
		_thr_initial = curthread;
		_thr_signal_init();
		if (_thread_event_mask & TD_CREATE)
			_thr_report_creation(curthread, curthread);
	}
}
Beispiel #21
0
static void
chvt(const char *fn)
{
	char dv[20];
	struct stat sb;
	int fd;

	/* for entropy */
	kshstate_f.h = evilhash(fn);

	if (*fn == '-') {
		memcpy(dv, "-/dev/null", sizeof("-/dev/null"));
		fn = dv + 1;
	} else {
		if (stat(fn, &sb)) {
			memcpy(dv, "/dev/ttyC", 9);
			strlcpy(dv + 9, fn, sizeof(dv) - 9);
			if (stat(dv, &sb)) {
				strlcpy(dv + 8, fn, sizeof(dv) - 8);
				if (stat(dv, &sb))
					errorf("chvt: can't find tty %s", fn);
			}
			fn = dv;
		}
		if (!(sb.st_mode & S_IFCHR))
			errorf("chvt: not a char device: %s", fn);
		if ((sb.st_uid != 0) && chown(fn, 0, 0))
			warningf(false, "chvt: cannot chown root %s", fn);
		if (((sb.st_mode & 07777) != 0600) && chmod(fn, (mode_t)0600))
			warningf(false, "chvt: cannot chmod 0600 %s", fn);
#if HAVE_REVOKE
		if (revoke(fn))
#endif
			warningf(false, "chvt: cannot revoke %s, new shell is"
			    " potentially insecure", fn);
	}
	if ((fd = open(fn, O_RDWR)) == -1) {
		sleep(1);
		if ((fd = open(fn, O_RDWR)) == -1)
			errorf("chvt: cannot open %s", fn);
	}
	switch (fork()) {
	case -1:
		errorf("chvt: %s failed", "fork");
	case 0:
		break;
	default:
		exit(0);
	}
	if (setsid() == -1)
		errorf("chvt: %s failed", "setsid");
	if (fn != dv + 1) {
		if (ioctl(fd, TIOCSCTTY, NULL) == -1)
			errorf("chvt: %s failed", "TIOCSCTTY");
		if (tcflush(fd, TCIOFLUSH))
			errorf("chvt: %s failed", "TCIOFLUSH");
	}
	ksh_dup2(fd, 0, false);
	ksh_dup2(fd, 1, false);
	ksh_dup2(fd, 2, false);
	if (fd > 2)
		close(fd);
	chvt_reinit();
}
Beispiel #22
0
/*
 * Threaded process initialization.
 *
 * This is only called under two conditions:
 *
 *   1) Some thread routines have detected that the library hasn't yet
 *      been initialized (_thr_initial == NULL && curthread == NULL), or
 *
 *   2) An explicit call to reinitialize after a fork (indicated
 *      by curthread != NULL)
 */
void
_libpthread_init(struct pthread *curthread)
{
	int fd;

	/* Check if this function has already been called: */
	if ((_thr_initial != NULL) && (curthread == NULL))
		/* Only initialize the threaded application once. */
		return;

	/*
	 * Make gcc quiescent about {,libgcc_}references not being
	 * referenced:
	 */
	if ((references[0] == NULL) || (libgcc_references[0] == NULL))
		PANIC("Failed loading mandatory references in _thread_init");

	/* Pull debug symbols in for static binary */
	_thread_state_running = PS_RUNNING;

	/*
	 * Check the size of the jump table to make sure it is preset
	 * with the correct number of entries.
	 */
	if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2))
		PANIC("Thread jump table not properly initialized");
	memcpy(__thr_jtable, jmp_table, sizeof(jmp_table));

	/*
	 * Check for the special case of this process running as
	 * or in place of init as pid = 1:
	 */
	if ((_thr_pid = getpid()) == 1) {
		/*
		 * Setup a new session for this process which is
		 * assumed to be running as root.
		 */
		if (setsid() == -1)
			PANIC("Can't set session ID");
		if (revoke(_PATH_CONSOLE) != 0)
			PANIC("Can't revoke console");
		if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
			PANIC("Can't open console");
		if (setlogin("root") == -1)
			PANIC("Can't set login to root");
		if (__sys_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1)
			PANIC("Can't set controlling terminal");
	}

	/* Initialize pthread private data. */
	init_private();
	_kse_init();

	/* Initialize the initial kse and kseg. */
	_kse_initial = _kse_alloc(NULL, _thread_scope_system > 0);
	if (_kse_initial == NULL)
		PANIC("Can't allocate initial kse.");
	_kse_initial->k_kseg = _kseg_alloc(NULL);
	if (_kse_initial->k_kseg == NULL)
		PANIC("Can't allocate initial kseg.");
	_kse_initial->k_kseg->kg_flags |= KGF_SINGLE_THREAD;
	_kse_initial->k_schedq = &_kse_initial->k_kseg->kg_schedq;

	TAILQ_INSERT_TAIL(&_kse_initial->k_kseg->kg_kseq, _kse_initial, k_kgqe);
	_kse_initial->k_kseg->kg_ksecount = 1;

	/* Set the initial thread. */
	if (curthread == NULL) {
		/* Create and initialize the initial thread. */
		curthread = _thr_alloc(NULL);
		if (curthread == NULL)
			PANIC("Can't allocate initial thread");
		_thr_initial = curthread;
		init_main_thread(curthread);
	} else {
		/*
		 * The initial thread is the current thread.  It is
		 * assumed that the current thread is already initialized
		 * because it is left over from a fork().
		 */
		_thr_initial = curthread;
	}
	_kse_initial->k_kseg->kg_threadcount = 0;
	_thr_initial->kse = _kse_initial;
	_thr_initial->kseg = _kse_initial->k_kseg;
	_thr_initial->active = 1;

	/*
	 * Add the thread to the thread list and to the KSEG's thread
         * queue.
	 */
	THR_LIST_ADD(_thr_initial);
	KSEG_THRQ_ADD(_kse_initial->k_kseg, _thr_initial);

	/* Setup the KSE/thread specific data for the current KSE/thread. */
	_thr_initial->kse->k_curthread = _thr_initial;
	_kcb_set(_thr_initial->kse->k_kcb);
	_tcb_set(_thr_initial->kse->k_kcb, _thr_initial->tcb);
	_thr_initial->kse->k_flags |= KF_INITIALIZED;

	_thr_signal_init();
	_kse_critical_leave(&_thr_initial->tcb->tcb_tmbx);
	/*
	 * activate threaded mode as soon as possible if we are
	 * being debugged
	 */
	if (_libkse_debug)
		_kse_setthreaded(1);
}
Beispiel #23
0
static void
chvt(const Getopt *go)
{
	const char *dv = go->optarg;
	char *cp = NULL;
	int fd;

	switch (*dv) {
	case '-':
		dv = "/dev/null";
		break;
	case '!':
		++dv;
		/* FALLTHROUGH */
	default: {
		struct stat sb;

		if (stat(dv, &sb)) {
			cp = shf_smprintf("/dev/ttyC%s", dv);
			dv = cp;
			if (stat(dv, &sb)) {
				memmove(cp + 1, cp, /* /dev/tty */ 8);
				dv = cp + 1;
				if (stat(dv, &sb)) {
					errorf("%s: %s: %s", "chvt",
					    "can't find tty", go->optarg);
				}
			}
		}
		if (!(sb.st_mode & S_IFCHR))
			errorf("%s: %s: %s", "chvt", "not a char device", dv);
#ifndef MKSH_DISABLE_REVOKE_WARNING
#if HAVE_REVOKE
		if (revoke(dv))
#endif
			warningf(false, "%s: %s %s", "chvt",
			    "new shell is potentially insecure, can't revoke",
			    dv);
#endif
	    }
	}
	if ((fd = binopen2(dv, O_RDWR)) < 0) {
		sleep(1);
		if ((fd = binopen2(dv, O_RDWR)) < 0) {
			errorf("%s: %s %s", "chvt", "can't open", dv);
		}
	}
	if (go->optarg[0] != '!') {
		switch (fork()) {
		case -1:
			errorf("%s: %s %s", "chvt", "fork", "failed");
		case 0:
			break;
		default:
			exit(0);
		}
	}
	if (setsid() == -1)
		errorf("%s: %s %s", "chvt", "setsid", "failed");
	if (go->optarg[0] != '-') {
		if (ioctl(fd, TIOCSCTTY, NULL) == -1)
			errorf("%s: %s %s", "chvt", "TIOCSCTTY", "failed");
		if (tcflush(fd, TCIOFLUSH))
			errorf("%s: %s %s", "chvt", "TCIOFLUSH", "failed");
	}
	ksh_dup2(fd, 0, false);
	ksh_dup2(fd, 1, false);
	ksh_dup2(fd, 2, false);
	if (fd > 2)
		close(fd);
	rndset((unsigned long)chvt_rndsetup(go, sizeof(Getopt)));
	chvt_reinit();
}
Beispiel #24
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
}
Beispiel #25
0
BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
  assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");

  // We can revoke the biases of anonymously-biased objects
  // efficiently enough that we should not cause these revocations to
  // update the heuristics because doing so may cause unwanted bulk
  // revocations (which are expensive) to occur.
  markOop mark = obj->mark();
  if (mark->is_biased_anonymously() && !attempt_rebias) {
    // We are probably trying to revoke the bias of this object due to
    // an identity hash code computation. Try to revoke the bias
    // without a safepoint. This is possible if we can successfully
    // compare-and-exchange an unbiased header into the mark word of
    // the object, meaning that no other thread has raced to acquire
    // the bias of the object.
    markOop biased_value       = mark;
    markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
    markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark);
    if (res_mark == biased_value) {
      return BIAS_REVOKED;
    }
  } else if (mark->has_bias_pattern()) {
    Klass* k = obj->klass();
    markOop prototype_header = k->prototype_header();
    if (!prototype_header->has_bias_pattern()) {
      // This object has a stale bias from before the bulk revocation
      // for this data type occurred. It's pointless to update the
      // heuristics at this point so simply update the header with a
      // CAS. If we fail this race, the object's bias has been revoked
      // by another thread so we simply return and let the caller deal
      // with it.
      markOop biased_value       = mark;
      markOop res_mark = (markOop) Atomic::cmpxchg_ptr(prototype_header, obj->mark_addr(), mark);
      assert(!(*(obj->mark_addr()))->has_bias_pattern(), "even if we raced, should still be revoked");
      return BIAS_REVOKED;
    } else if (prototype_header->bias_epoch() != mark->bias_epoch()) {
      // The epoch of this biasing has expired indicating that the
      // object is effectively unbiased. Depending on whether we need
      // to rebias or revoke the bias of this object we can do it
      // efficiently enough with a CAS that we shouldn't update the
      // heuristics. This is normally done in the assembly code but we
      // can reach this point due to various points in the runtime
      // needing to revoke biases.
      if (attempt_rebias) {
        assert(THREAD->is_Java_thread(), "");
        markOop biased_value       = mark;
        markOop rebiased_prototype = markOopDesc::encode((JavaThread*) THREAD, mark->age(), prototype_header->bias_epoch());
        markOop res_mark = (markOop) Atomic::cmpxchg_ptr(rebiased_prototype, obj->mark_addr(), mark);
        if (res_mark == biased_value) {
          return BIAS_REVOKED_AND_REBIASED;
        }
      } else {
        markOop biased_value       = mark;
        markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age());
        markOop res_mark = (markOop) Atomic::cmpxchg_ptr(unbiased_prototype, obj->mark_addr(), mark);
        if (res_mark == biased_value) {
          return BIAS_REVOKED;
        }
      }
    }
  }

  HeuristicsResult heuristics = update_heuristics(obj(), attempt_rebias);
  if (heuristics == HR_NOT_BIASED) {
    return NOT_BIASED;
  } else if (heuristics == HR_SINGLE_REVOKE) {
    Klass *k = obj->klass();
    markOop prototype_header = k->prototype_header();
    if (mark->biased_locker() == THREAD &&
        prototype_header->bias_epoch() == mark->bias_epoch()) {
      // A thread is trying to revoke the bias of an object biased
      // toward it, again likely due to an identity hash code
      // computation. We can again avoid a safepoint in this case
      // since we are only going to walk our own stack. There are no
      // races with revocations occurring in other threads because we
      // reach no safepoints in the revocation path.
      // Also check the epoch because even if threads match, another thread
      // can come in with a CAS to steal the bias of an object that has a
      // stale epoch.
      ResourceMark rm;
      if (TraceBiasedLocking) {
        tty->print_cr("Revoking bias by walking my own stack:");
      }
      BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD);
      ((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
      assert(cond == BIAS_REVOKED, "why not?");
      return cond;
    } else {
      VM_RevokeBias revoke(&obj, (JavaThread*) THREAD);
      VMThread::execute(&revoke);
      return revoke.status_code();
    }
  }

  assert((heuristics == HR_BULK_REVOKE) ||
         (heuristics == HR_BULK_REBIAS), "?");
  VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*) THREAD,
                                (heuristics == HR_BULK_REBIAS),
                                attempt_rebias);
  VMThread::execute(&bulk_revoke);
  return bulk_revoke.status_code();
}
Beispiel #26
0
int main () { return revoke("/") ; }
Beispiel #27
0
void
die_you_gravy_sucking_pig_dog(void)
{

	syslog(LOG_NOTICE, "%s by %s: %s",
	    doreboot ? "reboot" : dohalt ? "halt" : "shutdown", whom, mbuf);
	(void)sleep(2);

	(void)printf("\r\nSystem shutdown time has arrived\007\007\r\n");
	if (killflg) {
		(void)printf("\rbut you'll have to do it yourself\r\n");
		finish(0);
	}
	if (dofast)
		doitfast();
#ifdef DEBUG
	if (doreboot)
		(void)printf("reboot");
	else if (dohalt)
		(void)printf("halt");
	if (nosync)
		(void)printf(" no sync");
	if (dofast)
		(void)printf(" no fsck");
	if (dodump)
		(void)printf(" with dump");
	(void)printf("\nkill -HUP 1\n");
#else
	if (doreboot) {
		execle(_PATH_REBOOT, "reboot", "-l",
		    (nosync ? "-n" : (dodump ? "-d" : NULL)),
		    (dodump ? "-d" : NULL), (char *)NULL, (char *)NULL);
		syslog(LOG_ERR, "shutdown: can't exec %s: %m.", _PATH_REBOOT);
		warn(_PATH_REBOOT);
	}
	else if (dohalt) {
		execle(_PATH_HALT, "halt", "-l",
		    (dopower ? "-p" : (nosync ? "-n" : (dodump ? "-d" : NULL))),
		    (nosync ? "-n" : (dodump ? "-d" : NULL)),
		    (dodump ? "-d" : NULL), (char *)NULL, (char *)NULL);
		syslog(LOG_ERR, "shutdown: can't exec %s: %m.", _PATH_HALT);
		warn(_PATH_HALT);
	}
	if (access(_PATH_RC, R_OK) != -1) {
		pid_t pid;
		struct termios t;
		int fd;

		switch ((pid = fork())) {
		case -1:
			break;
		case 0:
			if (revoke(_PATH_CONSOLE) == -1)
				perror("revoke");
			if (setsid() == -1)
				perror("setsid");
			fd = open(_PATH_CONSOLE, O_RDWR);
			if (fd == -1)
				perror("open");
			dup2(fd, 0);
			dup2(fd, 1);
			dup2(fd, 2);
			if (fd > 2)
				close(fd);

			/* At a minimum... */
			tcgetattr(0, &t);
			t.c_oflag |= (ONLCR | OPOST);
			tcsetattr(0, TCSANOW, &t);

			execl(_PATH_BSHELL, "sh", _PATH_RC, "shutdown", (char *)NULL);
			_exit(1);
		default:
			waitpid(pid, NULL, 0);
		}
	}
	(void)kill(1, SIGTERM);		/* to single user */
#endif
	finish(0);
}