コード例 #1
0
ファイル: launcher.c プロジェクト: Blei/weston
static int
weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data)
{
	struct weston_xserver *mxs = data;
	char display[8], s[8];
	int sv[2], client_fd;

	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
		weston_log("socketpair failed\n");
		return 1;
	}

	mxs->process.pid = fork();
	switch (mxs->process.pid) {
	case 0:
		/* SOCK_CLOEXEC closes both ends, so we need to unset
		 * the flag on the client fd. */
		client_fd = dup(sv[1]);
		if (client_fd < 0)
			return 1;

		snprintf(s, sizeof s, "%d", client_fd);
		setenv("WAYLAND_SOCKET", s, 1);

		snprintf(display, sizeof display, ":%d", mxs->display);

		if (execl(XSERVER_PATH,
			  XSERVER_PATH,
			  display,
			  "-wayland",
			  "-rootless",
			  "-retro",
			  "-nolisten", "all",
			  "-terminate",
			  NULL) < 0)
			weston_log("exec failed: %m\n");
		exit(-1);

	default:
		weston_log("forked X server, pid %d\n", mxs->process.pid);

		close(sv[1]);
		mxs->client = wl_client_create(mxs->wl_display, sv[0]);

		weston_watch_process(&mxs->process);

		wl_event_source_remove(mxs->abstract_source);
		wl_event_source_remove(mxs->unix_source);
		break;

	case -1:
		weston_log( "failed to fork\n");
		break;
	}

	return 1;
}
コード例 #2
0
ファイル: xwayland.cpp プロジェクト: kendling/orbital
static pid_t
spawn_xserver(struct weston_xserver *wxs)
{
    int sv[2], wm[2];

    if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
        weston_log("wl connection socketpair failed\n");
        return 1;
    }

    if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wm) < 0) {
        weston_log("X wm connection socketpair failed\n");
        return 1;
    }

    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    env.insert(QStringLiteral("WAYLAND_SOCKET"), QString::number(dup(sv[1])));

    QString display = QStringLiteral(":%1").arg(wxs->display);
    QString abstract_fd = QString::number(dup(wxs->abstract_fd));
    QString unix_fd = QString::number(dup(wxs->unix_fd));
    QString wm_fd = QString::number(dup(wm[1]));

    s_process = new Process;
    s_process->setProcessChannelMode(QProcess::ForwardedChannels);
    s_process->setProcessEnvironment(env);

    s_process->connect(s_process, (void (QProcess::*)(int))&QProcess::finished, [wxs](int exitCode) {
        weston_xserver_exited(wxs, exitCode);
        if (s_process) {
            delete s_process;
            s_process = nullptr;
        }
    });
    s_process->start(QStringLiteral("Xwayland"), {
              display,
              QStringLiteral("-rootless"),
              QStringLiteral("-listen"), abstract_fd,
              QStringLiteral("-listen"), unix_fd,
              QStringLiteral("-wm"), wm_fd,
              QStringLiteral("-terminate") });

    close(sv[1]);
    wxs->client = wl_client_create(wxs->wl_display, sv[0]);

    close(wm[1]);
    wxs->wm_fd = wm[0];

    return s_process->processId();
}
コード例 #3
0
ファイル: launcher.c プロジェクト: ChristophHaag/weston
static int
weston_xserver_handle_event(int listen_fd, uint32_t mask, void *data)
{
	struct weston_xserver *wxs = data;
	char display[8], s[8], abstract_fd[8], unix_fd[8], wm_fd[8];
	int sv[2], wm[2], fd;
	char *xserver = NULL;
	struct weston_config_section *section;

	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) < 0) {
		weston_log("wl connection socketpair failed\n");
		return 1;
	}

	if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, wm) < 0) {
		weston_log("X wm connection socketpair failed\n");
		return 1;
	}

	wxs->process.pid = fork();
	switch (wxs->process.pid) {
	case 0:
		/* SOCK_CLOEXEC closes both ends, so we need to unset
		 * the flag on the client fd. */
		fd = dup(sv[1]);
		if (fd < 0)
			goto fail;
		snprintf(s, sizeof s, "%d", fd);
		setenv("WAYLAND_SOCKET", s, 1);

		snprintf(display, sizeof display, ":%d", wxs->display);

		fd = dup(wxs->abstract_fd);
		if (fd < 0)
			goto fail;
		snprintf(abstract_fd, sizeof abstract_fd, "%d", fd);
		fd = dup(wxs->unix_fd);
		if (fd < 0)
			goto fail;
		snprintf(unix_fd, sizeof unix_fd, "%d", fd);
		fd = dup(wm[1]);
		if (fd < 0)
			goto fail;
		snprintf(wm_fd, sizeof wm_fd, "%d", fd);

		section = weston_config_get_section(wxs->compositor->config,
						    "xwayland", NULL, NULL);
		weston_config_section_get_string(section, "path",
						 &xserver, XSERVER_PATH);

		/* Ignore SIGUSR1 in the child, which will make the X
		 * server send SIGUSR1 to the parent (weston) when
		 * it's done with initialization.  During
		 * initialization the X server will round trip and
		 * block on the wayland compositor, so avoid making
		 * blocking requests (like xcb_connect_to_fd) until
		 * it's done with that. */
		signal(SIGUSR1, SIG_IGN);

		if (execl(xserver,
			  xserver,
			  display,
			  "-rootless",
			  "-listen", abstract_fd,
			  "-listen", unix_fd,
			  "-wm", wm_fd,
			  "-terminate",
			  NULL) < 0)
			weston_log("exec of '%s %s -rootless "
                                   "-listen %s -listen %s -wm %s "
                                   "-terminate' failed: %m\n",
                                   xserver, display,
                                   abstract_fd, unix_fd, wm_fd);
	fail:
		_exit(EXIT_FAILURE);

	default:
		weston_log("forked X server, pid %d\n", wxs->process.pid);

		close(sv[1]);
		wxs->client = wl_client_create(wxs->wl_display, sv[0]);

		close(wm[1]);
		wxs->wm_fd = wm[0];

		weston_watch_process(&wxs->process);

		wl_event_source_remove(wxs->abstract_source);
		wl_event_source_remove(wxs->unix_source);
		break;

	case -1:
		weston_log( "failed to fork\n");
		break;
	}

	return 1;
}
コード例 #4
0
ファイル: meta-xwayland.c プロジェクト: ueno/mutter
gboolean
meta_xwayland_start (MetaXWaylandManager *manager,
                     struct wl_display   *wl_display)
{
  int xwayland_client_fd[2];
  int displayfd[2];
  gboolean started = FALSE;
  g_autoptr(GSubprocessLauncher) launcher = NULL;
  GSubprocessFlags flags;
  GSubprocess *proc;
  GError *error = NULL;

