Exemplo n.º 1
0
Arquivo: main.c Projeto: giszo/urubu
// =====================================================================================================================
int main(int argc, char** argv)
{
    libdevman_server_init();
    libdevman_client_init();
    libdevman_client_async_init(libdevman_server_get_port());

    init_screen();
    init_input();
    init_pty();

    // register the terminal server
    ipc_server_register("terminal", libdevman_server_get_port());

    // run the mainloop
    libdevman_server_run(terminal_handler);

    return 0;
}
Exemplo n.º 2
0
/* clients. */
static void
master_process(int s, char **argv, int waitattach, int statusfd)
{
	struct client *p, *next;
	fd_set readfds;
	int highest_fd;
	int nullfd;

	int has_attached_client = 0;

	/* Okay, disassociate ourselves from the original terminal, as we
	** don't care what happens to it. */
	setsid();

	/* Set a trap to unlink the socket when we die. */
	atexit(unlink_socket);

	/* Create a pty in which the process is running. */
	signal(SIGCHLD, die);
	if (init_pty(argv, statusfd) < 0)
	{
		if (statusfd != -1)
			dup2(statusfd, 1);
		if (errno == ENOENT)
			printf("%s: Could not find a pty.\n", progname);
		else
			printf("%s: init_pty: %s\n", progname, strerror(errno));
		exit(1);
	}

	/* Set up some signals. */
	signal(SIGPIPE, SIG_IGN);
	signal(SIGXFSZ, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGTTIN, SIG_IGN);
	signal(SIGTTOU, SIG_IGN);
	signal(SIGINT, die);
	signal(SIGTERM, die);

	/* Close statusfd, since we don't need it anymore. */
	if (statusfd != -1)
		close(statusfd);

	/* Make sure stdin/stdout/stderr point to /dev/null. We are now a
	** daemon. */
	nullfd = open("/dev/null", O_RDWR);
	dup2(nullfd, 0);
	dup2(nullfd, 1);
	dup2(nullfd, 2);
	if (nullfd > 2)
		close(nullfd);

	/* Loop forever. */
	while (1)
	{
		int new_has_attached_client = 0;

		/* Re-initialize the file descriptor set for select. */
		FD_ZERO(&readfds);
		FD_SET(s, &readfds);
		highest_fd = s;

		/*
		** When waitattach is set, wait until the client attaches
		** before trying to read from the pty.
		*/
		if (waitattach)
		{
			if (clients && clients->attached)
				waitattach = 0;
		}
		else
		{
			FD_SET(the_pty.fd, &readfds);
			if (the_pty.fd > highest_fd)
				highest_fd = the_pty.fd;
		}

		for (p = clients; p; p = p->next)
		{
			FD_SET(p->fd, &readfds);
			if (p->fd > highest_fd)
				highest_fd = p->fd;

			if (p->attached)
				new_has_attached_client = 1;
		}

		/* chmod the socket if necessary. */
		if (has_attached_client != new_has_attached_client)
		{
			update_socket_modes(new_has_attached_client);
			has_attached_client = new_has_attached_client;
		}

		/* Wait for something to happen. */
		if (select(highest_fd + 1, &readfds, NULL, NULL, NULL) < 0)
		{
			if (errno == EINTR || errno == EAGAIN)
				continue;
			exit(1);
		}

		/* New client? */
		if (FD_ISSET(s, &readfds))
			control_activity(s);
		/* Activity on a client? */
		for (p = clients; p; p = next)
		{
			next = p->next;
			if (FD_ISSET(p->fd, &readfds))
				client_activity(p);
		}
		/* pty activity? */
		if (FD_ISSET(the_pty.fd, &readfds))
			pty_activity(s);
	}
}
Exemplo n.º 3
0
Arquivo: ulock.c Projeto: jwilk/ulock
static void setup_signals(void)
{
  struct sigaction sa = { .sa_handler = signal_handler, .sa_flags = 0 };
  sigset_t ss;
  do
  {
    if (sigfillset(&ss) == -1) break;
    if (sigemptyset(&sa.sa_mask) == -1) break;
    if (sigaction(SIGCHLD, &sa, NULL) == -1 || sigdelset(&ss, SIGCHLD) == -1) break;
    if (sigaction(SIGUSR1, &sa, NULL) == -1 || sigdelset(&ss, SIGUSR1) == -1) break;
    if (sigaction(SIGUSR2, &sa, NULL) == -1 || sigdelset(&ss, SIGUSR2) == -1) break;
    if (sigprocmask(SIG_SETMASK, &ss, NULL) == -1) break;
    return;
  }
  while (false);
  fatal("Error while setting up signal handlers.\n");
}

