Commit fc28c720 authored by Geoff Simmons's avatar Geoff Simmons

Don't leak resources in the constructor if it fails.

parent 590c4359
......@@ -41,6 +41,7 @@
#include <signal.h>
#include <time.h>
#include <stdio.h>
#include <stdbool.h>
#include "cache/cache.h"
#include "vcl.h"
......@@ -347,13 +348,14 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
VCL_STRING name, VCL_STRING path, VCL_DURATION ttl,
VCL_BOOL log_checks, VCL_BOOL enable_sha256)
{
struct VPFX(file_reader) *rdr;
struct file_info *info;
struct VPFX(file_reader) *rdr = NULL;
struct file_info *info = NULL;
struct sigevent sigev;
timer_t timerid;
struct itimerspec timerspec;
struct obj_head *objh;
struct obj_entry *objent;
struct obj_entry *objent = NULL;
bool lock_init = false;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(rdrp);
......@@ -383,7 +385,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (rdr == NULL) {
VFAIL(ctx, "new %s: allocating space for object: %s",
vcl_name, VAS_errtxt(errno));
return;
goto init_err;
}
AZ(rdr->lock);
......@@ -392,7 +394,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (rdr->lock == NULL) {
VFAIL(ctx, "new %s: allocating space for lock: %s",
vcl_name, VAS_errtxt(errno));
return;
goto init_err;
}
AZ(info->sha256);
......@@ -402,11 +404,13 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (info->sha256 == NULL) {
VFAIL(ctx, "new %s: allocating space for SHA256: %s",
vcl_name, VAS_errtxt(errno));
return;
goto init_err;
}
}
rdr->info = info;
AZ(rdr->obj_name);
AZ(rdr->vcl_name);
rdr->obj_name = strdup(vcl_name);
rdr->vcl_name = strdup(VCL_Name(ctx->vcl));
info->log_checks = log_checks;
......@@ -421,7 +425,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
AZ(info->path);
if (path == NULL || *path == '\0') {
VFAIL(ctx, "new %s: path is empty", vcl_name);
return;
goto init_err;
}
search = VSB_new_auto();
for (const char *start = path; delim == ':'; VSB_clear(search),
......@@ -445,7 +449,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
VSB_destroy(&search);
closefd(&fd);
VFAIL(ctx, "new %s: allocating path", vcl_name);
return;
goto init_err;
}
strcpy(info->path, VSB_data(search));
break;
......@@ -456,7 +460,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (info->path == NULL) {
VFAIL(ctx, "new %s: %s not found or not readable on "
"path %s", vcl_name, name, path);
return;
goto init_err;
}
}
......@@ -464,17 +468,19 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (pthread_rwlock_init(rdr->lock, NULL) != 0) {
VFAIL(ctx, "new %s: initializing lock: %s", vcl_name,
VAS_errtxt(errno));
return;
goto init_err;
}
lock_init = true;
rdr->errlen = ERRMSG_LEN + strlen(name) + strlen(vcl_name)
+ strlen(VCL_Name(ctx->vcl));
AZ(rdr->errbuf);
errno = 0;
rdr->errbuf = malloc(rdr->errlen);
if (rdr->errbuf == NULL) {
VFAIL(ctx, "new %s: allocating error message buffer: %s",
vcl_name, VAS_errtxt(errno));
return;
goto init_err;
}
memset(&sigev, 0, sizeof(sigev));
......@@ -486,7 +492,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (timer_create(CLOCK_MONOTONIC, &sigev, &timerid) != 0) {
VFAIL(ctx, "new %s: cannot create update timer: %s", vcl_name,
VAS_errtxt(errno));
return;
goto init_err;
}
rdr->timerid = timerid;
rdr->flags |= RDR_TIMER_INIT;
......@@ -505,7 +511,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (objent == NULL) {
VFAIL(ctx, "new %s: allocating object list entry: %s", vcl_name,
VAS_errtxt(errno));
return;
goto init_err;
}
objent->obj = rdr;
VSLIST_INSERT_HEAD(objh, objent, list);
......@@ -519,7 +525,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (timer_settime(timerid, 0, &timerspec, NULL) != 0) {
VFAIL(ctx, "new %s: cannot start update timer: %s", vcl_name,
VAS_errtxt(errno));
return;
goto init_err;
}
rdr->flags |= RDR_TIMER_ON;
do {
......@@ -529,7 +535,7 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
if (rdr->flags & RDR_ERROR) {
AN(strcmp(rdr->errbuf, NO_ERR));
VFAIL(ctx, "new %s: %s", vcl_name, rdr->errbuf);
return;
goto init_err;
}
AN(rdr->flags & RDR_MAPPED);
......@@ -538,6 +544,58 @@ vmod_reader__init(VRT_CTX, struct VPFX(file_reader) **rdrp,
AN(rdr->info->mtime.tv_sec);
*rdrp = rdr;
return;
init_err:
if (objent != NULL) {
VSLIST_REMOVE(objh, objent, obj_entry, list);
FREE_OBJ(objent);
}
if (rdr != NULL) {
CHECK_OBJ(rdr, FILE_READER_MAGIC);
if (rdr->flags & RDR_TIMER_INIT) {
errno = 0;
if (timer_delete(timerid) != 0)
VSL(SLT_Error, NO_VXID, "vmod file %s.%s "
"deallocation: cannot delete timer: %s",
vcl_name, name, VAS_errtxt(errno));
}
if (rdr->addr != NULL && (rdr->flags & RDR_MAPPED)) {
errno = 0;
if (unmap(rdr, rdr->addr) != 0)
VSL(SLT_Error, NO_VXID, "vmod file %s.%s "
"deallocation: cannot unmap: %s",
vcl_name, name, VAS_errtxt(errno));
}
if (rdr->lock != NULL) {
if (lock_init) {
errno = 0;
if (pthread_rwlock_destroy(rdr->lock) != 0)
VSL(SLT_Error, NO_VXID,
"vmod file %s.%s deallocation: "
"cannot destroy lock: %s",
vcl_name, name, VAS_errtxt(errno));
}
free(rdr->lock);
}
if (rdr->errbuf != NULL)
free(rdr->errbuf);
if (rdr->obj_name != NULL)
free(rdr->obj_name);
if (rdr->vcl_name != NULL)
free(rdr->vcl_name);
FREE_OBJ(rdr);
}
if (info != NULL) {
CHECK_OBJ(info, FILE_INFO_MAGIC);
if (info->path != NULL)
free(info->path);
if (info->sha256 != NULL)
free(info->sha256);
FREE_OBJ(info);
}
}
VCL_VOID
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment