diff options
Diffstat (limited to 'common/gdm-common.c')
-rw-r--r-- | common/gdm-common.c | 398 |
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. |