#ifdef USE_UTMPX
# include <utmpx.h>
#endif
+#ifndef DONT_USE_X11
+# include <pthread.h>
+# include <X11/Xlib.h>
+#endif
static void sig_handler(int signal) {
#endif
static int login(int ptm) {
#if defined(USE_UTEMPTER)
- return utempter_add_record(ptm, NULL);
+ int result = utempter_add_record(ptm, NULL);
+ /* Exit value of utempter_*() is not correct on all systems, e.g.
+ * FreeBSD() always returns 0. Checking the utmpx database manually is
+ * difficult because we don't know the exact values for ut_id and ut_line,
+ * therefore we only check the return value on systems known to return a
+ * useful value. */
+# ifndef __linux
+ result = 1;
+# endif
+ return result;
#elif defined(USE_UTMPX)
return set_utmpx(USER_PROCESS, ptm);
#else
}
static int logout(int ptm) {
#if defined(USE_UTEMPTER)
- return utempter_remove_record(ptm);
+ int result = utempter_remove_record(ptm);
+ /* See above. */
+# ifndef __linux
+ result = 1;
+# endif
+ return result;
#elif defined(USE_UTMPX)
return set_utmpx(DEAD_PROCESS, ptm);
#else
pid_t pid;
- /* Skip argv[0]. */
- argv++;
-
if (pipe(fds) != 0) {
perror("pipe");
return;
pass_buffer_to_program(buffer, (size_t)r, argv);
}
}
+#ifndef DONT_USE_X11
+static void *x11_event_loop_thread(void *unused) {
+ Display *display;
+ XEvent event;
+
+ (void)unused;
+
+ pthread_detach(pthread_self());
+
+ display = XOpenDisplay(NULL);
+ if (!display) {
+ fprintf(stderr, "failed to connect to X server\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Do nothing. We just want to die if the X11 session is closed. */
+ while (1) {
+ XNextEvent(display, &event);
+ }
+}
+#endif
+
+static void usage(const char *argv0) {
+ fprintf(stderr, "usage: %s <cmd args..>\n", argv0);
+ exit(EXIT_FAILURE);
+}
int main(int argc, char **argv) {
int ptm, pts;
char *name;
+ const char *argv0;
+
+ argv0 = argv[0];
+ /* Don't pass our argv[0] to the notification program. */
+ argv++;
if (argc < 2) {
- fprintf(stderr, "usage: %s <cmd args..>\n", argv[0]);
- exit(EXIT_FAILURE);
+ usage(argv0);
}
ptm = open_tty();
exit(EXIT_FAILURE);
}
+#ifndef DONT_USE_X11
+ /* Start a thread which connects to X11. This way we die if the user logs
+ * out of its X11 session. */
+ {
+ pthread_t tid;
+
+ if (pthread_create(&tid, NULL, x11_event_loop_thread, NULL) != 0) {
+ perror("pthread_create");
+ exit(EXIT_FAILURE);
+ }
+ }
+#endif
+
/* Cleanup on signals. Necessary before login(). */
setup_signals();