├── .circleci └── config.yml ├── .gitignore ├── .travis.yml ├── CHANGES.rst ├── COPYING ├── LICENSE ├── Makefile.am ├── README.rst ├── autogen.sh ├── configure.ac ├── m4 └── ax_pthread.m4 ├── rename-vmod-script └── src ├── Makefile.am ├── tests └── test01.vtc ├── vmod_example.c └── vmod_example.vcc /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | # use circleci's pipeline argument to ease configuration. 4 | # this allows you to track the right packages, and to add extra dependencies if needed 5 | # just change the default here 6 | parameters: 7 | pc-repo: 8 | description: the packagecloud repository to find the Varnish Cache packages. It should match the version you are building against 9 | type: string 10 | default: "varnish-weekly" 11 | dep-pkgs: 12 | description: which packages to install to build your vmod(s) 13 | type: string 14 | default: "make automake libtool python-sphinx" 15 | 16 | # for now, we just build for centos:7, be we can do it for more platforms if needed 17 | jobs: 18 | build: 19 | docker: 20 | - image: centos:7 21 | working_directory: /workspace 22 | steps: 23 | - run: 24 | name: Install dependencies 25 | command: | 26 | curl -s https://packagecloud.io/install/repositories/varnishcache/<< pipeline.parameters.pc-repo >>/script.rpm.sh | bash 27 | yum install -y epel-release 28 | yum install -y git varnish-devel << pipeline.parameters.dep-pkgs >> 29 | - checkout 30 | - run: 31 | name: Build and test 32 | command: | 33 | ./autogen.sh 34 | ./configure 35 | make 36 | make check -j 4 37 | make install 38 | 39 | # two workflows, identical but for their triggers ()commit/scheduled 40 | workflows: 41 | version: 2 42 | # run the build job for all commits 43 | commit: &jobs 44 | jobs: 45 | - build 46 | # every week, run build too, in case packages got updated 47 | nightly: 48 | <<: *jobs 49 | triggers: 50 | - schedule: 51 | cron: "0 4 * * *" 52 | filters: 53 | branches: 54 | only: 55 | - master 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | Makefile.in 3 | .deps/ 4 | .libs/ 5 | *.o 6 | *.lo 7 | *.la 8 | *~ 9 | *.[1-9] 10 | *.log 11 | *.trs 12 | 13 | /aclocal.m4 14 | /autom4te.cache/ 15 | /build-aux/ 16 | /config.h 17 | /config.h.in 18 | /config.log 19 | /config.status 20 | /configure 21 | /libtool 22 | /stamp-h1 23 | /m4/libtool.m4 24 | /m4/ltoptions.m4 25 | /m4/ltsugar.m4 26 | /m4/ltversion.m4 27 | /m4/lt~obsolete.m4 28 | 29 | /src/vcc_*_if.c 30 | /src/vcc_*_if.h 31 | /src/vmod_*rst 32 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | sudo: required 3 | dist: xenial 4 | 5 | language: c 6 | 7 | addons: 8 | apt: 9 | packages: 10 | - python-docutils 11 | - python-sphinx 12 | 13 | before_install: 14 | - set -e 15 | - wget https://github.com/varnishcache/varnish-cache/archive/master.tar.gz 16 | - tar -zxf master.tar.gz 17 | - pushd varnish-cache-master 18 | - ./autogen.sh 19 | - ./configure --prefix=/usr 20 | - make -sj32 21 | - sudo make install 22 | - popd 23 | 24 | before_script: 25 | - ./autogen.sh 26 | - ./configure --prefix=/usr 27 | - make -j4 28 | 29 | script: 30 | - make check -j4 31 | 32 | compiler: 33 | - clang 34 | - gcc 35 | -------------------------------------------------------------------------------- /CHANGES.rst: -------------------------------------------------------------------------------- 1 | This is a running log of changes to libvmod-example. 2 | 3 | libvmod-example 0.2 (unreleased) 4 | -------------------------------- 5 | 6 | * The most recent release entry is at the top. 7 | 8 | libvmod-example 0.1 (1970-01-01) 9 | -------------------------------- 10 | 11 | * Add list items with changes done. 12 | * Issues fixed could also be list entries. 13 | 14 | If you need to, a paragraph or two of explanation for any complicated changes 15 | is appreciated. 16 | 17 | Make sure to mention any changing breaking user-visible interfaces. (function 18 | names, type of arguments, order of arguments) 19 | 20 | 21 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | See LICENSE for details. 2 | 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I m4 -I ${VARNISHAPI_DATAROOTDIR}/aclocal 2 | 3 | SUBDIRS = src 4 | 5 | dist_doc_DATA = README.rst LICENSE 6 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ============ 2 | vmod-example 3 | ============ 4 | 5 | notice 6 | ------ 7 | 8 | For new developments, we recommend to consider using 9 | https://github.com/Dridi/vcdk 10 | 11 | SYNOPSIS 12 | ======== 13 | 14 | import example; 15 | 16 | DESCRIPTION 17 | =========== 18 | 19 | Example Varnish vmod demonstrating how to write an out-of-tree Varnish vmod. 20 | 21 | Implements the traditional Hello World as a vmod. 22 | 23 | FUNCTIONS 24 | ========= 25 | 26 | hello 27 | ----- 28 | 29 | Prototype 30 | :: 31 | 32 | hello(STRING S) 33 | Return value 34 | STRING 35 | Description 36 | Returns "Hello, " prepended to S 37 | Example 38 | :: 39 | 40 | set resp.http.hello = example.hello("World"); 41 | 42 | INSTALLATION 43 | ============ 44 | 45 | The source tree is based on autotools to configure the building, and 46 | does also have the necessary bits in place to do functional unit tests 47 | using the ``varnishtest`` tool. 48 | 49 | Building requires the Varnish header files and uses pkg-config to find 50 | the necessary paths. 51 | 52 | Usage:: 53 | 54 | ./autogen.sh 55 | ./configure 56 | 57 | If you have installed Varnish to a non-standard directory, call 58 | ``autogen.sh`` and ``configure`` with ``PKG_CONFIG_PATH`` pointing to 59 | the appropriate path. For instance, when varnishd configure was called 60 | with ``--prefix=$PREFIX``, use 61 | 62 | :: 63 | 64 | export PKG_CONFIG_PATH=${PREFIX}/lib/pkgconfig 65 | export ACLOCAL_PATH=${PREFIX}/share/aclocal 66 | 67 | The module will inherit its prefix from Varnish, unless you specify a 68 | different ``--prefix`` when running the ``configure`` script for this 69 | module. 70 | 71 | Make targets: 72 | 73 | * make - builds the vmod. 74 | * make install - installs your vmod. 75 | * make check - runs the unit tests in ``src/tests/*.vtc``. 76 | * make distcheck - run check and prepare a tarball of the vmod. 77 | 78 | If you build a dist tarball, you don't need any of the autotools or 79 | pkg-config. You can build the module simply by running:: 80 | 81 | ./configure 82 | make 83 | 84 | Installation directories 85 | ------------------------ 86 | 87 | By default, the vmod ``configure`` script installs the built vmod in the 88 | directory relevant to the prefix. The vmod installation directory can be 89 | overridden by passing the ``vmoddir`` variable to ``make install``. 90 | 91 | USAGE 92 | ===== 93 | 94 | In your VCL you could then use this vmod along the following lines:: 95 | 96 | import example; 97 | 98 | sub vcl_deliver { 99 | # This sets resp.http.hello to "Hello, World" 100 | set resp.http.hello = example.hello("World"); 101 | } 102 | 103 | COMMON PROBLEMS 104 | =============== 105 | 106 | * configure: error: Need varnish.m4 -- see README.rst 107 | 108 | Check whether ``PKG_CONFIG_PATH`` and ``ACLOCAL_PATH`` were set correctly 109 | before calling ``autogen.sh`` and ``configure`` 110 | 111 | * Incompatibilities with different Varnish Cache versions 112 | 113 | Make sure you build this vmod against its correspondent Varnish Cache version. 114 | For instance, to build against Varnish Cache 4.1, this vmod must be built from 115 | branch 4.1. 116 | 117 | START YOUR OWN VMOD 118 | =================== 119 | 120 | The basic steps to start a new vmod from this example are:: 121 | 122 | name=myvmod 123 | git clone libvmod-example libvmod-$name 124 | cd libvmod-$name 125 | ./rename-vmod-script $name 126 | 127 | and follow the instructions output by rename-vmod-script 128 | 129 | .. image:: https://circleci.com/gh/varnishcache/libvmod-example/tree/master.svg?style=svg 130 | :target: https://app.circleci.com/pipelines/github/varnishcache/libvmod-example?branch=master 131 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | warn() { 4 | echo "WARNING: $@" 1>&2 5 | } 6 | 7 | case `uname -s` in 8 | Darwin) 9 | LIBTOOLIZE=glibtoolize 10 | ;; 11 | FreeBSD) 12 | LIBTOOLIZE=libtoolize 13 | ;; 14 | Linux) 15 | LIBTOOLIZE=libtoolize 16 | ;; 17 | SunOS) 18 | LIBTOOLIZE=libtoolize 19 | ;; 20 | *) 21 | warn "unrecognized platform:" `uname -s` 22 | LIBTOOLIZE=libtoolize 23 | esac 24 | 25 | automake_version=`automake --version | tr ' ' '\n' | egrep '^[0-9]\.[0-9a-z.-]+'` 26 | if [ -z "$automake_version" ] ; then 27 | warn "unable to determine automake version" 28 | else 29 | case $automake_version in 30 | 0.*|1.[0-8]|1.[0-8][.-]*) 31 | warn "automake ($automake_version) detected; 1.9 or newer recommended" 32 | ;; 33 | *) 34 | ;; 35 | esac 36 | fi 37 | 38 | # check for varnishapi.m4 in custom paths 39 | dataroot=$(pkg-config --variable=datarootdir varnishapi 2>/dev/null) 40 | if [ -z "$dataroot" ] ; then 41 | cat >&2 <<'EOF' 42 | Package varnishapi was not found in the pkg-config search path. 43 | Perhaps you should add the directory containing `varnishapi.pc' 44 | to the PKG_CONFIG_PATH environment variable 45 | EOF 46 | exit 1 47 | fi 48 | set -ex 49 | aclocal -I m4 -I ${dataroot}/aclocal 50 | $LIBTOOLIZE --copy --force 51 | autoheader 52 | automake --add-missing --copy --foreign 53 | autoconf 54 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_PREREQ([2.68]) 2 | AC_INIT([libvmod-example], [0.1], [], [vmod-example]) 3 | AC_COPYRIGHT([Public Domain]) 4 | AC_CONFIG_MACRO_DIR([m4]) 5 | AC_CONFIG_AUX_DIR([build-aux]) 6 | AC_CONFIG_SRCDIR(src/vmod_example.vcc) 7 | AC_CONFIG_HEADER([config.h]) 8 | 9 | AM_INIT_AUTOMAKE([1.12 -Wall -Werror foreign parallel-tests]) 10 | AM_SILENT_RULES([yes]) 11 | AM_PROG_AR 12 | 13 | LT_PREREQ([2.2.6]) 14 | LT_INIT([dlopen disable-static]) 15 | 16 | AX_PTHREAD(,[AC_MSG_ERROR([Could not configure pthreads support])]) 17 | 18 | LIBS="$PTHREAD_LIBS $LIBS" 19 | CFLAGS="$CFLAGS $PTHREAD_CFLAGS" 20 | CC="$PTHREAD_CC" 21 | 22 | AC_ARG_WITH([rst2man], 23 | [AS_HELP_STRING( 24 | [--with-rst2man=PATH], 25 | [Location of rst2man (auto)])], 26 | [RST2MAN="$withval"], 27 | [AC_CHECK_PROGS(RST2MAN, [rst2man rst2man.py], [])]) 28 | 29 | 30 | m4_ifndef([VARNISH_PREREQ], AC_MSG_ERROR([Need varnish.m4 -- see README.rst])) 31 | 32 | VARNISH_PREREQ([6.2]) 33 | VARNISH_VMODS([example]) 34 | 35 | VMOD_TESTS="$(cd $srcdir/src && echo tests/*.vtc)" 36 | AC_SUBST(VMOD_TESTS) 37 | 38 | PKG_CHECK_VAR([LIBVARNISHAPI_LIBDIR], [varnishapi], [libdir]) 39 | AC_SUBST([VARNISH_LIBRARY_PATH], 40 | [$LIBVARNISHAPI_LIBDIR:$LIBVARNISHAPI_LIBDIR/varnish]) 41 | 42 | AC_CONFIG_FILES([ 43 | Makefile 44 | src/Makefile 45 | ]) 46 | AC_OUTPUT 47 | -------------------------------------------------------------------------------- /m4/ax_pthread.m4: -------------------------------------------------------------------------------- 1 | # =========================================================================== 2 | # http://www.gnu.org/software/autoconf-archive/ax_pthread.html 3 | # =========================================================================== 4 | # 5 | # SYNOPSIS 6 | # 7 | # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) 8 | # 9 | # DESCRIPTION 10 | # 11 | # This macro figures out how to build C programs using POSIX threads. It 12 | # sets the PTHREAD_LIBS output variable to the threads library and linker 13 | # flags, and the PTHREAD_CFLAGS output variable to any special C compiler 14 | # flags that are needed. (The user can also force certain compiler 15 | # flags/libs to be tested by setting these environment variables.) 16 | # 17 | # Also sets PTHREAD_CC to any special C compiler that is needed for 18 | # multi-threaded programs (defaults to the value of CC otherwise). (This 19 | # is necessary on AIX to use the special cc_r compiler alias.) 20 | # 21 | # NOTE: You are assumed to not only compile your program with these flags, 22 | # but also to link with them as well. For example, you might link with 23 | # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS 24 | # 25 | # If you are only building threaded programs, you may wish to use these 26 | # variables in your default LIBS, CFLAGS, and CC: 27 | # 28 | # LIBS="$PTHREAD_LIBS $LIBS" 29 | # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" 30 | # CC="$PTHREAD_CC" 31 | # 32 | # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant 33 | # has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to 34 | # that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). 35 | # 36 | # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the 37 | # PTHREAD_PRIO_INHERIT symbol is defined when compiling with 38 | # PTHREAD_CFLAGS. 39 | # 40 | # ACTION-IF-FOUND is a list of shell commands to run if a threads library 41 | # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it 42 | # is not found. If ACTION-IF-FOUND is not specified, the default action 43 | # will define HAVE_PTHREAD. 44 | # 45 | # Please let the authors know if this macro fails on any platform, or if 46 | # you have any other suggestions or comments. This macro was based on work 47 | # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help 48 | # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by 49 | # Alejandro Forero Cuervo to the autoconf macro repository. We are also 50 | # grateful for the helpful feedback of numerous users. 51 | # 52 | # Updated for Autoconf 2.68 by Daniel Richard G. 53 | # 54 | # LICENSE 55 | # 56 | # Copyright (c) 2008 Steven G. Johnson 57 | # Copyright (c) 2011 Daniel Richard G. 58 | # 59 | # This program is free software: you can redistribute it and/or modify it 60 | # under the terms of the GNU General Public License as published by the 61 | # Free Software Foundation, either version 3 of the License, or (at your 62 | # option) any later version. 63 | # 64 | # This program is distributed in the hope that it will be useful, but 65 | # WITHOUT ANY WARRANTY; without even the implied warranty of 66 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 67 | # Public License for more details. 68 | # 69 | # You should have received a copy of the GNU General Public License along 70 | # with this program. If not, see . 71 | # 72 | # As a special exception, the respective Autoconf Macro's copyright owner 73 | # gives unlimited permission to copy, distribute and modify the configure 74 | # scripts that are the output of Autoconf when processing the Macro. You 75 | # need not follow the terms of the GNU General Public License when using 76 | # or distributing such scripts, even though portions of the text of the 77 | # Macro appear in them. The GNU General Public License (GPL) does govern 78 | # all other use of the material that constitutes the Autoconf Macro. 79 | # 80 | # This special exception to the GPL applies to versions of the Autoconf 81 | # Macro released by the Autoconf Archive. When you make and distribute a 82 | # modified version of the Autoconf Macro, you may extend this special 83 | # exception to the GPL to apply to your modified version as well. 84 | 85 | #serial 23 86 | 87 | AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) 88 | AC_DEFUN([AX_PTHREAD], [ 89 | AC_REQUIRE([AC_CANONICAL_HOST]) 90 | AC_REQUIRE([AC_PROG_CC]) 91 | AC_REQUIRE([AC_PROG_SED]) 92 | AC_LANG_PUSH([C]) 93 | ax_pthread_ok=no 94 | 95 | # We used to check for pthread.h first, but this fails if pthread.h 96 | # requires special compiler flags (e.g. on Tru64 or Sequent). 97 | # It gets checked for in the link test anyway. 98 | 99 | # First of all, check if the user has set any of the PTHREAD_LIBS, 100 | # etcetera environment variables, and if threads linking works using 101 | # them: 102 | if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then 103 | ax_pthread_save_CC="$CC" 104 | ax_pthread_save_CFLAGS="$CFLAGS" 105 | ax_pthread_save_LIBS="$LIBS" 106 | AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) 107 | CFLAGS="$CFLAGS $PTHREAD_CFLAGS" 108 | LIBS="$PTHREAD_LIBS $LIBS" 109 | AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) 110 | AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) 111 | AC_MSG_RESULT([$ax_pthread_ok]) 112 | if test "x$ax_pthread_ok" = "xno"; then 113 | PTHREAD_LIBS="" 114 | PTHREAD_CFLAGS="" 115 | fi 116 | CC="$ax_pthread_save_CC" 117 | CFLAGS="$ax_pthread_save_CFLAGS" 118 | LIBS="$ax_pthread_save_LIBS" 119 | fi 120 | 121 | # We must check for the threads library under a number of different 122 | # names; the ordering is very important because some systems 123 | # (e.g. DEC) have both -lpthread and -lpthreads, where one of the 124 | # libraries is broken (non-POSIX). 125 | 126 | # Create a list of thread flags to try. Items starting with a "-" are 127 | # C compiler flags, and other items are library names, except for "none" 128 | # which indicates that we try without any flags at all, and "pthread-config" 129 | # which is a program returning the flags for the Pth emulation library. 130 | 131 | ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" 132 | 133 | # The ordering *is* (sometimes) important. Some notes on the 134 | # individual items follow: 135 | 136 | # pthreads: AIX (must check this before -lpthread) 137 | # none: in case threads are in libc; should be tried before -Kthread and 138 | # other compiler flags to prevent continual compiler warnings 139 | # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) 140 | # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 141 | # (Note: HP C rejects this with "bad form for `-t' option") 142 | # -pthreads: Solaris/gcc (Note: HP C also rejects) 143 | # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it 144 | # doesn't hurt to check since this sometimes defines pthreads and 145 | # -D_REENTRANT too), HP C (must be checked before -lpthread, which 146 | # is present but should not be used directly; and before -mthreads, 147 | # because the compiler interprets this as "-mt" + "-hreads") 148 | # -mthreads: Mingw32/gcc, Lynx/gcc 149 | # pthread: Linux, etcetera 150 | # --thread-safe: KAI C++ 151 | # pthread-config: use pthread-config program (for GNU Pth library) 152 | 153 | case $host_os in 154 | 155 | freebsd*) 156 | 157 | # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) 158 | # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) 159 | 160 | ax_pthread_flags="-kthread lthread $ax_pthread_flags" 161 | ;; 162 | 163 | hpux*) 164 | 165 | # From the cc(1) man page: "[-mt] Sets various -D flags to enable 166 | # multi-threading and also sets -lpthread." 167 | 168 | ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" 169 | ;; 170 | 171 | openedition*) 172 | 173 | # IBM z/OS requires a feature-test macro to be defined in order to 174 | # enable POSIX threads at all, so give the user a hint if this is 175 | # not set. (We don't define these ourselves, as they can affect 176 | # other portions of the system API in unpredictable ways.) 177 | 178 | AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], 179 | [ 180 | # if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) 181 | AX_PTHREAD_ZOS_MISSING 182 | # endif 183 | ], 184 | [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) 185 | ;; 186 | 187 | solaris*) 188 | 189 | # On Solaris (at least, for some versions), libc contains stubbed 190 | # (non-functional) versions of the pthreads routines, so link-based 191 | # tests will erroneously succeed. (N.B.: The stubs are missing 192 | # pthread_cleanup_push, or rather a function called by this macro, 193 | # so we could check for that, but who knows whether they'll stub 194 | # that too in a future libc.) So we'll check first for the 195 | # standard Solaris way of linking pthreads (-mt -lpthread). 196 | 197 | ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" 198 | ;; 199 | esac 200 | 201 | # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) 202 | 203 | AS_IF([test "x$GCC" = "xyes"], 204 | [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) 205 | 206 | # The presence of a feature test macro requesting re-entrant function 207 | # definitions is, on some systems, a strong hint that pthreads support is 208 | # correctly enabled 209 | 210 | case $host_os in 211 | darwin* | hpux* | linux* | osf* | solaris*) 212 | ax_pthread_check_macro="_REENTRANT" 213 | ;; 214 | 215 | aix*) 216 | ax_pthread_check_macro="_THREAD_SAFE" 217 | ;; 218 | 219 | *) 220 | ax_pthread_check_macro="--" 221 | ;; 222 | esac 223 | AS_IF([test "x$ax_pthread_check_macro" = "x--"], 224 | [ax_pthread_check_cond=0], 225 | [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) 226 | 227 | # Are we compiling with Clang? 228 | 229 | AC_CACHE_CHECK([whether $CC is Clang], 230 | [ax_cv_PTHREAD_CLANG], 231 | [ax_cv_PTHREAD_CLANG=no 232 | # Note that Autoconf sets GCC=yes for Clang as well as GCC 233 | if test "x$GCC" = "xyes"; then 234 | AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], 235 | [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ 236 | # if defined(__clang__) && defined(__llvm__) 237 | AX_PTHREAD_CC_IS_CLANG 238 | # endif 239 | ], 240 | [ax_cv_PTHREAD_CLANG=yes]) 241 | fi 242 | ]) 243 | ax_pthread_clang="$ax_cv_PTHREAD_CLANG" 244 | 245 | ax_pthread_clang_warning=no 246 | 247 | # Clang needs special handling, because older versions handle the -pthread 248 | # option in a rather... idiosyncratic way 249 | 250 | if test "x$ax_pthread_clang" = "xyes"; then 251 | 252 | # Clang takes -pthread; it has never supported any other flag 253 | 254 | # (Note 1: This will need to be revisited if a system that Clang 255 | # supports has POSIX threads in a separate library. This tends not 256 | # to be the way of modern systems, but it's conceivable.) 257 | 258 | # (Note 2: On some systems, notably Darwin, -pthread is not needed 259 | # to get POSIX threads support; the API is always present and 260 | # active. We could reasonably leave PTHREAD_CFLAGS empty. But 261 | # -pthread does define _REENTRANT, and while the Darwin headers 262 | # ignore this macro, third-party headers might not.) 263 | 264 | PTHREAD_CFLAGS="-pthread" 265 | PTHREAD_LIBS= 266 | 267 | ax_pthread_ok=yes 268 | 269 | # However, older versions of Clang make a point of warning the user 270 | # that, in an invocation where only linking and no compilation is 271 | # taking place, the -pthread option has no effect ("argument unused 272 | # during compilation"). They expect -pthread to be passed in only 273 | # when source code is being compiled. 274 | # 275 | # Problem is, this is at odds with the way Automake and most other 276 | # C build frameworks function, which is that the same flags used in 277 | # compilation (CFLAGS) are also used in linking. Many systems 278 | # supported by AX_PTHREAD require exactly this for POSIX threads 279 | # support, and in fact it is often not straightforward to specify a 280 | # flag that is used only in the compilation phase and not in 281 | # linking. Such a scenario is extremely rare in practice. 282 | # 283 | # Even though use of the -pthread flag in linking would only print 284 | # a warning, this can be a nuisance for well-run software projects 285 | # that build with -Werror. So if the active version of Clang has 286 | # this misfeature, we search for an option to squash it. 287 | 288 | AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], 289 | [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], 290 | [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown 291 | # Create an alternate version of $ac_link that compiles and 292 | # links in two steps (.c -> .o, .o -> exe) instead of one 293 | # (.c -> exe), because the warning occurs only in the second 294 | # step 295 | ax_pthread_save_ac_link="$ac_link" 296 | ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' 297 | ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` 298 | ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" 299 | ax_pthread_save_CFLAGS="$CFLAGS" 300 | for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do 301 | AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) 302 | CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" 303 | ac_link="$ax_pthread_save_ac_link" 304 | AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], 305 | [ac_link="$ax_pthread_2step_ac_link" 306 | AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], 307 | [break]) 308 | ]) 309 | done 310 | ac_link="$ax_pthread_save_ac_link" 311 | CFLAGS="$ax_pthread_save_CFLAGS" 312 | AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) 313 | ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" 314 | ]) 315 | 316 | case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in 317 | no | unknown) ;; 318 | *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; 319 | esac 320 | 321 | fi # $ax_pthread_clang = yes 322 | 323 | if test "x$ax_pthread_ok" = "xno"; then 324 | for ax_pthread_try_flag in $ax_pthread_flags; do 325 | 326 | case $ax_pthread_try_flag in 327 | none) 328 | AC_MSG_CHECKING([whether pthreads work without any flags]) 329 | ;; 330 | 331 | -mt,pthread) 332 | AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) 333 | PTHREAD_CFLAGS="-mt" 334 | PTHREAD_LIBS="-lpthread" 335 | ;; 336 | 337 | -*) 338 | AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) 339 | PTHREAD_CFLAGS="$ax_pthread_try_flag" 340 | ;; 341 | 342 | pthread-config) 343 | AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) 344 | AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) 345 | PTHREAD_CFLAGS="`pthread-config --cflags`" 346 | PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" 347 | ;; 348 | 349 | *) 350 | AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) 351 | PTHREAD_LIBS="-l$ax_pthread_try_flag" 352 | ;; 353 | esac 354 | 355 | ax_pthread_save_CFLAGS="$CFLAGS" 356 | ax_pthread_save_LIBS="$LIBS" 357 | CFLAGS="$CFLAGS $PTHREAD_CFLAGS" 358 | LIBS="$PTHREAD_LIBS $LIBS" 359 | 360 | # Check for various functions. We must include pthread.h, 361 | # since some functions may be macros. (On the Sequent, we 362 | # need a special flag -Kthread to make this header compile.) 363 | # We check for pthread_join because it is in -lpthread on IRIX 364 | # while pthread_create is in libc. We check for pthread_attr_init 365 | # due to DEC craziness with -lpthreads. We check for 366 | # pthread_cleanup_push because it is one of the few pthread 367 | # functions on Solaris that doesn't have a non-functional libc stub. 368 | # We try pthread_create on general principles. 369 | 370 | AC_LINK_IFELSE([AC_LANG_PROGRAM([#include 371 | # if $ax_pthread_check_cond 372 | # error "$ax_pthread_check_macro must be defined" 373 | # endif 374 | static void routine(void *a) { a = 0; } 375 | static void *start_routine(void *a) { return a; }], 376 | [pthread_t th; pthread_attr_t attr; 377 | pthread_create(&th, 0, start_routine, 0); 378 | pthread_join(th, 0); 379 | pthread_attr_init(&attr); 380 | pthread_cleanup_push(routine, 0); 381 | pthread_cleanup_pop(0) /* ; */])], 382 | [ax_pthread_ok=yes], 383 | []) 384 | 385 | CFLAGS="$ax_pthread_save_CFLAGS" 386 | LIBS="$ax_pthread_save_LIBS" 387 | 388 | AC_MSG_RESULT([$ax_pthread_ok]) 389 | AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) 390 | 391 | PTHREAD_LIBS="" 392 | PTHREAD_CFLAGS="" 393 | done 394 | fi 395 | 396 | # Various other checks: 397 | if test "x$ax_pthread_ok" = "xyes"; then 398 | ax_pthread_save_CFLAGS="$CFLAGS" 399 | ax_pthread_save_LIBS="$LIBS" 400 | CFLAGS="$CFLAGS $PTHREAD_CFLAGS" 401 | LIBS="$PTHREAD_LIBS $LIBS" 402 | 403 | # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. 404 | AC_CACHE_CHECK([for joinable pthread attribute], 405 | [ax_cv_PTHREAD_JOINABLE_ATTR], 406 | [ax_cv_PTHREAD_JOINABLE_ATTR=unknown 407 | for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do 408 | AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], 409 | [int attr = $ax_pthread_attr; return attr /* ; */])], 410 | [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], 411 | []) 412 | done 413 | ]) 414 | AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ 415 | test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ 416 | test "x$ax_pthread_joinable_attr_defined" != "xyes"], 417 | [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], 418 | [$ax_cv_PTHREAD_JOINABLE_ATTR], 419 | [Define to necessary symbol if this constant 420 | uses a non-standard name on your system.]) 421 | ax_pthread_joinable_attr_defined=yes 422 | ]) 423 | 424 | AC_CACHE_CHECK([whether more special flags are required for pthreads], 425 | [ax_cv_PTHREAD_SPECIAL_FLAGS], 426 | [ax_cv_PTHREAD_SPECIAL_FLAGS=no 427 | case $host_os in 428 | solaris*) 429 | ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" 430 | ;; 431 | esac 432 | ]) 433 | AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ 434 | test "x$ax_pthread_special_flags_added" != "xyes"], 435 | [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" 436 | ax_pthread_special_flags_added=yes]) 437 | 438 | AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], 439 | [ax_cv_PTHREAD_PRIO_INHERIT], 440 | [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], 441 | [[int i = PTHREAD_PRIO_INHERIT;]])], 442 | [ax_cv_PTHREAD_PRIO_INHERIT=yes], 443 | [ax_cv_PTHREAD_PRIO_INHERIT=no]) 444 | ]) 445 | AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ 446 | test "x$ax_pthread_prio_inherit_defined" != "xyes"], 447 | [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) 448 | ax_pthread_prio_inherit_defined=yes 449 | ]) 450 | 451 | CFLAGS="$ax_pthread_save_CFLAGS" 452 | LIBS="$ax_pthread_save_LIBS" 453 | 454 | # More AIX lossage: compile with *_r variant 455 | if test "x$GCC" != "xyes"; then 456 | case $host_os in 457 | aix*) 458 | AS_CASE(["x/$CC"], 459 | [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], 460 | [#handle absolute path differently from PATH based program lookup 461 | AS_CASE(["x$CC"], 462 | [x/*], 463 | [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], 464 | [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) 465 | ;; 466 | esac 467 | fi 468 | fi 469 | 470 | test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" 471 | 472 | AC_SUBST([PTHREAD_LIBS]) 473 | AC_SUBST([PTHREAD_CFLAGS]) 474 | AC_SUBST([PTHREAD_CC]) 475 | 476 | # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: 477 | if test "x$ax_pthread_ok" = "xyes"; then 478 | ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) 479 | : 480 | else 481 | ax_pthread_ok=no 482 | $2 483 | fi 484 | AC_LANG_POP 485 | ])dnl AX_PTHREAD 486 | -------------------------------------------------------------------------------- /rename-vmod-script: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Script to rename libvmod-example into libvmod-foo. 4 | # (where "foo" is your new vmod name, of course.) 5 | # 6 | # Leaves the changes uncommitted in the working tree, so you get to fix any 7 | # unintended changes. 8 | # 9 | # Author: Lasse Karstensen , September 2014. 10 | # 11 | set -o errexit 12 | 13 | NAME=$1 14 | if [ -z "$NAME" ]; then 15 | echo "Usage: $0 " 16 | echo "Rename libvmod-example source tree." 17 | echo "If the name is an acronym, you can use capital letters." 18 | echo 19 | exit -1 20 | fi 21 | 22 | SYM_NAME=${NAME,,*} 23 | CAP_NAME=${NAME^?} 24 | UPP_NAME=${NAME^^?} 25 | 26 | if ! git diff-index --quiet HEAD --; then 27 | echo "ERROR: Need a clean working tree. Run \"git stash\" first." 28 | exit -2 29 | fi 30 | 31 | git mv src/vmod_example.c src/vmod_${SYM_NAME}.c 32 | git mv src/vmod_example.vcc src/vmod_${SYM_NAME}.vcc 33 | 34 | git grep -z -l example | xargs -0 sed -i -s -e "s/example/${SYM_NAME}/g" 35 | git grep -z -l Example | xargs -0 sed -i -s -e "s/Example/${CAP_NAME}/g" 36 | git grep -z -l EXAMPLE | xargs -0 sed -i -s -e "s/EXAMPLE/${UPP_NAME}/g" 37 | sed -i '/circleci.com\/gh\/varnishcache\/libvmod-example/d' README.rst 38 | 39 | git rm -f rename-vmod-script 40 | 41 | # restore foreign files 42 | git checkout -- m4/ 43 | 44 | cat < 4 | #include 5 | 6 | #include "cache/cache.h" 7 | 8 | #include "vtim.h" 9 | #include "vcc_example_if.h" 10 | 11 | const size_t infosz = 64; 12 | char *info; 13 | 14 | /* 15 | * handle vmod internal state, vmod init/fini and/or varnish callback 16 | * (un)registration here. 17 | * 18 | * malloc'ing the info buffer is only indended as a demonstration, for any 19 | * real-world vmod, a fixed-sized buffer should be a global variable 20 | */ 21 | 22 | int v_matchproto_(vmod_event_f) 23 | vmod_event_function(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e) 24 | { 25 | char ts[VTIM_FORMAT_SIZE]; 26 | const char *event = NULL; 27 | 28 | (void) ctx; 29 | (void) priv; 30 | 31 | switch (e) { 32 | case VCL_EVENT_LOAD: 33 | info = malloc(infosz); 34 | if (! info) 35 | return (-1); 36 | event = "loaded"; 37 | break; 38 | case VCL_EVENT_WARM: 39 | event = "warmed"; 40 | break; 41 | case VCL_EVENT_COLD: 42 | event = "cooled"; 43 | break; 44 | case VCL_EVENT_DISCARD: 45 | free(info); 46 | return (0); 47 | break; 48 | default: 49 | return (0); 50 | } 51 | AN(event); 52 | VTIM_format(VTIM_real(), ts); 53 | snprintf(info, infosz, "vmod_example %s at %s", event, ts); 54 | 55 | return (0); 56 | } 57 | 58 | VCL_STRING 59 | vmod_info(VRT_CTX) 60 | { 61 | (void) ctx; 62 | 63 | return (info); 64 | } 65 | 66 | VCL_STRING 67 | vmod_hello(VRT_CTX, VCL_STRING name) 68 | { 69 | char *p; 70 | unsigned u, v; 71 | 72 | u = WS_ReserveAll(ctx->ws); /* Reserve some work space */ 73 | p = ctx->ws->f; /* Front of workspace area */ 74 | v = snprintf(p, u, "Hello, %s", name); 75 | v++; 76 | if (v > u) { 77 | /* No space, reset and leave */ 78 | WS_Release(ctx->ws, 0); 79 | return (NULL); 80 | } 81 | /* Update work space with what we've used */ 82 | WS_Release(ctx->ws, v); 83 | return (p); 84 | } 85 | -------------------------------------------------------------------------------- /src/vmod_example.vcc: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright YOU (c) 1900. 3 | # 4 | # (vmodtool requires this format.) 5 | # 6 | 7 | $Module example 3 Example VMOD 8 | 9 | DESCRIPTION 10 | =========== 11 | 12 | This is the embedded documentation for the example VMOD. It should 13 | mention what the vmod is intended to do. 14 | 15 | It can span multiple lines and is written in RST format. 16 | You can even have links and lists in here: 17 | 18 | * https://github.com/varnish/libvmod-example/ 19 | * https://www.varnish-cache.org/ 20 | 21 | $Event event_function 22 | $Function STRING info() 23 | 24 | Returns a string set by the last VCL event, demonstrating the use of 25 | event functions. 26 | 27 | $Function STRING hello(STRING) 28 | 29 | The different functions provided by the VMOD should also have their own 30 | embedded documentation. This section is for the hello() function. 31 | --------------------------------------------------------------------------------