[gdm/gnome-2-30] Wrap getpw* calls to retry in EINTR



commit 6e4f853c9b23d0e464c571558054b1dfee60a278
Author: William Jon McCann <jmccann redhat com>
Date:   Wed Jun 30 10:20:43 2010 -0400

    Wrap getpw* calls to retry in EINTR
    
    if getpwnam(username) returns NULL, errno needs to be
    checked for EINTR. This indicates that a signal was received while waiting for
    the blocking call to return, and getpwnam() should be retried.

 common/gdm-common.c                   |   19 +++++++++++++
 common/gdm-common.h                   |    3 ++
 daemon/gdm-chooser-server.c           |    3 +-
 daemon/gdm-display-access-file.c      |    2 +-
 daemon/gdm-greeter-server.c           |    3 +-
 daemon/gdm-server.c                   |    4 +-
 daemon/gdm-session-linux-auditor.c    |    6 +++-
 daemon/gdm-session-solaris-auditor.c  |    4 +-
 daemon/gdm-session-worker.c           |   14 ++++++---
 daemon/gdm-slave.c                    |    6 ++--
 daemon/gdm-welcome-session.c          |    6 ++--
 daemon/main.c                         |    2 +-
 gui/simple-greeter/gdm-user-manager.c |   49 +++++++++++++++++++++++++++++----
 13 files changed, 94 insertions(+), 27 deletions(-)
---
diff --git a/common/gdm-common.c b/common/gdm-common.c
index b428f5b..1b344f3 100644
--- a/common/gdm-common.c
+++ b/common/gdm-common.c
@@ -26,6 +26,7 @@
 #include <locale.h>
 #include <fcntl.h>
 #include <sys/wait.h>
+#include <pwd.h>
 
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -73,6 +74,24 @@ gdm_set_fatal_warnings_if_unstable (void)
         }
 }
 
