* 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 *
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)
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;
int cf_lex(void);
void cf_lex_init(int is_cli, struct config *c);
+void cf_lex_unwind(void);
+
struct symbol *cf_find_symbol(byte *c);
struct symbol *cf_default_name(char *template, int *counter);
struct symbol *cf_define_symbol(struct symbol *symbol, int type, void *def);