This to enable regression testing on e.g. VCC compiler segfaults, as
these previously would return CLIS_PARAM(106) (the same as any bad
vcl), thus not really tripping the test case.
---
 bin/varnishd/mgt/mgt_vcc.c |   61 ++++++++++++++++++++++++++------------------
 include/vcli.h             |    3 +-
 include/vsub.h             |    2 +-
 lib/libvarnish/vsub.c      |   15 ++++++++---
 4 files changed, 50 insertions(+), 31 deletions(-)

diff --git a/bin/varnishd/mgt/mgt_vcc.c b/bin/varnishd/mgt/mgt_vcc.c
index 12433ad..a8981b3 100644
--- a/bin/varnishd/mgt/mgt_vcc.c
+++ b/bin/varnishd/mgt/mgt_vcc.c
@@ -215,25 +215,31 @@ run_dlopen(void *priv)
 }
 
 /*--------------------------------------------------------------------
- * Compile a VCL program, return shared object, errors in sb.
+ * Compile a VCL program, shared object in pof, errors in sb.
+ * Returns:
+ *   -2: Critical error
+ *   -1: Parse/compile error
+ *    0: Success (file name in 'pof')
  */
 
-static char *
-mgt_run_cc(const char *vcl, struct vsb *sb, int C_flag)
+static int
+mgt_run_cc(const char *vcl, struct vsb *sb, int C_flag, char **pof)
 {
        char *csrc;
        struct vsb *cmdsb;
        char sf[] = "./vcl.########.c";
        char of[sizeof sf + 1];
-       char *retval;
        int sfd, i;
        struct vcc_priv vp;
 
+       AN(pof);
+       *pof = NULL;
+
        /* Create temporary C source file */
        sfd = VFIL_tmpfile(sf);
        if (sfd < 0) {
                VSB_printf(sb, "Failed to create %s: %s", sf, strerror(errno));
-               return (NULL);
+               return (-2);
        }
        AZ(close(sfd));
 
@@ -242,9 +248,9 @@ mgt_run_cc(const char *vcl, struct vsb *sb, int C_flag)
        vp.magic = VCC_PRIV_MAGIC;
        vp.sf = sf;
        vp.vcl = vcl;
-       if (VSUB_run(sb, run_vcc, &vp, "VCC-compiler", -1)) {
+       if ((i = VSUB_run(sb, run_vcc, &vp, "VCC-compiler", -1))) {
                (void)unlink(sf);
-               return (NULL);
+               return (i);
        }
 
        if (C_flag) {
@@ -276,33 +282,35 @@ mgt_run_cc(const char *vcl, struct vsb *sb, int C_flag)
        /* Ensure the file is readable to the unprivileged user */
        if (!i) {
                i = chmod(of, 0755);
-               if (i)
+               if (i) {
                        VSB_printf(sb, "Failed to set permissions on %s: %s",
                                   of, strerror(errno));
+                       i = -2;
+               }
        }
 
        if (i) {
                (void)unlink(of);
-               return (NULL);
+               return (i);
        }
 
-       retval = strdup(of);
-       XXXAN(retval);
-       return (retval);
+       *pof = strdup(of);
+       XXXAN(*pof);
+       return (i);
 }
 
 /*--------------------------------------------------------------------*/
 
-static char *
-mgt_VccCompile(struct vsb **sb, const char *b, int C_flag)
+static int
+mgt_VccCompile(struct vsb **sb, const char *b, int C_flag, char **pvf)
 {
-       char *vf;
+       int i;
 
        *sb = VSB_new_auto();
        XXXAN(*sb);
-       vf = mgt_run_cc(b, *sb, C_flag);
+       i = mgt_run_cc(b, *sb, C_flag, pvf);
        AZ(VSB_finish(*sb));
-       return (vf);
+       return (i);
 }
 
 /*--------------------------------------------------------------------*/
@@ -358,7 +366,6 @@ mgt_vcc_delbyname(const char *name)
 }
 
 /*--------------------------------------------------------------------*/
-
 int
 mgt_vcc_default(const char *b_arg, const char *f_arg, char *vcl, int C_flag)
 {
@@ -389,7 +396,7 @@ mgt_vcc_default(const char *b_arg, const char *f_arg, char 
*vcl, int C_flag)
        }
        strcpy(buf, "boot");
 
-       vf = mgt_VccCompile(&sb, vcl, C_flag);
+       (void)mgt_VccCompile(&sb, vcl, C_flag, &vf);
        free(vcl);
        if (VSB_len(sb) > 0)
                fprintf(stderr, "%s", VSB_data(sb));
@@ -481,6 +488,7 @@ mcf_config_inline(struct cli *cli, const char * const *av, 
void *priv)
        struct vsb *sb;
        unsigned status;
        struct vclprog *vp;
+       int i;
 
        (void)priv;
 
@@ -491,13 +499,14 @@ mcf_config_inline(struct cli *cli, const char * const 
*av, void *priv)
                return;
        }
 
