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:
parent
0c162f7af0
commit
74beff80ff
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user