]> err.no Git - varnish/commitdiff
Make the C-compiler command a paramter, and generally clean up the
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 20 Aug 2007 10:21:07 +0000 (10:21 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 20 Aug 2007 10:21:07 +0000 (10:21 +0000)
code that invokes it.

If fmtcheck(3) is available, we refuse pedal target practice.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1882 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/mgt.h
varnish-cache/bin/varnishd/mgt_param.c
varnish-cache/bin/varnishd/mgt_vcc.c

index afd8fb4c1aa0856efe909e0a26e6b748c01919e6..3224d7e41dca706eee6e7d7b5598a274e03ea432 100644 (file)
@@ -60,6 +60,7 @@ void MCF_ParamSet(struct cli *, const char *param, const char *val);
 void mgt_vcc_init(void);
 int mgt_vcc_default(const char *bflag, const char *fflag, int f_fd, int Cflag);
 int mgt_push_vcls_and_start(unsigned *status, char **p);
+extern char *mgt_cc_cmd;
 
 #include "hash_slinger.h"
 
index d400d99c8c4a37b5b87c4eaa710f6a9c32d8b290..5d8ba53c1b3d01b2e74cdcaf9ef01cda0e97814a 100644 (file)
@@ -527,6 +527,30 @@ tweak_ping_interval(struct cli *cli, struct parspec *par, const char *arg)
 
 /*--------------------------------------------------------------------*/
 
+static void
+tweak_cc_command(struct cli *cli, struct parspec *par, const char *arg)
+{
+
+       (void)par;
+       if (arg == NULL) {
+               cli_out(cli, "%s", mgt_cc_cmd);
+       } else {
+#if defined(HAVE_FMTCHECK)
+               if (arg != fmtcheck(arg, "%s %s")) {
+                       cli_out(cli,
+                           "Parameter has dangerous %%-string expansions.");
+                       cli_result(cli, CLIS_PARAM);
+                       return;
+               } 
+#endif
+               free(mgt_cc_cmd);
+               mgt_cc_cmd = strdup(arg);
+               XXXAN(mgt_cc_cmd);
+       }
+}
+
+/*--------------------------------------------------------------------*/
+
 /*
  * Make sure to end all lines with either a space or newline of the
  * formatting will go haywire.
@@ -539,6 +563,10 @@ tweak_ping_interval(struct cli *cli, struct parspec *par, const char *arg)
        "\nNB: This parameter will not take any effect until the " \
        "child process has been restarted.\n"
 
+#define MUST_RELOAD \
+       "\nNB: This parameter will not take any effect until the " \
+       "VCL programs have been reloaded.\n"
+
 #define EXPERIMENTAL \
        "\nNB: We don't know yet if it is a good idea to change " \
        "this parameter.  Caution advised.\n"
@@ -700,6 +728,20 @@ static struct parspec parspec[] = {
                "it possible to attach a debugger to the child.\n"
                MUST_RESTART,
                "3", "seconds" },
+       { "cc_command", tweak_cc_command,
+               "Command used for compiling the C source code to a "
+               "dlopen(3) loadable object.\n"
+               "NB: The string must contain two %%s sequences which "
+               "will be replaced by the binary and source file names "
+               "respectively.\n"
+               MUST_RELOAD,
+#ifdef __APPLE__
+               "exec cc -dynamiclib -Wl,-undefined,dynamic_lookup -o %s -x c"
+               " - < %s"
+#else
+               "exec cc -nostdinc -fpic -shared -Wl,-x -o %s -x c - < %s"
+#endif
+               , NULL },
        { NULL, NULL, NULL }
 };
 
index efe959496eaef6e292dc18d2b2dfe97640851cde..2b34509b5b4104047fd7646007e722dfa71e7587 100644 (file)
@@ -38,6 +38,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/wait.h>
 
 #ifndef HAVE_ASPRINTF
 #include "compat/asprintf.h"
@@ -65,6 +66,8 @@ struct vclprog {
 
 static TAILQ_HEAD(, vclprog) vclhead = TAILQ_HEAD_INITIALIZER(vclhead);
 
+char *mgt_cc_cmd;
+
 /*--------------------------------------------------------------------*/
 
 /* keep this in synch with man/vcl.7 */
@@ -148,8 +151,9 @@ mgt_CallCc(const char *source, struct vsb *sb)
        FILE *fo, *fs;
        char sf[] = "./vcl.XXXXXXXX";
        char *of;
-       char buf[BUFSIZ];
-       int i, j, len, sfd;
+       struct vsb *cccmd;
+       char buf[128];
+       int i, j, sfd;
        void *p;
 
        /* Create temporary C source file */
@@ -161,7 +165,7 @@ mgt_CallCc(const char *source, struct vsb *sb)
                return (NULL);
        }
        fs = fdopen(sfd, "r+");