static void child_setup_signals(void)
{
  do
  {
    struct sigaction sa = { .sa_handler = SIG_DFL, .sa_flags = 0 };
    if (sigemptyset(&sa.sa_mask) == -1) break;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) break;
    if (sigaction(SIGUSR1, &sa, NULL) == -1) break;
    if (sigaction(SIGUSR2, &sa, NULL) == -1) break;
    if (sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL) == -1) break;
    return;
  }
  while (false);
  fatal("<child> Error while setting up signal handlers.\n");
}

static void invoke_command(char *command, char **argv, pid_t *child_pid, int *ptm)
{
  char* slavename = open_ptm(ptm);
  if (slavename == NULL)
    fatal("Error while opening pseudo-terminal.\n");

  struct winsize wsize;
  if (ioctl(STDIN_FILENO, TIOCGWINSZ, &wsize) == -1)
    fatal("Error while getting the terminal size.\n");

  struct termios attr;
  if (tcgetattr(*ptm, &attr) == -1)
    fatal("Error while getting the pseudo-terminal attributes.\n");

  switch (*child_pid = fork())
  {
  case -1:
    fatal("Fork failed.\n");
  case 0:
    /* child: */
    drop_privileges();
    if (close(*ptm) == -1)
      fatal("<child> Error while closing the master pseudo-terminal\n");
    if (setsid() == -1)
      fatal("<child> Error while creating a session\n");
    assert(slavename != NULL);
    int pts = open(slavename, O_RDWR);
    if (pts == -1)
      fatal("<child> Error while opening the slave pseudo-terminal\n");
    init_pty(pts, &wsize, attr);

    child_setup_signals();
    execvp(command, argv);
    fatal("<child> Execution failed.\n");
  default:
    /* parent: */
    return;
  }
}

static void clear(void)
{
  writes(STDOUT_FILENO, "\033[0m\033[H\033[J");
}
Exemplo n.º 4
0
static int
setup_child(pid_t *pid, const char *term, const char *attr, char *const *argv)
{
  int master;
  char ttyname[20];

  DBUG_ENTER("setup_child");
  switch ((*pid = pty_fork(&master, ttyname, 0, 0))) {
  case -1:
    DBUG_PRINT("startup", ("forkpty: failed"));
    DBUG_RETURN(-errno);
    /*NOTREACHED*/
  case 0: {
    const char *shell;
    DBUG_PROCESS("child");

    DBUG_PRINT("info", ("TERM=%s", term));
    if (term) setenv("TERM", term, 1);

    DBUG_PRINT("info", ("attributes=%s", attr));
    if (attr) init_pty(0, attr);

    if (!(shell = argv[0])) {
      char *s0;
      uid_t uid;
      struct passwd *pw;
      shell = "/bin/bash";
      s0 = "-bash";
      /* get user's login shell */
      if (!(pw = getpwuid(uid = getuid()))) {
        DBUG_PRINT("error", ("getpwuid(%ld) failed: %s",
          uid, strerror(errno)));
      }
      else if (!(shell = pw->pw_shell) || *shell != '/') {
        DBUG_PRINT("error", ("bad shell for user id %ld", uid));
      }
      else {
        DBUG_PRINT("info", ("got shell %s", shell));
        s0 = strrchr(shell, '/');
        s0 = str_dup(s0);
        assert(s0 != 0);
        s0[0] = '-';
      }
      DBUG_PRINT("info", ("startup %s (%s)", shell, s0));
      execl(shell, s0, (char *)0);
    }
    else {
      DBUG_PRINT("info", ("startup %s", *argv));
      execvp(*argv, argv);
    }

    DBUG_PRINT("error", ("exec* failed: %s", strerror(errno)));
    perror(shell);
    exit(111);
    /*NOTREACHED*/ }
  default: { // Parent process.
      fcntl(master, F_SETFL, O_NONBLOCK);
      char *dev = ptsname(master);
      if (dev) {
        struct utmp ut;
        memset(&ut, 0, sizeof ut);
        if (!strncmp(dev, "/dev/", 5))
          dev += 5;
        strlcpy(ut.ut_line, dev, sizeof ut.ut_line);
        if (dev[1] == 't' && dev[2] == 'y')
          dev += 3;
        if (!strncmp(dev, "pts/", 4))
          dev += 4;
        strncpy(ut.ut_id, dev, sizeof ut.ut_id);
        ut.ut_type = USER_PROCESS;
        ut.ut_pid = (long int)*pid;
        ut.ut_time = time(0);
        strlcpy(ut.ut_user, getlogin() ?: "?", sizeof ut.ut_user);
        gethostname(ut.ut_host, sizeof ut.ut_host);
        login(&ut);
      }
    }
  }
  DBUG_PRINT("startup", ("forkpty:pid=%ld:master=%d:ttyname=%s",
    (long int)*pid, master, ttyname));
  DBUG_RETURN(master);
}