Rebased ref, commits from common ancestor:
commit 4e0c2aaae495ebd480f6d358223a13c927048242
Author:     Jan-Marek Glogowski <glo...@fbihome.de>
AuthorDate: Fri May 14 15:26:39 2021 +0200
Commit:     Jan-Marek Glogowski <glo...@fbihome.de>
CommitDate: Fri May 14 15:47:08 2021 +0200

    gbuild: serialize dynamic link for static builds
    
    This uses a the lockfile tool / liblockfile 1.17. Since it polls
    the file, I adjusted the poll timeout to 5s max, because I found
    the 60s wait much too long. Maybe even 1s would be ok...
    
    Since it's just a build tool, I simply copied the source, instead
    of creating an external project. Since it's just used for cross
    builds, even an external project wouldn't be a problem.
    
    Change-Id: I16bc4579a273dcf1aac811ae4723ca325a0b9eba

diff --git a/.gitignore b/.gitignore
index 4562c89b7e05..7422744a695e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -180,3 +180,6 @@ LibreOffice.VC.VC.opendb
 /a.out
 /a.out.js
 /a.out.wasm
+
+# lockfile config header
+/solenv/lockfile/autoconf.h
diff --git a/Makefile.gbuild b/Makefile.gbuild
index f369c9e9fb4d..88ece09917c1 100644
--- a/Makefile.gbuild
+++ b/Makefile.gbuild
@@ -22,6 +22,7 @@ $(eval $(call 
gb_Module_make_global_targets,$(SRCDIR)/RepositoryModule_$(gb_Side
 
 ifneq (,$(DISABLE_DYNLOADING))
 include $(SRCDIR)/solenv/gbuild/static.mk
+$(if $(gb_LinkTarget__Lock),$(shell rm -f $(gb_LinkTarget__Lock)))
 endif
 
 upload-symbols:
diff --git a/Repository.mk b/Repository.mk
index b49195566d6b..f4f1dd0964ea 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -46,6 +46,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \
        $(if $(filter iOS,$(OS)),LibreOffice) \
        lngconvex \
        localize \
+       lockfile \
        makedepend \
        mbsdiff \
        osl_process_child \
diff --git a/configure.ac b/configure.ac
index a7c82b3bca34..32038cc5c04d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5264,6 +5264,7 @@ if test "$cross_compiling" = "yes"; then
         config_host/*.in \
         sysui/desktop/macosx/Info.plist.in \
         .vscode/vs-code-template.code-workspace.in \
+        solenv/lockfile/autoconf.h.in \
         ) \
     | (cd CONF-FOR-BUILD && tar xf -)
     cp configure CONF-FOR-BUILD
@@ -5496,6 +5497,12 @@ AC_SUBST(WORKDIR_FOR_BUILD)
 AC_SUBST(CC_FOR_BUILD)
 AC_SUBST(CXX_FOR_BUILD)
 
+dnl ===================================================================
+dnl Check for lockfile deps
+dnl ===================================================================
+AC_CHECK_HEADERS([getopt.h paths.h sys/param.h])
+AC_CHECK_FUNCS([utime utimes])
+
 dnl ===================================================================
 dnl Check for syslog header
 dnl ===================================================================
@@ -14235,6 +14242,7 @@ AC_CONFIG_HEADERS([config_host/config_oauth2.h])
 AC_CONFIG_HEADERS([config_host/config_poppler.h])
 AC_CONFIG_HEADERS([config_host/config_python.h])
 AC_CONFIG_HEADERS([config_host/config_writerperfect.h])
+AC_CONFIG_HEADERS([solenv/lockfile/autoconf.h])
 AC_OUTPUT
 
 if test "$CROSS_COMPILING" = TRUE; then
diff --git a/solenv/Executable_lockfile.mk b/solenv/Executable_lockfile.mk
new file mode 100644
index 000000000000..3e82a52d273b
--- /dev/null
+++ b/solenv/Executable_lockfile.mk
@@ -0,0 +1,22 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Executable_Executable,lockfile))
+
+$(eval $(call gb_Executable_set_include,lockfile, \
+    -I$(SRCDIR)/solenv/lockfile \
+))
+
+$(eval $(call gb_Executable_add_cobjects,lockfile, \
+    solenv/lockfile/dotlockfile \
+    solenv/lockfile/lockfile \
+    , $(gb_COMPILEROPTFLAGS) \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/solenv/Module_solenv.mk b/solenv/Module_solenv.mk
index 70eb5f9fb7c3..8c266874876d 100644
--- a/solenv/Module_solenv.mk
+++ b/solenv/Module_solenv.mk
@@ -12,6 +12,7 @@ $(eval $(call gb_Module_Module,solenv))
 $(eval $(call gb_Module_add_targets_for_build,solenv,\
        Executable_concat-deps \
        Executable_gbuildtojson \
+       Executable_lockfile \
 ))
 
 ifeq ($(COM),MSC)
diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist
index ae149d09096b..4bd8a77ee51b 100644
--- a/solenv/clang-format/excludelist
+++ b/solenv/clang-format/excludelist
@@ -10923,6 +10923,11 @@ smoketest/smoketest.cxx
 solenv/bin/concat-deps.c
 solenv/gbuildtojson/gbuildtojson.cxx
 solenv/gcc-wrappers/wrapper.cxx
+solenv/lockfile/autoconf.h.in
+solenv/lockfile/dotlockfile.c
+solenv/lockfile/lockfile.c
+solenv/lockfile/lockfile.h
+solenv/lockfile/maillock.h
 soltools/cpp/_eval.c
 soltools/cpp/_getopt.c
 soltools/cpp/_include.c
diff --git a/solenv/gbuild/extensions/pre_BuildTools.mk 
b/solenv/gbuild/extensions/pre_BuildTools.mk
index 9327cbe41714..717e41239a36 100644
--- a/solenv/gbuild/extensions/pre_BuildTools.mk
+++ b/solenv/gbuild/extensions/pre_BuildTools.mk
@@ -24,6 +24,7 @@ gb_BUILD_TOOLS = \
                helpex \
                idxdict \
                javamaker \
+               lockfile \
                makedepend \
                propex \
                saxparser \
diff --git a/solenv/gbuild/partial_build.mk b/solenv/gbuild/partial_build.mk
index b4fb84c8ebfd..8e9c9d4ff1c7 100644
--- a/solenv/gbuild/partial_build.mk
+++ b/solenv/gbuild/partial_build.mk
@@ -39,6 +39,7 @@ $(eval $(call gb_Module_make_global_targets,$(wildcard 
$(module_directory)Module
 
 ifneq (,$(DISABLE_DYNLOADING))
 include $(SRCDIR)/solenv/gbuild/static.mk
+$(if $(gb_LinkTarget__Lock),$(shell rm -f $(gb_LinkTarget__Lock)))
 endif
 
 # vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/unxgcc.mk b/solenv/gbuild/platform/unxgcc.mk
index 43579bd0c6aa..1de65ac81264 100644
--- a/solenv/gbuild/platform/unxgcc.mk
+++ b/solenv/gbuild/platform/unxgcc.mk
@@ -109,6 +109,10 @@ gb_LinkTarget__RPATHS := \
 gb_LinkTarget_CFLAGS := $(gb_CFLAGS)
 gb_LinkTarget_CXXFLAGS := $(gb_CXXFLAGS)
 
+gb_LinkTarget__cmd_lockfile = $(call gb_Executable_get_command,lockfile)
+gb_LinkTarget__Lock := $(WORKDIR)/LinkTarget/link.lock
+gb_LinkTarget__WantLock = $(if $(and $(filter 
TRUE,$(DISABLE_DYNLOADING)),$(CROSS_COMPILING),$(filter CppunitTest 
Executable,$(TARGETTYPE))),$(true))
+
 # note that `cat $(extraobjectlist)` is needed to build with older gcc 
versions, e.g. 4.1.2 on SLED10
 # we want to use @$(extraobjectlist) in the long run
 # link with C compiler if there are no C++ files (pyuno_wrapper depends on 
this)
@@ -117,6 +121,7 @@ gb_LinkTarget_CXXFLAGS := $(gb_CXXFLAGS)
 # libclang_rt.ubsan_cxx-x86_64.a, and oosplash links against sal but itself 
only
 # contains .c sources:
 define gb_LinkTarget__command_dynamiclink
+$(if $(gb_LinkTarget__WantLock),$(gb_LinkTarget__cmd_lockfile) -r -1 
$(gb_LinkTarget__Lock))
 $(call gb_Helper_abbreviate_dirs,\
        $(if $(CXXOBJECTS)$(GENCXXOBJECTS)$(EXTRAOBJECTLISTS)$(filter-out 
XTRUE,X$(ENABLE_RUNTIME_OPTIMIZATIONS)),$(or $(T_CXX),$(gb_CXX)) 
$(gb_CXX_LINKFLAGS),$(or $(T_CC),$(gb_CC))) \
                $(if $(filter Library 
CppunitTest,$(TARGETTYPE)),$(gb_Library_TARGETTYPEFLAGS)) \
@@ -148,17 +153,19 @@ $(call gb_Helper_abbreviate_dirs,\
                    $(patsubst lib%.a,-l%,$(patsubst lib%.so,-l%,$(patsubst 
%.$(gb_Library_UDK_MAJORVER),%,$(foreach lib,$(LINKED_LIBS),$(call 
gb_Library_get_filename,$(lib)))))) \
                 ) \
                -o $(1) \
-       $(if $(SOVERSIONSCRIPT),&& ln -sf ../../program/$(notdir $(1)) 
$(ILIBTARGET)))
-       $(if $(filter Library,$(TARGETTYPE)), $(call gb_Helper_abbreviate_dirs,\
-               $(READELF) -d $(1) | grep SONAME > 
$(WORKDIR)/LinkTarget/$(2).exports.tmp; \
-               $(NM) $(gb_LTOPLUGINFLAGS) --dynamic --extern-only 
--defined-only --format=posix $(1) \
-                       | cut -d' ' -f1-2 \
-                       >> $(WORKDIR)/LinkTarget/$(2).exports.tmp && \
-               $(call 
gb_Helper_replace_if_different_and_touch,$(WORKDIR)/LinkTarget/$(2).exports.tmp,
 \
-                       $(WORKDIR)/LinkTarget/$(2).exports,$(1))))
-       $(if $(and $(filter CppunitTest Executable,$(TARGETTYPE)),$(filter 
EMSCRIPTEN,$(OS)),$(filter TRUE,$(ENABLE_QT5))), \
-               cp $(QT5_PLATFORMS_SRCDIR)/qtlogo.svg 
$(QT5_PLATFORMS_SRCDIR)/qtloader.js $(dir $(1)) ; \
-               sed -e 's/@APPNAME@/$(subst $(gb_Executable_EXT),,$(notdir 
$(1)))/' $(QT5_PLATFORMS_SRCDIR)/wasm_shell.html > $(dir $(1))qt_$(notdir $(1)))
+       $(if $(SOVERSIONSCRIPT),&& ln -sf ../../program/$(notdir $(1)) 
$(ILIBTARGET)) \
+       $(if $(gb_LinkTarget__WantLock),; RC=$$? ; rm -f 
$(gb_LinkTarget__Lock); if test $$RC -ne 0; then exit $$RC; fi))
+$(if $(filter Library,$(TARGETTYPE)), $(call gb_Helper_abbreviate_dirs,\
+       $(READELF) -d $(1) | grep SONAME > 
$(WORKDIR)/LinkTarget/$(2).exports.tmp; \
+       $(NM) $(gb_LTOPLUGINFLAGS) --dynamic --extern-only --defined-only 
--format=posix $(1) \
+               | cut -d' ' -f1-2 \
+               >> $(WORKDIR)/LinkTarget/$(2).exports.tmp && \
+       $(call 
gb_Helper_replace_if_different_and_touch,$(WORKDIR)/LinkTarget/$(2).exports.tmp,
 \
+               $(WORKDIR)/LinkTarget/$(2).exports,$(1))))
+$(if $(and $(filter CppunitTest Executable,$(TARGETTYPE)),$(filter 
EMSCRIPTEN,$(OS)),$(filter TRUE,$(ENABLE_QT5))), \
+       cp $(QT5_PLATFORMS_SRCDIR)/qtlogo.svg 
$(QT5_PLATFORMS_SRCDIR)/qtloader.js $(dir $(1)) ; \
+       sed -e 's/@APPNAME@/$(subst $(gb_Executable_EXT),,$(notdir $(1)))/' 
$(QT5_PLATFORMS_SRCDIR)/wasm_shell.html > $(dir $(1))qt_$(notdir $(1)))
+
 endef
 
 define gb_LinkTarget__command_staticlink
diff --git a/solenv/lockfile/README b/solenv/lockfile/README
new file mode 100644
index 000000000000..94a0182c2244
--- /dev/null
+++ b/solenv/lockfile/README
@@ -0,0 +1,6 @@
+All files (except for the dummy maillock.h) were copied from liblockfile 1.17.
+
+Just the max sleep time was adjusted in lockfile.c / 
lockfile_create_save_tmplock:
+
++                      if (sleeptime > 60) sleeptime = 60;
+-                      if (sleeptime > 5) sleeptime = 5;
diff --git a/solenv/lockfile/autoconf.h.in b/solenv/lockfile/autoconf.h.in
new file mode 100644
index 000000000000..7695d549649e
--- /dev/null
+++ b/solenv/lockfile/autoconf.h.in
@@ -0,0 +1,30 @@
+/* autoconf.h.in.  Generated automatically from configure.in by autoheader.  */
+/*
+
+acconfig.h - template used by autoheader to create config.h.in
+config.h.in - used by autoconf to create config.h
+config.h - created by autoconf; contains defines generated by autoconf
+
+*/
+
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Is the mailspool group writable */
+#undef MAILGROUP
+
+/* Define if you have the utime function.  */
+#undef HAVE_UTIME
+
+/* Define if you have the utimes function.  */
+#undef HAVE_UTIMES
+
+/* Define if you have the <getopt.h> header file.  */
+#undef HAVE_GETOPT_H
+
+/* Define if you have the <paths.h> header file.  */
+#undef HAVE_PATHS_H
+
+/* Define if you have the <sys/param.h> header file.  */
+#undef HAVE_SYS_PARAM_H
diff --git a/solenv/lockfile/dotlockfile.c b/solenv/lockfile/dotlockfile.c
new file mode 100644
index 000000000000..3670ecc238a6
--- /dev/null
+++ b/solenv/lockfile/dotlockfile.c
@@ -0,0 +1,459 @@
+/*
+ * dotlockfile.c       Command line version of liblockfile.
+ *                     Runs setgid mail so is able to lock mailboxes
+ *                     as well. Liblockfile can call this command.
+ *
+ *             Copyright (C) Miquel van Smoorenburg and contributors 1999-2021
+ *
+ *             This program is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU General Public License
+ *             as published by the Free Software Foundation; either version 2
+ *             of the License, or (at your option) any later version.
+ */
+
+#include "autoconf.h"
+
+#include <sys/types.h>
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <sys/wait.h>
+#include <stdio.h>
+#include <string.h>
+#include <pwd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <time.h>
+#include <errno.h>
+#include <maillock.h>
+#include <lockfile.h>
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+
+#ifndef HAVE_GETOPT_H
+extern int getopt();
+extern char *optarg;
+extern int optind;
+#endif
+
+extern int is_maillock(const char *lockfile);
+extern int lockfile_create_set_tmplock(const char *lockfile,
+                       volatile char **tmplock, int retries, int flags, struct 
__lockargs *);
+
+static volatile char *tmplock;
+static int quiet;
+
+/*
+ *     If we got SIGINT, SIGQUIT, SIGHUP, remove the
+ *     tempfile and re-raise the signal.
+ */
+void got_signal(int sig)
+{
+       if (tmplock && tmplock[0])
+               unlink((char *)tmplock);
+       signal(sig, SIG_DFL);
+       raise(sig);
+}
+
+void ignore_signal(int sig)
+{
+}
+
+/*
+ *     Install signal handler only if the signal was
+ *     not ignored already.
+ */
+int set_signal(int sig, void (*handler)(int))
+{
+       struct sigaction sa;
+
+       if (sigaction(sig, NULL, &sa) < 0)
+               return -1;
+       if (sa.sa_handler == SIG_IGN)
+               return 0;
+       memset(&sa, 0, sizeof(sa));
+       sa.sa_handler = handler;
+       return sigaction(sig, &sa, NULL);
+}
+
+/*
+ *     Sleep for an amount of time while regulary checking if
+ *     our parent is still alive.
+ */
+int check_sleep(int sleeptime, int flags)
+{
+       int             i;
+       int             interval = 5;
+       static int      ppid = 0;
+
+       if (ppid == 0) ppid = getppid();
+
+       if (flags & __L_INTERVAL)
+               interval = 1;
+
+       for (i = 0; i < sleeptime; i += interval) {
+               sleep(interval);
+               if (kill(ppid, 0) < 0 && errno == ESRCH)
+                       return L_ERROR;
+       }
+       return 0;
+}
+
+/*
+ *     Split a filename up in  file and directory.
+ */
+int fn_split(char *fn, char **fn_p, char **dir_p)
+{
+       static char     *buf = NULL;
+       char            *p;
+
+       if (buf)
+               free (buf);
+       buf = (char *) malloc (strlen (fn) + 1);
+       if (! buf)
+               return L_ERROR;
+       strcpy(buf, fn);
+       if ((p = strrchr(buf, '/')) != NULL) {
+               *p++   = 0;
+               *fn_p  = p;
+               *dir_p = buf;
+       } else {
+               *fn_p  = fn;
+               *dir_p = ".";
+       }
+       return L_SUCCESS;
+}
+
+
+/*
+ *     Return name of lockfile for mail.
+ */
+char *mlockname(char *user)
+{
+       static char     *buf = NULL;
+       char            *e;
+
+       if (buf)
+               free(buf);
+
+       e = getenv("MAIL");
+       if (e) {
+               buf = (char *)malloc(strlen(e)+6);
+               if (!buf)
+                       return NULL;
+               sprintf(buf, "%s.lock", e);
+       } else {
+               buf = (char *)malloc(strlen(MAILDIR)+strlen(user)+6);
+               if (!buf)
+                       return NULL;
+               sprintf(buf, "%s%s.lock", MAILDIR, user);
+       }
+       return buf;
+}
+
+void perror_exit(const char *why) {
+       if (!quiet) {
+               fprintf(stderr, "dotlockfile: ");
+               perror(why);
+       }
+       exit(L_ERROR);
+}
+
+/*
+ *     Print usage mesage and exit.
+ */
+void usage(void)
+{
+       fprintf(stderr, "Usage:  dotlockfile -l [-r retries] [-i interval] [-p] 
[-q] <-m|lockfile>\n");
+       fprintf(stderr, "        dotlockfile -l [-r retries] [-i interval] [-p] 
[-q] <-m|lockfile> [-P] command args...\n");
+       fprintf(stderr, "        dotlockfile -u|-t\n");
+       exit(1);
+}
+
+int main(int argc, char **argv)
+{
+       struct passwd   *pwd;
+       struct __lockargs args = { 0 };
+       gid_t           gid, egid;
+       char            *lockfile = NULL;
+       char            **cmd = NULL;
+       int             c, r;
+       int             retries = 5;
+       int             interval = 0;
+       int             flags = 0;
+       int             lock = 0;
+       int             unlock = 0;
+       int             check = 0;
+       int             touch = 0;
+       int             writepid = 0;
+       int             passthrough = 0;
+
+       /*
+        *      Remember real and effective gid, and
+        *      drop privs for now.
+        */
+       if ((gid = getgid()) < 0)
+               perror_exit("getgid");
+       if ((egid = getegid()) < 0)
+               perror_exit("getegid");
+       if (gid != egid) {
+               if (setregid(-1, gid) < 0)
+                       perror_exit("setregid(-1, gid)");
+       }
+
+       set_signal(SIGINT, got_signal);
+       set_signal(SIGQUIT, got_signal);
+       set_signal(SIGHUP, got_signal);
+       set_signal(SIGTERM, got_signal);
+       set_signal(SIGPIPE, got_signal);
+
+       /*
+        *      Process the options.
+        */
+       while ((c = getopt(argc, argv, "+qpNr:mluci:tP")) != EOF) switch(c) {
+               case 'q':
+                       quiet = 1;
+                       break;
+               case 'p':
+                       writepid = 1;
+                       break;
+               case 'N':
+                       /* NOP */
+                       break;
+               case 'r':
+                       retries = atoi(optarg);
+                       if (retries <= 0 &&
+                           retries != -1 && strcmp(optarg, "0") != 0) {
+                               if (!quiet)
+                                       fprintf(stderr, "dotlockfile: "
+                                               "-r %s: invalid argument\n",
+                                               optarg);
+                               return L_ERROR;
+                       }
+                       if (retries == -1) {
+                               /* 4000 years */
+                               retries = 0x7ffffff0;
+                       }
+                       break;
+               case 'm':
+                       if ((pwd = getpwuid(geteuid())) == NULL) {
+                               if (!quiet)
+                                       fprintf(stderr, "dotlockfile: You don't 
exist. Go away.\n");
+                               return L_ERROR;
+                       }
+                       lockfile = mlockname(pwd->pw_name);
+                       if (!lockfile) {
+                               if (!quiet)
+                                       perror("dotlockfile");
+                               return L_ERROR;
+                       }
+                       break;
+               case 'l':
+                       lock = 1;
+                       break;
+               case 'u':
+                       unlock = 1;
+                       break;
+               case 'c':
+                       check = 1;
+                       break;
+               case 'i':
+                       interval = atoi(optarg);
+                       if (interval <= 0 && strcmp(optarg, "0") != 0) {
+                               fprintf(stderr, "dotlockfile: -i needs argument 
>= 0\n");
+                               return L_ERROR;
+                       }
+                       flags |= __L_INTERVAL;
+                       args.interval = interval;
+                       break;
+               case 't':
+                       touch = 1;
+                       break;
+               case 'P':
+                       passthrough = 1;
+                       break;
+               default:
+                       usage();
+                       break;
+       }
+
+       /*
+        * next argument may be lockfile name
+        */
+       if (!lockfile) {
+               if (optind == argc)
+                       usage();
+               lockfile = argv[optind++];
+       }
+
+       /*
+        * next arguments may be command [args...]
+        */
+       if (optind < argc)
+               cmd = argv + optind;
+
+       /*
+        *      Options sanity check
+        */
+       if ((cmd || lock) && (touch || check || unlock))
+               usage();
+
+       if (writepid)
+               flags |= (cmd ? L_PID : L_PPID);
+
+#ifdef MAXPATHLEN
+       if (strlen(lockfile) >= MAXPATHLEN) {
+               if (!quiet)
+                       fprintf(stderr, "dotlockfile: %s: name too long\n", 
lockfile);
+               return L_NAMELEN;
+       }
+#endif
+
+       /*
+        *      Check if we run setgid.
+        */
+       int cwd_fd = -1;
+       int need_privs = 0;
+#ifdef MAILGROUP
+       if (gid != egid) {
+               /*
+                *      See if the requested lock is for a mailbox.
+                *      First, remember currect working directory.
+                */
+#ifdef O_PATH
+               cwd_fd = open(".", O_PATH|O_CLOEXEC);
+#else
+               cwd_fd = open(".", O_RDONLY|O_CLOEXEC);
+#endif
+               if (cwd_fd < 0) {
+                       if (!quiet)
+                               fprintf(stderr, "dotlockfile: opening \".\": 
%s\n",
+                                       strerror(errno));
+                       return L_ERROR;
+               }
+               /*
+                *      Now change directory to the directory the lockfile is 
in.
+                */
+               char *file, *dir;
+               r = fn_split(lockfile, &file, &dir);
+               if (r != L_SUCCESS) {
+                       if (!quiet)
+                               perror("dotlockfile");
+                       return L_ERROR;
+               }
+               if (chdir(dir) != 0) {
+                       if (!quiet)
+                               fprintf(stderr, "dotlockfile: %s: %s\n", dir, 
strerror(errno));
+                       return L_ERROR;
+               }
+
+               lockfile = file;
+               need_privs = is_maillock(lockfile);
+       }
+#endif
+
+       /*
+        *      See if we actually need to run setgid.
+        */
+       if (need_privs) {
+               if (setregid(gid, egid) != 0)
+                       perror_exit("setregid");
+       } else {
+               if (gid != egid && setgid(gid) != 0)
+                       perror_exit("setgid");
+       }
+
+       /*
+        *      Simple check for a valid lockfile ?
+        */
+       if (check)
+               return (lockfile_check(lockfile, flags) < 0) ? 1 : 0;
+
+
+       /*
+        *      Touch lock ?
+        */
+       if (touch)
+               return (lockfile_touch(lockfile) < 0) ? 1 : 0;
+
+       /*
+        *      Remove lockfile?
+        */
+       if (unlock)
+               return (lockfile_remove(lockfile) == 0) ? 0 : 1;
+
+
+       /*
+        *      No, lock.
+        */
+       r = lockfile_create_set_tmplock(lockfile, &tmplock, retries, flags, 
&args);
+       if (r != 0 || !cmd)
+               return r;
+
+
+       /*
+        *      Spawn command.
+        *
+        *      Using an empty signal handler means that we ignore the
+        *      signal, but that it's restored to SIG_DFL at execve().
+        */
+       set_signal(SIGINT, ignore_signal);
+       set_signal(SIGQUIT, ignore_signal);
+       set_signal(SIGHUP, ignore_signal);
+       set_signal(SIGALRM, ignore_signal);
+
+       pid_t pid = fork();
+       if (pid < 0) {
+               if (!quiet)
+                       perror("fork");
+               lockfile_remove(lockfile);
+               exit(L_ERROR);
+       }
+       if (pid == 0) {
+               /* drop setgid */
+               if (gid != egid && setgid(gid) < 0) {
+                       perror("setgid");
+                       exit(127);
+               }
+               /* restore current working directory */
+               if (cwd_fd >= 0) {
+                       if (fchdir(cwd_fd) < 0) {
+                               perror("dotlockfile: restoring cwd:");
+                               exit(127);
+                       }
+                       close(cwd_fd);
+               }
+               /* exec */
+               execvp(cmd[0], cmd);
+               perror(cmd[0]);
+               exit(127);
+       }
+
+       /* wait for child */
+       int e, wstatus;
+       while (1) {
+               if (!writepid)
+                       alarm(30);
+               e = waitpid(pid, &wstatus, 0);
+               if (e >= 0 || errno != EINTR)
+                       break;
+               if (!writepid)
+                       lockfile_touch(lockfile);
+       }
+
+       alarm(0);
+       lockfile_remove(lockfile);
+
+       if (passthrough) {
+               if (WIFEXITED(wstatus))
+                       return WEXITSTATUS(wstatus);
+               if (WIFSIGNALED(wstatus))
+                       return 128+WTERMSIG(wstatus);
+       }
+       return 0;
+}
+
diff --git a/solenv/lockfile/lockfile.c b/solenv/lockfile/lockfile.c
new file mode 100644
index 000000000000..d67050a52cee
--- /dev/null
+++ b/solenv/lockfile/lockfile.c
@@ -0,0 +1,614 @@
+/*
+ * lockfile.c  Safely creates a lockfile, also over NFS.
+ *             This file also holds the implementation for
+ *             the Svr4 maillock functions.
+ *
+ *             Copyright (C) Miquel van Smoorenburg and contributors 1997-2021.
+ *
+ *             This library is free software; you can redistribute it and/or
+ *             modify it under the terms of the GNU Library General Public
+ *             License as published by the Free Software Foundation; either
+ *             version 2 of the License, or (at your option) any later version.
+ */
+
+#include "autoconf.h"
+
+#include <sys/types.h>
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <errno.h>
+#include <lockfile.h>
+#include <maillock.h>
+
+#ifdef HAVE_UTIME
+#include <utime.h>
+#endif
+
+#ifdef LIB
+static char *mlockfile;
+static int  islocked = 0;
+#endif
+
+#ifndef LIB
+extern int check_sleep(int, int);
+#endif
+
+#ifdef MAILGROUP
+/*
+ *     Get the id of the mailgroup, by statting the helper program.
+ *     If it is setgroup-id, then the group is the mailgroup.
+ */
+static int mailgid()
+{
+       struct stat st;
+
+       if (stat(LOCKPROG, &st) != 0)
+               return (gid_t)-1;
+       if ((st.st_mode & 02000) == 0)
+               return (gid_t)-1;
+       return st.st_gid;
+}
+
+/*
+ *     Is this a lock for a mailbox? Check:
+ *     - is the file in /path/to/USERNAME.lock format
+ *     - is /path/to/USERNAME present and owned by us
+ *     - is /path/to writable by group mail
+ *
+ *     To be safe in a setgid program, chdir() into the lockfile
+ *     directory first, then pass in the basename of the lockfile.
+ */
+#ifdef LIB
+static
+#endif
+int is_maillock(const char *lockfile)
+{
+       struct stat     st;
+       gid_t           gid;
+       char            tmp[1024];
+       char            *p;
+
+       /* remove .lock suffix */
+       strncpy(tmp, lockfile, sizeof(tmp) - 1);
+       tmp[sizeof(tmp) - 1] = 0;
+       if ((p = strrchr(tmp, '.')) == NULL || strcmp(p, ".lock") != 0)
+               return 0;
+       *p = 0;
+
+       /* file to lock must exist, and must be owned by us */
+       if (lstat(tmp, &st) != 0 ||
+           (st.st_mode & S_IFMT) != S_IFREG || st.st_uid != getuid())
+               return 0;
+
+       /* Directory this file is in must be writable by group mail. */
+       if ((gid = mailgid()) == (gid_t)-1)
+               return 0;
+       if ((p = strrchr(tmp, '/')) != NULL)
+               *p = 0;
+       else
+               strncpy(tmp, ".", sizeof(tmp));
+       if (stat(tmp, &st) != 0 || st.st_gid != gid || (st.st_mode & 0020) == 0)
+               return 0;
+
+       return 1;
+}
+
+#ifdef LIB
+/*
+ *     Call external program to do the actual locking.
+ */
+static int run_helper(char *opt, const char *lockfile, int retries, int flags)
+{
+       sigset_t        set, oldset;
+       char            buf[8];
+       pid_t           pid, n;
+       int             st;
+
+       /*
+        * Better safe than sorry.
+        */
+       if (geteuid() == 0)
+               return L_ERROR;
+
+       /*
+        *      Block SIGCHLD. The main program might have installed
+        *      handlers we don't want to call.
+        */
+       sigemptyset(&set);
+       sigaddset(&set, SIGCHLD);
+       sigprocmask(SIG_BLOCK, &set, &oldset);
+
+       /*
+        *      Fork, execute locking program and wait.
+        */
+       if ((pid = fork()) < 0)
+               return L_ERROR;
+       if (pid == 0) {
+               /* drop privs */
+               if (setuid(geteuid()) < 0) {
+                       perror("setuid");
+                       _exit(L_ERROR);
+               }
+               snprintf(buf, sizeof(buf), "%d", retries % 1000);
+               execl(LOCKPROG, LOCKPROG, opt, "-r", buf, "-q",
+                       (flags & L_PID) ? "-p" : "-N", lockfile, NULL);
+               _exit(L_ERROR);
+       }
+
+       /*
+        *      Wait for return status - do something appropriate
+        *      if program died or returned L_ERROR.
+        */
+       while ((n = waitpid(pid, &st, 0)) != pid)
+               if (n < 0 && errno != EINTR)
+                       break;
+       if (!sigismember(&oldset, SIGCHLD))
+               sigprocmask(SIG_UNBLOCK, &set, NULL);
+       if (n < 0)
+               return L_ERROR;
+       if (!WIFEXITED(st) || WEXITSTATUS(st) == L_ERROR) {
+               errno = EINTR;
+               return L_ERROR;
+       }
+
+       return WEXITSTATUS(st);
+}
+#endif /* LIB*/
+
+#endif /* MAILGROUP */
+
+#define TMPLOCKSTR             ".lk"
+#define TMPLOCKSTRSZ           strlen(TMPLOCKSTR)
+#define TMPLOCKPIDSZ           5
+#define TMPLOCKTIMESZ          1
+#define TMPLOCKSYSNAMESZ       23
+#define TMPLOCKFILENAMESZ      (TMPLOCKSTRSZ + TMPLOCKPIDSZ + \
+                                TMPLOCKTIMESZ + TMPLOCKSYSNAMESZ)
+
+static int lockfilename(const char *lockfile, char *tmplock, int tmplocksz)
+{
+       char            sysname[256];
+       char            *p;
+
+#ifdef MAXPATHLEN
+       /*
+        *      Safety measure.
+        */
+       if (strlen(lockfile) + TMPLOCKFILENAMESZ > MAXPATHLEN) {
+               errno = ENAMETOOLONG;
+               return L_ERROR;
+       }
+#endif
+
+       if (strlen(lockfile) + TMPLOCKFILENAMESZ + 1 > tmplocksz) {
+               errno = EINVAL;
+               return L_ERROR;
+       }
+
+       /*
+        *      Create a temp lockfile (hopefully unique) and write
+        *      either our pid/ppid in it, or 0\0 for svr4 compatibility.
+        */
+       if (gethostname(sysname, sizeof(sysname)) < 0)
+               return L_ERROR;
+       if ((p = strchr(sysname, '.')) != NULL)
+               *p = 0;
+       /* strcpy is safe: length-check above, limited at snprintf below */
+       strcpy(tmplock, lockfile);
+       if ((p = strrchr(tmplock, '/')) == NULL)
+               p = tmplock;
+       else
+               p++;
+       if (snprintf(p, TMPLOCKFILENAMESZ, "%s%0*d%0*x%s", TMPLOCKSTR,
+                       TMPLOCKPIDSZ, (int)getpid(),
+                       TMPLOCKTIMESZ, (int)time(NULL) & 15,
+                       sysname) < 0) {
+               // never happens but gets rid of gcc truncation warning.
+               errno = EOVERFLOW;
+               return L_ERROR;
+       }
+
+       return 0;
+}
+
+/*
+ *     Create a lockfile.
+ */
+static int lockfile_create_save_tmplock(const char *lockfile,
+               char *tmplock, int tmplocksz,
+               volatile char **xtmplock,
+               int retries, int flags, struct __lockargs *args)
+{
+       struct stat     st, st1;
+       char            pidbuf[40];
+       pid_t           pid = 0;
+       int             sleeptime = 0;
+       int             statfailed = 0;
+       int             fd;
+       int             i, e, pidlen;
+       int             dontsleep = 1;
+       int             tries = retries + 1;
+
+       /* process optional flags that have arguments */
+       if (flags & __L_INTERVAL) {
+               sleeptime = args->interval;
+       }
+
+       /* decide which PID to write to the lockfile */
+       if (flags & L_PID)
+               pid = getpid();
+       if (flags & L_PPID) {
+               pid = getppid();
+               if (pid == 1) {
+                       /* orphaned */
+                       return L_ORPHANED;
+               }
+       }
+       pidlen = snprintf(pidbuf, sizeof(pidbuf), "%d\n", pid);
+       if (pidlen > sizeof(pidbuf) - 1) {
+               errno = EOVERFLOW;
+               return L_ERROR;
+       }
+
+       /* create temporary lockfile */
+       if ((i = lockfilename(lockfile, tmplock, tmplocksz)) != 0)
+               return i;
+       if (xtmplock)
+               *xtmplock = tmplock;
+       fd = open(tmplock, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0644);
+       if (fd < 0) {
+               /* permission denied? perhaps try suid helper */
+#if defined(LIB) && defined(MAILGROUP)
+               if (errno == EACCES && is_maillock(lockfile))
+                       return run_helper("-l", lockfile, retries, flags);
+#endif
+               return L_TMPLOCK;
+       }
+       i = write(fd, pidbuf, pidlen);
+       e = errno;
+
+       if (close(fd) != 0) {
+               e = errno;
+               i = -1;
+       }
+       if (i != pidlen) {
+               unlink(tmplock);
+               tmplock[0] = 0;
+               errno = i < 0 ? e : EAGAIN;
+               return L_TMPWRITE;
+       }
+
+       /*
+        *      Now try to link the temporary lock to the lock.
+        */
+       for (i = 0; i < tries && tries > 0; i++) {
+               if (!dontsleep) {
+                       if (!(flags & __L_INTERVAL))
+                               sleeptime += 5;
+
+                       if (sleeptime > 5) sleeptime = 5;
+#ifdef LIB
+                       sleep(sleeptime);
+#else
+                       if ((e = check_sleep(sleeptime, flags)) != 0) {
+                               unlink(tmplock);
+                               tmplock[0] = 0;
+                               return e;
+                       }
+#endif
+               }
+               dontsleep = 0;
+
+
+               /*
+                *      Now lock by linking the tempfile to the lock.
+                *
+                *      KLUDGE: some people say the return code of
+                *      link() over NFS can't be trusted.
+                *      EXTRA FIX: the value of the nlink field
+                *      can't be trusted (may be cached).
+                */
+               (void)!link(tmplock, lockfile);
+
+               if (lstat(tmplock, &st1) < 0) {
+                       tmplock[0] = 0;
+                       return L_ERROR; /* Can't happen */
+               }
+
+               if (lstat(lockfile, &st) < 0) {
+                       if (statfailed++ > 5) {
+                               /*
+                                *      Normally, this can't happen; either
+                                *      another process holds the lockfile or
+                                *      we do. So if this error pops up
+                                *      repeatedly, just exit...
+                                */
+                               e = errno;
+                               (void)unlink(tmplock);
+                               tmplock[0] = 0;
+                               errno = e;
+                               return L_MAXTRYS;
+                       }
+                       continue;
+               }
+
+               /*
+                *      See if we got the lock.
+                */
+               if (st.st_rdev == st1.st_rdev &&
+                   st.st_ino  == st1.st_ino) {
+                       (void)unlink(tmplock);
+                       tmplock[0] = 0;
+                       return L_SUCCESS;
+               }
+               statfailed = 0;
+
+               /*
+                *      If there is a lockfile and it is invalid,
+                *      remove the lockfile.
+                */
+               if (lockfile_check(lockfile, flags) == -1) {
+                       if (unlink(lockfile) < 0 && errno != ENOENT) {
+                               /*
+                                *      we failed to unlink the stale
+                                *      lockfile, give up.
+                                */
+                               return L_RMSTALE;
+                       }
+                       dontsleep = 1;
+                       /*
+                        *      If the lockfile was invalid, then the first
+                        *      try wasn't valid either - make sure we
+                        *      try at least once more.
+                        */
+                       if (tries == 1) tries++;
+               }
+
+       }
+       (void)unlink(tmplock);
+       tmplock[0] = 0;
+       errno = EAGAIN;
+       return L_MAXTRYS;
+}
+
+#ifdef LIB
+static
+#endif
+int lockfile_create_set_tmplock(const char *lockfile, volatile char 
**xtmplock, int retries, int flags, struct __lockargs *args)
+{
+       char *tmplock;
+       int l, r, e;
+
+       l = strlen(lockfile)+TMPLOCKFILENAMESZ+1;
+       if ((tmplock = (char *)malloc(l)) == NULL)
+               return L_ERROR;
+       tmplock[0] = 0;
+       r = lockfile_create_save_tmplock(lockfile,
+                                               tmplock, l, xtmplock, retries, 
flags, args);
+       if (xtmplock)
+               *xtmplock = NULL;
+       e = errno;
+       free(tmplock);
+       errno = e;
+       return r;
+}
+
+#ifdef LIB
+int lockfile_create(const char *lockfile, int retries, int flags)
+{
+       /* check against unknown flags */
+       if (flags & ~(L_PID|L_PPID)) {
+               errno = EINVAL;
+               return L_ERROR;
+       }
+       return lockfile_create_set_tmplock(lockfile, NULL, retries, flags, 
NULL);
+}
+
+#ifdef STATIC
+int lockfile_create2(const char *lockfile, int retries,
+               int flags, struct __lockargs *args, int args_sz)
+{
+
+       #define FLAGS_WITH_ARGS (__L_INTERVAL)
+       #define KNOWN_FLAGS (L_PID|L_PPID|__L_INTERVAL)
+
+       /* check if size is the same (version check) */
+       if (args != NULL && sizeof(struct __lockargs) != args_sz) {
+               errno = EINVAL;
+               return L_ERROR;
+       }
+       /* some flags _must_ have a non-null args */
+       if (args == NULL && (flags & FLAGS_WITH_ARGS)) {
+               errno = EINVAL;
+               return L_ERROR;
+       }
+       /* check against unknown flags */
+       if (flags & ~KNOWN_FLAGS) {
+               errno = EINVAL;
+               return L_ERROR;
+       }
+       return lockfile_create_set_tmplock(lockfile, NULL, retries, flags, 
args);
+}
+#endif
+
+#endif
+
+/*
+ *     See if a valid lockfile is present.
+ *     Returns 0 if so, -1 if not.
+ */
+int lockfile_check(const char *lockfile, int flags)
+{
+       struct stat     st, st2;
+       char            buf[16];
+       time_t          now;
+       pid_t           pid;
+       int             fd, len, r;
+
+       if (stat(lockfile, &st) < 0)
+               return -1;
+
+       /*
+        *      Get the contents and mtime of the lockfile.
+        */
+       time(&now);
+       pid = 0;
+       if ((fd = open(lockfile, O_RDONLY)) >= 0) {
+               /*
+                *      Try to use 'atime after read' as now, this is
+                *      the time of the filesystem. Should not get
+                *      confused by 'atime' or 'noatime' mount options.
+                */
+               len = 0;
+               if (fstat(fd, &st) == 0 &&
+                   (len = read(fd, buf, sizeof(buf))) >= 0 &&
+                   fstat(fd, &st2) == 0 &&
+                   st.st_atime != st2.st_atime)
+                       now = st.st_atime;
+               close(fd);
+               if (len > 0 && (flags & (L_PID|L_PPID))) {
+                       buf[len] = 0;
+                       pid = atoi(buf);
+               }
+       }
+
+       if (pid > 0) {
+               /*
+                *      If we have a pid, see if the process
+                *      owning the lockfile is still alive.
+                */
+               r = kill(pid, 0);
+               if (r == 0 || errno == EPERM)
+                       return 0;
+               if (r < 0 && errno == ESRCH)
+                       return -1;
+               /* EINVAL - FALLTHRU */
+       }
+
+       /*
+        *      Without a pid in the lockfile, the lock
+        *      is valid if it is newer than 5 mins.
+        */
+
+       if (now < st.st_mtime + 300)
+               return 0;
+
+       return -1;
+}
+
+/*
+ *     Remove a lock.
+ */
+int lockfile_remove(const char *lockfile)
+{
+       if (unlink(lockfile) < 0) {
+#if defined(LIB) && defined(MAILGROUP)
+               if (errno == EACCES && is_maillock(lockfile))
+                       return run_helper("-u", lockfile, 0, 0);
+#endif
+               return errno == ENOENT ? 0 : -1;
+       }
+       return 0;
+}
+
+/*
+ *     Touch a lock.
+ */
+int lockfile_touch(const char *lockfile)
+{
+#ifdef HAVE_UTIME
+       return utime(lockfile, NULL);
+#else
+       return utimes(lockfile, NULL);
+#endif
+}
+
+#ifdef LIB
+/*
+ *     Lock a mailfile. This looks a lot like the SVR4 function.
+ *     Arguments: lusername, retries.
+ */
+int maillock(const char *name, int retries)
+{
+       char            *p, *mail;
+       char            *newlock;
+       int             i, e;
+       int             len, newlen;
+
+       if (islocked) return 0;
+
+#ifdef MAXPATHLEN
+       if (strlen(name) + sizeof(MAILDIR) + 6 > MAXPATHLEN) {
+               errno = ENAMETOOLONG;
+               return L_NAMELEN;
+       }
+#endif
+
+       /*
+        *      If $MAIL is for the same username as "name"
+        *      then use $MAIL instead.
+        */
+
+       len = strlen(name)+strlen(MAILDIR)+6;
+       mlockfile = (char *)malloc(len);
+       if (!mlockfile)
+               return L_ERROR;
+       sprintf(mlockfile, "%s%s.lock", MAILDIR, name);
+       if ((mail = getenv("MAIL")) != NULL) {
+               if ((p = strrchr(mail, '/')) != NULL)
+                       p++;
+               else
+                       p = mail;
+               if (strcmp(p, name) == 0) {
+                       newlen = strlen(mail)+6;
+#ifdef MAXPATHLEN
+                       if (newlen > MAXPATHLEN) {
+                               errno = ENAMETOOLONG;
+                               return L_NAMELEN;
+                       }
+#endif
+                       if (newlen > len) {
+                               newlock = (char *)realloc (mlockfile, newlen);
+                               if (newlock == NULL) {
+                                       e = errno;
+                                       free (mlockfile);
+                                       mlockfile = NULL;
+                                       errno = e;
+                                       return L_ERROR;
+                               }
+                               mlockfile = newlock;
+                       }
+                       sprintf(mlockfile, "%s.lock", mail);
+               }
+       }
+       i = lockfile_create(mlockfile, retries, 0);
+       if (i == 0) islocked = 1;
+
+       return i;
+}
+
+void mailunlock(void)
+{
+       if (!islocked) return;
+       lockfile_remove(mlockfile);
+       free (mlockfile);
+       islocked = 0;
+}
+
+void touchlock(void)
+{
+       lockfile_touch(mlockfile);
+}
+#endif
+
diff --git a/solenv/lockfile/lockfile.h b/solenv/lockfile/lockfile.h
new file mode 100644
index 000000000000..12e7d494bb05
--- /dev/null
+++ b/solenv/lockfile/lockfile.h
@@ -0,0 +1,65 @@
+/*
+ *     Copyright (C) 1999 Miquel van Smoorenburg
+ *
+ *     This library is free software; you can redistribute it and/or modify
+ *     it under the terms of the GNU Library General Public License as
+ *     published by the Free Software Foundation; either version 2 of the
+ *     License, or (at your option) any later version.
+ *
+ *     On Debian GNU/Linux systems, the complete text of the GNU Library
+ *     General Public License can be found in `/usr/doc/copyright/LGPL'.
+ *     You can also find a copy on the GNU website at http://www.gnu.org/
+ */
+#ifndef _LOCKFILE_H
+#define _LOCKFILE_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ *     Prototypes.
+ */
+int    lockfile_create(const char *lockfile, int retries, int flags);
+int    lockfile_remove(const char *lockfile);
+int    lockfile_touch(const char *lockfile);
+int    lockfile_check(const char *lockfile, int flags);
+
+/*
+ *     Return values for lockfile_create()
+ */
+#define        L_SUCCESS       0       /* Lockfile created                     
*/
+#define L_NAMELEN      1       /* Recipient name too long              */
+#define L_TMPLOCK      2       /* Error creating temp lockfile         */
+#define L_TMPWRITE     3       /* Can't write pid into temp lockfile   */
+#define L_MAXTRYS      4       /* Failed after max. number of attempts */
+#define L_ERROR                5       /* Unknown error; check errno           
*/
+#define L_MANLOCK      6       /* Cannot set mandatory lock on tempfile */
+#define L_ORPHANED     7       /* Called with L_PPID but parent is gone */
+#define L_RMSTALE      8       /* Failed to remove stale lockfile      */
+
+/*
+ *     Flag values for lockfile_create()
+ */
+#define L_PID          16      /* Put PID in lockfile                  */
+#define L_PPID         32      /* Put PPID in lockfile                 */
+
+/*
+ * Experimental.
+ */
+struct __lockargs {
+       int interval;           /* Static interval between retries      */
+};
+#define __L_INTERVAL   64      /* Specify consistent retry interval    */
+#ifdef LOCKFILE_EXPERIMENTAL
+#define lockargs       __lockargs
+#define L_INTERVAL     __L_INTERVAL
+int    lockfile_create2(const char *lockfile, int retries,
+               int flags, struct lockargs *args, int args_sz);
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* _LOCKFILE_H */
diff --git a/solenv/lockfile/maillock.h b/solenv/lockfile/maillock.h
new file mode 100644
index 000000000000..565e002d0f2b
--- /dev/null
+++ b/solenv/lockfile/maillock.h
@@ -0,0 +1 @@
+#define MAILDIR "/very/likely/doesnt/exists"
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to