From 74beff80ff3624761ecd20fafac0485f48c9c873 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Sun, 28 Jun 2015 00:00:00 -0500 Subject: [PATCH] library: make reads & unref logic a little more robust Since we are not using a higher level standard C fopen all of the read requests were made signal sensitive as that can result in a 'temporarily' failed i/o request. Also, protection against some user calling the 'unref' function on already free memory has been incorporated. This will protect us from some nasty 'Abort' surprise. Signed-off-by: Jim Warner --- proc/meminfo.c | 15 +++++++++++---- proc/readstat.c | 15 +++++++++++---- proc/vmstat.c | 15 +++++++++++---- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/proc/meminfo.c b/proc/meminfo.c index 7ab1cc9e..6cfe808c 100644 --- a/proc/meminfo.c +++ b/proc/meminfo.c @@ -110,9 +110,16 @@ PROCPS_EXPORT int procps_meminfo_read ( if (lseek(info->meminfo_fd, 0L, SEEK_SET) == -1) { return -errno; } - if ((size = read(info->meminfo_fd, buf, sizeof(buf)-1)) < 0) { - return -1; + for (;;) { + if ((size = read(info->meminfo_fd, buf, sizeof(buf)-1)) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -errno; + } + break; } + if (size == 0) + return 0; buf[size] = '\0'; /* Scan the file */ @@ -219,11 +226,11 @@ PROCPS_EXPORT struct procps_meminfo *procps_meminfo_ref ( PROCPS_EXPORT struct procps_meminfo *procps_meminfo_unref ( struct procps_meminfo *info) { - if (info == NULL) + if (info == NULL || info->refcount == 0) return NULL; info->refcount--; if (info->refcount > 0) - return NULL; + return info; free(info); return NULL; } diff --git a/proc/readstat.c b/proc/readstat.c index c8873e77..16322ad3 100644 --- a/proc/readstat.c +++ b/proc/readstat.c @@ -90,9 +90,16 @@ PROCPS_EXPORT int procps_stat_read ( if (lseek(info->stat_fd, 0L, SEEK_SET) == -1) { return -errno; } - if ((size = read(info->stat_fd, buf, sizeof(buf)-1)) < 0) { - return -1; + for (;;) { + if ((size = read(info->stat_fd, buf, sizeof(buf)-1)) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -errno; + } + break; } + if (size == 0) + return 0; buf[size] = '\0'; /* Scan the file */ @@ -155,11 +162,11 @@ PROCPS_EXPORT struct procps_statinfo *procps_stat_ref ( PROCPS_EXPORT struct procps_statinfo *procps_stat_unref ( struct procps_statinfo *info) { - if (info == NULL) + if (info == NULL || info->refcount == 0) return NULL; info->refcount--; if (info->refcount > 0) - return NULL; + return info; free(info); return NULL; } diff --git a/proc/vmstat.c b/proc/vmstat.c index 8f9f1f6f..953c8b6a 100644 --- a/proc/vmstat.c +++ b/proc/vmstat.c @@ -83,9 +83,16 @@ PROCPS_EXPORT int procps_vmstat_read ( if (lseek(info->vmstat_fd, 0L, SEEK_SET) == -1) { return -errno; } - if ((size = read(info->vmstat_fd, buf, sizeof(buf)-1)) < 0) { - return -1; + for (;;) { + if ((size = read(info->vmstat_fd, buf, sizeof(buf)-1)) < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -errno; + } + break; } + if (size == 0) + return 0; buf[size] = '\0'; /* Scan the file */ @@ -130,11 +137,11 @@ PROCPS_EXPORT struct procps_vmstat *procps_vmstat_ref ( PROCPS_EXPORT struct procps_vmstat *procps_vmstat_unref ( struct procps_vmstat *info) { - if (info == NULL) + if (info == NULL || info->refcount == 0) return NULL; info->refcount--; if (info->refcount > 0) - return NULL; + return info; free(info); return NULL; }