summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Jon McCann <mccann@jhu.edu>2007-08-21 11:27:04 -0400
committerWilliam Jon McCann <mccann@jhu.edu>2007-08-21 11:27:04 -0400
commit0145691112f14352ef15b49c1ea3079a8e80f6e8 (patch)
treeba3477be1e65fb3b6069cadbf3bb9e1a1fe2fe0a
parent3e6bbcaea6d441956c9c1173d7586bd346a8c77b (diff)
more solaris support
based on patch from Brian Cameron.
-rw-r--r--src/ck-sysdeps-linux.c14
-rw-r--r--src/ck-sysdeps-solaris.c109
-rw-r--r--src/ck-sysdeps-unix.c40
-rw-r--r--src/ck-sysdeps.h2
-rw-r--r--src/ck-vt-monitor.c14
5 files changed, 136 insertions, 43 deletions
diff --git a/src/ck-sysdeps-linux.c b/src/ck-sysdeps-linux.c
index 624bfc4..4b751d7 100644
--- a/src/ck-sysdeps-linux.c
+++ b/src/ck-sysdeps-linux.c
@@ -28,6 +28,10 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/vt.h>
+#include <linux/tty.h>
+#include <linux/kd.h>
+
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif /* HAVE_PATHS_H */
@@ -603,3 +607,13 @@ ck_unix_pid_get_ppid (pid_t pid)
out:
return ppid;
}
+
+gboolean
+ck_get_max_num_consoles (guint *num)
+{
+ if (num != NULL) {
+ *num = MAX_NR_CONSOLES;
+ }
+
+ return TRUE;
+}
diff --git a/src/ck-sysdeps-solaris.c b/src/ck-sysdeps-solaris.c
index caea4c7..c1b1b64 100644
--- a/src/ck-sysdeps-solaris.c
+++ b/src/ck-sysdeps-solaris.c
@@ -224,38 +224,37 @@ ck_process_stat_free (CkProcessStat *stat)
}
GHashTable *
-proc_pid_get_env_hash (pid_t pid)
+ck_unix_pid_get_env_hash (pid_t pid)
{
- GHashTable *hash;
- gboolean res;
- CkProcessStat *stat;
- char *env[400];
- char buf[BUFSIZ];
- int fd;
- int i;
-
- res = ck_process_stat_new_for_unix_pid (pid, &stat, NULL);
- if (! res) {
- goto out;
- }
+ GHashTable *hash;
+ char *cmd;
+ char buf[BUFSIZ];
+ FILE *fp;
+ int i;
- hash = NULL;
hash = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
g_free);
- pread (fd, env, 400, stat->penv);
+ cmd = g_strdup_printf ("pargs -e %d", pid);
+ fp = popen (cmd, "r");
+ g_free (cmd);
- i = 0;
- while (env[i] != NULL && i < 400) {
- char **vals;
+ while (fgets (buf, BUFSIZ, fp) != NULL) {
+ g_strchomp (buf);
+ if (g_str_has_prefix (buf, "envp[")) {
+ char *skip_prefix;
- pread (fd, buf, BUFSIZ, env[i++]);
+ skip_prefix = strstr (buf, " ");
- vals = g_strsplit (buf, "=", 2);
- if (vals != NULL) {
- g_hash_table_insert (hash, vals[0], vals[1]);
+ if (skip_prefix != NULL) {
+ char **vals;
+ vals = g_strsplit (buf, "=", 2);
+ if (vals != NULL) {
+ g_hash_table_insert (hash, vals[0], vals[1]);
+ }
+ }
}
}
@@ -264,14 +263,20 @@ 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)
{
GHashTable *hash;
char *val;
- hash = proc_pid_get_env_hash (pid);
- val = g_hash_table_lookup (hash, var);
+ /*
+ * 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;
}
@@ -322,3 +327,55 @@ proc_pid_get_ppid (pid_t pid)
out:
return ppid;
}
+
+gboolean
+ck_get_max_num_consoles (guint *num)
+{
+ GError *error;
+ char *svcprop_stdout;
+ int status;
+ 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;
+}
diff --git a/src/ck-sysdeps-unix.c b/src/ck-sysdeps-unix.c
index 4bad4b6..fa18dac 100644
--- a/src/ck-sysdeps-unix.c
+++ b/src/ck-sysdeps-unix.c
@@ -154,33 +154,51 @@ 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)
- return fd;
+ if (fd >= 0) {
+ goto done;
+ }
#endif
fd = open_a_console ("/dev/tty");
- if (fd >= 0)
- return fd;
+ if (fd >= 0) {
+ goto done;
+ }
#ifdef _PATH_CONSOLE
fd = open_a_console (_PATH_CONSOLE);
- if (fd >= 0)
- return fd;
+ if (fd >= 0) {
+ goto done;
+ }
#endif
fd = open_a_console ("/dev/console");
- if (fd >= 0)
- return fd;
+ if (fd >= 0) {
+ goto done;
+ }
for (fd = 0; fd < 3; fd++) {
if (ck_fd_is_a_console (fd)) {
- return fd;
+ goto done;
}
}
-
- return -1;
+ done:
+ return fd;
}
gboolean
diff --git a/src/ck-sysdeps.h b/src/ck-sysdeps.h
index 86d4425..986018e 100644
--- a/src/ck-sysdeps.h
+++ b/src/ck-sysdeps.h
@@ -62,6 +62,8 @@ gboolean ck_fd_is_a_console (int fd);
gboolean ck_is_root_user (void);
+gboolean ck_get_max_num_consoles (guint *num);
+
G_END_DECLS
#endif /* __CK_SYSDEPS_H */
diff --git a/src/ck-vt-monitor.c b/src/ck-vt-monitor.c
index 4291bdd..5c37a64 100644
--- a/src/ck-vt-monitor.c
+++ b/src/ck-vt-monitor.c
@@ -29,11 +29,6 @@
#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>
#include <glib/gstdio.h>
@@ -358,6 +353,7 @@ vt_add_watch_unlocked (CkVtMonitor *vt_monitor,
static void
vt_add_watches (CkVtMonitor *vt_monitor)
{
+ guint max_consoles;
int i;
gint32 current_num;
@@ -365,7 +361,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 */
+ }
+
+ for (i = 1; i < max_consoles; i++) {
gpointer id;
/* don't wait on the active vc */