From a9aa00ff0fea79452a60a2448dd1f2714918884a Mon Sep 17 00:00:00 2001 From: William Jon McCann Date: Wed, 18 Jul 2007 17:24:00 -0400 Subject: Add new helper for getting tty from DISPLAY --- tools/linux/Makefile.am | 11 +++ tools/linux/ck-get-x11-display-device.c | 138 ++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 tools/linux/ck-get-x11-display-device.c diff --git a/tools/linux/Makefile.am b/tools/linux/Makefile.am index 3283b5e..4b570a7 100644 --- a/tools/linux/Makefile.am +++ b/tools/linux/Makefile.am @@ -26,6 +26,7 @@ INCLUDES = \ libexec_PROGRAMS = \ ck-collect-session-info \ ck-get-x11-server-pid \ + ck-get-x11-display-device \ $(NULL) ck_collect_session_info_SOURCES = \ @@ -46,6 +47,16 @@ ck_get_x11_server_pid_LDADD = \ $(TOOLS_LIBS) \ $(NULL) +ck_get_x11_display_device_SOURCES = \ + $(top_srcdir)/src/proc.h \ + $(top_srcdir)/src/proc-linux.c \ + ck-get-x11-display-device.c \ + $(NULL) + +ck_get_x11_display_device_LDADD = \ + $(TOOLS_LIBS) \ + $(NULL) + EXTRA_DIST = \ $(NULL) diff --git a/tools/linux/ck-get-x11-display-device.c b/tools/linux/ck-get-x11-display-device.c new file mode 100644 index 0000000..c0d3772 --- /dev/null +++ b/tools/linux/ck-get-x11-display-device.c @@ -0,0 +1,138 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Authors: William Jon McCann + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include "proc.h" + +static char * +get_tty_for_pid (int pid) +{ + GError *error; + char *device; + gboolean res; + proc_stat_t *xorg_stat; + + error = NULL; + res = proc_stat_new_for_pid (pid, &xorg_stat, &error); + if (! res) { + if (error != NULL) { + g_warning ("stat on pid %d failed: %s", pid, error->message); + g_error_free (error); + } + /* keep the tty value */ + return NULL; + } + + device = proc_stat_get_tty (xorg_stat); + proc_stat_free (xorg_stat); + return device; +} + +static int +get_peer_pid (int fd) +{ + int pid = -1; +#ifdef SO_PEERCRED + struct ucred cr; + socklen_t cr_len; + + cr_len = sizeof (cr); + + if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 && cr_len == sizeof (cr)) { + /* paranoia check for peer running as root */ + if (cr.uid == 0) { + pid = cr.pid; + } + } else { + g_warning ("Failed to getsockopt() credentials, returned len %d/%d: %s\n", + cr_len, + (int) sizeof (cr), + g_strerror (errno)); + } +#endif + return pid; +} + +static Display * +display_init (int *argc, char ***argv) +{ + const char *display_name; + Display *xdisplay; + + display_name = g_getenv ("DISPLAY"); + + if (display_name == NULL) { + g_warning ("DISPLAY is not set"); + exit (1); + } + + xdisplay = XOpenDisplay (display_name); + if (xdisplay == NULL) { + g_warning ("cannot open display: %s", display_name ? display_name : ""); + exit (1); + } + + return xdisplay; +} + +int +main (int argc, + char **argv) +{ + int fd; + int ret; + Display *xdisplay; + + ret = 1; + + xdisplay = display_init (&argc, &argv); + + fd = ConnectionNumber (xdisplay); + + if (fd > 0) { + int pid; + char *device; + + ret = 0; + pid = get_peer_pid (fd); + if (pid != -1) { + device = get_tty_for_pid (pid); + if (device != NULL) { + printf ("%s\n", device); + g_free (device); + } + } + } + + return ret; +} -- cgit