-       AN(fs);
+       XXXAN(fs);
 
        if (fputs(source, fs) < 0 || fflush(fs)) {
                vsb_printf(sb,
@@ -173,55 +177,92 @@ mgt_CallCc(const char *source, struct vsb *sb)
        }
        rewind(fs);
 
-       /* Name the output shared library */
+       /* Name the output shared library by brutally overwriting "./vcl." */
        of = strdup(sf);
-       AN(of);
+       XXXAN(of);
        memcpy(of, "./bin", 5);
 
-       /* Attempt to open a pipe to the system C-compiler */
-       len = snprintf(buf, sizeof buf,
-            "ln -f %s _.c ;"                   /* XXX: for debugging */
-#ifdef __APPLE__
-           "exec cc -dynamiclib -Wl,-undefined,dynamic_lookup -o %s -x c - < %s 2>&1",
-#else
-           "env -i cc -nostdinc -fpic -shared -Wl,-x -o %s -x c - < %s 2>&1",
-#endif
-           sf, of, sf);
-       xxxassert(len < sizeof buf);
-
-       fo = popen(buf, "r");
+       cccmd = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND);
+       XXXAN(cccmd);
+
+       /*
+        * Attempt to open a pipe to the system C-compiler.
+        * ------------------------------------------------
+        *
+        * The arguments to the C-compiler must be whatever it takes to
+        * create a dlopen(3) compatible object file named $of from a
+        * source file named $sf.
+        *
+        * The source code is entirely selfcontained, so options should be
+        * specified to prevent the C-compiler from doing any DWITYW 
+        * processing.  For GCC this amounts to at least "-nostdinc".
+        *
+        * We wrap the entire command in a 'sh -c "..." 2>&1' to get any
+        * errors from popen(3)'s shell redirected to our stderr as well.
+        * 
+        */
+       vsb_printf(cccmd, "exec /bin/sh -c \"" );
+       vsb_printf(cccmd, mgt_cc_cmd, of, sf);
+       vsb_printf(cccmd, "\" 2>&1");
+       vsb_finish(cccmd);
+       /* XXX: check that vsb is happy about cccmd */
+
+       fo = popen(vsb_data(cccmd), "r");
        if (fo == NULL) {
                vsb_printf(sb,
-                   "Internal error: Cannot execute cc(1): %s\n",
-                   strerror(errno));
+                   "System error: Cannot execute C-compiler: %s\n"
+                   "\tcommand attempted: %s\n",
+                   strerror(errno), vsb_data(cccmd));
                free(of);
                unlink(sf);
                fclose(fs);
+               vsb_delete(cccmd);
                return (NULL);
        }
 
-       /* If we get any output, it's bad */
+       /* Any output is considered fatal */
        j = 0;
        while (1) {
-               if (fgets(buf, sizeof buf, fo) == NULL)
+               i  = fread(buf, 1, sizeof buf, fo);
+               if (i == 0)
                        break;
                if (!j) {
-                       vsb_printf(sb, "Internal error: cc(1) complained:\n");
+                       vsb_printf(sb,
+                           "System error:\n"
+                           "C-compiler command complained.\n"
+                           "Command attempted: %s\nMessage:\n",
+                           vsb_data(cccmd));
                        j++;
                }
-               vsb_cat(sb, buf);
+               vsb_bcat(sb, buf, i);
        }
 
        i = pclose(fo);
-       if (j == 0 && i != 0)
+
+       unlink(sf);
+       fclose(fs);
+
+       if (j == 0 && i != 0) {
+               vsb_printf(sb,
+                   "System error:\n"
+                   "C-compiler command failed");
+               if (WIFEXITED(i)) 
+                   vsb_printf(sb, ", exit %d", WEXITSTATUS(i));
+               if (WIFSIGNALED(i))
+                   vsb_printf(sb, ", signal %d", WTERMSIG(i));
+               if (WCOREDUMP(i))
+                   vsb_printf(sb, ", core dumped");
                vsb_printf(sb,
-                   "Internal error: cc(1) exit status 0x%04x\n", i);
+                   "\nCommand attempted: %s\n", vsb_data(cccmd));
+       }
+
+       vsb_delete(cccmd);
 
        /* If the compiler complained, or exited non-zero, fail */
        if (i || j) {
                unlink(of);
                free(of);
-               of = NULL;
+               return (NULL);
        }
 
        /* Next, try to load the object into the management process */
@@ -231,13 +272,10 @@ mgt_CallCc(const char *source, struct vsb *sb)
                    dlerror());
                unlink(of);
                free(of);
-               of = NULL;
-       } else
-               (void)dlclose(p);
+               return (NULL);
+       } 
 
-       /* clean up and return */
-       unlink(sf);
-       fclose(fs);
+       (void)dlclose(p);
        return (of);
 }