int lbx_errno = 0;
struct lbx_state {
- const char *name;
+ char *name;
const struct lbx_file_ops *fops;
int (*dtor)(void *handle);
return lbx;
}
+static char *str_dup(const char *s)
+{
+ char *buf;
+
+ buf = malloc(strlen(s)+1);
+ if (buf)
+ strcpy(buf, s);
+ return buf;
+}
+
struct lbx_state *lbx_open(void *f, const struct lbx_file_ops *fops,
int (*destructor)(void *), const char *name)
{
unsigned char hdr_buf[LBX_HDR_SIZE];
- struct lbx_state *lbx;
+ struct lbx_state *lbx = NULL;
+ char *dupname = NULL;
+
+ dupname = str_dup(name);
+ if (!dupname) {
+ lbx_errno = -errno;
+ goto err;
+ }
if (fops->read(hdr_buf, sizeof hdr_buf, f) != sizeof hdr_buf) {
lbx_errno = -errno;
- return NULL;
+ goto err;
}
lbx = lbx_init(hdr_buf);
if (!lbx)
- return NULL;
+ goto err;
+ lbx->name = dupname;
lbx->dtor = destructor;
- lbx->name = name;
lbx->fops = fops;
lbx->f = f;
lbx_errno = -errno;
if (fops->eof(f))
lbx_errno = LBX_EEOF;
- free(lbx);
- return NULL;
+ goto err;
}
lbx->offsets[i] = unpack_32_le(buf);
}
return lbx;
+err:
+ free(dupname);
+ free(lbx);
+ return NULL;
}
struct lbx_state *lbx_fopen(FILE *f, const char *name)
if (lbx && lbx->dtor)
rc = lbx->dtor(lbx->f);
+ free(lbx->name);
free(lbx);
return rc;