diff options
| -rw-r--r-- | lib/replace/libreplace.m4 | 7 | ||||
| -rw-r--r-- | lib/replace/test/incoherent_mmap.c | 83 | ||||
| -rw-r--r-- | lib/replace/wscript | 7 | 
3 files changed, 97 insertions, 0 deletions
diff --git a/lib/replace/libreplace.m4 b/lib/replace/libreplace.m4 index ca0c6846ab..e14fadabf1 100644 --- a/lib/replace/libreplace.m4 +++ b/lib/replace/libreplace.m4 @@ -107,6 +107,13 @@ if test x"$libreplace_cv_HAVE_MREMAP" = x"yes"; then      AC_DEFINE(HAVE_MREMAP,1,[Whether mremap works])  fi +AC_CACHE_CHECK([for incoherent mmap],libreplace_cv_HAVE_INCOHERENT_MMAP,[ +AC_TRY_RUN([#include "$libreplacedir/test/incoherent_mmap.c"], +           libreplace_cv_HAVE_INCOHERENT_MMAP=yes,libreplace_cv_HAVE_INCOHERENT_MMAP=no,libreplace_cv_HAVE_INCOHERENT_MMAP=cross)]) +if test x"$libreplace_cv_HAVE_INCOHERENT_MMAP" = x"yes"; then +    AC_DEFINE(HAVE_INCOHERENT_MMAP,1,[Whether mmap is incoherent against write]) +fi +  AC_CHECK_HEADERS(sys/syslog.h syslog.h)  AC_CHECK_HEADERS(sys/time.h time.h) diff --git a/lib/replace/test/incoherent_mmap.c b/lib/replace/test/incoherent_mmap.c new file mode 100644 index 0000000000..ee288fd806 --- /dev/null +++ b/lib/replace/test/incoherent_mmap.c @@ -0,0 +1,83 @@ +/* In OpenBSD, if you write to a file, another process doesn't see it + * in its mmap.  Returns with exit status 0 if that is the case, 1 if + * it's coherent, and other if there's a problem. */ +#include <err.h> +#include <sys/mman.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#define DATA "coherent.mmap" + +int main(int argc, char *argv[]) +{ +	int tochild[2], toparent[2]; +	int fd; +	volatile unsigned char *map; +	unsigned char *page; +        const char *fname = argv[1]; +	char c = 0; + +	if (pipe(tochild) != 0 || pipe(toparent) != 0) +		err(2, "Creating pipe"); + +	if (!fname) +		fname = DATA; + +	fd = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0600); +	if (fd < 0) +		err(2, "opening %s", fname); +	unlink(fname); + +	switch (fork()) { +	case -1: +		err(2, "Fork"); +	case 0: +		close(tochild[1]); +		close(toparent[0]); + +		/* Wait for parent to create file. */ +		if (read(tochild[0], &c, 1) != 1) +			err(2, "reading from parent"); + +		/* Alter first byte. */ +		pwrite(fd, &c, 1, 0); + +		if (write(toparent[1], &c, 1) != 1) +			err(2, "writing to parent"); +		exit(0); + +	default: +		close(tochild[0]); +		close(toparent[1]); + +		/* Create a file and mmap it. */ +		page = malloc(getpagesize()); +		memset(page, 0x42, getpagesize()); +		if (write(fd, page, getpagesize()) != getpagesize()) +			err(2, "writing first page"); +		map = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE, +			   MAP_SHARED, fd, 0); +		if (map == MAP_FAILED) +			err(2, "mapping file"); + +		if (*map != 0x42) +			errx(2, "first byte isn't 0x42!"); + +		/* Tell child to alter file. */ +		if (write(tochild[1], &c, 1) != 1) +			err(2, "writing to child"); + +		if (read(toparent[0], &c, 1) != 1) +			err(2, "reading from child"); + +		if (*map) +			errx(0, "mmap incoherent: first byte isn't 0."); + +		exit(1); +	} +} diff --git a/lib/replace/wscript b/lib/replace/wscript index 36c2f0f3e1..63944c3800 100644 --- a/lib/replace/wscript +++ b/lib/replace/wscript @@ -299,6 +299,13 @@ def configure(conf):                      addmain=False,                      msg="Checking for C99 vsnprintf") +    # OpenBSD (and I've heard HPUX) doesn't sync between mmap and write. +    # FIXME: Anything other than a 0 or 1 exit code should abort configure! +    conf.CHECK_CODE('#include "test/incoherent_mmap.c"', +                    addmain=False, add_headers=False, execute=True, +                    define='HAVE_INCOHERENT_MMAP', +                    msg="Checking for HAVE_INCOHERENT_MMAP") +      conf.SAMBA_BUILD_ENV()      conf.CHECK_CODE('''  | 
