summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2018-08-07 13:43:31 +0300
committerPanu Matilainen <pmatilai@redhat.com>2018-08-08 15:23:39 +0300
commit2be92a0bedb84821aa0f9e7fb39c7c7fcf196b90 (patch)
tree3da502f5facc3202c38efabd7d3b9500a3e7f6f7
parent0600d96f32892634770e03b3b3fe3d4eac809c6a (diff)
downloadrpm-2be92a0bedb84821aa0f9e7fb39c7c7fcf196b90.tar.gz
Clean up and improve rpmlog error handling + reporting
Centralize the log failure printing to a helper function, handle the common conditions there. Remember the last error and only print a new one if the error differs to avoid unnecessary flooding. Finally, make the actual message more concise and mark it for i18n. Oh and add a testcase as well. This will still try to perror() in vain even if it's stderr that's returning the errors in the first place, but maybe that's perror()'s problem and not ours. (cherry picked from commit 41cf6f9c8038a99e1e4930a8e70289ca5c8eff5e)
-rw-r--r--rpmio/rpmlog.c40
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/rpmio.at13
3 files changed, 37 insertions, 18 deletions
diff --git a/rpmio/rpmlog.c b/rpmio/rpmlog.c
index d3f69c429..d9f5cfaab 100644
--- a/rpmio/rpmlog.c
+++ b/rpmio/rpmlog.c
@@ -261,10 +261,17 @@ static int getColorConfig(void)
return rc;
}
+static void logerror(void)
+{
+ static __thread int lasterr = 0;
+ if (errno != EPIPE && errno != lasterr) {
+ lasterr = errno;
+ perror(_("Error writing to log"));
+ }
+}
+
static int rpmlogDefault(FILE *stdlog, rpmlogRec rec)
{
- static const char fubar[] =
- "Error occurred during writing of a log message";
FILE *msgout = (stdlog ? stdlog : stderr);
static __thread int color = -1;
const char * colorOn = NULL;
@@ -288,16 +295,15 @@ static int rpmlogDefault(FILE *stdlog, rpmlogRec rec)
case RPMLOG_WARNING:
case RPMLOG_DEBUG:
if (colorOn && *colorOn)
- if (fputs(rpmlogLevelColor(rec->pri), msgout) == EOF
- && errno != EPIPE)
- perror(fubar);
+ if (fputs(rpmlogLevelColor(rec->pri), msgout) == EOF)
+ logerror();
break;
default:
break;
}
- if (fputs(rpmlogLevelPrefix(rec->pri), msgout) == EOF && errno != EPIPE)
- perror(fubar);
+ if (fputs(rpmlogLevelPrefix(rec->pri), msgout) == EOF)
+ logerror();
switch (rec->pri) {
case RPMLOG_INFO:
@@ -309,10 +315,10 @@ static int rpmlogDefault(FILE *stdlog, rpmlogRec rec)
case RPMLOG_ERR:
case RPMLOG_WARNING:
if (colorOn && *colorOn) {
- if (fputs(ANSI_COLOR_RESET, msgout) == EOF && errno != EPIPE)
- perror(fubar);
- if (fputs(ANSI_COLOR_BOLD, msgout) == EOF && errno != EPIPE)
- perror(fubar);
+ if (fputs(ANSI_COLOR_RESET, msgout) == EOF)
+ logerror();
+ if (fputs(ANSI_COLOR_BOLD, msgout) == EOF)
+ logerror();
}
case RPMLOG_DEBUG:
default:
@@ -320,8 +326,8 @@ static int rpmlogDefault(FILE *stdlog, rpmlogRec rec)
}
if (rec->message)
- if (fputs(rec->message, msgout) == EOF && errno != EPIPE)
- perror(fubar);
+ if (fputs(rec->message, msgout) == EOF)
+ logerror();
switch (rec->pri) {
case RPMLOG_INFO:
@@ -334,15 +340,15 @@ static int rpmlogDefault(FILE *stdlog, rpmlogRec rec)
case RPMLOG_WARNING:
case RPMLOG_DEBUG:
if (colorOn && *colorOn)
- if (fputs(ANSI_COLOR_RESET, msgout) == EOF && errno != EPIPE)
- perror(fubar);
+ if (fputs(ANSI_COLOR_RESET, msgout) == EOF)
+ logerror();
break;
default:
break;
}
- if (fflush(msgout) == EOF && errno != EPIPE)
- perror(fubar);
+ if (fflush(msgout) == EOF)
+ logerror();
return (rec->pri <= RPMLOG_CRIT ? RPMLOG_EXIT : 0);
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8cc27610b..eaf817cc2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -135,7 +135,7 @@ testing$(bindir)/rpmbuild: ../rpmbuild
cp -r ${srcdir}/data/ testing/
chmod -R u+w testing/data/
for d in dev etc magic tmp var; do if [ ! -d testing/$${d} ]; then mkdir testing/$${d}; fi; done
- for node in urandom stdin stderr stdout null; do ln -s /dev/$${node} testing/dev/$${node}; done
+ for node in urandom stdin stderr stdout null full; do ln -s /dev/$${node} testing/dev/$${node}; done
for cf in hosts resolv.conf passwd shadow group gshadow mtab ; do [ -f /etc/$${cf} ] && ln -s /etc/$${cf} testing/etc/$${cf}; done
for prog in gzip cat patch tar sh ln chmod rm mkdir uname grep sed find file ionice mktemp nice cut sort diff touch install wc coreutils; do p=`which $${prog}`; if [ "$${p}" != "" ]; then ln -s $${p} testing/$(bindir)/; fi; done
for d in /proc /sys /selinux /etc/selinux; do if [ -d $${d} ]; then ln -s $${d} testing/$${d}; fi; done
diff --git a/tests/rpmio.at b/tests/rpmio.at
index 46d713b4c..7f4c99631 100644
--- a/tests/rpmio.at
+++ b/tests/rpmio.at
@@ -48,3 +48,16 @@ AT_CLEANUP
#[])
#AT_CLEANUP
+AT_SETUP([rpmlog error handling])
+AT_KEYWORDS([log])
+AT_CHECK([
+RPMDB_CLEAR
+RPMDB_INIT
+
+runroot rpm -qpl /data/RPMS/hello-2.0-1.x86_64.rpm > /dev/full
+],
+[0],
+[],
+[Error writing to log: No space left on device
+])
+AT_CLEANUP