diff options
author | Eric Koegel <eric.koegel@gmail.com> | 2017-06-22 17:08:27 +0300 |
---|---|---|
committer | Eric Koegel <eric.koegel@gmail.com> | 2017-06-22 19:19:34 +0300 |
commit | 2095226293fc8d13e3fad30ca83d50d8692abc37 (patch) | |
tree | fbdc643db75043d5850f0555295c0d4d43a30027 | |
parent | c8ca45ab96888d35ccb37d33a0c213d16f94fba4 (diff) | |
download | ConsoleKit2-2095226293fc8d13e3fad30ca83d50d8692abc37.tar.gz |
fix: FreeBSD session activation
This is based heavily on the work of Jesper Schmitz Mouridsen in:
https://bugs.freebsd.org/bugzilla/attachment.cgi?id=179399&action=diff
from:
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=202269
Fixes: https://github.com/ConsoleKit2/ConsoleKit2/issues/85
-rw-r--r-- | configure.ac | 7 | ||||
-rw-r--r-- | src/ck-sysdeps-freebsd.c | 2 | ||||
-rw-r--r-- | src/ck-sysdeps-unix.c | 38 | ||||
-rw-r--r-- | tools/ck-get-x11-display-device.c | 76 |
4 files changed, 112 insertions, 11 deletions
diff --git a/configure.ac b/configure.ac index 525cf62..35e2c4d 100644 --- a/configure.ac +++ b/configure.ac @@ -71,7 +71,7 @@ AC_CHECK_HEADERS([unistd.h paths.h sys/vt.h sys/consio.h fcntl.h limits.h \ sys/wait.h sys/resource.h sys/mount.h sys/param.h ftw.h \ sys/sysmacros.h sys/types.h libudev.h linux/input.h \ sys/mkdev.h devattr.h sys/kd.h sys/kbio.h libprop/proplib.h \ - linux/kd.h]) + linux/kd.h sys/queue.h sys/stat.h sys/fcntl.h]) AC_CHECK_FUNCS([getpeerucred getpeereid memset setenv strchr strdup \ strerror strrchr strspn strstr strtol strtoul uname \ @@ -203,6 +203,11 @@ case "$host" in if test "x$have_kvm" = "xyes"; then KVM_LIBS="-lkvm" fi + AC_CHECK_LIB(procstat, procstat_open_sysctl, have_procstat=yes, + AC_MSG_WARN([Unable to find libprocstat which is used on FreeBSD])) + if test "x$have_procstat" = "xyes"; then + KVM_LIBS="${KVM_LIBS} -lprocstat" + fi ;; *-*-netbsd*) CK_BACKEND="netbsd" diff --git a/src/ck-sysdeps-freebsd.c b/src/ck-sysdeps-freebsd.c index 6396cda..66babdd 100644 --- a/src/ck-sysdeps-freebsd.c +++ b/src/ck-sysdeps-freebsd.c @@ -128,7 +128,7 @@ ck_process_stat_get_tty (CkProcessStat *stat) { g_return_val_if_fail (stat != NULL, NULL); - return g_strdup (stat->tty_text); + return g_strdup_printf ("/dev/%s", stat->tty_text); } static gboolean diff --git a/src/ck-sysdeps-unix.c b/src/ck-sysdeps-unix.c index 6d39dff..dcf6be0 100644 --- a/src/ck-sysdeps-unix.c +++ b/src/ck-sysdeps-unix.c @@ -57,6 +57,14 @@ #include <ucred.h> #endif +#ifdef __FreeBSD__ +#include <kvm.h> +#include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/user.h> +#include <paths.h> +#endif + #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -134,6 +142,10 @@ ck_get_socket_peer_credentials (int socket_fd, } #elif defined(HAVE_GETPEEREID) gid_t dummy; + char errbuf[_POSIX2_LINE_MAX]; + int cnt = 0; + kvm_t* kd; + struct kinfo_proc * prc; if (getpeereid (socket_fd, &uid_read, &dummy) == 0) { ret = TRUE; @@ -141,6 +153,23 @@ ck_get_socket_peer_credentials (int socket_fd, g_warning ("Failed to getpeereid() credentials: %s\n", g_strerror (errno)); } +#ifdef __FreeBSD__ + kd = kvm_openfiles (NULL, _PATH_DEVNULL, NULL, O_RDONLY, errbuf); + if (kd == NULL) { + g_warning ("kvm_openfiles failed: %s", errbuf); + return FALSE; + } + + prc = kvm_getprocs (kd, KERN_PROC_UID, uid_read, &cnt); + for (int i = 0; i < cnt; i++) { + if(strncmp (prc[i].ki_comm, "Xorg", 4) == 0) { + pid_read = prc[i].ki_pid; + break; + } + } + + kvm_close(kd); +#endif /* __FreeBSD__ */ #else /* !SO_PEERCRED && !HAVE_GETPEERUCRED */ g_warning ("Socket credentials not supported on this OS\n"); #endif @@ -238,15 +267,6 @@ ck_get_a_console_fd (void) fd = -1; -#ifdef __FreeBSD__ - /* On FreeBSD, try /dev/consolectl first as this will survive - * /etc/ttys initialization. */ - fd = ck_open_a_console ("/dev/consolectl"); - if (fd >= 0) { - goto done; - } -#endif - #ifdef __sun /* On Solaris, first try Sun VT device. */ fd = ck_open_a_console ("/dev/vt/active"); diff --git a/tools/ck-get-x11-display-device.c b/tools/ck-get-x11-display-device.c index 348115c..7925e76 100644 --- a/tools/ck-get-x11-display-device.c +++ b/tools/ck-get-x11-display-device.c @@ -28,6 +28,33 @@ #include <libintl.h> #include <locale.h> +#ifdef HAVE_KVM_H +#include <kvm.h> +#endif + +#ifdef HAVE_SYS_QUEUE_H +#include <sys/queue.h> +#endif + +#ifdef HAVE_SYS_FCNTL_H +#include <sys/fcntl.h> +#endif +#ifdef HAVE_SYS_USER_H +#include <sys/user.h> +#endif +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif +#ifdef HAVE_SYS_SYSCTL_H +#include <sys/sysctl.h> +#endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + #include <X11/Xlib.h> #include <X11/Xatom.h> #include <glib.h> @@ -35,6 +62,54 @@ #include "ck-sysdeps.h" +#ifdef __FreeBSD__ +#include <libprocstat.h> + + +static char * +get_tty_for_pid (int pid) +{ + gchar *device = NULL; + gboolean res; + char errstr[_POSIX2_LINE_MAX]; + int cnt = 0; + struct vnstat vn; + struct filestat_list *head; + struct filestat *fst; + kvm_t* kd; + struct kinfo_proc * prc; + struct procstat *procstat; + + kd = kvm_openfiles (NULL, "/dev/null", NULL, O_RDONLY, errstr); + prc = kvm_getprocs (kd, KERN_PROC_PID, pid, &cnt); + procstat = procstat_open_sysctl (); + + for (int i = 0; i < cnt; i++) { + head = procstat_getfiles (procstat,&prc[i], 0); + + STAILQ_FOREACH (fst, head, next) { + if (fst->fs_type == PS_FST_TYPE_VNODE) { + procstat_get_vnode_info (procstat, fst, &vn, NULL); + + if (vn.vn_type == PS_FST_VTYPE_VCHR) { + char *ctty = devname( prc[i].ki_tdev,S_IFCHR); + const char * pre = "ttyv"; + + if(strncmp (pre, vn.vn_devname, strlen (pre)) == 0 && strncmp (vn.vn_devname, ctty, strlen(ctty)) != 0) { + device = g_strdup_printf ("/dev/%s", vn.vn_devname); + procstat_freefiles (procstat, head); + res = TRUE; + return device; + } + } + } + } + } + + procstat_freefiles(procstat, head); + return device; +} +#else /* __FreeBSD__ */ static char * get_tty_for_pid (int pid) { @@ -58,6 +133,7 @@ get_tty_for_pid (int pid) ck_process_stat_free (xorg_stat); return device; } +#endif /* __FreeBSD__ */ static Display * display_init (const char *display_name) |