summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am53
-rw-r--r--src/Makefile.in140
-rw-r--r--src/ck-file-monitor-inotify.c2
-rw-r--r--src/ck-job.c23
-rw-r--r--src/ck-log.c8
-rw-r--r--src/ck-manager-glue.h10
-rw-r--r--src/ck-manager.c116
-rw-r--r--src/ck-seat-glue.h17
-rw-r--r--src/ck-seat.c234
-rw-r--r--src/ck-seat.h36
-rw-r--r--src/ck-seat.xml9
-rw-r--r--src/ck-session-glue.h6
-rw-r--r--src/ck-session.c8
-rw-r--r--src/ck-sysdeps-freebsd.c423
-rw-r--r--src/ck-sysdeps-linux.c (renamed from src/proc-linux.c)163
-rw-r--r--src/ck-sysdeps-solaris.c469
-rw-r--r--src/ck-sysdeps-unix.c305
-rw-r--r--src/ck-sysdeps.h75
-rw-r--r--src/ck-vt-monitor.c94
-rw-r--r--src/getfd.c75
-rw-r--r--src/main.c18
-rw-r--r--src/proc.h48
-rw-r--r--src/test-tty-idle-monitor.c39
-rw-r--r--src/test-vt-monitor.c95
24 files changed, 2115 insertions, 351 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 0977591..3f142a3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -23,6 +23,38 @@ INCLUDES = \
$(DBUS_CFLAGS) \
$(NULL)
+noinst_LTLIBRARIES = \
+ libck.la \
+ $(NULL)
+
+libck_la_SOURCES = \
+ ck-sysdeps.h \
+ ck-sysdeps-unix.c \
+ $(NULL)
+
+if CK_COMPILE_LINUX
+libck_la_SOURCES += \
+ ck-sysdeps-linux.c \
+ $(NULL)
+endif
+if CK_COMPILE_SOLARIS
+libck_la_SOURCES += \
+ ck-sysdeps-solaris.c \
+ $(NULL)
+endif
+if CK_COMPILE_FREEBSD
+libck_la_SOURCES += \
+ ck-sysdeps-freebsd.c \
+ $(NULL)
+libck_la_LIBADD = $(KVM_LIBS)
+endif
+
+EXTRA_libck_la_SOURCES = \
+ ck-sysdeps-linux.c \
+ ck-sysdeps-solaris.c \
+ ck-sysdeps-freebsd.c \
+ $(NULL)
+
sbin_PROGRAMS = \
console-kit-daemon \
$(NULL)
@@ -49,10 +81,6 @@ ck-marshal.c: ck-marshal.list
ck-marshal.h: ck-marshal.list
@GLIB_GENMARSHAL@ $< --prefix=ck_marshal --header > $@
-PLATFORM_SOURCES = \
- proc-linux.c \
- $(NULL)
-
console_kit_daemon_SOURCES = \
main.c \
ck-manager.h \
@@ -70,9 +98,6 @@ console_kit_daemon_SOURCES = \
ck-session.c \
ck-log.h \
ck-log.c \
- getfd.c \
- proc.h \
- $(PLATFORM_SOURCES) \
$(BUILT_SOURCES) \
$(NULL)
@@ -91,10 +116,23 @@ EXTRA_console_kit_daemon_SOURCES = \
console_kit_daemon_LDADD = \
$(CONSOLE_KIT_LIBS) \
+ libck.la \
$(NULL)
noinst_PROGRAMS = \
test-tty-idle-monitor \
+ test-vt-monitor \
+ $(NULL)
+
+test_vt_monitor_SOURCES = \
+ ck-vt-monitor.h \
+ ck-vt-monitor.c \
+ test-vt-monitor.c \
+ $(NULL)
+
+test_vt_monitor_LDADD = \
+ $(CONSOLE_KIT_LIBS) \
+ libck.la \
$(NULL)
test_tty_idle_monitor_SOURCES = \
@@ -107,6 +145,7 @@ test_tty_idle_monitor_SOURCES = \
test_tty_idle_monitor_LDADD = \
$(CONSOLE_KIT_LIBS) \
+ libck.la \
$(NULL)
EXTRA_DIST = \
diff --git a/src/Makefile.in b/src/Makefile.in
index 336a570..2e660af 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -14,6 +14,7 @@
@SET_MAKE@
+
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
@@ -36,8 +37,21 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+@CK_COMPILE_LINUX_TRUE@am__append_1 = \
+@CK_COMPILE_LINUX_TRUE@ ck-sysdeps-linux.c \
+@CK_COMPILE_LINUX_TRUE@ $(NULL)
+
+@CK_COMPILE_SOLARIS_TRUE@am__append_2 = \
+@CK_COMPILE_SOLARIS_TRUE@ ck-sysdeps-solaris.c \
+@CK_COMPILE_SOLARIS_TRUE@ $(NULL)
+
+@CK_COMPILE_FREEBSD_TRUE@am__append_3 = \
+@CK_COMPILE_FREEBSD_TRUE@ ck-sysdeps-freebsd.c \
+@CK_COMPILE_FREEBSD_TRUE@ $(NULL)
+
sbin_PROGRAMS = console-kit-daemon$(EXEEXT) $(am__EXEEXT_1)
-noinst_PROGRAMS = test-tty-idle-monitor$(EXEEXT) $(am__EXEEXT_1)
+noinst_PROGRAMS = test-tty-idle-monitor$(EXEEXT) \
+ test-vt-monitor$(EXEEXT) $(am__EXEEXT_1)
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -48,6 +62,22 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+@CK_COMPILE_FREEBSD_TRUE@libck_la_DEPENDENCIES = \
+@CK_COMPILE_FREEBSD_TRUE@ $(am__DEPENDENCIES_1)
+am__libck_la_SOURCES_DIST = ck-sysdeps.h ck-sysdeps-unix.c \
+ ck-sysdeps-linux.c ck-sysdeps-solaris.c ck-sysdeps-freebsd.c
+am__objects_1 =
+@CK_COMPILE_LINUX_TRUE@am__objects_2 = ck-sysdeps-linux.lo \
+@CK_COMPILE_LINUX_TRUE@ $(am__objects_1)
+@CK_COMPILE_SOLARIS_TRUE@am__objects_3 = ck-sysdeps-solaris.lo \
+@CK_COMPILE_SOLARIS_TRUE@ $(am__objects_1)
+@CK_COMPILE_FREEBSD_TRUE@am__objects_4 = ck-sysdeps-freebsd.lo \
+@CK_COMPILE_FREEBSD_TRUE@ $(am__objects_1)
+am_libck_la_OBJECTS = ck-sysdeps-unix.lo $(am__objects_1) \
+ $(am__objects_2) $(am__objects_3) $(am__objects_4)
+libck_la_OBJECTS = $(am_libck_la_OBJECTS)
am__EXEEXT_1 =
am__installdirs = "$(DESTDIR)$(sbindir)"
sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
@@ -56,33 +86,35 @@ am__console_kit_daemon_SOURCES_DIST = main.c ck-manager.h ck-manager.c \
ck-vt-monitor.h ck-vt-monitor.c ck-tty-idle-monitor.h \
ck-tty-idle-monitor.c ck-file-monitor.h ck-job.h ck-job.c \
ck-seat.h ck-seat.c ck-session.h ck-session.c ck-log.h \
- ck-log.c getfd.c proc.h proc-linux.c ck-manager-glue.h \
- ck-seat-glue.h ck-session-glue.h ck-marshal.c ck-marshal.h \
- ck-file-monitor-dummy.c ck-file-monitor-inotify.c
-am__objects_1 =
-am__objects_2 = proc-linux.$(OBJEXT) $(am__objects_1)
-am__objects_3 = ck-marshal.$(OBJEXT) $(am__objects_1)
-@ENABLE_INOTIFY_FALSE@am__objects_4 = ck-file-monitor-dummy.$(OBJEXT)
-@ENABLE_INOTIFY_TRUE@am__objects_4 = \
+ ck-log.c ck-manager-glue.h ck-seat-glue.h ck-session-glue.h \
+ ck-marshal.c ck-marshal.h ck-file-monitor-dummy.c \
+ ck-file-monitor-inotify.c
+am__objects_5 = ck-marshal.$(OBJEXT) $(am__objects_1)
+@ENABLE_INOTIFY_FALSE@am__objects_6 = ck-file-monitor-dummy.$(OBJEXT)
+@ENABLE_INOTIFY_TRUE@am__objects_6 = \
@ENABLE_INOTIFY_TRUE@ ck-file-monitor-inotify.$(OBJEXT)
am_console_kit_daemon_OBJECTS = main.$(OBJEXT) ck-manager.$(OBJEXT) \
ck-vt-monitor.$(OBJEXT) ck-tty-idle-monitor.$(OBJEXT) \
ck-job.$(OBJEXT) ck-seat.$(OBJEXT) ck-session.$(OBJEXT) \
- ck-log.$(OBJEXT) getfd.$(OBJEXT) $(am__objects_2) \
- $(am__objects_3) $(am__objects_1) $(am__objects_4)
+ ck-log.$(OBJEXT) $(am__objects_5) $(am__objects_1) \
+ $(am__objects_6)
console_kit_daemon_OBJECTS = $(am_console_kit_daemon_OBJECTS)
-am__DEPENDENCIES_1 =
-console_kit_daemon_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+console_kit_daemon_DEPENDENCIES = $(am__DEPENDENCIES_1) libck.la \
$(am__DEPENDENCIES_1)
am__test_tty_idle_monitor_SOURCES_DIST = ck-tty-idle-monitor.h \
ck-tty-idle-monitor.c ck-file-monitor.h \
ck-file-monitor-dummy.c ck-file-monitor-inotify.c \
test-tty-idle-monitor.c
am_test_tty_idle_monitor_OBJECTS = ck-tty-idle-monitor.$(OBJEXT) \
- $(am__objects_4) test-tty-idle-monitor.$(OBJEXT) \
+ $(am__objects_6) test-tty-idle-monitor.$(OBJEXT) \
$(am__objects_1)
test_tty_idle_monitor_OBJECTS = $(am_test_tty_idle_monitor_OBJECTS)
-test_tty_idle_monitor_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+test_tty_idle_monitor_DEPENDENCIES = $(am__DEPENDENCIES_1) libck.la \
+ $(am__DEPENDENCIES_1)
+am_test_vt_monitor_OBJECTS = ck-vt-monitor.$(OBJEXT) \
+ test-vt-monitor.$(OBJEXT) $(am__objects_1)
+test_vt_monitor_OBJECTS = $(am_test_vt_monitor_OBJECTS)
+test_vt_monitor_DEPENDENCIES = $(am__DEPENDENCIES_1) libck.la \
$(am__DEPENDENCIES_1)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
@@ -95,12 +127,15 @@ LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(console_kit_daemon_SOURCES) \
+SOURCES = $(libck_la_SOURCES) $(EXTRA_libck_la_SOURCES) \
+ $(console_kit_daemon_SOURCES) \
$(EXTRA_console_kit_daemon_SOURCES) \
- $(test_tty_idle_monitor_SOURCES)
-DIST_SOURCES = $(am__console_kit_daemon_SOURCES_DIST) \
+ $(test_tty_idle_monitor_SOURCES) $(test_vt_monitor_SOURCES)
+DIST_SOURCES = $(am__libck_la_SOURCES_DIST) $(EXTRA_libck_la_SOURCES) \
+ $(am__console_kit_daemon_SOURCES_DIST) \
$(EXTRA_console_kit_daemon_SOURCES) \
- $(am__test_tty_idle_monitor_SOURCES_DIST)
+ $(am__test_tty_idle_monitor_SOURCES_DIST) \
+ $(test_vt_monitor_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
@@ -176,6 +211,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INSTOBJEXT = @INSTOBJEXT@
INTLLIBS = @INTLLIBS@
+KVM_LIBS = @KVM_LIBS@
LDFLAGS = @LDFLAGS@
LIBDBUS_CFLAGS = @LIBDBUS_CFLAGS@
LIBDBUS_LIBS = @LIBDBUS_LIBS@
@@ -286,6 +322,19 @@ INCLUDES = \
$(DBUS_CFLAGS) \
$(NULL)
+noinst_LTLIBRARIES = \
+ libck.la \
+ $(NULL)
+
+libck_la_SOURCES = ck-sysdeps.h ck-sysdeps-unix.c $(NULL) \
+ $(am__append_1) $(am__append_2) $(am__append_3)
+@CK_COMPILE_FREEBSD_TRUE@libck_la_LIBADD = $(KVM_LIBS)
+EXTRA_libck_la_SOURCES = \
+ ck-sysdeps-linux.c \
+ ck-sysdeps-solaris.c \
+ ck-sysdeps-freebsd.c \
+ $(NULL)
+
BUILT_SOURCES = \
ck-manager-glue.h \
ck-seat-glue.h \
@@ -294,16 +343,11 @@ BUILT_SOURCES = \
ck-marshal.h \
$(NULL)
-PLATFORM_SOURCES = \
- proc-linux.c \
- $(NULL)
-
console_kit_daemon_SOURCES = main.c ck-manager.h ck-manager.c \
ck-vt-monitor.h ck-vt-monitor.c ck-tty-idle-monitor.h \
ck-tty-idle-monitor.c ck-file-monitor.h ck-job.h ck-job.c \
ck-seat.h ck-seat.c ck-session.h ck-session.c ck-log.h \
- ck-log.c getfd.c proc.h $(PLATFORM_SOURCES) $(BUILT_SOURCES) \
- $(NULL) $(FILE_MONITOR_BACKEND)
+ ck-log.c $(BUILT_SOURCES) $(NULL) $(FILE_MONITOR_BACKEND)
@ENABLE_INOTIFY_FALSE@FILE_MONITOR_BACKEND = ck-file-monitor-dummy.c
@ENABLE_INOTIFY_TRUE@FILE_MONITOR_BACKEND = ck-file-monitor-inotify.c
EXTRA_console_kit_daemon_SOURCES = \
@@ -313,6 +357,18 @@ EXTRA_console_kit_daemon_SOURCES = \
console_kit_daemon_LDADD = \
$(CONSOLE_KIT_LIBS) \
+ libck.la \
+ $(NULL)
+
+test_vt_monitor_SOURCES = \
+ ck-vt-monitor.h \
+ ck-vt-monitor.c \
+ test-vt-monitor.c \
+ $(NULL)
+
+test_vt_monitor_LDADD = \
+ $(CONSOLE_KIT_LIBS) \
+ libck.la \
$(NULL)
test_tty_idle_monitor_SOURCES = \
@@ -325,6 +381,7 @@ test_tty_idle_monitor_SOURCES = \
test_tty_idle_monitor_LDADD = \
$(CONSOLE_KIT_LIBS) \
+ libck.la \
$(NULL)
EXTRA_DIST = \
@@ -377,6 +434,17 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libck.la: $(libck_la_OBJECTS) $(libck_la_DEPENDENCIES)
+ $(LINK) $(libck_la_LDFLAGS) $(libck_la_OBJECTS) $(libck_la_LIBADD) $(LIBS)
+
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; for p in $$list; do \
f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
@@ -417,6 +485,9 @@ console-kit-daemon$(EXEEXT): $(console_kit_daemon_OBJECTS) $(console_kit_daemon_
test-tty-idle-monitor$(EXEEXT): $(test_tty_idle_monitor_OBJECTS) $(test_tty_idle_monitor_DEPENDENCIES)
@rm -f test-tty-idle-monitor$(EXEEXT)
$(LINK) $(test_tty_idle_monitor_LDFLAGS) $(test_tty_idle_monitor_OBJECTS) $(test_tty_idle_monitor_LDADD) $(LIBS)
+test-vt-monitor$(EXEEXT): $(test_vt_monitor_OBJECTS) $(test_vt_monitor_DEPENDENCIES)
+ @rm -f test-vt-monitor$(EXEEXT)
+ $(LINK) $(test_vt_monitor_LDFLAGS) $(test_vt_monitor_OBJECTS) $(test_vt_monitor_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -432,12 +503,15 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ck-marshal.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ck-seat.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ck-session.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ck-sysdeps-freebsd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ck-sysdeps-linux.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ck-sysdeps-solaris.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ck-sysdeps-unix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ck-tty-idle-monitor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ck-vt-monitor.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getfd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc-linux.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-tty-idle-monitor.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-vt-monitor.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@@ -647,7 +721,7 @@ distdir: $(DISTFILES)
check-am: all-am
check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-recursive
-all-am: Makefile $(PROGRAMS)
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS)
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(sbindir)"; do \
@@ -683,8 +757,8 @@ maintainer-clean-generic:
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
clean: clean-recursive
-clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
- clean-sbinPROGRAMS mostlyclean-am
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-noinstPROGRAMS clean-sbinPROGRAMS mostlyclean-am
distclean: distclean-recursive
-rm -rf ./$(DEPDIR)
@@ -735,9 +809,9 @@ uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \
- clean clean-generic clean-libtool clean-noinstPROGRAMS \
- clean-recursive clean-sbinPROGRAMS ctags ctags-recursive \
- distclean distclean-compile distclean-generic \
+ clean clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ clean-noinstPROGRAMS clean-recursive clean-sbinPROGRAMS ctags \
+ ctags-recursive distclean distclean-compile distclean-generic \
distclean-libtool distclean-recursive distclean-tags distdir \
dvi dvi-am html html-am info info-am install install-am \
install-data install-data-am install-exec install-exec-am \
diff --git a/src/ck-file-monitor-inotify.c b/src/ck-file-monitor-inotify.c
index 6e775e2..4fdd6aa 100644
--- a/src/ck-file-monitor-inotify.c
+++ b/src/ck-file-monitor-inotify.c
@@ -407,7 +407,7 @@ handle_inotify_event (CkFileMonitor *monitor,
static gboolean
inotify_data_pending (GIOChannel *source,
- GIOCondition condition,
+ GIOCondition condition,
CkFileMonitor *monitor)
{
int len;
diff --git a/src/ck-job.c b/src/ck-job.c
index 1093629..891c743 100644
--- a/src/ck-job.c
+++ b/src/ck-job.c
@@ -28,6 +28,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
+#include <signal.h>
#include <glib.h>
#include <glib/gi18n.h>
@@ -44,8 +45,8 @@ struct CkJobPrivate
guint out_watch_id;
char *command;
- GString *stdout;
- GString *stderr;
+ GString *std_out;
+ GString *std_err;
GPid child_pid;
};
@@ -138,7 +139,7 @@ error_watch (GIOChannel *source,
switch (status) {
case G_IO_STATUS_NORMAL:
g_debug ("command error output: %s", line);
- g_string_append (job->priv->stderr, line);
+ g_string_append (job->priv->std_err, line);
break;
case G_IO_STATUS_EOF:
finished = TRUE;
@@ -183,7 +184,7 @@ out_watch (GIOChannel *source,
switch (status) {
case G_IO_STATUS_NORMAL:
g_debug ("command output: %s", line);
- g_string_append (job->priv->stdout, line);
+ g_string_append (job->priv->std_out, line);
break;
case G_IO_STATUS_EOF:
finished = TRUE;
@@ -281,10 +282,10 @@ ck_job_execute (CkJob *job,
gboolean
ck_job_get_stdout (CkJob *job,
- char **stdout)
+ char **std_outp)
{
- if (stdout != NULL) {
- *stdout = g_strdup (job->priv->stdout->str);
+ if (std_outp != NULL) {
+ *std_outp = g_strdup (job->priv->std_out->str);
}
return TRUE;
}
@@ -335,8 +336,8 @@ ck_job_init (CkJob *job)
{
job->priv = CK_JOB_GET_PRIVATE (job);
- job->priv->stderr = g_string_new (NULL);
- job->priv->stdout = g_string_new (NULL);
+ job->priv->std_err = g_string_new (NULL);
+ job->priv->std_out = g_string_new (NULL);
}
gboolean
@@ -374,8 +375,8 @@ ck_job_finalize (GObject *object)
g_source_remove (job->priv->err_watch_id);
}
g_free (job->priv->command);
- g_string_free (job->priv->stdout, TRUE);
- g_string_free (job->priv->stderr, TRUE);
+ g_string_free (job->priv->std_out, TRUE);
+ g_string_free (job->priv->std_err, TRUE);
G_OBJECT_CLASS (ck_job_parent_class)->finalize (object);
}
diff --git a/src/ck-log.c b/src/ck-log.c
index 9f49352..e7ae05b 100644
--- a/src/ck-log.c
+++ b/src/ck-log.c
@@ -178,12 +178,18 @@ void
ck_log_init (void)
{
const char *prg_name;
+ int options;
g_log_set_default_handler (ck_log_default_handler, NULL);
prg_name = g_get_prgname ();
- openlog (prg_name, LOG_PERROR|LOG_PID, LOG_DAEMON);
+ options = LOG_PID;
+#ifdef LOG_PERROR
+ options |= LOG_PERROR;
+#endif
+
+ openlog (prg_name, options, LOG_DAEMON);
initialized = TRUE;
}
diff --git a/src/ck-manager-glue.h b/src/ck-manager-glue.h
index 6172f7d..0def872 100644
--- a/src/ck-manager-glue.h
+++ b/src/ck-manager-glue.h
@@ -53,7 +53,7 @@ G_BEGIN_DECLS
#endif /* !G_ENABLE_DEBUG */
-/* BOOLEAN:POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.87ODQT:1) */
+/* BOOLEAN:POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.2JLIYT:1) */
extern void dbus_glib_marshal_ck_manager_BOOLEAN__POINTER_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -100,11 +100,11 @@ dbus_glib_marshal_ck_manager_BOOLEAN__POINTER_POINTER (GClosure *closure,
g_value_set_boolean (return_value, v_return);
}
-/* NONE:UINT,POINTER (/tmp/dbus-binding-tool-c-marshallers.87ODQT:2) */
+/* NONE:UINT,POINTER (/tmp/dbus-binding-tool-c-marshallers.2JLIYT:2) */
#define dbus_glib_marshal_ck_manager_VOID__UINT_POINTER g_cclosure_marshal_VOID__UINT_POINTER
#define dbus_glib_marshal_ck_manager_NONE__UINT_POINTER dbus_glib_marshal_ck_manager_VOID__UINT_POINTER
-/* NONE:STRING,POINTER (/tmp/dbus-binding-tool-c-marshallers.87ODQT:3) */
+/* NONE:STRING,POINTER (/tmp/dbus-binding-tool-c-marshallers.2JLIYT:3) */
extern void dbus_glib_marshal_ck_manager_VOID__STRING_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -148,11 +148,11 @@ dbus_glib_marshal_ck_manager_VOID__STRING_POINTER (GClosure *closure,
}
#define dbus_glib_marshal_ck_manager_NONE__STRING_POINTER dbus_glib_marshal_ck_manager_VOID__STRING_POINTER
-/* NONE:POINTER (/tmp/dbus-binding-tool-c-marshallers.87ODQT:4) */
+/* NONE:POINTER (/tmp/dbus-binding-tool-c-marshallers.2JLIYT:4) */
#define dbus_glib_marshal_ck_manager_VOID__POINTER g_cclosure_marshal_VOID__POINTER
#define dbus_glib_marshal_ck_manager_NONE__POINTER dbus_glib_marshal_ck_manager_VOID__POINTER
-/* NONE:BOXED,POINTER (/tmp/dbus-binding-tool-c-marshallers.87ODQT:5) */
+/* NONE:BOXED,POINTER (/tmp/dbus-binding-tool-c-marshallers.2JLIYT:5) */
extern void dbus_glib_marshal_ck_manager_VOID__BOXED_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
diff --git a/src/ck-manager.c b/src/ck-manager.c
index 99eeed6..377cef0 100644
--- a/src/ck-manager.c
+++ b/src/ck-manager.c
@@ -43,20 +43,22 @@
#include "ck-job.h"
#include "ck-marshal.h"
-#include "proc.h"
+#include "ck-sysdeps.h"
#define CK_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CK_TYPE_MANAGER, CkManagerPrivate))
+#define CK_SEAT_DIR SYSCONFDIR "/ConsoleKit/seats.d"
+
#define CK_DBUS_PATH "/org/freedesktop/ConsoleKit"
#define CK_MANAGER_DBUS_PATH CK_DBUS_PATH "/Manager"
#define CK_MANAGER_DBUS_NAME "org.freedesktop.ConsoleKit.Manager"
#define CK_TYPE_PARAMETER_STRUCT (dbus_g_type_get_struct ("GValueArray", \
- G_TYPE_STRING, \
- G_TYPE_VALUE, \
- G_TYPE_INVALID))
+ G_TYPE_STRING, \
+ G_TYPE_VALUE, \
+ G_TYPE_INVALID))
#define CK_TYPE_PARAMETER_LIST (dbus_g_type_get_collection ("GPtrArray", \
- CK_TYPE_PARAMETER_STRUCT))
+ CK_TYPE_PARAMETER_STRUCT))
struct CkManagerPrivate
{
GHashTable *seats;
@@ -514,13 +516,13 @@ _g_time_val_to_iso8601 (GTimeVal *time_)
g_return_val_if_fail (time_->tv_usec >= 0 && time_->tv_usec < G_USEC_PER_SEC, NULL);
-#define ISO_8601_LEN 21
+#define ISO_8601_LEN 21
#define ISO_8601_FORMAT "%Y-%m-%dT%H:%M:%SZ"
retval = g_new0 (gchar, ISO_8601_LEN + 1);
strftime (retval, ISO_8601_LEN,
- ISO_8601_FORMAT,
- gmtime (&(time_->tv_sec)));
+ ISO_8601_FORMAT,
+ gmtime (&(time_->tv_sec)));
return retval;
}
@@ -694,7 +696,7 @@ typedef void (* CkAddParamFunc) (GPtrArray *arr,
const char *value);
static struct {
- char *key;
+ char *key;
CkAddParamFunc func;
} parse_ops[] = {
{ "display-device", add_param_string },
@@ -931,15 +933,15 @@ ck_manager_get_session_for_cookie (CkManager *manager,
const char *cookie,
DBusGMethodInvocation *context)
{
- gboolean res;
- char *sender;
- uid_t calling_uid;
- pid_t calling_pid;
- proc_stat_t *stat;
- char *ssid;
- CkSession *session;
- LeaderInfo *leader_info;
- GError *local_error;
+ gboolean res;
+ char *sender;
+ uid_t calling_uid;
+ pid_t calling_pid;
+ CkProcessStat *stat;
+ char *ssid;
+ CkSession *session;
+ LeaderInfo *leader_info;
+ GError *local_error;
ssid = NULL;
@@ -962,7 +964,7 @@ ck_manager_get_session_for_cookie (CkManager *manager,
}
local_error = NULL;
- res = proc_stat_new_for_pid (calling_pid, &stat, &local_error);
+ res = ck_process_stat_new_for_unix_pid (calling_pid, &stat, &local_error);
if (! res) {
GError *error;
error = g_error_new (CK_MANAGER_ERROR,
@@ -980,7 +982,7 @@ ck_manager_get_session_for_cookie (CkManager *manager,
}
/* FIXME: should we restrict this by uid? */
- proc_stat_free (stat);
+ ck_process_stat_free (stat);
leader_info = g_hash_table_lookup (manager->priv->leaders, cookie);
if (leader_info == NULL) {
@@ -1021,7 +1023,7 @@ get_cookie_for_pid (CkManager *manager,
/* FIXME: need a better way to get the cookie */
- cookie = proc_pid_get_env (pid, "XDG_SESSION_COOKIE");
+ cookie = ck_unix_pid_get_env (pid, "XDG_SESSION_COOKIE");
return cookie;
}
@@ -1038,13 +1040,13 @@ ck_manager_get_session_for_unix_process (CkManager *manager,
guint pid,
DBusGMethodInvocation *context)
{
- gboolean res;
- char *sender;
- uid_t calling_uid;
- pid_t calling_pid;
- proc_stat_t *stat;
- char *cookie;
- GError *error;
+ gboolean res;
+ char *sender;
+ uid_t calling_uid;
+ pid_t calling_pid;
+ CkProcessStat *stat;
+ char *cookie;
+ GError *error;
sender = dbus_g_method_get_sender (context);
@@ -1065,7 +1067,7 @@ ck_manager_get_session_for_unix_process (CkManager *manager,
}
error = NULL;
- res = proc_stat_new_for_pid (calling_pid, &stat, &error);
+ res = ck_process_stat_new_for_unix_pid (calling_pid, &stat, &error);
if (! res) {
GError *error;
g_debug ("stat on pid %d failed", calling_pid);
@@ -1080,7 +1082,7 @@ ck_manager_get_session_for_unix_process (CkManager *manager,
/* FIXME: check stuff? */
- proc_stat_free (stat);
+ ck_process_stat_free (stat);
cookie = get_cookie_for_pid (manager, pid);
if (cookie == NULL) {
@@ -1545,11 +1547,61 @@ ck_manager_get_seats (CkManager *manager,
}
static void
-create_seats (CkManager *manager)
+add_seat_for_file (CkManager *manager,
+ const char *filename)
{
+ char *sid;
CkSeat *seat;
- seat = add_new_seat (manager, CK_SEAT_KIND_STATIC);
+ sid = generate_seat_id (manager);
+
+ seat = ck_seat_new_from_file (sid, filename);
+ if (seat == NULL) {
+ /* returns null if connection to bus fails */
+ g_free (sid);
+ return;
+ }
+
+ g_hash_table_insert (manager->priv->seats, sid, seat);
+
+ g_debug ("Added seat: %s", sid);
+
+ g_signal_emit (manager, signals [SEAT_ADDED], 0, sid);
+}
+
+static gboolean
+load_seats_from_dir (CkManager *manager)
+{
+ GDir *d;
+ GError *error;
+ const char *file;
+
+ error = NULL;
+ d = g_dir_open (CK_SEAT_DIR,
+ 0,
+ &error);
+ if (d == NULL) {
+ g_warning ("Couldn't open seat dir: %s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ while ((file = g_dir_read_name (d)) != NULL) {
+ char *path;
+ path = g_build_filename (CK_SEAT_DIR, file, NULL);
+ add_seat_for_file (manager, path);
+ g_free (path);
+ }
+
+ g_dir_close (d);
+
+ return TRUE;
+}
+
+static void
+create_seats (CkManager *manager)
+{
+ load_seats_from_dir (manager);
}
static void
diff --git a/src/ck-seat-glue.h b/src/ck-seat-glue.h
index af823bc..d6cbca1 100644
--- a/src/ck-seat-glue.h
+++ b/src/ck-seat-glue.h
@@ -53,7 +53,7 @@ G_BEGIN_DECLS
#endif /* !G_ENABLE_DEBUG */
-/* BOOLEAN:POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.NT25PT:1) */
+/* BOOLEAN:POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.33NIYT:1) */
extern void dbus_glib_marshal_ck_seat_BOOLEAN__POINTER_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -100,7 +100,7 @@ dbus_glib_marshal_ck_seat_BOOLEAN__POINTER_POINTER (GClosure *closure,
g_value_set_boolean (return_value, v_return);
}
-/* NONE:BOXED,POINTER (/tmp/dbus-binding-tool-c-marshallers.NT25PT:2) */
+/* NONE:BOXED,POINTER (/tmp/dbus-binding-tool-c-marshallers.33NIYT:2) */
extern void dbus_glib_marshal_ck_seat_VOID__BOXED_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -152,17 +152,18 @@ G_END_DECLS
static const DBusGMethodInfo dbus_glib_ck_seat_methods[] = {
{ (GCallback) ck_seat_get_id, dbus_glib_marshal_ck_seat_BOOLEAN__POINTER_POINTER, 0 },
{ (GCallback) ck_seat_get_sessions, dbus_glib_marshal_ck_seat_BOOLEAN__POINTER_POINTER, 53 },
- { (GCallback) ck_seat_get_active_session, dbus_glib_marshal_ck_seat_BOOLEAN__POINTER_POINTER, 118 },
- { (GCallback) ck_seat_can_activate_sessions, dbus_glib_marshal_ck_seat_BOOLEAN__POINTER_POINTER, 183 },
- { (GCallback) ck_seat_activate_session, dbus_glib_marshal_ck_seat_NONE__BOXED_POINTER, 259 },
+ { (GCallback) ck_seat_get_devices, dbus_glib_marshal_ck_seat_BOOLEAN__POINTER_POINTER, 118 },
+ { (GCallback) ck_seat_get_active_session, dbus_glib_marshal_ck_seat_BOOLEAN__POINTER_POINTER, 184 },
+ { (GCallback) ck_seat_can_activate_sessions, dbus_glib_marshal_ck_seat_BOOLEAN__POINTER_POINTER, 249 },
+ { (GCallback) ck_seat_activate_session, dbus_glib_marshal_ck_seat_NONE__BOXED_POINTER, 325 },
};
const DBusGObjectInfo dbus_glib_ck_seat_object_info = {
0,
dbus_glib_ck_seat_methods,
- 5,
-"org.freedesktop.ConsoleKit.Seat\0GetId\0S\0sid\0O\0F\0N\0o\0\0org.freedesktop.ConsoleKit.Seat\0GetSessions\0S\0sessions\0O\0F\0N\0ao\0\0org.freedesktop.ConsoleKit.Seat\0GetActiveSession\0S\0ssid\0O\0F\0N\0o\0\0org.freedesktop.ConsoleKit.Seat\0CanActivateSessions\0S\0can_activate\0O\0F\0N\0b\0\0org.freedesktop.ConsoleKit.Seat\0ActivateSession\0A\0ssid\0I\0o\0\0\0",
-"org.freedesktop.ConsoleKit.Seat\0ActiveSessionChanged\0org.freedesktop.ConsoleKit.Seat\0SessionAdded\0org.freedesktop.ConsoleKit.Seat\0SessionRemoved\0\0",
+ 6,
+"org.freedesktop.ConsoleKit.Seat\0GetId\0S\0sid\0O\0F\0N\0o\0\0org.freedesktop.ConsoleKit.Seat\0GetSessions\0S\0sessions\0O\0F\0N\0ao\0\0org.freedesktop.ConsoleKit.Seat\0GetDevices\0S\0devices\0O\0F\0N\0a(ss)\0\0org.freedesktop.ConsoleKit.Seat\0GetActiveSession\0S\0ssid\0O\0F\0N\0o\0\0org.freedesktop.ConsoleKit.Seat\0CanActivateSessions\0S\0can_activate\0O\0F\0N\0b\0\0org.freedesktop.ConsoleKit.Seat\0ActivateSession\0A\0ssid\0I\0o\0\0\0",
+"org.freedesktop.ConsoleKit.Seat\0ActiveSessionChanged\0org.freedesktop.ConsoleKit.Seat\0SessionAdded\0org.freedesktop.ConsoleKit.Seat\0SessionRemoved\0org.freedesktop.ConsoleKit.Seat\0DeviceAdded\0org.freedesktop.ConsoleKit.Seat\0DeviceRemoved\0\0",
"\0"
};
diff --git a/src/ck-seat.c b/src/ck-seat.c
index a77e0b1..e04b569 100644
--- a/src/ck-seat.c
+++ b/src/ck-seat.c
@@ -25,13 +25,6 @@
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
-#ifdef HAVE_PATHS_H
-#include <paths.h>
-#endif /* HAVE_PATHS_H */
-
-#ifndef _PATH_TTY
-#define _PATH_TTY "/dev/tty"
-#endif
#include <glib.h>
#include <glib/gi18n.h>
@@ -41,6 +34,8 @@
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
+#include "ck-sysdeps.h"
+
#include "ck-seat.h"
#include "ck-seat-glue.h"
#include "ck-marshal.h"
@@ -53,11 +48,13 @@
#define CK_DBUS_PATH "/org/freedesktop/ConsoleKit"
#define CK_DBUS_NAME "org.freedesktop.ConsoleKit"
+
struct CkSeatPrivate
{
char *id;
CkSeatKind kind;
GHashTable *sessions;
+ GPtrArray *devices;
CkSession *active_session;
@@ -70,6 +67,8 @@ enum {
ACTIVE_SESSION_CHANGED,
SESSION_ADDED,
SESSION_REMOVED,
+ DEVICE_ADDED,
+ DEVICE_REMOVED,
LAST_SIGNAL
};
@@ -169,6 +168,7 @@ _seat_activate_session (CkSeat *seat,
CkSession *session,
DBusGMethodInvocation *context)
{
+ gboolean res;
gboolean ret;
guint num;
char *device;
@@ -202,7 +202,8 @@ _seat_activate_session (CkSeat *seat,
ck_session_get_display_device (session, &device, NULL);
- if (device == NULL || (sscanf (device, _PATH_TTY "%u", &num) != 1)) {
+ res = ck_get_console_num_from_device (device, &num);
+ if (! res) {
GError *error;
error = g_error_new (CK_SEAT_ERROR,
CK_SEAT_ERROR_GENERAL,
@@ -486,7 +487,7 @@ update_active_vt (CkSeat *seat,
CkSession *session;
char *device;
- device = g_strdup_printf (_PATH_TTY "%u", num);
+ device = ck_get_console_device_for_num (num);
g_debug ("Active device: %s", device);
@@ -605,6 +606,60 @@ ck_seat_can_activate_sessions (CkSeat *seat,
return TRUE;
}
+static gboolean
+ck_seat_has_device (CkSeat *seat,
+ GValueArray *device,
+ gboolean *result,
+ GError *error)
+{
+ g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
+
+ return TRUE;
+}
+
+gboolean
+ck_seat_add_device (CkSeat *seat,
+ GValueArray *device,
+ GError **error)
+{
+ gboolean present;
+
+ g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
+
+ /* FIXME: check if already present */
+ present = FALSE;
+ ck_seat_has_device (seat, device, &present, NULL);
+ if (present) {
+ g_set_error (error, CK_SEAT_ERROR, CK_SEAT_ERROR_GENERAL, "%s", "Device already present");
+ return FALSE;
+ }
+
+ g_ptr_array_add (seat->priv->devices, g_boxed_copy (CK_TYPE_DEVICE, device));
+
+ g_debug ("Emitting device added signal");
+
+ g_signal_emit (seat, signals [DEVICE_ADDED], 0, device);
+
+ return TRUE;
+}
+
+gboolean
+ck_seat_remove_device (CkSeat *seat,
+ GValueArray *device,
+ GError **error)
+{
+ g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
+
+ /* FIXME: check if already present */
+ if (0) {
+ g_debug ("Emitting device removed signal");
+
+ g_signal_emit (seat, signals [DEVICE_REMOVED], 0, device);
+ }
+
+ return TRUE;
+}
+
gboolean
ck_seat_get_kind (CkSeat *seat,
CkSeatKind *kind,
@@ -689,6 +744,38 @@ ck_seat_get_sessions (CkSeat *seat,
}
static void
+copy_devices (gpointer data,
+ GPtrArray **array)
+{
+ g_ptr_array_add (*array, data);
+}
+
+/*
+ Example:
+ dbus-send --system --dest=org.freedesktop.ConsoleKit \
+ --type=method_call --print-reply --reply-timeout=2000 \
+ /org/freedesktop/ConsoleKit/Seat1 \
+ org.freedesktop.ConsoleKit.Seat.GetDevices
+*/
+
+gboolean
+ck_seat_get_devices (CkSeat *seat,
+ GPtrArray **devices,
+ GError **error)
+{
+ g_return_val_if_fail (CK_IS_SEAT (seat), FALSE);
+
+ if (devices == NULL) {
+ return FALSE;
+ }
+
+ *devices = g_ptr_array_sized_new (seat->priv->devices->len);
+ g_ptr_array_foreach (seat->priv->devices, (GFunc)copy_devices, devices);
+
+ return TRUE;
+}
+
+static void
_ck_seat_set_id (CkSeat *seat,
const char *id)
{
@@ -809,6 +896,25 @@ ck_seat_class_init (CkSeatClass *klass)
G_TYPE_NONE,
1, G_TYPE_STRING);
+ signals [DEVICE_ADDED] = g_signal_new ("device-added",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CkSeatClass, device_added),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1, CK_TYPE_DEVICE);
+ signals [DEVICE_REMOVED] = g_signal_new ("device-removed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CkSeatClass, device_removed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE,
+ 1, CK_TYPE_DEVICE);
+
g_object_class_install_property (object_class,
PROP_ID,
g_param_spec_string ("id",
@@ -839,6 +945,7 @@ ck_seat_init (CkSeat *seat)
g_str_equal,
g_free,
(GDestroyNotify) g_object_unref);
+ seat->priv->devices = g_ptr_array_new ();
}
static void
@@ -861,6 +968,7 @@ ck_seat_finalize (GObject *object)
g_object_unref (seat->priv->active_session);
}
+ g_ptr_array_free (seat->priv->devices, TRUE);
g_hash_table_destroy (seat->priv->sessions);
g_free (seat->priv->id);
@@ -887,3 +995,111 @@ ck_seat_new (const char *sid,
return CK_SEAT (object);
}
+
+CkSeat *
+ck_seat_new_with_devices (const char *sid,
+ CkSeatKind kind,
+ GPtrArray *devices)
+{
+ GObject *object;
+ gboolean res;
+ int i;
+
+ object = g_object_new (CK_TYPE_SEAT,
+ "id", sid,
+ "kind", kind,
+ NULL);
+
+ if (devices != NULL) {
+ for (i = 0; i < devices->len; i++) {
+ ck_seat_add_device (CK_SEAT (object), g_ptr_array_index (devices, i), NULL);
+ }
+ }
+
+ res = register_seat (CK_SEAT (object));
+ if (! res) {
+ g_object_unref (object);
+ return NULL;
+ }
+
+ return CK_SEAT (object);
+}
+
+CkSeat *
+ck_seat_new_from_file (const char *sid,
+ const char *path)
+{
+ GKeyFile *key_file;
+ gboolean res;
+ GError *error;
+ char *group;
+ CkSeat *seat;
+ gboolean hidden;
+ GPtrArray *devices;
+ char **device_list;
+ gsize ndevices;
+ gsize i;
+
+ key_file = g_key_file_new ();
+ error = NULL;
+ res = g_key_file_load_from_file (key_file,
+ path,
+ G_KEY_FILE_NONE,
+ &error);
+ if (! res) {
+ g_warning ("Unable to load seats from file %s: %s", path, error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ group = g_key_file_get_start_group (key_file);
+ if (group == NULL || strcmp (group, "Seat Entry") != 0) {
+ g_warning ("Not a seat file: %s", path);
+ return NULL;
+ }
+
+ hidden = g_key_file_get_boolean (key_file, group, "Hidden", NULL);
+ if (hidden) {
+ g_debug ("Seat is hidden");
+ return NULL;
+ }
+
+ device_list = g_key_file_get_string_list (key_file, group, "Devices", &ndevices, NULL);
+
+ g_debug ("Creating seat %s with %d devices", sid, ndevices);
+
+ devices = g_ptr_array_sized_new (ndevices);
+
+ for (i = 0; i < ndevices; i++) {
+ char **split;
+ GValue device_val = { 0, };
+
+ split = g_strsplit (device_list[i], ":", 2);
+
+ if (split == NULL) {
+ continue;
+ }
+
+ g_debug ("Adding device: %s %s", split[0], split[1]);
+
+ g_value_init (&device_val, CK_TYPE_DEVICE);
+ g_value_take_boxed (&device_val,
+ dbus_g_type_specialized_construct (CK_TYPE_DEVICE));
+ dbus_g_type_struct_set (&device_val,
+ 0, split[0],
+ 1, split[1],
+ G_MAXUINT);
+
+ g_ptr_array_add (devices, g_value_get_boxed (&device_val));
+
+ g_strfreev (split);
+ }
+
+ g_free (group);
+
+ seat = ck_seat_new_with_devices (sid, CK_SEAT_KIND_STATIC, devices);
+
+ g_ptr_array_free (devices, TRUE);
+
+ return seat;
+}
diff --git a/src/ck-seat.h b/src/ck-seat.h
index 4707bf9..63ab3d5 100644
--- a/src/ck-seat.h
+++ b/src/ck-seat.h
@@ -47,12 +47,16 @@ typedef struct
{
GObjectClass parent_class;
- void (* active_session_changed) (CkSeat *seat,
- const char *ssid);
- void (* session_added) (CkSeat *seat,
- const char *ssid);
- void (* session_removed) (CkSeat *seat,
- const char *ssid);
+ void (* active_session_changed) (CkSeat *seat,
+ const char *ssid);
+ void (* session_added) (CkSeat *seat,
+ const char *ssid);
+ void (* session_removed) (CkSeat *seat,
+ const char *ssid);
+ void (* device_added) (CkSeat *seat,
+ GValueArray *device);
+ void (* device_removed) (CkSeat *seat,
+ GValueArray *device);
} CkSeatClass;
typedef enum
@@ -71,10 +75,21 @@ typedef enum
#define CK_SEAT_ERROR ck_seat_error_quark ()
+
+#define CK_TYPE_DEVICE (dbus_g_type_get_struct ("GValueArray", \
+ G_TYPE_STRING, \
+ G_TYPE_STRING, \
+ G_TYPE_INVALID))
+
GQuark ck_seat_error_quark (void);
GType ck_seat_get_type (void);
CkSeat * ck_seat_new (const char *sid,
CkSeatKind kind);
+CkSeat * ck_seat_new_from_file (const char *sid,
+ const char *path);
+CkSeat * ck_seat_new_with_devices (const char *sid,
+ CkSeatKind kind,
+ GPtrArray *devices);
gboolean ck_seat_get_kind (CkSeat *seat,
CkSeatKind *kind,
GError **error);
@@ -87,6 +102,12 @@ gboolean ck_seat_remove_session (CkSeat *seat,
gboolean ck_seat_set_active_session (CkSeat *seat,
CkSession *session,
GError **error);
+gboolean ck_seat_add_device (CkSeat *seat,
+ GValueArray *device,
+ GError **error);
+gboolean ck_seat_remove_device (CkSeat *seat,
+ GValueArray *device,
+ GError **error);
/* exported methods */
gboolean ck_seat_get_id (CkSeat *seat,
@@ -95,6 +116,9 @@ gboolean ck_seat_get_id (CkSeat *seat,
gboolean ck_seat_get_sessions (CkSeat *seat,
GPtrArray **sessions,
GError **error);
+gboolean ck_seat_get_devices (CkSeat *seat,
+ GPtrArray **devices,
+ GError **error);
gboolean ck_seat_get_active_session (CkSeat *seat,
char **ssid,
GError **error);
diff --git a/src/ck-seat.xml b/src/ck-seat.xml
index 5fda057..b66fcaa 100644
--- a/src/ck-seat.xml
+++ b/src/ck-seat.xml
@@ -7,6 +7,9 @@
<method name="GetSessions">
<arg name="sessions" direction="out" type="ao"/>
</method>
+ <method name="GetDevices">
+ <arg name="devices" direction="out" type="a(ss)"/>
+ </method>
<method name="GetActiveSession">
<arg name="ssid" direction="out" type="o"/>
</method>
@@ -26,5 +29,11 @@
<signal name="SessionRemoved">
<arg name="ssid" type="o"/>
</signal>
+ <signal name="DeviceAdded">
+ <arg name="device" type="(ss)"/>
+ </signal>
+ <signal name="DeviceRemoved">
+ <arg name="device" type="(ss)"/>
+ </signal>
</interface>
</node>
diff --git a/src/ck-session-glue.h b/src/ck-session-glue.h
index 9323c73..cabded2 100644
--- a/src/ck-session-glue.h
+++ b/src/ck-session-glue.h
@@ -53,7 +53,7 @@ G_BEGIN_DECLS
#endif /* !G_ENABLE_DEBUG */
-/* BOOLEAN:POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.CVG6PT:1) */
+/* BOOLEAN:POINTER,POINTER (/tmp/dbus-binding-tool-c-marshallers.8HEIYT:1) */
extern void dbus_glib_marshal_ck_session_BOOLEAN__POINTER_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -100,7 +100,7 @@ dbus_glib_marshal_ck_session_BOOLEAN__POINTER_POINTER (GClosure *closure,
g_value_set_boolean (return_value, v_return);
}
-/* NONE:BOOLEAN,POINTER (/tmp/dbus-binding-tool-c-marshallers.CVG6PT:2) */
+/* NONE:BOOLEAN,POINTER (/tmp/dbus-binding-tool-c-marshallers.8HEIYT:2) */
extern void dbus_glib_marshal_ck_session_VOID__BOOLEAN_POINTER (GClosure *closure,
GValue *return_value,
guint n_param_values,
@@ -144,7 +144,7 @@ dbus_glib_marshal_ck_session_VOID__BOOLEAN_POINTER (GClosure *closure,
}
#define dbus_glib_marshal_ck_session_NONE__BOOLEAN_POINTER dbus_glib_marshal_ck_session_VOID__BOOLEAN_POINTER
-/* NONE:POINTER (/tmp/dbus-binding-tool-c-marshallers.CVG6PT:3) */
+/* NONE:POINTER (/tmp/dbus-binding-tool-c-marshallers.8HEIYT:3) */
#define dbus_glib_marshal_ck_session_VOID__POINTER g_cclosure_marshal_VOID__POINTER
#define dbus_glib_marshal_ck_session_NONE__POINTER dbus_glib_marshal_ck_session_VOID__POINTER
diff --git a/src/ck-session.c b/src/ck-session.c
index c4e286a..f136333 100644
--- a/src/ck-session.c
+++ b/src/ck-session.c
@@ -321,13 +321,13 @@ _g_time_val_to_iso8601 (GTimeVal *time_)
g_return_val_if_fail (time_->tv_usec >= 0 && time_->tv_usec < G_USEC_PER_SEC, NULL);
-#define ISO_8601_LEN 21
+#define ISO_8601_LEN 21
#define ISO_8601_FORMAT "%Y-%m-%dT%H:%M:%SZ"
retval = g_new0 (gchar, ISO_8601_LEN + 1);
strftime (retval, ISO_8601_LEN,
- ISO_8601_FORMAT,
- gmtime (&(time_->tv_sec)));
+ ISO_8601_FORMAT,
+ gmtime (&(time_->tv_sec)));
return retval;
}
@@ -1103,7 +1103,7 @@ ck_session_new_with_parameters (const char *ssid,
guint n_allocated_params;
guint n_params;
GObjectClass *class;
- GType object_type;
+ GType object_type;
object_type = CK_TYPE_SESSION;
class = g_type_class_ref (object_type);
diff --git a/src/ck-sysdeps-freebsd.c b/src/ck-sysdeps-freebsd.c
new file mode 100644
index 0000000..d7c7c0c
--- /dev/null
+++ b/src/ck-sysdeps-freebsd.c
@@ -0,0 +1,423 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
+ * Copyright (C) 2007 Joe Marcus Clarke <marcus@FreeBSD.org>
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <paths.h>
+#include <ttyent.h>
+#include <kvm.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
+#include <sys/ioctl.h>
+
+#include <sys/consio.h>
+
+#define DEV_ENCODE(M,m) ( \
+ ( (M&0xfff) << 8) | ( (m&0xfff00) << 12) | (m&0xff) \
+)
+
+#include "ck-sysdeps.h"
+
+#ifndef ERROR
+#define ERROR -1
+#endif
+
+/* adapted from procps */
+struct _CkProcessStat
+{
+ int pid;
+ int ppid; /* stat,status pid of parent process */
+ char state; /* stat,status single-char code for process state (S=sleeping) */
+ char cmd[16]; /* stat,status basename of executable file in call to exec(2) */
+ unsigned long long utime; /* stat user-mode CPU time accumulated by process */
+ unsigned long long stime; /* stat kernel-mode CPU time accumulated by process */
+ unsigned long long cutime; /* stat cumulative utime of process and reaped children */
+ unsigned long long cstime; /* stat cumulative stime of process and reaped children */
+ unsigned long long start_time; /* stat start time of process -- seconds since 1-1-70 */
+ unsigned long start_code; /* stat address of beginning of code segment */
+ unsigned long end_code; /* stat address of end of code segment */
+ unsigned long start_stack; /* stat address of the bottom of stack for the process */
+ unsigned long kstk_esp; /* stat kernel stack pointer */
+ unsigned long kstk_eip; /* stat kernel instruction pointer */
+ unsigned long wchan; /* stat (special) address of kernel wait channel proc is sleeping in */
+ long priority; /* stat kernel scheduling priority */
+ long nice; /* stat standard unix nice level of process */
+ long rss; /* stat resident set size from /proc/#/stat (pages) */
+ long alarm; /* stat ? */
+ unsigned long rtprio; /* stat real-time priority */
+ unsigned long sched; /* stat scheduling class */
+ unsigned long vsize; /* stat number of pages of virtual memory ... */
+ unsigned long rss_rlim; /* stat resident set size limit? */
+ unsigned long flags; /* stat kernel flags for the process */
+ unsigned long min_flt; /* stat number of minor page faults since process start */
+ unsigned long maj_flt; /* stat number of major page faults since process start */
+ unsigned long cmin_flt; /* stat cumulative min_flt of process and child processes */
+ unsigned long cmaj_flt; /* stat cumulative maj_flt of process and child processes */
+ int pgrp; /* stat process group id */
+ int session; /* stat session id */
+ int nlwp; /* stat number of threads, or 0 if no clue */
+ int tty; /* stat full device number of controlling terminal */
+ int tpgid; /* stat terminal process group id */
+ int exit_signal; /* stat might not be SIGCHLD */
+ int processor; /* stat current (or most recent?) CPU */
+ uintptr_t penv; /* stat address of initial environment vector */
+ char tty_text[16]; /* stat device name */
+
+};
+
+pid_t
+ck_process_stat_get_ppid (CkProcessStat *stat)
+{
+ g_return_val_if_fail (stat != NULL, -1);
+
+ return stat->ppid;
+}
+
+char *
+ck_process_stat_get_cmd (CkProcessStat *stat)
+{
+ g_return_val_if_fail (stat != NULL, NULL);
+
+ return g_strdup (stat->cmd);
+}
+
+char *
+ck_process_stat_get_tty (CkProcessStat *stat)
+{
+ g_return_val_if_fail (stat != NULL, NULL);
+
+ return g_strdup (stat->tty_text);
+}
+
+static gboolean
+get_kinfo_proc (pid_t pid,
+ struct kinfo_proc *p)
+{
+ int mib[4];
+ size_t len;
+
+ len = 4;
+ sysctlnametomib ("kern.proc.pid", mib, &len);
+
+ len = sizeof(struct kinfo_proc);
+ mib[3] = pid;
+
+ if (sysctl (mib, 4, p, &len, NULL, 0) == -1) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* return 1 if it works, or 0 for failure */
+static gboolean
+stat2proc (pid_t pid,
+ CkProcessStat *P)
+{
+ struct kinfo_proc p;
+ char *ttname;
+ int num;
+ int tty_maj;
+ int tty_min;
+
+ if (! get_kinfo_proc (pid, &p)) {
+ return FALSE;
+ }
+
+ num = OCOMMLEN;
+ if (num >= sizeof P->cmd) {
+ num = sizeof P->cmd - 1;
+ }
+
+ memcpy (P->cmd, p.ki_ocomm, num);
+
+ P->cmd[num] = '\0';
+ P->pid = p.ki_pid;
+ P->ppid = p.ki_ppid;
+ P->pgrp = p.ki_pgid;
+ P->session = p.ki_sid;
+ P->rss = p.ki_rssize;
+ P->vsize = p.ki_size;
+ P->start_time = p.ki_start.tv_sec;
+ P->wchan = (unsigned long) p.ki_wchan;
+ P->state = p.ki_stat;
+ P->nice = p.ki_nice;
+ P->flags = p.ki_sflag;
+ P->tpgid = p.ki_tpgid;
+ P->processor = p.ki_oncpu;
+ P->nlwp = p.ki_numthreads;
+
+ /* we like it Linux-encoded :-) */
+ tty_maj = major (p.ki_tdev);
+ tty_min = minor (p.ki_tdev);
+ P->tty = DEV_ENCODE (tty_maj,tty_min);
+
+ snprintf (P->tty_text, sizeof P->tty_text, "%3d,%-3d", tty_maj, tty_min);
+
+ if (p.ki_tdev != NODEV && (ttname = devname (p.ki_tdev, S_IFCHR)) != NULL) {
+ memcpy (P->tty_text, ttname, sizeof P->tty_text);
+ }
+
+ if (p.ki_tdev == NODEV) {
+ memcpy (P->tty_text, " ? ", sizeof P->tty_text);
+ }
+
+ if (P->pid != pid) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+ck_process_stat_new_for_unix_pid (pid_t pid,
+ CkProcessStat **stat,
+ GError **error)
+{
+ gboolean res;
+ GError *local_error;
+ CkProcessStat *proc;
+
+ g_return_val_if_fail (pid > 1, FALSE);
+
+ if (stat == NULL) {
+ return FALSE;
+ }
+
+ proc = g_new0 (CkProcessStat, 1);
+ proc->pid = pid;
+ res = stat2proc (pid, proc);
+ if (res) {
+ *stat = proc;
+ } else {
+ g_propagate_error (error, local_error);
+ *stat = NULL;
+ }
+
+ return res;
+}
+
+void
+ck_process_stat_free (CkProcessStat *stat)
+{
+ g_free (stat);
+}
+
+GHashTable *
+ck_unix_pid_get_env_hash (pid_t pid)
+{
+ GHashTable *hash;
+ char **penv;
+ kvm_t *kd;
+ struct kinfo_proc p;
+ int i;
+
+ kd = kvm_openfiles (_PATH_DEVNULL, _PATH_DEVNULL, NULL, O_RDONLY, NULL);
+ if (kd == NULL) {
+ return NULL;
+ }
+
+ if (! get_kinfo_proc (pid, &p)) {
+ return NULL;
+ }
+
+ penv = kvm_getenvv (kd, &p, 0);
+ if (penv == NULL) {
+ return NULL;
+ }
+
+ hash = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ g_free);
+
+ for (i = 0; penv[i] != NULL; i++) {
+ char **vals;
+
+ vals = g_strsplit (penv[i], "=", 2);
+ if (vals != NULL) {
+ g_hash_table_insert (hash,
+ g_strdup (vals[0]),
+ g_strdup (vals[1]));
+ g_strfreev (vals);
+ }
+ }
+
+ kvm_close (kd);
+
+ return hash;
+}
+
+char *
+ck_unix_pid_get_env (pid_t pid,
+ const char *var)
+{
+ GHashTable *hash;
+ char *val;
+
+ /*
+ * Would probably be more efficient to just loop through the
+ * environment and return the value, avoiding building the hash
+ * table, but this works for now.
+ */
+ hash = ck_unix_pid_get_env_hash (pid);
+ val = g_strdup (g_hash_table_lookup (hash, var));
+ g_hash_table_destroy (hash);
+
+ return val;
+}
+
+uid_t
+ck_unix_pid_get_uid (pid_t pid)
+{
+ uid_t uid;
+ gboolean res;
+ struct kinfo_proc p;
+
+ g_return_val_if_fail (pid > 1, 0);
+
+ uid = -1;
+
+ res = get_kinfo_proc (pid, &p);
+
+ if (res) {
+ uid = p.ki_uid;
+ }
+
+ return uid;
+}
+
+gboolean
+ck_get_max_num_consoles (guint *num)
+{
+ int max_consoles;
+ int res;
+ gboolean ret;
+ struct ttyent *t;
+
+ ret = FALSE;
+ max_consoles = 0;
+
+ res = setttyent ();
+ if (res == 0) {
+ goto done;
+ }
+
+ while ((t = getttyent ()) != NULL) {
+ if (t->ty_status & TTY_ON && strncmp (t->ty_name, "ttyv", 4) == 0)
+ max_consoles++;
+ }
+
+ /* Increment one more so that all consoles are properly counted
+ * this is arguable a bug in vt_add_watches().
+ */
+ max_consoles++;
+
+ ret = TRUE;
+
+ endttyent ();
+
+done:
+ if (num != NULL) {
+ *num = max_consoles;
+ }
+
+ return ret;
+}
+
+char *
+ck_get_console_device_for_num (guint num)
+{
+ char *device;
+
+ /* The device number is always one less than the VT number. */
+ num--;
+
+ device = g_strdup_printf ("/dev/ttyv%u", num);
+
+ return device;
+}
+
+gboolean
+ck_get_console_num_from_device (const char *device,
+ guint *num)
+{
+ guint n;
+ gboolean ret;
+
+ n = 0;
+ ret = FALSE;
+
+ if (device == NULL) {
+ return FALSE;
+ }
+
+ if (sscanf (device, "/dev/ttyv%u", &n) == 1) {
+ /* The VT number is always one more than the device number. */
+ n++;
+ ret = TRUE;
+ }
+
+ if (num != NULL) {
+ *num = n;
+ }
+
+ return ret;
+}
+
+gboolean
+ck_get_active_console_num (int console_fd,
+ guint *num)
+{
+ gboolean ret;
+ int res;
+ int active;
+
+ g_assert (console_fd != -1);
+
+ active = 0;
+ ret = FALSE;
+
+ res = ioctl (console_fd, VT_GETACTIVE, &active);
+ if (res == ERROR) {
+ perror ("ioctl VT_GETACTIVE");
+ goto out;
+ }
+
+ g_debug ("Active VT is: %d (ttyv%d)", active, active - 1);
+ ret = TRUE;
+
+ out:
+ if (num != NULL) {
+ *num = active;
+ }
+
+ return ret;
+}
diff --git a/src/proc-linux.c b/src/ck-sysdeps-linux.c
index d704e18..7dc99f7 100644
--- a/src/proc-linux.c
+++ b/src/ck-sysdeps-linux.c
@@ -25,17 +25,27 @@
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
+#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <sys/vt.h>
+#include <linux/tty.h>
+#include <linux/kd.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif /* HAVE_PATHS_H */
-#include "proc.h"
+#include "ck-sysdeps.h"
+
+#ifndef ERROR
+#define ERROR -1
+#endif
/* adapted from procps */
-struct _proc_stat_t
+struct _CkProcessStat
{
int pid;
int ppid; /* stat,status pid of parent process */
@@ -111,7 +121,7 @@ load_drivers (void)
buf[bytes] = '\0';
p = buf;
- while ((p = strstr (p, " " _PATH_DEV))){
+ while ((p = strstr (p, " " _PATH_DEV))) {
tty_map_node *tmn;
int len;
char *end;
@@ -263,7 +273,7 @@ link_name (guint maj,
}
pid_t
-proc_stat_get_ppid (proc_stat_t *stat)
+ck_process_stat_get_ppid (CkProcessStat *stat)
{
g_return_val_if_fail (stat != NULL, -1);
@@ -271,7 +281,7 @@ proc_stat_get_ppid (proc_stat_t *stat)
}
char *
-proc_stat_get_cmd (proc_stat_t *stat)
+ck_process_stat_get_cmd (CkProcessStat *stat)
{
g_return_val_if_fail (stat != NULL, NULL);
@@ -280,7 +290,7 @@ proc_stat_get_cmd (proc_stat_t *stat)
/* adapted from procps */
char *
-proc_stat_get_tty (proc_stat_t *stat)
+ck_process_stat_get_tty (CkProcessStat *stat)
{
guint dev;
char *tty;
@@ -328,8 +338,8 @@ proc_stat_get_tty (proc_stat_t *stat)
#define KLF "l"
/* adapted from procps */
static void
-stat2proc (const char *S,
- proc_stat_t *P)
+stat2proc (const char *S,
+ CkProcessStat *P)
{
unsigned num;
char * tmp;
@@ -392,16 +402,16 @@ stat2proc (const char *S,
}
gboolean
-proc_stat_new_for_pid (pid_t pid,
- proc_stat_t **stat,
- GError **error)
+ck_process_stat_new_for_unix_pid (pid_t pid,
+ CkProcessStat **stat,
+ GError **error)
{
- char *path;
- char *contents;
- gsize length;
- gboolean res;
- GError *local_error;
- proc_stat_t *proc;
+ char *path;
+ char *contents;
+ gsize length;
+ gboolean res;
+ GError *local_error;
+ CkProcessStat *proc;
g_return_val_if_fail (pid > 1, FALSE);
@@ -418,7 +428,7 @@ proc_stat_new_for_pid (pid_t pid,
&length,
&local_error);
if (res) {
- proc = g_new0 (proc_stat_t, 1);
+ proc = g_new0 (CkProcessStat, 1);
proc->pid = pid;
stat2proc (contents, proc);
*stat = proc;
@@ -434,13 +444,13 @@ proc_stat_new_for_pid (pid_t pid,
}
void
-proc_stat_free (proc_stat_t *stat)
+ck_process_stat_free (CkProcessStat *stat)
{
g_free (stat);
}
GHashTable *
-proc_pid_get_env_hash (pid_t pid)
+ck_unix_pid_get_env_hash (pid_t pid)
{
char *path;
gboolean res;
@@ -484,7 +494,10 @@ proc_pid_get_env_hash (pid_t pid)
char **vals;
vals = g_strsplit (contents + i, "=", 2);
if (vals != NULL) {
- g_hash_table_insert (hash, vals[0], vals[1]);
+ g_hash_table_insert (hash,
+ g_strdup (vals[0]),
+ g_strdup (vals[1]));
+ g_strfreev (vals);
}
}
last_was_null = FALSE;
@@ -498,8 +511,8 @@ proc_pid_get_env_hash (pid_t pid)
}
char *
-proc_pid_get_env (pid_t pid,
- const char *var)
+ck_unix_pid_get_env (pid_t pid,
+ const char *var)
{
char *path;
gboolean res;
@@ -558,7 +571,7 @@ proc_pid_get_env (pid_t pid,
}
uid_t
-proc_pid_get_uid (pid_t pid)
+ck_unix_pid_get_uid (pid_t pid)
{
struct stat st;
char *path;
@@ -581,25 +594,113 @@ proc_pid_get_uid (pid_t pid)
}
pid_t
-proc_pid_get_ppid (pid_t pid)
+ck_unix_pid_get_ppid (pid_t pid)
{
- int ppid;
- gboolean res;
- proc_stat_t *stat;
+ int ppid;
+ gboolean res;
+ CkProcessStat *stat;
g_return_val_if_fail (pid > 1, 0);
ppid = -1;
- res = proc_stat_new_for_pid (pid, &stat, NULL);
+ res = ck_process_stat_new_for_unix_pid (pid, &stat, NULL);
if (! res) {
goto out;
}
- ppid = proc_stat_get_ppid (stat);
+ ppid = ck_process_stat_get_ppid (stat);
- proc_stat_free (stat);
+ ck_process_stat_free (stat);
out:
return ppid;
}
+
+gboolean
+ck_get_max_num_consoles (guint *num)
+{
+ if (num != NULL) {
+ *num = MAX_NR_CONSOLES;
+ }
+
+ return TRUE;
+}
+
+char *
+ck_get_console_device_for_num (guint num)
+{
+ char *device;
+
+ device = g_strdup_printf (_PATH_TTY "%u", num);
+
+ return device;
+}
+
+gboolean
+ck_get_console_num_from_device (const char *device,
+ guint *num)
+{
+ guint n;
+ gboolean ret;
+
+ n = 0;
+ ret = FALSE;
+
+ if (device == NULL) {
+ return FALSE;
+ }
+
+ if (sscanf (device, _PATH_TTY "%u", &n) == 1) {
+ ret = TRUE;
+ }
+
+ if (num != NULL) {
+ *num = n;
+ }
+
+ return ret;
+}
+
+gboolean
+ck_get_active_console_num (int console_fd,
+ guint *num)
+{
+ gboolean ret;
+ int res;
+ guint active;
+ struct vt_stat stat;
+
+ g_assert (console_fd != -1);
+
+ active = 0;
+ ret = FALSE;
+
+ res = ioctl (console_fd, VT_GETSTATE, &stat);
+ if (res == ERROR) {
+ perror ("ioctl VT_GETSTATE");
+ goto out;
+ }
+
+ {
+ int i;
+
+ g_debug ("Current VT: tty%d", stat.v_active);
+ for (i = 1; i <= 16; i++) {
+ gboolean is_on;
+ is_on = stat.v_state & (1 << i);
+
+ g_debug ("VT %d:%s", i, is_on ? "on" : "off");
+ }
+ }
+
+ active = stat.v_active;
+ ret = TRUE;
+
+ out:
+ if (num != NULL) {
+ *num = active;
+ }
+
+ return ret;
+}
diff --git a/src/ck-sysdeps-solaris.c b/src/ck-sysdeps-solaris.c
new file mode 100644
index 0000000..9cfec2e
--- /dev/null
+++ b/src/ck-sysdeps-solaris.c
@@ -0,0 +1,469 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#define DEV_ENCODE(M,m) ( \
+ ( (M&0xfff) << 8) | ( (m&0xfff00) << 12) | (m&0xff) \
+)
+
+#include <sys/int_types.h>
+#include <sys/mkdev.h>
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+#define NO_TTY_VALUE DEV_ENCODE(-1,-1)
+
+#include "ck-sysdeps.h"
+
+#ifndef ERROR
+#define ERROR -1
+#endif
+
+/* adapted from procps */
+struct _CkProcessStat
+{
+ int pid;
+ int ppid; /* stat,status pid of parent process */
+ char state; /* stat,status single-char code for process state (S=sleeping) */
+ char cmd[16]; /* stat,status basename of executable file in call to exec(2) */
+ unsigned long long utime; /* stat user-mode CPU time accumulated by process */
+ unsigned long long stime; /* stat kernel-mode CPU time accumulated by process */
+ unsigned long long cutime; /* stat cumulative utime of process and reaped children */
+ unsigned long long cstime; /* stat cumulative stime of process and reaped children */
+ unsigned long long start_time; /* stat start time of process -- seconds since 1-1-70 */
+ unsigned long start_code; /* stat address of beginning of code segment */
+ unsigned long end_code; /* stat address of end of code segment */
+ unsigned long start_stack; /* stat address of the bottom of stack for the process */
+ unsigned long kstk_esp; /* stat kernel stack pointer */
+ unsigned long kstk_eip; /* stat kernel instruction pointer */
+ unsigned long wchan; /* stat (special) address of kernel wait channel proc is sleeping in */
+ long priority; /* stat kernel scheduling priority */
+ long nice; /* stat standard unix nice level of process */
+ long rss; /* stat resident set size from /proc/#/stat (pages) */
+ long alarm; /* stat ? */
+ unsigned long rtprio; /* stat real-time priority */
+ unsigned long sched; /* stat scheduling class */
+ unsigned long vsize; /* stat number of pages of virtual memory ... */
+ unsigned long rss_rlim; /* stat resident set size limit? */
+ unsigned long flags; /* stat kernel flags for the process */
+ unsigned long min_flt; /* stat number of minor page faults since process start */
+ unsigned long maj_flt; /* stat number of major page faults since process start */
+ unsigned long cmin_flt; /* stat cumulative min_flt of process and child processes */
+ unsigned long cmaj_flt; /* stat cumulative maj_flt of process and child processes */
+ int pgrp; /* stat process group id */
+ int session; /* stat session id */
+ int nlwp; /* stat number of threads, or 0 if no clue */
+ int tty; /* stat full device number of controlling terminal */
+ int tpgid; /* stat terminal process group id */
+ int exit_signal; /* stat might not be SIGCHLD */
+ int processor; /* stat current (or most recent?) CPU */
+ uintptr_t penv; /* stat address of initial environment vector */
+ char tty_text[16]; /* stat device name */
+
+};
+
+pid_t
+ck_process_stat_get_ppid (CkProcessStat *stat)
+{
+ g_return_val_if_fail (stat != NULL, -1);
+
+ return stat->ppid;
+}
+
+char *
+ck_process_stat_get_cmd (CkProcessStat *stat)
+{
+ g_return_val_if_fail (stat != NULL, NULL);
+
+ return g_strdup (stat->cmd);
+}
+
+/* adapted from procps */
+char *
+ck_process_stat_get_tty (CkProcessStat *stat)
+{
+ guint dev;
+ char *tty;
+ guint dev_maj;
+ guint dev_min;
+ pid_t pid;
+
+ g_return_val_if_fail (stat != NULL, NULL);
+
+ return g_strdup (stat->tty_text);
+}
+
+/* return 1 if it works, or 0 for failure */
+static gboolean
+stat2proc (pid_t pid,
+ CkProcessStat *P)
+{
+ struct psinfo p;
+ char buf[32];
+ int num;
+ int fd;
+ int tty_maj;
+ int tty_min;
+
+ snprintf (buf, sizeof buf, "/proc/%d/psinfo", pid);
+
+ if ((fd = open (buf, O_RDONLY, 0) ) == -1 ) {
+ return FALSE;
+ }
+
+ num = read (fd, &p, sizeof p);
+ close (fd);
+
+ if (num != sizeof p) {
+ return FALSE;
+ }
+
+ num = PRFNSZ;
+ if (num >= sizeof P->cmd) {
+ num = sizeof P->cmd - 1;
+ }
+
+ memcpy (P->cmd, p.pr_fname, num); /* p.pr_fname or p.pr_lwp.pr_name */
+
+ P->cmd[num] = '\0';
+ P->pid = p.pr_pid;
+ P->ppid = p.pr_ppid;
+ P->pgrp = p.pr_pgid;
+ P->session = p.pr_sid;
+ P->rss = p.pr_rssize;
+ P->vsize = p.pr_size;
+ P->start_time = p.pr_start.tv_sec;
+ P->wchan = p.pr_lwp.pr_wchan;
+ P->state = p.pr_lwp.pr_sname;
+ P->nice = p.pr_lwp.pr_nice;
+ P->priority = p.pr_lwp.pr_pri; /* or pr_oldpri */
+ P->penv = p.pr_envp;
+
+ /* we like it Linux-encoded :-) */
+ tty_maj = major (p.pr_ttydev);
+ tty_min = minor (p.pr_ttydev);
+ P->tty = DEV_ENCODE (tty_maj,tty_min);
+
+ snprintf (P->tty_text, sizeof P->tty_text, "%3d,%-3d", tty_maj, tty_min);
+
+ if (tty_maj == 24) {
+ snprintf (P->tty_text, sizeof P->tty_text, "pts/%-3u", tty_min);
+ }
+
+ if (P->tty == NO_TTY_VALUE) {
+ memcpy (P->tty_text, " ? ", 8);
+ }
+
+ if (P->tty == DEV_ENCODE(0,0)) {
+ memcpy (P->tty_text, "console", 8);
+ }
+
+ if (P->pid != pid) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+ck_process_stat_new_for_unix_pid (pid_t pid,
+ CkProcessStat **stat,
+ GError **error)
+{
+ char *path;
+ char *contents;
+ gsize length;
+ gboolean res;
+ GError *local_error;
+ CkProcessStat *proc;
+
+ g_return_val_if_fail (pid > 1, FALSE);
+
+ if (stat == NULL) {
+ return FALSE;
+ }
+
+ proc = g_new0 (CkProcessStat, 1);
+ proc->pid = pid;
+ res = stat2proc (pid, proc);
+ if (res) {
+ *stat = proc;
+ } else {
+ g_propagate_error (error, local_error);
+ *stat = NULL;
+ }
+
+ return res;
+}
+
+void
+ck_process_stat_free (CkProcessStat *stat)
+{
+ g_free (stat);
+}
+
+GHashTable *
+ck_unix_pid_get_env_hash (pid_t pid)
+{
+ GHashTable *hash;
+ char *cmd;
+ char buf[BUFSIZ];
+ FILE *fp;
+ int i;
+
+ hash = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ g_free);
+
+ cmd = g_strdup_printf ("pargs -e %d", pid);
+ fp = popen (cmd, "r");
+ g_free (cmd);
+
+ while (fgets (buf, BUFSIZ, fp) != NULL) {
+ g_strchomp (buf);
+ if (g_str_has_prefix (buf, "envp[")) {
+ char *skip_prefix;
+
+ skip_prefix = strstr (buf, " ");
+
+ if (skip_prefix != NULL) {
+ char **vals;
+ vals = g_strsplit (buf, "=", 2);
+ if (vals != NULL) {
+ g_hash_table_insert (hash,
+ g_strdup (vals[0]),
+ g_strdup (vals[1]));
+ g_strfreev (vals);
+ }
+ }
+ }
+ }
+
+ out:
+ return hash;
+}
+
+char *
+ck_unix_pid_get_env (pid_t pid,
+ const char *var)
+{
+ GHashTable *hash;
+ char *val;
+
+ /*
+ * Would probably be more efficient to just loop through the
+ * environment and return the value, avoiding building the hash
+ * table, but this works for now.
+ */
+ hash = ck_unix_pid_get_env_hash (pid);
+ val = g_strdup (g_hash_table_lookup (hash, var));
+ g_hash_table_destroy (hash);
+
+ return val;
+}
+
+uid_t
+ck_unix_pid_get_uid (pid_t pid)
+{
+ struct stat st;
+ char *path;
+ int uid;
+ int res;
+
+ g_return_val_if_fail (pid > 1, 0);
+
+ uid = -1;
+
+ path = g_strdup_printf ("/proc/%u", (guint)pid);
+ res = stat (path, &st);
+ g_free (path);
+
+ if (res == 0) {
+ uid = st.st_uid;
+ }
+
+ return uid;
+}
+
+pid_t
+ck_unix_pid_get_ppid (pid_t pid)
+{
+ int ppid;
+ gboolean res;
+ CkProcessStat *stat;
+
+ g_return_val_if_fail (pid > 1, 0);
+
+ ppid = -1;
+
+ res = ck_process_stat_new_for_unix_pid (pid, &stat, NULL);
+ if (! res) {
+ goto out;
+ }
+
+ ppid = ck_process_stat_get_ppid (stat);
+
+ ck_process_stat_free (stat);
+
+ out:
+ return ppid;
+}
+
+gboolean
+ck_get_max_num_consoles (guint *num)
+{
+ GError *error;
+ char *svcprop_stdout;
+ int status;
+ int max_consoles;
+ gboolean res;
+ gboolean ret;
+
+ ret = FALSE;
+
+ /*
+ * On Solaris, the default number of VT's is determined by
+ * resources and is stored in the vtdaemon SVC property
+ * options/vtnodecount. If the svcprop command fails, then it can
+ * be safely assumed that VT is not supported on this release of
+ * Solaris.
+ */
+
+ error = NULL;
+ svcprop_stdout = NULL;
+ status = 0;
+ res = g_spawn_command_line_sync ("/usr/bin/svcprop -p options/vtnodecount vtdaemon",
+ &svcprop_stdout,
+ NULL,
+ &status,
+ &error);
+
+ if (res) {
+ if (error == NULL && svcprop_stdout != NULL) {
+ char *end;
+
+ end = NULL;
+ errno = 0;
+ max_consoles = strtol (svcprop_stdout, &end, 0);
+ if (end == NULL || end == svcprop_stdout || errno != 0) {
+ max_consoles = 0;
+ } else {
+ ret = TRUE;
+ }
+ }
+ }
+
+ if (num != NULL) {
+ *num = max_consoles;
+ }
+
+ g_free (svcprop_stdout);
+
+ return ret;
+}
+
+char *
+ck_get_console_device_for_num (guint num)
+{
+ char *device;
+
+ device = g_strdup_printf ("/dev/vt/%u", num);
+
+ return device;
+}
+
+gboolean
+ck_get_console_num_from_device (const char *device,
+ guint *num)
+{
+ guint n;
+ gboolean ret;
+
+ n = 0;
+ ret = FALSE;
+
+ if (device == NULL) {
+ return FALSE;
+ }
+
+ if (sscanf (device, "/dev/vt/%u", &n) == 1) {
+ ret = TRUE;
+ }
+
+ if (num != NULL) {
+ *num = n;
+ }
+
+ return ret;
+}
+
+gboolean
+ck_get_active_console_num (int console_fd,
+ guint *num)
+{
+ gboolean ret;
+ int res;
+ guint active;
+ struct vt_stat stat;
+
+ g_assert (console_fd != -1);
+
+ active = 0;
+ ret = FALSE;
+
+ res = ioctl (console_fd, VT_GETSTATE, &stat);
+ if (res == ERROR) {
+ perror ("ioctl VT_GETSTATE");
+ goto out;
+ }
+
+ {
+ int i;
+
+ g_debug ("Current VT: tty%d", stat.v_active);
+ for (i = 1; i <= 16; i++) {
+ gboolean is_on;
+ is_on = stat.v_state & (1 << i);
+
+ g_debug ("VT %d:%s", i, is_on ? "on" : "off");
+ }
+ }
+
+ active = stat.v_active;
+ ret = TRUE;
+
+ out:
+ if (num != NULL) {
+ *num = active;
+ }
+
+ return ret;
+}
diff --git a/src/ck-sysdeps-unix.c b/src/ck-sysdeps-unix.c
new file mode 100644
index 0000000..0001b6b
--- /dev/null
+++ b/src/ck-sysdeps-unix.c
@@ -0,0 +1,305 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+#ifdef __linux__
+#include <linux/kd.h>
+#include <sys/vt.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <sys/consio.h>
+#endif
+
+#ifdef HAVE_GETPEERUCRED
+#include <ucred.h>
+#endif
+
+#include "ck-sysdeps.h"
+
+#ifndef ERROR
+#define ERROR -1
+#endif
+
+/* Adapted from dbus-sysdeps-unix.c:_dbus_read_credentials_socket() */
+gboolean
+ck_get_socket_peer_credentials (int socket_fd,
+ pid_t *pid,
+ uid_t *uid,
+ GError **error)
+{
+ gboolean ret;
+ uid_t uid_read;
+ pid_t pid_read;
+
+ pid_read = -1;
+ uid_read = -1;
+ ret = FALSE;
+
+#ifdef SO_PEERCRED
+ struct ucred cr;
+ socklen_t cr_len;
+
+ cr_len = sizeof (cr);
+
+ if (getsockopt (socket_fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) == 0 && cr_len == sizeof (cr)) {
+ pid_read = cr.pid;
+ uid_read = cr.uid;
+ ret = TRUE;
+ } else {
+ g_warning ("Failed to getsockopt() credentials, returned len %d/%d: %s\n",
+ cr_len,
+ (int) sizeof (cr),
+ g_strerror (errno));
+ }
+#elif defined(HAVE_GETPEERUCRED)
+ ucred_t *ucred;
+
+ ucred = NULL;
+ if (getpeerucred (socket_fd, &ucred) == 0) {
+ pid_read = ucred_getpid (ucred);
+ uid_read = ucred_geteuid (ucred);
+ ret = TRUE;
+ } else {
+ g_warning ("Failed to getpeerucred() credentials: %s\n",
+ g_strerror (errno));
+ }
+ if (ucred != NULL) {
+ ucred_free (ucred);
+ }
+#else /* !SO_PEERCRED && !HAVE_GETPEERUCRED */
+ g_warning ("Socket credentials not supported on this OS\n");
+#endif
+
+ if (pid != NULL) {
+ *pid = pid_read;
+ }
+
+ if (uid != NULL) {
+ *uid = uid_read;
+ }
+
+ return ret;
+}
+
+
+/*
+ * getfd.c
+ *
+ * Get an fd for use with kbd/console ioctls.
+ * We try several things because opening /dev/console will fail
+ * if someone else used X (which does a chown on /dev/console).
+ */
+
+gboolean
+ck_fd_is_a_console (int fd)
+{
+#ifdef __linux__
+ char arg = 0;
+#elif defined(__FreeBSD__)
+ int vers;
+#endif
+ int kb_ok;
+
+#ifdef __linux__
+ kb_ok = (ioctl (fd, KDGKBTYPE, &arg) == 0
+ && ((arg == KB_101) || (arg == KB_84)));
+#elif defined(__FreeBSD__)
+ kb_ok = (ioctl (fd, CONS_GETVERS, &vers) == 0);
+#else
+ kb_ok = 1;
+#endif
+
+ return (isatty (fd) && kb_ok);
+}
+
+static int
+open_a_console (char *fnam)
+{
+ int fd;
+
+ fd = open (fnam, O_RDONLY | O_NOCTTY);
+ if (fd < 0 && errno == EACCES)
+ fd = open (fnam, O_WRONLY | O_NOCTTY);
+
+ if (fd < 0)
+ return -1;
+
+ if (! ck_fd_is_a_console (fd)) {
+ close (fd);
+ fd = -1;
+ }
+
+ return fd;
+}
+
+int
+ck_get_a_console_fd (void)
+{
+ int fd;
+
+ fd = -1;
+
+#ifdef __sun
+ /* On Solaris, first try Sun VT device. */
+ fd = open_a_console ("/dev/vt/active");
+ if (fd >= 0) {
+ goto done;
+ }
+ fd = open_a_console ("/dev/vt/0");
+ if (fd >= 0) {
+ goto done;
+ }
+#endif
+
+#ifdef _PATH_TTY
+ fd = open_a_console (_PATH_TTY);
+ if (fd >= 0) {
+ goto done;
+ }
+#endif
+
+ fd = open_a_console ("/dev/tty");
+ if (fd >= 0) {
+ goto done;
+ }
+
+#ifdef _PATH_CONSOLE
+ fd = open_a_console (_PATH_CONSOLE);
+ if (fd >= 0) {
+ goto done;
+ }
+#endif
+
+ fd = open_a_console ("/dev/console");
+ if (fd >= 0) {
+ goto done;
+ }
+
+ for (fd = 0; fd < 3; fd++) {
+ if (ck_fd_is_a_console (fd)) {
+ goto done;
+ }
+ }
+ done:
+ return fd;
+}
+
+gboolean
+ck_is_root_user (void)
+{
+#ifndef G_OS_WIN32
+ uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
+ gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
+
+#ifdef HAVE_GETRESUID
+ if (getresuid (&ruid, &euid, &suid) != 0 ||
+ getresgid (&rgid, &egid, &sgid) != 0)
+#endif /* HAVE_GETRESUID */
+ {
+ suid = ruid = getuid ();
+ sgid = rgid = getgid ();
+ euid = geteuid ();
+ egid = getegid ();
+ }
+
+ if (ruid == 0) {
+ return TRUE;
+ }
+
+#endif
+ return FALSE;
+}
+
+gboolean
+ck_wait_for_active_console_num (int console_fd,
+ guint num)
+{
+ gboolean ret;
+ int res;
+
+ g_assert (console_fd != -1);
+
+ again:
+ ret = FALSE;
+
+ g_debug ("VT_WAITACTIVE for vt %d", num);
+ errno = 0;
+ res = ioctl (console_fd, VT_WAITACTIVE, num);
+
+ g_debug ("VT_WAITACTIVE for vt %d returned %d", num, ret);
+
+ if (res == ERROR) {
+ const char *errmsg;
+
+ errmsg = g_strerror (errno);
+
+ if (errno == EINTR) {
+ g_debug ("Interrupted waiting for native console %d activation: %s",
+ num,
+ errmsg);
+ goto again;
+ } else {
+ g_warning ("Error waiting for native console %d activation: %s",
+ num,
+ errmsg);
+ }
+ goto out;
+ }
+
+ ret = TRUE;
+
+ out:
+ return ret;
+}
+
+gboolean
+ck_activate_console_num (int console_fd,
+ guint num)
+{
+ gboolean ret;
+ int res;
+
+ g_assert (console_fd != -1);
+
+ ret = FALSE;
+
+ errno = 0;
+ res = ioctl (console_fd, VT_ACTIVATE, num);
+ if (res == 0) {
+ ret = TRUE;
+ } else {
+ g_warning ("Unable to activate console: %s", g_strerror (errno));
+ }
+
+ return ret;
+}
diff --git a/src/ck-sysdeps.h b/src/ck-sysdeps.h
new file mode 100644
index 0000000..f0fceb7
--- /dev/null
+++ b/src/ck-sysdeps.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __CK_SYSDEPS_H
+#define __CK_SYSDEPS_H
+
+#include "config.h"
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _CkProcessStat CkProcessStat;
+
+gboolean ck_process_stat_new_for_unix_pid (pid_t pid,
+ CkProcessStat **stat,
+ GError **error);
+pid_t ck_process_stat_get_ppid (CkProcessStat *stat);
+char *ck_process_stat_get_tty (CkProcessStat *stat);
+char *ck_process_stat_get_cmd (CkProcessStat *stat);
+void ck_process_stat_free (CkProcessStat *stat);
+
+
+char *ck_unix_pid_get_env (pid_t pid,
+ const char *var);
+
+GHashTable *ck_unix_pid_get_env_hash (pid_t pid);
+
+pid_t ck_unix_pid_get_ppid (pid_t pid);
+uid_t ck_unix_pid_get_uid (pid_t pid);
+
+
+gboolean ck_get_socket_peer_credentials (int socket_fd,
+ pid_t *pid,
+ uid_t *uid,
+ GError **error);
+
+int ck_get_a_console_fd (void);
+
+gboolean ck_fd_is_a_console (int fd);
+
+gboolean ck_is_root_user (void);
+
+gboolean ck_get_max_num_consoles (guint *num);
+
+char * ck_get_console_device_for_num (guint num);
+gboolean ck_get_console_num_from_device (const char *device,
+ guint *num);
+gboolean ck_get_active_console_num (int console_fd,
+ guint *num);
+gboolean ck_activate_console_num (int console_fd,
+ guint num);
+gboolean ck_wait_for_active_console_num (int console_fd,
+ guint num);
+
+G_END_DECLS
+
+#endif /* __CK_SYSDEPS_H */
diff --git a/src/ck-vt-monitor.c b/src/ck-vt-monitor.c
index 40f834a..59d3d1c 100644
--- a/src/ck-vt-monitor.c
+++ b/src/ck-vt-monitor.c
@@ -26,13 +26,6 @@
#include <unistd.h>
#include <string.h>
#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/vt.h>
-
-#if defined (__linux__)
-#include <linux/tty.h>
-#include <linux/kd.h>
-#endif /* linux */
#include <glib.h>
#include <glib/gi18n.h>
@@ -44,9 +37,12 @@
#include <dbus/dbus-glib-lowlevel.h>
#include "ck-vt-monitor.h"
+#include "ck-sysdeps.h"
#include "ck-marshal.h"
+#ifndef ERROR
#define ERROR -1
+#endif
#define CK_VT_MONITOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CK_TYPE_VT_MONITOR, CkVtMonitorPrivate))
@@ -121,8 +117,8 @@ ck_vt_monitor_set_active (CkVtMonitor *vt_monitor,
return FALSE;
}
- res = ioctl (vt_monitor->priv->vfd, VT_ACTIVATE, num);
- if (res == 0) {
+ res = ck_activate_console_num (vt_monitor->priv->vfd, num);
+ if (res) {
ret = TRUE;
} else {
g_set_error (error,
@@ -272,35 +268,16 @@ static void *
vt_thread_start (ThreadData *data)
{
CkVtMonitor *vt_monitor;
+ gboolean res;
int ret;
gint32 num;
vt_monitor = data->vt_monitor;
num = data->num;
- again:
- g_debug ("VT_WAITACTIVE for vt %d", num);
- ret = ioctl (vt_monitor->priv->vfd, VT_WAITACTIVE, num);
-
- g_debug ("VT_WAITACTIVE for vt %d returned %d", num, ret);
-
- if (ret == ERROR) {
- const char *errmsg;
-
- errmsg = g_strerror (errno);
-
- if (errno == EINTR) {
- g_debug ("Interrupted waiting for native console %d activation: %s",
- num,
- errmsg);
- goto again;
- } else {
- g_warning ("Error waiting for native console %d activation: %s",
- num,
- errmsg);
- }
-
- g_free (data);
+ res = ck_wait_for_active_console_num (vt_monitor->priv->vfd, num);
+ if (! res) {
+ /* FIXME: what do we do if it fails? */
} else {
EventData *event;
@@ -357,6 +334,7 @@ vt_add_watch_unlocked (CkVtMonitor *vt_monitor,
static void
vt_add_watches (CkVtMonitor *vt_monitor)
{
+ guint max_consoles;
int i;
gint32 current_num;
@@ -364,7 +342,13 @@ vt_add_watches (CkVtMonitor *vt_monitor)
current_num = vt_monitor->priv->active_num;
- for (i = 1; i < MAX_NR_CONSOLES; i++) {
+ max_consoles = 1;
+
+ if (! ck_get_max_num_consoles (&max_consoles)) {
+ /* FIXME: this can fail on solaris and freebsd */
+ }
+
+ for (i = 1; i < max_consoles; i++) {
gpointer id;
/* don't wait on the active vc */
@@ -383,33 +367,6 @@ vt_add_watches (CkVtMonitor *vt_monitor)
G_UNLOCK (hash_lock);
}
-static guint
-get_active_native (CkVtMonitor *vt_monitor)
-{
- int ret;
- struct vt_stat stat;
-
- ret = ioctl (vt_monitor->priv->vfd, VT_GETSTATE, &stat);
- if (ret == ERROR) {
- perror ("ioctl VT_GETSTATE");
- return -1;
- }
-
- {
- int i;
-
- g_debug ("Current VT: tty%d", stat.v_active);
- for (i = 1; i <= 16; i++) {
- gboolean is_on;
- is_on = stat.v_state & (1 << i);
-
- g_debug ("VT %d:%s", i, is_on ? "on" : "off");
- }
- }
-
- return stat.v_active;
-}
-
static void
ck_vt_monitor_class_init (CkVtMonitorClass *klass)
{
@@ -430,8 +387,6 @@ ck_vt_monitor_class_init (CkVtMonitorClass *klass)
g_type_class_add_private (klass, sizeof (CkVtMonitorPrivate));
}
-extern int getfd (void);
-
static void
ck_vt_monitor_init (CkVtMonitor *vt_monitor)
{
@@ -439,7 +394,7 @@ ck_vt_monitor_init (CkVtMonitor *vt_monitor)
vt_monitor->priv = CK_VT_MONITOR_GET_PRIVATE (vt_monitor);
- fd = getfd ();
+ fd = ck_get_a_console_fd ();
vt_monitor->priv->vfd = fd;
if (fd == ERROR) {
@@ -447,11 +402,20 @@ ck_vt_monitor_init (CkVtMonitor *vt_monitor)
errmsg = g_strerror (errno);
g_warning ("Unable to open a console: %s", errmsg);
} else {
+ gboolean res;
+ guint active;
+
+ res = ck_get_active_console_num (fd, &active);
+ if (! res) {
+ /* FIXME: handle failure */
+ g_warning ("Could not determine active console");
+ active = 0;
+ }
+
+ vt_monitor->priv->active_num = active;
vt_monitor->priv->event_queue = g_async_queue_new ();
vt_monitor->priv->vt_thread_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
- vt_monitor->priv->active_num = get_active_native (vt_monitor);
-
vt_add_watches (vt_monitor);
}
}
diff --git a/src/getfd.c b/src/getfd.c
deleted file mode 100644
index 69c37a3..0000000
--- a/src/getfd.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Adapted from kbd-1.12
- * License: GPL
- *
- */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <linux/kd.h>
-#include <sys/ioctl.h>
-
-#ifdef HAVE_PATHS_H
-#include <paths.h>
-#endif /* HAVE_PATHS_H */
-
-/*
- * getfd.c
- *
- * Get an fd for use with kbd/console ioctls.
- * We try several things because opening /dev/console will fail
- * if someone else used X (which does a chown on /dev/console).
- */
-
-static int
-is_a_console (int fd)
-{
- char arg;
-
- arg = 0;
- return (ioctl (fd, KDGKBTYPE, &arg) == 0
- && ((arg == KB_101) || (arg == KB_84)));
-}
-
-static int
-open_a_console (char *fnam)
-{
- int fd;
-
- fd = open (fnam, O_RDONLY);
- if (fd < 0 && errno == EACCES)
- fd = open(fnam, O_WRONLY);
- if (fd < 0 || ! is_a_console (fd))
- return -1;
- return fd;
-}
-
-int getfd (void)
-{
- int fd;
-
- fd = open_a_console (_PATH_TTY);
- if (fd >= 0)
- return fd;
-
- fd = open_a_console ("/dev/tty");
- if (fd >= 0)
- return fd;
-
- fd = open_a_console (_PATH_CONSOLE);
- if (fd >= 0)
- return fd;
-
- fd = open_a_console ("/dev/console");
- if (fd >= 0)
- return fd;
-
- for (fd = 0; fd < 3; fd++)
- if (is_a_console (fd))
- return fd;
-
- return -1;
-}
diff --git a/src/main.c b/src/main.c
index 90856db..11b6f2e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -38,6 +38,7 @@
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
+#include "ck-sysdeps.h"
#include "ck-manager.h"
#include "ck-log.h"
@@ -49,8 +50,8 @@ static void bus_proxy_destroyed_cb (DBusGProxy *bus_proxy,
static gboolean
timed_exit_cb (GMainLoop *loop)
{
- g_main_loop_quit (loop);
- return FALSE;
+ g_main_loop_quit (loop);
+ return FALSE;
}
static DBusGProxy *
@@ -58,7 +59,7 @@ get_bus_proxy (DBusGConnection *connection)
{
DBusGProxy *bus_proxy;
- bus_proxy = dbus_g_proxy_new_for_name (connection,
+ bus_proxy = dbus_g_proxy_new_for_name (connection,
DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS);
@@ -80,7 +81,7 @@ acquire_name_on_proxy (DBusGProxy *bus_proxy)
}
error = NULL;
- res = dbus_g_proxy_call (bus_proxy,
+ res = dbus_g_proxy_call (bus_proxy,
"RequestName",
&error,
G_TYPE_STRING, CK_DBUS_NAME,
@@ -96,9 +97,9 @@ acquire_name_on_proxy (DBusGProxy *bus_proxy)
g_warning ("Failed to acquire %s", CK_DBUS_NAME);
}
goto out;
- }
+ }
- if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
if (error != NULL) {
g_warning ("Failed to acquire %s: %s", CK_DBUS_NAME, error->message);
g_error_free (error);
@@ -283,6 +284,11 @@ main (int argc,
dbus_g_thread_init ();
g_type_init ();
+ if (! ck_is_root_user ()) {
+ g_warning ("Must be run as root");
+ exit (1);
+ }
+
context = g_option_context_new (_("Console kit daemon"));
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_parse (context, &argc, &argv, NULL);
diff --git a/src/proc.h b/src/proc.h
deleted file mode 100644
index 8c3fc64..0000000
--- a/src/proc.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2006 William Jon McCann <mccann@jhu.edu>
- *
- * 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.
- *
- */
-
-#ifndef __PROC_H
-#define __PROC_H
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-typedef struct _proc_stat_t proc_stat_t;
-
-gboolean proc_stat_new_for_pid (pid_t pid,
- proc_stat_t **stat,
- GError **error);
-pid_t proc_stat_get_ppid (proc_stat_t *stat);
-char *proc_stat_get_tty (proc_stat_t *stat);
-char *proc_stat_get_cmd (proc_stat_t *stat);
-void proc_stat_free (proc_stat_t *stat);
-
-char *proc_pid_get_env (pid_t pid,
- const char *var);
-
-GHashTable *proc_pid_get_env_hash (pid_t pid);
-
-pid_t proc_pid_get_ppid (pid_t pid);
-uid_t proc_pid_get_uid (pid_t pid);
-
-G_END_DECLS
-
-#endif /* __PROC_H */
diff --git a/src/test-tty-idle-monitor.c b/src/test-tty-idle-monitor.c
index 7d44b26..f56b37f 100644
--- a/src/test-tty-idle-monitor.c
+++ b/src/test-tty-idle-monitor.c
@@ -23,16 +23,20 @@
#include <stdlib.h>
#include <stdio.h>
+#include <unistd.h>
#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
#include <pwd.h>
#include <string.h>
#include <errno.h>
-
#include <locale.h>
#include <glib.h>
#include "ck-tty-idle-monitor.h"
+#include "ck-sysdeps.h"
static void
idle_changed_cb (CkTtyIdleMonitor *monitor,
@@ -42,6 +46,26 @@ idle_changed_cb (CkTtyIdleMonitor *monitor,
g_message ("idle hint changed: %s", idle_hint ? "idle" : "not idle");
}
+static gboolean
+is_console (const char *device)
+{
+ int fd;
+ gboolean ret;
+
+ ret = FALSE;
+ fd = open (device, O_RDONLY | O_NOCTTY);
+ if (fd < 0) {
+ goto out;
+ }
+
+ ret = ck_fd_is_a_console (fd);
+
+ close (fd);
+
+ out:
+ return ret;
+}
+
int
main (int argc, char **argv)
{
@@ -52,15 +76,18 @@ main (int argc, char **argv)
g_type_init ();
if (argc < 2) {
- device = g_file_read_link ("/proc/self/fd/0", NULL);
- if (device == NULL) {
- g_warning ("%s not a link", "/proc/self/fd/0");
- exit (1);
- }
+ device = ttyname (0);
} else {
device = g_strdup (argv[1]);
}
+ if (! is_console (device)) {
+ g_warning ("Device is not a console");
+ exit (1);
+ }
+
+ g_message ("Testing the TTY idle monitor.\n1. Wait for idleness to be detected.\n2. Hit keys on the keyboard to see if activity is noticed.");
+
monitor = ck_tty_idle_monitor_new (device);
g_signal_connect (monitor,
diff --git a/src/test-vt-monitor.c b/src/test-vt-monitor.c
new file mode 100644
index 0000000..c445865
--- /dev/null
+++ b/src/test-vt-monitor.c
@@ -0,0 +1,95 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
+ *
+ * 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.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <locale.h>
+
+#include <glib.h>
+
+#include "ck-vt-monitor.h"
+#include "ck-sysdeps.h"
+
+static void
+activated_cb (CkVtMonitor *monitor,
+ guint num,
+ gpointer data)
+{
+ g_message ("VT %u activated", num);
+}
+
+int
+main (int argc, char **argv)
+{
+ GMainLoop *loop;
+ CkVtMonitor *monitor;
+ GError *error;
+ guint num;
+ gboolean res;
+
+ if (! g_thread_supported ()) {
+ g_thread_init (NULL);
+ }
+ g_type_init ();
+
+ if (! ck_is_root_user ()) {
+ g_warning ("Must be run as root");
+ exit (1);
+ }
+
+ g_message ("Testing the VT monitor.\n Should print messages when VT is switched.");
+
+ monitor = ck_vt_monitor_new ();
+
+ res = ck_vt_monitor_get_active (monitor, &num, &error);
+ if (! res) {
+ g_warning ("Couldn't determine active VT: %s", error->message);
+ exit (1);
+ }
+
+ g_message ("VT %u is currently active", num);
+
+ g_signal_connect (monitor,
+ "active-changed",
+ G_CALLBACK (activated_cb),
+ NULL);
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ g_main_loop_run (loop);
+
+ g_object_unref (monitor);
+
+ g_main_loop_unref (loop);
+
+ return 0;
+}