+gboolean
+gdm_get_pwent_for_name (const char     *name,
+                        struct passwd **pwentp)
+{
+        struct passwd *pwent;
+
+        do {
+                errno = 0;
+                pwent = getpwnam (name);
+        } while (errno != EINTR);
+
+        if (pwentp != NULL) {
+                *pwentp = pwent;
+        }
+
+        return (pwent != NULL);
+}
+
 int
 gdm_wait_on_pid (int pid)
 {
diff --git a/common/gdm-common.h b/common/gdm-common.h
index 191bd70..ae7469e 100644
--- a/common/gdm-common.h
+++ b/common/gdm-common.h
@@ -22,6 +22,7 @@
 #define _GDM_COMMON_H
 
 #include <glib.h>
+#include <pwd.h>
 
 #include "gdm-common-unknown-origin.h"
 
@@ -33,6 +34,8 @@ void           gdm_set_fatal_warnings_if_unstable (void);
 int            gdm_wait_on_pid           (int pid);
 int            gdm_signal_pid            (int pid,
                                           int signal);
+gboolean       gdm_get_pwent_for_name    (const char     *name,
+                                          struct passwd **pwentp);
 
 const char *   gdm_make_temp_dir         (char    *template);
 
diff --git a/daemon/gdm-chooser-server.c b/daemon/gdm-chooser-server.c
index 2268838..fc9fd3c 100644
--- a/daemon/gdm-chooser-server.c
+++ b/daemon/gdm-chooser-server.c
@@ -43,6 +43,7 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
+#include "gdm-common.h"
 #include "gdm-chooser-server.h"
 
 #define GDM_CHOOSER_SERVER_DBUS_PATH      "/org/gnome/DisplayManager/ChooserServer"
@@ -325,7 +326,7 @@ allow_user_function (DBusConnection *connection,
                 return FALSE;
         }
 
-        pwent = getpwnam (chooser_server->priv->user_name);
+        gdm_get_pwent_for_name (chooser_server->priv->user_name, &pwent);
         if (pwent == NULL) {
                 return FALSE;
         }
diff --git a/daemon/gdm-display-access-file.c b/daemon/gdm-display-access-file.c
index 1b52f15..2fc0c78 100644
--- a/daemon/gdm-display-access-file.c
+++ b/daemon/gdm-display-access-file.c
@@ -209,7 +209,7 @@ _get_uid_and_gid_for_user (const char *username,
         g_assert (gid != NULL);
 
         errno = 0;
-        passwd_entry = getpwnam (username);
+        gdm_get_pwent_for_name (username, &passwd_entry);
 
         if (passwd_entry == NULL) {
                 return FALSE;
diff --git a/daemon/gdm-greeter-server.c b/daemon/gdm-greeter-server.c
index cecce83..0c67f1e 100644
--- a/daemon/gdm-greeter-server.c
+++ b/daemon/gdm-greeter-server.c
@@ -43,6 +43,7 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
+#include "gdm-common.h"
 #include "gdm-greeter-server.h"
 
 #define GDM_GREETER_SERVER_DBUS_PATH      "/org/gnome/DisplayManager/GreeterServer"
@@ -885,7 +886,7 @@ allow_user_function (DBusConnection *connection,
                 return FALSE;
         }
 
-        pwent = getpwnam (greeter_server->priv->user_name);
+        gdm_get_pwent_for_name (greeter_server->priv->user_name, &pwent);
         if (pwent == NULL) {
                 return FALSE;
         }
diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
index c829199..feaf673 100644
--- a/daemon/gdm-server.c
+++ b/daemon/gdm-server.c
@@ -360,7 +360,7 @@ change_user (GdmServer *server)
                 return;
         }
 
-        pwent = getpwnam (server->priv->user_name);
+        gdm_get_pwent_for_name (server->priv->user_name, &pwent);
         if (pwent == NULL) {
                 g_warning (_("Server was to be spawned by user %s but that user doesn't exist"),
                            server->priv->user_name);
@@ -531,7 +531,7 @@ get_server_environment (GdmServer *server)
         if (server->priv->user_name != NULL) {
                 struct passwd *pwent;
 
-                pwent = getpwnam (server->priv->user_name);
+                gdm_get_pwent_for_name (server->priv->user_name, &pwent);
 
                 if (pwent->pw_dir != NULL
                     && g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS)) {
diff --git a/daemon/gdm-session-linux-auditor.c b/daemon/gdm-session-linux-auditor.c
index 1542563..6c581f7 100644
--- a/daemon/gdm-session-linux-auditor.c
+++ b/daemon/gdm-session-linux-auditor.c
@@ -1,4 +1,4 @@
-/* gdm-session-linux-auditor.c - Object for Linux auditing of session login/logout
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
  *
  * Copyright (C) 2004, 2008 Sun Microsystems, Inc.
  * Copyright (C) 2005, 2008 Red Hat, Inc.
@@ -35,6 +35,8 @@
 
 #include <glib.h>
 
+#include "gdm-common.h"
+
 struct _GdmSessionLinuxAuditorPrivate
 {
         int audit_fd;
@@ -63,7 +65,7 @@ log_user_message (GdmSessionAuditor *auditor,
         g_object_get (G_OBJECT (auditor), "display-device", &display_device, NULL);
 
         if (username != NULL) {
-                pw = getpwnam (username);
+                gdm_get_pwent_for_name (username, &pw);
         } else {
                 username = g_strdup ("unknown");
                 pw = NULL;
diff --git a/daemon/gdm-session-solaris-auditor.c b/daemon/gdm-session-solaris-auditor.c
index badbdbb..aa7c5c9 100644
--- a/daemon/gdm-session-solaris-auditor.c
+++ b/daemon/gdm-session-solaris-auditor.c
@@ -1,4 +1,4 @@
-/* gdm-session-solaris-auditor.c - Object for Solaris auditing of session login/logout
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
  *
  * Copyright (C) 2004, 2008 Sun Microsystems, Inc.
  * Copyright (C) 2005, 2008 Red Hat, Inc.
@@ -326,7 +326,7 @@ on_username_set (GdmSessionSolarisAuditor *auditor)
 
         g_object_get (G_OBJECT (auditor), "username", &username, NULL);
 
-        passwd_entry = getpwnam (username);
+        gdm_get_pwent_for_name (username, &passwd_entry);
 
         if (passwd_entry != NULL) {
                 auditor->priv->uid = passwd_entry->pw_uid;
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index ea3662a..35a6bfe 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -52,6 +52,7 @@
 
 #include "ck-connector.h"
 
+#include "gdm-common.h"
 #include "gdm-session-worker.h"
 #include "gdm-marshal.h"
 
@@ -210,7 +211,7 @@ open_ck_session (GdmSessionWorker  *worker)
                 is_local = FALSE;
         }
 
-        pwent = getpwnam (worker->priv->username);
+        gdm_get_pwent_for_name (worker->priv->username, &pwent);
         if (pwent == NULL) {
                 goto out;
         }
@@ -1095,7 +1096,7 @@ gdm_session_worker_cache_userfiles (GdmSessionWorker *worker)
         char          *userfile;
         gboolean       res;
 
-        passwd_entry = getpwnam (worker->priv->username);
+        gdm_get_pwent_for_name (worker->priv->username, &passwd_entry);
         if (passwd_entry == NULL)
                 return;
 
@@ -1603,6 +1604,7 @@ _lookup_passwd_info (const char *username,
          * passwd_entry doesn't potentially get stomped on
          * by a PAM module
          */
+ again:
         passwd_entry = NULL;
 #ifdef HAVE_POSIX_GETPWNAM_R
         errno = getpwnam_r (username,
@@ -1617,8 +1619,10 @@ _lookup_passwd_info (const char *username,
                                    (size_t) aux_buffer_size);
         errno = 0;
 #endif /* !HAVE_POSIX_GETPWNAM_R */
-
-        if (errno != 0) {
+        if (errno == EINTR) {
+                g_debug ("%s", g_strerror (errno));
+                goto again;
+        } else if (errno != 0) {
                 g_warning ("%s", g_strerror (errno));
                 goto out;
         }
@@ -1982,7 +1986,7 @@ gdm_session_worker_start_user_session (GdmSessionWorker  *worker,
 
         register_ck_session (worker);
 
-        passwd_entry = getpwnam (worker->priv->username);
+        gdm_get_pwent_for_name (worker->priv->username, &passwd_entry);
 
 #ifdef  HAVE_LOGINDEVPERM
         /*
diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c
index a3d43fc..2915da0 100644
--- a/daemon/gdm-slave.c
+++ b/daemon/gdm-slave.c
@@ -201,7 +201,7 @@ get_script_environment (GdmSlave   *slave,
                 g_hash_table_insert (hash, g_strdup ("USERNAME"),
                                      g_strdup (username));
 
-                pwent = getpwnam (username);
+                gdm_get_pwent_for_name (username, &pwent);
                 if (pwent != NULL) {
                         if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') {
                                 g_hash_table_insert (hash, g_strdup ("HOME"),
@@ -1018,7 +1018,7 @@ gdm_slave_get_timed_login_details (GdmSlave   *slave,
         g_free (username);
 
         if (usernamep != NULL && *usernamep != NULL) {
-                pwent = getpwnam (*usernamep);
+                gdm_get_pwent_for_name (*usernamep, &pwent);
                 if (pwent == NULL) {
                         g_debug ("Invalid username %s for auto/timed login",
                                  *usernamep);
@@ -1052,7 +1052,7 @@ _get_uid_and_gid_for_user (const char *username,
         g_assert (username != NULL);
 
         errno = 0;
-        passwd_entry = getpwnam (username);
+        gdm_get_pwent_for_name (username, &passwd_entry);
 
         if (passwd_entry == NULL) {
                 return FALSE;
diff --git a/daemon/gdm-welcome-session.c b/daemon/gdm-welcome-session.c
index 9fc6717..39c53d8 100644
--- a/daemon/gdm-welcome-session.c
+++ b/daemon/gdm-welcome-session.c
@@ -145,7 +145,7 @@ open_welcome_session (GdmWelcomeSession *welcome_session)
 
         session_type = "LoginWindow";
 
-        pwent = getpwnam (welcome_session->priv->user_name);
+        gdm_get_pwent_for_name (welcome_session->priv->user_name, &pwent);
         if (pwent == NULL) {
                 /* FIXME: */
                 g_warning ("Couldn't look up uid");
@@ -412,7 +412,7 @@ get_welcome_environment (GdmWelcomeSession *welcome_session)
         g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup ("/"));
         g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup ("/bin/sh"));
 
-        pwent = getpwnam (welcome_session->priv->user_name);
+        gdm_get_pwent_for_name (welcome_session->priv->user_name, &pwent);
         if (pwent != NULL) {
                 if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') {
                         g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup (pwent->pw_dir));
@@ -530,7 +530,7 @@ spawn_child_setup (SpawnChildData *data)
                 return;
         }
 
-        pwent = getpwnam (data->user_name);
+        gdm_get_pwent_for_name (data->user_name, &pwent);
         if (pwent == NULL) {
                 g_warning (_("User %s doesn't exist"),
                            data->user_name);
diff --git a/daemon/main.c b/daemon/main.c
index 89b5bef..ddc4ca3 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -408,7 +408,7 @@ gdm_daemon_change_user (uid_t *uidp,
         g_debug ("Changing user:group to %s:%s", username, groupname);
 
         /* Lookup user and groupid for the GDM user */
-        pwent = getpwnam (username);
+        gdm_get_pwent_for_name (username, &pwent);
 
         /* Set uid and gid */
         if G_UNLIKELY (pwent == NULL) {
diff --git a/gui/simple-greeter/gdm-user-manager.c b/gui/simple-greeter/gdm-user-manager.c
index 2b6bd47..b0fd88a 100644
--- a/gui/simple-greeter/gdm-user-manager.c
+++ b/gui/simple-greeter/gdm-user-manager.c
@@ -998,6 +998,42 @@ failed:
         unload_new_session (new_session);
 }
 
+static gboolean
+get_pwent_for_name (const char     *name,
+                    struct passwd **pwentp)
+{
+        struct passwd *pwent;
+
+        do {
+                errno = 0;
+                pwent = getpwnam (name);
+        } while (errno != EINTR);
+
+        if (pwentp != NULL) {
+                *pwentp = pwent;
+        }
+
+        return (pwent != NULL);
+}
+
+static gboolean
+get_pwent_for_uid (uid_t           uid,
+                   struct passwd **pwentp)
+{
+        struct passwd *pwent;
+
+        do {
+                errno = 0;
+                pwent = getpwuid (uid);
+        } while (errno != EINTR);
+
+        if (pwentp != NULL) {
+                *pwentp = pwent;
+        }
+
+        return (pwent != NULL);
+}
+
 static void
 maybe_add_new_session (GdmUserManagerNewSession *new_session)
 {
@@ -1009,7 +1045,7 @@ maybe_add_new_session (GdmUserManagerNewSession *new_session)
         manager = GDM_USER_MANAGER (new_session->manager);
 
         errno = 0;
-        pwent = getpwuid (new_session->uid);
+        get_pwent_for_uid (new_session->uid, &pwent);
         if (pwent == NULL) {
                 g_warning ("Unable to lookup user ID %d: %s",
                            (int) new_session->uid, g_strerror (errno));
@@ -1274,8 +1310,7 @@ gdm_user_manager_get_user (GdmUserManager *manager,
         if (user == NULL) {
                 struct passwd *pwent;
 
-                pwent = getpwnam (username);
-
+                get_pwent_for_name (username, &pwent);
                 if (pwent != NULL) {
                         user = add_new_user_for_pwent (manager, pwent);
                 }
@@ -1293,7 +1328,7 @@ gdm_user_manager_get_user_by_uid (GdmUserManager *manager,
 
         g_return_val_if_fail (GDM_IS_USER_MANAGER (manager), NULL);
 
-        pwent = getpwuid (uid);
+        get_pwent_for_uid (uid, &pwent);
         if (pwent == NULL) {
                 g_warning ("GdmUserManager: unable to lookup uid %d", (int)uid);
                 return NULL;
@@ -1689,7 +1724,8 @@ reload_passwd_file (GHashTable *valid_shells,
         g_hash_table_iter_init (&iter, current_users_by_name);
         while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &user)) {
                 struct passwd *pwent;
-                pwent = getpwnam (name);
+
+                get_pwent_for_name (name, &pwent);
                 if (pwent == NULL) {
                         continue;
                 }
@@ -1703,7 +1739,8 @@ reload_passwd_file (GHashTable *valid_shells,
                 GSList *l;
                 for (l = include_users; l != NULL; l = l->next) {
                         struct passwd *pwent;
-                        pwent = getpwnam (l->data);
+
+                        get_pwent_for_name (l->data, &pwent);
                         if (pwent == NULL) {
                                 continue;
                         }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]