-       vf = mgt_VccCompile(&sb, av[3], 0);
+       i = mgt_VccCompile(&sb, av[3], 0, &vf);
        if (VSB_len(sb) > 0)
                VCLI_Out(cli, "%s\n", VSB_data(sb));
        VSB_delete(sb);
-       if (vf == NULL) {
+       if (i) {
+               AZ(vf);
                VCLI_Out(cli, "VCL compilation failed");
-               VCLI_SetResult(cli, CLIS_PARAM);
+               VCLI_SetResult(cli, (i < -1 ? CLIS_INTERROR : CLIS_PARAM));
                return;
        }
        VCLI_Out(cli, "VCL compiled.");
@@ -519,6 +528,7 @@ mcf_config_load(struct cli *cli, const char * const *av, 
void *priv)
        unsigned status;
        char *p = NULL;
        struct vclprog *vp;
+       int i;
 
        (void)priv;
        vp = mgt_vcc_byname(av[2]);
@@ -535,15 +545,16 @@ mcf_config_load(struct cli *cli, const char * const *av, 
void *priv)
                return;
        }
 
-       vf = mgt_VccCompile(&sb, vcl, 0);
+       i = mgt_VccCompile(&sb, vcl, 0, &vf);
        free(vcl);
 
        if (VSB_len(sb) > 0)
                VCLI_Out(cli, "%s", VSB_data(sb));
        VSB_delete(sb);
-       if (vf == NULL) {
+       if (i) {
+               AZ(vf);
                VCLI_Out(cli, "VCL compilation failed");
-               VCLI_SetResult(cli, CLIS_PARAM);
+               VCLI_SetResult(cli, (i < -1 ? CLIS_INTERROR : CLIS_PARAM));
                return;
        }
        VCLI_Out(cli, "VCL compiled.");
diff --git a/include/vcli.h b/include/vcli.h
index 04ac11c..21bfa26 100644
--- a/include/vcli.h
+++ b/include/vcli.h
@@ -202,7 +202,8 @@ enum VCLI_status_e {
        CLIS_TRUNCATED  = 201,
        CLIS_CANT       = 300,
        CLIS_COMMS      = 400,
-       CLIS_CLOSE      = 500
+       CLIS_CLOSE      = 500,
+       CLIS_INTERROR   = 503
 };
 
 /* Length of first line of response */
diff --git a/include/vsub.h b/include/vsub.h
index 6705b11..ae89be5 100644
--- a/include/vsub.h
+++ b/include/vsub.h
@@ -28,7 +28,7 @@
  *
  */
 
-/* from libvarnish/subproc.c */
+/* from libvarnish/vsub.c */
 typedef void vsub_func_f(void*);
 
 int VSUB_run(struct vsb *sb, vsub_func_f *func, void *priv, const char *name,
diff --git a/lib/libvarnish/vsub.c b/lib/libvarnish/vsub.c
index 497119c..3550259 100644
--- a/lib/libvarnish/vsub.c
+++ b/lib/libvarnish/vsub.c
@@ -64,6 +64,13 @@ vsub_vlu(void *priv, const char *str)
        return (0);
 }
 
+/* Fork and execute a function
+   Returns:
+     -2: Critical error (syscall failure or exit on signal)
+     -1: Non-zero return value
+      0: Success (zero exit value)
+*/
+
 int
 VSUB_run(struct vsb *sb, vsub_func_f *func, void *priv, const char *name,
     int maxlines)
@@ -81,7 +88,7 @@ VSUB_run(struct vsb *sb, vsub_func_f *func, void *priv, const 
char *name,
        if (pipe(p) < 0) {
                VSB_printf(sb, "Starting %s: pipe() failed: %s",
                    name, strerror(errno));
-               return (-1);
+               return (-2);
        }
        assert(p[0] > STDERR_FILENO);
        assert(p[1] > STDERR_FILENO);
@@ -90,7 +97,7 @@ VSUB_run(struct vsb *sb, vsub_func_f *func, void *priv, const 
char *name,
                    name, strerror(errno));
                AZ(close(p[0]));
                AZ(close(p[1]));
-               return (-1);
+               return (-2);
        }
        if (pid == 0) {
                AZ(close(STDIN_FILENO));
@@ -117,7 +124,7 @@ VSUB_run(struct vsb *sb, vsub_func_f *func, void *priv, 
const char *name,
                if (rv < 0 && errno != EINTR) {
                        VSB_printf(sb, "Running %s: waitpid() failed: %s\n",
                            name, strerror(errno));
-                       return (-1);
+                       return (-2);
                }
        } while (rv < 0);
        if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
@@ -129,7 +136,7 @@ VSUB_run(struct vsb *sb, vsub_func_f *func, void *priv, 
const char *name,
                if (WCOREDUMP(status))
                        VSB_printf(sb, ", core dumped");
                VSB_printf(sb, "\n");
-               return (-1);
+               return (WIFSIGNALED(status) ? -2 : -1);
        }
        return (0);
 }
-- 
1.7.4.1


_______________________________________________
varnish-dev mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev

Reply via email to