summaryrefslogtreecommitdiff
path: root/0002-Repeat-pututxline-if-it-fails-with-EINTR.patch
diff options
context:
space:
mode:
Diffstat (limited to '0002-Repeat-pututxline-if-it-fails-with-EINTR.patch')
-rw-r--r--0002-Repeat-pututxline-if-it-fails-with-EINTR.patch105
1 files changed, 105 insertions, 0 deletions
diff --git a/0002-Repeat-pututxline-if-it-fails-with-EINTR.patch b/0002-Repeat-pututxline-if-it-fails-with-EINTR.patch
new file mode 100644
index 0000000..e89efcf
--- /dev/null
+++ b/0002-Repeat-pututxline-if-it-fails-with-EINTR.patch
@@ -0,0 +1,105 @@
+From 896b3694ca062d747cd67e9e9ba246adb3fc706b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com>
+Date: Mon, 5 Aug 2019 13:55:37 +0200
+Subject: [PATCH 2/2] Repeat pututxline() if it fails with EINTR
+
+This is a partial fix for rhbz#1688848. We cannot resolve it
+completely until glibc bug rhbz#1734791 is fixed. See
+https://bugzilla.redhat.com/show_bug.cgi?id=1688848#c13.
+
+The maximum number of attempts is currently 2, which might seem
+low. However setting it to 2 was a decision based on data - see
+https://bugzilla.redhat.com/show_bug.cgi?id=1688848#c16.
+
+Resolves: rhbz#1688848
+---
+ sysdeputil.c | 53 +++++++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 46 insertions(+), 7 deletions(-)
+
+diff --git a/sysdeputil.c b/sysdeputil.c
+index bd1e8c9..4fbcca7 100644
+--- a/sysdeputil.c
++++ b/sysdeputil.c
+@@ -1203,6 +1203,8 @@ void
+ vsf_insert_uwtmp(const struct mystr* p_user_str,
+ const struct mystr* p_host_str)
+ {
++ int attempts;
++
+ if (sizeof(s_utent.ut_line) < 16)
+ {
+ return;
+@@ -1231,16 +1233,35 @@ vsf_insert_uwtmp(const struct mystr* p_user_str,
+ vsf_sysutil_strcpy(s_utent.ut_host, str_getbuf(p_host_str),
+ sizeof(s_utent.ut_host));
+ s_utent.ut_tv.tv_sec = vsf_sysutil_get_time_sec();
+- setutxent();
+- (void) pututxline(&s_utent);
+- endutxent();
+- s_uwtmp_inserted = 1;
++ for (attempts = 2; attempts > 0; --attempts)
++ {
++ struct utmpx* p_res;
++ setutxent();
++ p_res = pututxline(&s_utent);
++ /* For now we'll ignore errors other than EINTR and EAGAIN */
++ if (p_res != NULL || (errno != EINTR && errno != EAGAIN))
++ {
++ break;
++ }
++ }
++ if (attempts == 0)
++ {
++ /* This makes us skip pututxline() in vsf_remove_uwtmp() */
++ s_uwtmp_inserted = -1;
++ }
++ else
++ {
++ s_uwtmp_inserted = 1;
++ endutxent();
++ }
+ updwtmpx(WTMPX_FILE, &s_utent);
+ }
+
+ void
+ vsf_remove_uwtmp(void)
+ {
++ int attempts;
++
+ if (!s_uwtmp_inserted)
+ {
+ return;
+@@ -1249,9 +1270,27 @@ vsf_remove_uwtmp(void)
+ vsf_sysutil_memclr(s_utent.ut_user, sizeof(s_utent.ut_user));
+ vsf_sysutil_memclr(s_utent.ut_host, sizeof(s_utent.ut_host));
+ s_utent.ut_tv.tv_sec = 0;
+- setutxent();
+- (void) pututxline(&s_utent);
+- endutxent();
++ if (s_uwtmp_inserted == 1)
++ {
++ for (attempts = 2; attempts > 0; --attempts)
++ {
++ struct utmpx* p_res;
++ setutxent();
++ p_res = pututxline(&s_utent);
++ /* For now we'll ignore errors other than EINTR and EAGAIN */
++ if (p_res != NULL || (errno != EINTR && errno != EAGAIN))
++ {
++ break;
++ }
++ }
++ if (attempts != 0)
++ {
++ endutxent();
++ }
++ }
++ /* Set s_uwtmp_inserted to 0 regardless of the result of
++ * pututxline() to make sure we won't run this function twice.
++ */
+ s_uwtmp_inserted = 0;
+ s_utent.ut_tv.tv_sec = vsf_sysutil_get_time_sec();
+ updwtmpx(WTMPX_FILE, &s_utent);
+--
+2.20.1
+