chiark / gitweb /
checkpath.c: Allocate the state from a resource pool.
authorMark Wooding <mdw@distorted.org.uk>
Wed, 17 Jul 2024 12:04:52 +0000 (13:04 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Wed, 17 Jul 2024 12:23:10 +0000 (13:23 +0100)
I think you can see where this is going.

checkpath.c

index e4d83e11d079d1ed4fa94ba7267860e0abc65bfd..95524ae24f34c3b9fc01d670c9c1585cd029b32a 100644 (file)
@@ -44,6 +44,7 @@
 #include <mLib/alloc.h>
 #include <mLib/dstr.h>
 #include <mLib/macros.h>
 #include <mLib/alloc.h>
 #include <mLib/dstr.h>
 #include <mLib/macros.h>
+#include <mLib/pool.h>
 
 #include "checkpath.h"
 
 
 #include "checkpath.h"
 
@@ -64,6 +65,7 @@ struct elt {
 };
 
 struct state {
 };
 
 struct state {
+  pool *p;                             /* Allocation pool */
   struct elt *sp;                      /* Stack pointer for list */
   dstr path;                           /* Current path string */
 };
   struct elt *sp;                      /* Stack pointer for list */
   dstr path;                           /* Current path string */
 };
@@ -355,7 +357,8 @@ unsigned checkpath(const char *p, const struct checkpath *cp)
 {
   char cwd[PATH_MAX];
   struct elt *e, *ee;
 {
   char cwd[PATH_MAX];
   struct elt *e, *ee;
-  struct state state;
+  struct state *state;
+  pool *pp;
   struct stat st;
   unsigned bad = 0;
   dstr buf = DSTR_INIT;
   struct stat st;
   unsigned bad = 0;
   dstr buf = DSTR_INIT;
@@ -363,8 +366,11 @@ unsigned checkpath(const char *p, const struct checkpath *cp)
 
   /* --- Initialize the state --- */
 
 
   /* --- Initialize the state --- */
 
-  state.sp = (/*unconst*/ struct elt *)&rootnode;
-  dstr_create(&state.path);
+  pp = pool_create(arena_global);
+  state = pool_alloc(pp, sizeof(*state));
+  state->p = pp;
+  state->sp = (/*unconst*/ struct elt *)&rootnode;
+  dstr_create(&state->path);
 
   /* --- Try to find the current directory --- */
 
 
   /* --- Try to find the current directory --- */
 
@@ -405,7 +411,7 @@ unsigned checkpath(const char *p, const struct checkpath *cp)
     /* --- Backtrack on `..' elements --- */
 
     else if (strcmp(ee->e_name, "..") == 0) {
     /* --- Backtrack on `..' elements --- */
 
     else if (strcmp(ee->e_name, "..") == 0) {
-      pop(&state);
+      pop(state);
       xfree(ee);
       ee = e;
       continue;
       xfree(ee);
       ee = e;
       continue;
@@ -413,13 +419,13 @@ unsigned checkpath(const char *p, const struct checkpath *cp)
 
     /* --- Everything else gets pushed on the end --- */
 
 
     /* --- Everything else gets pushed on the end --- */
 
-    push(&state, ee);
+    push(state, ee);
     ee = e;
 
     /* --- Find out what sort of a thing this is --- */
 
     ee = e;
 
     /* --- Find out what sort of a thing this is --- */
 
-    if (lstat(state.path.buf, &st)) {
-      report(cp, CP_ERROR, 0, state.path.buf, "can't stat: %e");
+    if (lstat(state->path.buf, &st)) {
+      report(cp, CP_ERROR, 0, state->path.buf, "can't stat: %e");
       bad |= CP_ERROR;
       break;
     }
       bad |= CP_ERROR;
       break;
     }
@@ -432,13 +438,13 @@ unsigned checkpath(const char *p, const struct checkpath *cp)
 
       dstr_reset(&buf);
       dstr_ensure(&buf, st.st_size + 1);
 
       dstr_reset(&buf);
       dstr_ensure(&buf, st.st_size + 1);
-      if ((i = readlink(state.path.buf, buf.buf, buf.sz)) < 0) {
-       report(cp, CP_ERROR, 0, state.path.buf, "can't readlink: %e");
+      if ((i = readlink(state->path.buf, buf.buf, buf.sz)) < 0) {
+       report(cp, CP_ERROR, 0, state->path.buf, "can't readlink: %e");
        bad |= CP_ERROR;
        break;
       }
       buf.buf[i] = 0;
        bad |= CP_ERROR;
        break;
       }
       buf.buf[i] = 0;
-      report(cp, CP_SYMLINK, 2, state.path.buf, "symlink -> `%s'", buf.buf);
+      report(cp, CP_SYMLINK, 2, state->path.buf, "symlink -> `%s'", buf.buf);
 
       /* --- Handle sticky parents --- *
        *
 
       /* --- Handle sticky parents --- *
        *
@@ -448,31 +454,31 @@ unsigned checkpath(const char *p, const struct checkpath *cp)
        */
 
       if ((cp->cp_what & CP_WROTHUSR) &&
        */
 
       if ((cp->cp_what & CP_WROTHUSR) &&
-         (state.sp->e_link->e_flags & EF_STICKY) &&
+         (state->sp->e_link->e_flags & EF_STICKY) &&
          st.st_uid != cp->cp_uid && st.st_uid != 0) {
        bad |= CP_WROTHUSR;
          st.st_uid != cp->cp_uid && st.st_uid != 0) {
        bad |= CP_WROTHUSR;
-       report(cp, CP_WROTHUSR, 1, state.path.buf,
+       report(cp, CP_WROTHUSR, 1, state->path.buf,
               "symlink modifiable by user %u", st.st_uid);
       }
 
       /* --- Sort out what to do from here --- */
 
       if (buf.buf[0] == '/')
               "symlink modifiable by user %u", st.st_uid);
       }
 
       /* --- Sort out what to do from here --- */
 
       if (buf.buf[0] == '/')
-       popall(&state);
+       popall(state);
       else
       else
-       pop(&state);
+       pop(state);
       ee = splitpath(buf.buf, ee);
       continue;
     }
 
     /* --- Run the sanity check on this path element --- */
 
       ee = splitpath(buf.buf, ee);
       continue;
     }
 
     /* --- Run the sanity check on this path element --- */
 
-    bad |= sanity(state.path.buf, &st, cp, ee ? 0 : SF_LAST);
+    bad |= sanity(state->path.buf, &st, cp, ee ? 0 : SF_LAST);
 
     if (S_ISDIR(st.st_mode)) {
       if (st.st_mode & S_ISVTX)
 
     if (S_ISDIR(st.st_mode)) {
       if (st.st_mode & S_ISVTX)
-       state.sp->e_flags |= EF_STICKY;
-      report(cp, CP_REPORT, 4, state.path.buf, "directory");
+       state->sp->e_flags |= EF_STICKY;
+      report(cp, CP_REPORT, 4, state->path.buf, "directory");
       continue;
     }
 
       continue;
     }
 
@@ -493,9 +499,10 @@ unsigned checkpath(const char *p, const struct checkpath *cp)
     }
   }
 
     }
   }
 
-  popall(&state);
-  dstr_destroy(&state.path);
+  popall(state);
+  dstr_destroy(&state->path);
   dstr_destroy(&buf);
   dstr_destroy(&buf);
+  pool_destroy(state->p);
   return (bad);
 }
 
   return (bad);
 }