summaryrefslogtreecommitdiff
path: root/common/gdm-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/gdm-common.c')
-rw-r--r--common/gdm-common.c398
1 files changed, 13 insertions, 385 deletions
diff --git a/common/gdm-common.c b/common/gdm-common.c
index 7ea3a488..d3e4fcd8 100644
--- a/common/gdm-common.c
+++ b/common/gdm-common.c
@@ -2,6 +2,7 @@
*
* (c) 2000 Eazel, Inc.
* (c) 2001,2002 George Lebl
+ * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -42,188 +43,6 @@
#include "gdm-common.h"
#include "gdm-md5.h"
-int
-gdm_fdgetc (int fd)
-{
- char buf[1];
- int bytes;
-
- VE_IGNORE_EINTR (bytes = read (fd, buf, 1));
- if (bytes != 1)
- return EOF;
- else
- return (int)buf[0];
-}
-
-char *
-gdm_fdgets (int fd)
-{
- int c;
- int bytes = 0;
- GString *gs = g_string_new (NULL);
- for (;;) {
- c = gdm_fdgetc (fd);
- if (c == '\n')
- return g_string_free (gs, FALSE);
- /* on EOF */
- if (c < 0) {
- if (bytes == 0) {
- g_string_free (gs, TRUE);
- return NULL;
- } else {
- return g_string_free (gs, FALSE);
- }
- } else {
- bytes++;
- g_string_append_c (gs, c);
- }
- }
-}
-
-void
-gdm_fdprintf (int fd, const gchar *format, ...)
-{
- va_list args;
- gchar *s;
- int written, len;
-
- va_start (args, format);
- s = g_strdup_vprintf (format, args);
- va_end (args);
-
- len = strlen (s);
-
- if (len == 0) {
- g_free (s);
- return;
- }
-
- written = 0;
- while (written < len) {
- int w;
- VE_IGNORE_EINTR (w = write (fd, &s[written], len - written));
- if (w < 0)
- /* evil! */
- break;
- written += w;
- }
-
- g_free (s);
-}
-
-void
-gdm_close_all_descriptors (int from, int except, int except2)
-{
- DIR *dir;
- struct dirent *ent;
- GSList *openfds = NULL;
-
- /*
- * Evil, but less evil then going to _SC_OPEN_MAX
- * which can be very VERY large
- */
- dir = opendir ("/proc/self/fd/"); /* This is the Linux dir */
- if (dir == NULL)
- dir = opendir ("/dev/fd/"); /* This is the FreeBSD dir */
- if G_LIKELY (dir != NULL) {
- GSList *li;
- while ((ent = readdir (dir)) != NULL) {
- int fd;
- if (ent->d_name[0] == '.')
- continue;
- fd = atoi (ent->d_name);
- if (fd >= from && fd != except && fd != except2)
- openfds = g_slist_prepend (openfds, GINT_TO_POINTER (fd));
- }
- closedir (dir);
- for (li = openfds; li != NULL; li = li->next) {
- int fd = GPOINTER_TO_INT (li->data);
- VE_IGNORE_EINTR (close (fd));
- }
- g_slist_free (openfds);
- } else {
- int i;
- int max = sysconf (_SC_OPEN_MAX);
- /*
- * Don't go higher then this. This is
- * a safety measure to not hang on crazy
- * systems
- */
- if G_UNLIKELY (max > 4096) {
- /* FIXME: warn about this perhaps */
- /*
- * Try an open, in case we're really
- * leaking fds somewhere badly, this
- * should be very high
- */
- i = gdm_open_dev_null (O_RDONLY);
- max = MAX (i+1, 4096);
- }
- for (i = from; i < max; i++) {
- if G_LIKELY (i != except && i != except2)
- VE_IGNORE_EINTR (close (i));
- }
- }
-}
-
-void
-gdm_signal_ignore (int signal)
-{
- struct sigaction ign_signal;
-
- ign_signal.sa_handler = SIG_IGN;
- ign_signal.sa_flags = SA_RESTART;
- sigemptyset (&ign_signal.sa_mask);
-
- if G_UNLIKELY (sigaction (signal, &ign_signal, NULL) < 0)
- g_warning (_("%s: Error setting signal %d to %s"),
- "gdm_signal_ignore", signal, "SIG_IGN");
-}
-
-void
-gdm_signal_default (int signal)
-{
- struct sigaction def_signal;
-
- def_signal.sa_handler = SIG_DFL;
- def_signal.sa_flags = SA_RESTART;
- sigemptyset (&def_signal.sa_mask);
-
- if G_UNLIKELY (sigaction (signal, &def_signal, NULL) < 0)
- g_warning (_("%s: Error setting signal %d to %s"),
- "gdm_signal_ignore", signal, "SIG_DFL");
-}
-
-int
-gdm_open_dev_null (mode_t mode)
-{
- int ret;
- VE_IGNORE_EINTR (ret = open ("/dev/null", mode));
- if G_UNLIKELY (ret < 0) {
- /*
- * Never output anything, we're likely in some
- * strange state right now
- */
- gdm_signal_ignore (SIGPIPE);
- VE_IGNORE_EINTR (close (2));
- g_error ("Cannot open /dev/null, system on crack!");
- }
-
- return ret;
-}
-
-char *
-gdm_make_filename (const char *dir,
- const char *name,
- const char *extension)
-{
- char *base = g_strconcat (name, extension, NULL);
- char *full = g_build_filename (dir, base, NULL);
- g_free (base);
- return full;
-}
-
-
static int sigchld_blocked = 0;
static sigset_t sigchldblock_mask, sigchldblock_oldmask;
@@ -317,80 +136,33 @@ gdm_sigusr2_block_pop (void)
/* Like fopen with "w" */
FILE *
-gdm_safe_fopen_w (const char *file, mode_t perm)
+gdm_safe_fopen_w (const char *file,
+ mode_t perm)
{
int fd;
FILE *ret;
VE_IGNORE_EINTR (g_unlink (file));
do {
+ int flags;
+
errno = 0;
- fd = open (file, O_EXCL|O_CREAT|O_TRUNC|O_WRONLY
+ flags = O_EXCL | O_CREAT | O_TRUNC | O_WRONLY;
#ifdef O_NOCTTY
- |O_NOCTTY
+ flags |= O_NOCTTY;
#endif
#ifdef O_NOFOLLOW
- |O_NOFOLLOW
+ flags |= O_NOFOLLOW;
#endif
- , perm);
- } while G_UNLIKELY (errno == EINTR);
- if (fd < 0)
- return NULL;
- VE_IGNORE_EINTR (ret = fdopen (fd, "w"));
- return ret;
-}
-/* Like fopen with "a+" */
-FILE *
-gdm_safe_fopen_ap (const char *file, mode_t perm)
-{
- int fd;
- FILE *ret;
+ fd = g_open (file, flags, perm);
+ } while (errno == EINTR);
- if (g_access (file, F_OK) == 0) {
- do {
- errno = 0;
- fd = open (file, O_APPEND|O_RDWR
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
-#ifdef O_NOFOLLOW
- |O_NOFOLLOW
-#endif
- );
- } while G_UNLIKELY (errno == EINTR);
- } else {
- /* Doesn't exist, open with O_EXCL */
- do {
- errno = 0;
- fd = open (file, O_EXCL|O_CREAT|O_RDWR
-#ifdef O_NOCTTY
- |O_NOCTTY
-#endif
-#ifdef O_NOFOLLOW
- |O_NOFOLLOW
-#endif
- , perm);
- } while G_UNLIKELY (errno == EINTR);
- }
- if (fd < 0)
+ if (fd < 0) {
return NULL;
- VE_IGNORE_EINTR (ret = fdopen (fd, "a+"));
- return ret;
-}
-
-void
-gdm_fd_set_close_on_exec (int fd)
-{
- int flags;
-
- flags = fcntl (fd, F_GETFD, 0);
- if (flags < 0) {
- return;
}
- flags |= FD_CLOEXEC;
-
- fcntl (fd, F_SETFD, flags);
+ ret = fdopen (fd, "w");
+ return ret;
}
/**
@@ -420,151 +192,7 @@ ve_clearenv (void)
#endif
}
-char *
-ve_first_word (const char *s)
-{
- int argc;
- char **argv;
- char *ret;
-
- if (s == NULL)
- return NULL;
-
- if ( ! g_shell_parse_argv (s, &argc, &argv, NULL)) {
- char *p;
- ret = g_strdup (s);
- p = strchr (ret, ' ');
- if (p != NULL)
- *p = '\0';
- return ret;
- }
-
- ret = g_strdup (argv[0]);
-
- g_strfreev (argv);
-
- return ret;
-}
-
-static gboolean
-ve_first_word_executable (const char *s,
- gboolean only_existance)
-{
- char *bin = ve_first_word (s);
- if (bin == NULL)
- return FALSE;
- if (g_access (bin, only_existance ? F_OK : X_OK) == 0) {
- g_free (bin);
- return TRUE;
- } else {
- g_free (bin);
- return FALSE;
- }
-}
-
-char *
-ve_get_first_working_command (const char *list,
- gboolean only_existance)
-{
- int i;
- char **vector;
- char *ret = NULL;
-
- if (list == NULL)
- return NULL;
-
- vector = g_strsplit (list, ";", -1);
- for (i = 0; vector[i] != NULL; i++) {
- if (ve_first_word_executable (vector[i],
- only_existance)) {
- ret = g_strdup (vector[i]);
- break;
- }
- }
- g_strfreev (vector);
- return ret;
-}
-
-char *
-ve_locale_to_utf8 (const char *str)
-{
- char *ret = g_locale_to_utf8 (str, -1, NULL, NULL, NULL);
-
- if (ret == NULL) {
- g_warning ("string not in proper locale encoding: \"%s\"", str);
- return g_strdup (str);
- } else {
- return ret;
- }
-}
-
-char *
-ve_locale_from_utf8 (const char *str)
-{
- char *ret = g_locale_from_utf8 (str, -1, NULL, NULL, NULL);
-
- if (ret == NULL) {
- g_warning ("string not in proper utf8 encoding: \"%s\"", str);
- return g_strdup (str);
- } else {
- return ret;
- }
-}
-
-char *
-ve_filename_to_utf8 (const char *str)
-{
- char *ret = g_filename_to_utf8 (str, -1, NULL, NULL, NULL);
- if (ret == NULL) {
- g_warning ("string not in proper locale encoding: \"%s\"", str);
- return g_strdup (str);
- } else {
- return ret;
- }
-}
-
-char *
-ve_filename_from_utf8 (const char *str)
-{
- char *ret = g_filename_from_utf8 (str, -1, NULL, NULL, NULL);
- if (ret == NULL) {
- g_warning ("string not in proper utf8 encoding: \"%s\"", str);
- return g_strdup (str);
- } else {
- return ret;
- }
-}
-
-pid_t
-ve_waitpid_no_signal (pid_t pid, int *status, int options)
-{
- pid_t ret;
-
- for (;;) {
- ret = waitpid (pid, status, options);
- if (ret == 0)
- return 0;
- if (errno != EINTR)
- return ret;
- }
-}
-
-gboolean
-ve_locale_exists (const char *loc)
-{
- gboolean ret;
- char *old = g_strdup (setlocale (LC_MESSAGES, NULL));
- if (setlocale (LC_MESSAGES, loc) != NULL)
- ret = TRUE;
- else
- ret = FALSE;
- setlocale (LC_MESSAGES, old);
- g_free (old);
- return ret;
-}
-
/* hex conversion adapted from D-Bus */
-
/**
* Appends a two-character hex digit to a string, where the hex digit
* has the value of the given byte.