summaryrefslogtreecommitdiff
path: root/conf/cf-lex.l
diff options
context:
space:
mode:
Diffstat (limited to 'conf/cf-lex.l')
-rw-r--r--conf/cf-lex.l33
1 files changed, 28 insertions, 5 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index b1bbeae2..99785057 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -275,9 +275,6 @@ cf_hash(byte *c)
* match - these do not have fd and flex buffer yet).
*
* FIXME: Most of these ifs and include functions are really sysdep/unix.
- *
- * FIXME: Resources (fd, flex buffers and glob data) in IFS stack
- * are not freed when cf_error() is called.
*/
static struct include_file_stack *
@@ -316,13 +313,36 @@ enter_ifs(struct include_file_stack *new)
yy_switch_to_buffer(new->buffer);
}
+/**
+ * cf_lex_unwind - unwind lexer state during error
+ *
+ * cf_lex_unwind() frees the internal state on IFS stack when the lexical
+ * analyzer is terminated by cf_error().
+ */
+void
+cf_lex_unwind(void)
+{
+ struct include_file_stack *n;
+
+ for (n = ifs; n != ifs_head; n = n->prev)
+ {
+ /* Memory is freed automatically */
+ if (n->buffer)
+ yy_delete_buffer(n->buffer);
+ if (n->fd)
+ close(n->fd);
+ }
+
+ ifs = ifs_head;
+}
+
static void
cf_include(char *arg, int alen)
{
struct include_file_stack *base_ifs = ifs;
int new_depth, rv, i;
char *patt;
- glob_t g;
+ glob_t g = {};
new_depth = ifs->depth + 1;
if (new_depth > MAX_INCLUDE_DEPTH)
@@ -370,7 +390,10 @@ cf_include(char *arg, int alen)
struct stat fs;
if (stat(fname, &fs) < 0)
- cf_error("Unable to stat included file %s: %m", fname);
+ {
+ globfree(&g);
+ cf_error("Unable to stat included file %s: %m", fname);
+ }
if (fs.st_mode & S_IFDIR)
continue;