  if (!choose_xdisplay (manager))
    goto out;

  /* We want xwayland to be a wayland client so we make a socketpair to setup a
   * wayland protocol connection. */
  if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, xwayland_client_fd) < 0)
    {
      g_warning ("xwayland_client_fd socketpair failed\n");
      goto out;
    }

  if (socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, displayfd) < 0)
    {
      g_warning ("displayfd socketpair failed\n");
      goto out;
    }

  /* xwayland, please. */
  flags = G_SUBPROCESS_FLAGS_NONE;

  if (getenv ("XWAYLAND_STFU"))
    {
      flags |= G_SUBPROCESS_FLAGS_STDOUT_SILENCE;
      flags |= G_SUBPROCESS_FLAGS_STDERR_SILENCE;
    }

  launcher = g_subprocess_launcher_new (flags);

  g_subprocess_launcher_take_fd (launcher, xwayland_client_fd[1], 3);
  g_subprocess_launcher_take_fd (launcher, manager->abstract_fd, 4);
  g_subprocess_launcher_take_fd (launcher, manager->unix_fd, 5);
  g_subprocess_launcher_take_fd (launcher, displayfd[1], 6);

  g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
  proc = g_subprocess_launcher_spawn (launcher, &error,
                                      XWAYLAND_PATH, manager->display_name,
                                      "-rootless", "-noreset",
                                      "-listen", "4",
                                      "-listen", "5",
                                      "-displayfd", "6",
                                      NULL);
  if (!proc)
    {
      g_error ("Failed to spawn Xwayland: %s", error->message);
      goto out;
    }

  g_subprocess_wait_async  (proc, NULL, xserver_died, NULL);
  g_unix_fd_add (displayfd[0], G_IO_IN, on_displayfd_ready, manager);
  manager->client = wl_client_create (wl_display, xwayland_client_fd[0]);

  /* We need to run a mainloop until we know xwayland has a binding
   * for our xserver interface at which point we can assume it's
   * ready to start accepting connections. */
  manager->init_loop = g_main_loop_new (NULL, FALSE);
  g_main_loop_run (manager->init_loop);

  started = TRUE;

out:
  if (!started)
    {
      unlink (manager->lock_file);
      g_clear_pointer (&manager->lock_file, g_free);
    }
  return started;
}