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 <james.warner@comcast.net>
This commit is contained in:
Jim Warner 2015-06-28 00:00:00 -05:00 committed by Craig Small
parent 0c162f7af0
commit 74beff80ff
3 changed files with 33 additions and 12 deletions

View File

@ -110,9 +110,16 @@ PROCPS_EXPORT int procps_meminfo_read (
if (lseek(info->meminfo_fd, 0L, SEEK_SET) == -1) { if (lseek(info->meminfo_fd, 0L, SEEK_SET) == -1) {
return -errno; return -errno;
} }
for (;;) {
if ((size = read(info->meminfo_fd, buf, sizeof(buf)-1)) < 0) { if ((size = read(info->meminfo_fd, buf, sizeof(buf)-1)) < 0) {
return -1; if (errno == EINTR || errno == EAGAIN)
continue;
return -errno;
} }
break;
}
if (size == 0)
return 0;
buf[size] = '\0'; buf[size] = '\0';
/* Scan the file */ /* Scan the file */
@ -219,11 +226,11 @@ PROCPS_EXPORT struct procps_meminfo *procps_meminfo_ref (
PROCPS_EXPORT struct procps_meminfo *procps_meminfo_unref ( PROCPS_EXPORT struct procps_meminfo *procps_meminfo_unref (
struct procps_meminfo *info) struct procps_meminfo *info)
{ {
if (info == NULL) if (info == NULL || info->refcount == 0)
return NULL; return NULL;
info->refcount--; info->refcount--;
if (info->refcount > 0) if (info->refcount > 0)
return NULL; return info;
free(info); free(info);
return NULL; return NULL;
} }

View File

@ -90,9 +90,16 @@ PROCPS_EXPORT int procps_stat_read (
if (lseek(info->stat_fd, 0L, SEEK_SET) == -1) { if (lseek(info->stat_fd, 0L, SEEK_SET) == -1) {
return -errno; return -errno;
} }
for (;;) {
if ((size = read(info->stat_fd, buf, sizeof(buf)-1)) < 0) { if ((size = read(info->stat_fd, buf, sizeof(buf)-1)) < 0) {
return -1; if (errno == EINTR || errno == EAGAIN)
continue;
return -errno;
} }
break;
}
if (size == 0)
return 0;
buf[size] = '\0'; buf[size] = '\0';
/* Scan the file */ /* Scan the file */
@ -155,11 +162,11 @@ PROCPS_EXPORT struct procps_statinfo *procps_stat_ref (
PROCPS_EXPORT struct procps_statinfo *procps_stat_unref ( PROCPS_EXPORT struct procps_statinfo *procps_stat_unref (
struct procps_statinfo *info) struct procps_statinfo *info)
{ {
if (info == NULL) if (info == NULL || info->refcount == 0)
return NULL; return NULL;
info->refcount--; info->refcount--;
if (info->refcount > 0) if (info->refcount > 0)
return NULL; return info;
free(info); free(info);
return NULL; return NULL;
} }

View File

@ -83,9 +83,16 @@ PROCPS_EXPORT int procps_vmstat_read (
if (lseek(info->vmstat_fd, 0L, SEEK_SET) == -1) { if (lseek(info->vmstat_fd, 0L, SEEK_SET) == -1) {
return -errno; return -errno;
} }
for (;;) {
if ((size = read(info->vmstat_fd, buf, sizeof(buf)-1)) < 0) { if ((size = read(info->vmstat_fd, buf, sizeof(buf)-1)) < 0) {
return -1; if (errno == EINTR || errno == EAGAIN)
continue;
return -errno;
} }
break;
}
if (size == 0)
return 0;
buf[size] = '\0'; buf[size] = '\0';
/* Scan the file */ /* Scan the file */
@ -130,11 +137,11 @@ PROCPS_EXPORT struct procps_vmstat *procps_vmstat_ref (
PROCPS_EXPORT struct procps_vmstat *procps_vmstat_unref ( PROCPS_EXPORT struct procps_vmstat *procps_vmstat_unref (
struct procps_vmstat *info) struct procps_vmstat *info)
{ {
if (info == NULL) if (info == NULL || info->refcount == 0)
return NULL; return NULL;
info->refcount--; info->refcount--;
if (info->refcount > 0) if (info->refcount > 0)
return NULL; return info;
free(info); free(info);
return NULL; return NULL;
} }