From 28d2f6bd12adca868d55aef2da93092f752b36bc Mon Sep 17 00:00:00 2001 From: phk Date: Mon, 9 Apr 2007 20:28:08 +0000 Subject: [PATCH] Move the function that pushes the compiled VCL programs C source through the systems cc(1) from the VCL compiler library to the varnishd process. This reduces the VCL-compiler library to a text-procesing functionality and makes it easier to build other tools, including test-suites, around the VCL-compiler. It also moves the actual compiler invocation string into the varnishd sources, where it can be handled appropriately, possibly as a paramter. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1306 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/mgt_vcc.c | 127 ++++++++++++++++++++++++- varnish-cache/lib/libvcl/vcc_compile.c | 97 +------------------ 2 files changed, 126 insertions(+), 98 deletions(-) diff --git a/varnish-cache/bin/varnishd/mgt_vcc.c b/varnish-cache/bin/varnishd/mgt_vcc.c index 0e01241a..9ebd94a5 100644 --- a/varnish-cache/bin/varnishd/mgt_vcc.c +++ b/varnish-cache/bin/varnishd/mgt_vcc.c @@ -118,6 +118,125 @@ static const char *default_vcl = " discard;\n" "}\n"; +/*-------------------------------------------------------------------- + * Invoke system C compiler on source and return resulting dlfile. + * Errors goes in sb; + */ + +static char * +mgt_CallCc(const char *source, struct vsb *sb) +{ + FILE *fo, *fs; + char *of, *sf, buf[BUFSIZ]; + int i, j, sfd; + + /* Create temporary C source file */ + sf = strdup("/tmp/vcl.XXXXXXXX"); + assert(sf != NULL); + sfd = mkstemp(sf); + if (sfd < 0) { + vsb_printf(sb, + "Cannot open temporary source file \"%s\": %s\n", + sf, strerror(errno)); + free(sf); + return (NULL); + } + fs = fdopen(sfd, "r+"); + assert(fs != NULL); + + if (fputs(source, fs) || fflush(fs)) { + vsb_printf(sb, + "Write error to C source file: %s\n", + strerror(errno)); + unlink(sf); + fclose(fs); + return (NULL); + } + rewind(fs); + + /* Name the output shared library */ + of = strdup("/tmp/vcl.XXXXXXXX"); + assert(of != NULL); + of = mktemp(of); + assert(of != NULL); + + /* Attempt to open a pipe to the system C-compiler */ + sprintf(buf, + "ln -f %s /tmp/_.c ;" /* XXX: for debugging */ + "exec cc -fpic -shared -Wl,-x -o %s -x c - < %s 2>&1", + sf, of, sf); + + fo = popen(buf, "r"); + if (fo == NULL) { + vsb_printf(sb, + "Internal error: Cannot execute cc(1): %s\n", + strerror(errno)); + free(of); + unlink(sf); + fclose(fs); + return (NULL); + } + + /* If we get any output, it's bad */ + j = 0; + while (1) { + if (fgets(buf, sizeof buf, fo) == NULL) + break; + if (!j) { + vsb_printf(sb, "Internal error: cc(1) complained:\n"); + j++; + } + vsb_cat(sb, buf); + } + + i = pclose(fo); + if (j == 0 && i != 0) + vsb_printf(sb, + "Internal error: cc(1) exit status 0x%04x\n", i); + + /* If the compiler complained, or exited non-zero, fail */ + if (i || j) { + unlink(of); + free(of); + of = NULL; + } + + /* clean up and return */ + unlink(sf); + free(sf); + fclose(fs); + return (of); +} + +/*--------------------------------------------------------------------*/ + +static char * +mgt_VccCompile(struct vsb *sb, const char *b, const char *e) +{ + char *csrc, *vf; + + csrc = VCC_Compile(sb, b, e); + if (csrc != NULL) { + vf = mgt_CallCc(csrc, sb); + free(csrc); + } + return (vf); +} + +static char * +mgt_VccCompileFile(struct vsb *sb, const char *fn) +{ + char *csrc, *vf; + + csrc = VCC_CompileFile(sb, fn); + if (csrc != NULL) { + vf = mgt_CallCc(csrc, sb); + free(csrc); + } + return (vf); +} + + /*--------------------------------------------------------------------*/ static struct vclprog * @@ -193,10 +312,10 @@ mgt_vcc_default(const char *b_arg, const char *f_arg) free(addr); free(port); AN(buf); - vf = VCC_Compile(sb, buf, NULL); + vf = mgt_VccCompile(sb, buf, NULL); free(buf); } else { - vf = VCC_CompileFile(sb, f_arg); + vf = mgt_VccCompileFile(sb, f_arg); } vsb_finish(sb); if (vsb_len(sb) > 0) { @@ -275,7 +394,7 @@ mcf_config_inline(struct cli *cli, char **av, void *priv) sb = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND); XXXAN(sb); - vf = VCC_Compile(sb, av[3], NULL); + vf = mgt_VccCompile(sb, av[3], NULL); vsb_finish(sb); if (vsb_len(sb) > 0) { cli_out(cli, "%s", vsb_data(sb)); @@ -306,7 +425,7 @@ mcf_config_load(struct cli *cli, char **av, void *priv) sb = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND); XXXAN(sb); - vf = VCC_CompileFile(sb, av[3]); + vf = mgt_VccCompileFile(sb, av[3]); vsb_finish(sb); if (vsb_len(sb) > 0) { cli_out(cli, "%s", vsb_data(sb)); diff --git a/varnish-cache/lib/libvcl/vcc_compile.c b/varnish-cache/lib/libvcl/vcc_compile.c index 765d4086..b081402b 100644 --- a/varnish-cache/lib/libvcl/vcc_compile.c +++ b/varnish-cache/lib/libvcl/vcc_compile.c @@ -577,98 +577,7 @@ vcc_DestroyTokenList(struct tokenlist *tl, char *ret) } /*-------------------------------------------------------------------- - * Invoke system C compiler on source and return resulting dlfile. - * Errors goes in sb; - */ - -static char * -vcc_CallCc(const char *source, struct vsb *sb) -{ - FILE *fo, *fs; - char *of, *sf, buf[BUFSIZ]; - int i, j, sfd; - - /* Create temporary C source file */ - sf = strdup("/tmp/vcl.XXXXXXXX"); - assert(sf != NULL); - sfd = mkstemp(sf); - if (sfd < 0) { - vsb_printf(sb, - "Cannot open temporary source file \"%s\": %s\n", - sf, strerror(errno)); - free(sf); - return (NULL); - } - fs = fdopen(sfd, "r+"); - assert(fs != NULL); - - if (fputs(source, fs) || fflush(fs)) { - vsb_printf(sb, - "Write error to C source file: %s\n", - strerror(errno)); - unlink(sf); - fclose(fs); - return (NULL); - } - rewind(fs); - - /* Name the output shared library */ - of = strdup("/tmp/vcl.XXXXXXXX"); - assert(of != NULL); - of = mktemp(of); - assert(of != NULL); - - /* Attempt to open a pipe to the system C-compiler */ - sprintf(buf, - "ln -f %s /tmp/_.c ;" /* XXX: for debugging */ - "exec cc -fpic -shared -Wl,-x -o %s -x c - < %s 2>&1", - sf, of, sf); - - fo = popen(buf, "r"); - if (fo == NULL) { - vsb_printf(sb, - "Internal error: Cannot execute cc(1): %s\n", - strerror(errno)); - free(of); - unlink(sf); - fclose(fs); - return (NULL); - } - - /* If we get any output, it's bad */ - j = 0; - while (1) { - if (fgets(buf, sizeof buf, fo) == NULL) - break; - if (!j) { - vsb_printf(sb, "Internal error: cc(1) complained:\n"); - j++; - } - vsb_cat(sb, buf); - } - - i = pclose(fo); - if (j == 0 && i != 0) - vsb_printf(sb, - "Internal error: cc(1) exit status 0x%04x\n", i); - - /* If the compiler complained, or exited non-zero, fail */ - if (i || j) { - unlink(of); - free(of); - of = NULL; - } - - /* clean up and return */ - unlink(sf); - free(sf); - fclose(fs); - return (of); -} - -/*-------------------------------------------------------------------- - * Compile the VCL code from the given source and return the filename - * of the resulting shared library. + * Compile the VCL code from the given source and return the C-source */ static char * @@ -755,8 +664,8 @@ vcc_CompileSource(struct vsb *sb, struct source *sp) vsb_cat(tl->fh, vsb_data(tl->fc)); vsb_finish(tl->fh); - /* Grind it through cc(1) */ - of = vcc_CallCc(vsb_data(tl->fh), sb); + of = strdup(vsb_data(tl->fh)); + AN(of); /* done */ return (vcc_DestroyTokenList(tl, of)); -- 2.39.5