diff --git a/.gitignore b/.gitignore index 1fe15621e2..89f0ae797c 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,13 @@ config.cache /guix-package /guix/config.scm /guix-import +/nix/nix-daemon/nix-daemon.cc +/nix/config.h +/nix/config.h.in +stamp-h[0-9] +/nix/AUTHORS +/nix/COPYING +/libformat.a +/libstore.a +/libutil.a +/guix-daemon diff --git a/Makefile.am b/Makefile.am index 8bb3b55634..7e5be0be2a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -222,6 +222,12 @@ SUBDIRS = po info_TEXINFOS = doc/guix.texi EXTRA_DIST += doc/fdl-1.3.texi +if BUILD_DAEMON + +include daemon.am + +endif BUILD_DAEMON + ACLOCAL_AMFLAGS = -I m4 AM_DISTCHECK_CONFIGURE_FLAGS = \ --with-libgcrypt-prefix="$(LIBGCRYPT_PREFIX)" \ diff --git a/config-daemon.ac b/config-daemon.ac new file mode 100644 index 0000000000..7570814705 --- /dev/null +++ b/config-daemon.ac @@ -0,0 +1,64 @@ +dnl -*- Autoconf -*- fragment for the C++ daemon. + +AC_ARG_ENABLE([daemon], + [AS_HELP_STRING([--enable-daemon], [build the Nix daemon (C++)])], + [guix_build_daemon="$enableval"], + [guix_build_daemon="no"]) + +AC_MSG_CHECKING([whether to build daemon]) +AC_MSG_RESULT([$guix_build_daemon]) + +dnl C++ environment. This macro must be used unconditionnaly. +AC_PROG_CXX + +if test "x$guix_build_daemon" = "xyes"; then + + AC_PROG_RANLIB + AC_CONFIG_HEADER([nix/config.h]) + + dnl Use 64-bit file system calls so that we can support files > 2 GiB. + AC_SYS_LARGEFILE + + dnl Look for libbz2, a required dependency. + AC_CHECK_LIB([bz2], [BZ2_bzWriteOpen], [true], + [AC_MSG_ERROR([Guix requires libbz2, which is part of bzip2. See http://www.bzip.org/.])]) + AC_CHECK_HEADERS([bzlib.h], [true], + [AC_MSG_ERROR([Guix requires libbz2, which is part of bzip2. See http://www.bzip.org/.])]) + + dnl Look for SQLite, a required dependency. + PKG_CHECK_MODULES([SQLITE3], [sqlite3 >= 3.6.19]) + + AC_DEFINE([NIX_VERSION], ["0.0.0"], [Fake Nix version number.]) + AC_DEFINE_UNQUOTED([SYSTEM], ["\"$guix_system\""], + [Guix host system type--i.e., platform and OS kernel tuple.]) + + case "$LIBGCRYPT_PREFIX" in + no) + LIBGCRYPT_CFLAGS="" + LIBGCRYPT_LIBS="" + ;; + *) + LIBGCRYPT_CFLAGS="-I$LIBGCRYPT_PREFIX/include" + LIBGCRYPT_LIBS="-L$LIBGCRYPT_PREFIX/lib -lgcrypt" + ;; + esac + AC_SUBST([LIBGCRYPT_CFLAGS]) + AC_SUBST([LIBGCRYPT_LIBS]) + + save_CFLAGS="$CFLAGS" + save_LDFLAGS="$LDFLAGS" + CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS" + LDFLAGS="$LDFLAGS $LIBGCRYPT_LDFLAGS" + + have_gcrypt=yes + AC_CHECK_LIB([gcrypt], [gcry_md_open], [:], [have_gcrypt=no]) + AC_CHECK_HEADER([gcrypt.h], [:], [have_gcrypt=no]) + if test "x$have_gcrypt" != "xyes"; then + AC_MSG_ERROR([GNU libgcrypt not found; please install it.]) + fi + + CFLAGS="$save_CFLAGS" + LDFLAGS="$save_LDFLAGS" +fi + +AM_CONDITIONAL([BUILD_DAEMON], [test "x$guix_build_daemon" = "xyes"]) diff --git a/configure.ac b/configure.ac index 65fc01857f..6c7be59895 100644 --- a/configure.ac +++ b/configure.ac @@ -12,13 +12,23 @@ AM_INIT_AUTOMAKE([1.11 gnu silent-rules subdir-objects \ AC_CONFIG_SRCDIR([guix.scm]) AC_CONFIG_MACRO_DIR([m4]) +dnl For the C++ code. This must be used early. +AC_USE_SYSTEM_EXTENSIONS + AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION([0.18.1]) guilemoduledir="${datarootdir}/guile/site/2.0" AC_SUBST([guilemoduledir]) -AC_CANONICAL_HOST +GUIX_SYSTEM_TYPE + +AC_ARG_WITH(store-dir, + AC_HELP_STRING([--with-store-dir=PATH], + [path of the store (defaults to /nix/store)]), + [storedir="$withval"], + [storedir="/nix/store"]) +AC_SUBST(storedir) PKG_CHECK_MODULES([GUILE], [guile-2.0]) AC_PATH_PROG([GUILE], [guile]) @@ -83,6 +93,9 @@ AC_SUBST([LIBGCRYPT_PREFIX]) GUIX_ASSERT_LIBGCRYPT_USABLE +AC_CACHE_SAVE + +m4_include([config-daemon.ac]) AC_CONFIG_FILES([Makefile po/Makefile.in diff --git a/daemon.am b/daemon.am new file mode 100644 index 0000000000..e150e54d6b --- /dev/null +++ b/daemon.am @@ -0,0 +1,152 @@ +# Guix --- Nix package management from Guile. -*- coding: utf-8 -*- +# Copyright (C) 2012 Ludovic Courtès +# +# This file is part of Guix. +# +# Guix 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 3 of the License, or (at +# your option) any later version. +# +# Guix is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Guix. If not, see . + +# +# Integration of the `guix-daemon' code taken from upstream Nix. +# + +BUILT_SOURCES = nix/libstore/schema.sql.hh +CLEANFILES += $(BUILT_SOURCES) + +noinst_LIBRARIES = libformat.a libutil.a libstore.a + +libformat_a_SOURCES = \ + nix/boost/format/free_funcs.cc \ + nix/boost/format/parsing.cc \ + nix/boost/format/format_implementation.cc + +libformat_headers = \ + nix/boost/weak_ptr.hpp \ + nix/boost/throw_exception.hpp \ + nix/boost/checked_delete.hpp \ + nix/boost/shared_ptr.hpp \ + nix/boost/format.hpp \ + nix/boost/assert.hpp \ + nix/boost/format/macros_default.hpp \ + nix/boost/format/format_fwd.hpp \ + nix/boost/format/format_class.hpp \ + nix/boost/format/exceptions.hpp \ + nix/boost/format/group.hpp \ + nix/boost/format/feed_args.hpp \ + nix/boost/format/internals_fwd.hpp \ + nix/boost/format/internals.hpp \ + nix/boost/detail/workaround.hpp \ + nix/boost/detail/shared_count.hpp \ + nix/boost/enable_shared_from_this.hpp + +libformat_a_CPPFLAGS = \ + -I$(top_srcdir)/nix + +libutil_a_SOURCES = \ + nix/libutil/archive.cc \ + nix/libutil/serialise.cc \ + nix/libutil/immutable.cc \ + nix/libutil/util.cc \ + nix/libutil/xml-writer.cc \ + nix/libutil/hash.cc \ + nix/libutil/gcrypt-hash.cc + +libutil_headers = \ + nix/libutil/immutable.hh \ + nix/libutil/hash.hh \ + nix/libutil/serialise.hh \ + nix/libutil/xml-writer.hh \ + nix/libutil/util.hh \ + nix/libutil/archive.hh \ + nix/libutil/types.hh \ + nix/libutil/gcrypt-hash.hh \ + nix/libutil/md5.h \ + nix/libutil/sha1.h \ + nix/libutil/sha256.h + +libutil_a_CPPFLAGS = \ + -I$(top_builddir)/nix \ + -I$(top_srcdir)/nix/libutil \ + $(libformat_a_CPPFLAGS) + +libstore_a_SOURCES = \ + nix/libstore/gc.cc \ + nix/libstore/globals.cc \ + nix/libstore/misc.cc \ + nix/libstore/references.cc \ + nix/libstore/store-api.cc \ + nix/libstore/optimise-store.cc \ + nix/libstore/local-store.cc \ + nix/libstore/remote-store.cc \ + nix/libstore/build.cc \ + nix/libstore/pathlocks.cc \ + nix/libstore/derivations.cc + +libstore_headers = \ + nix/libstore/references.hh \ + nix/libstore/pathlocks.hh \ + nix/libstore/globals.hh \ + nix/libstore/schema.sql.hh \ + nix/libstore/worker-protocol.hh \ + nix/libstore/remote-store.hh \ + nix/libstore/derivations.hh \ + nix/libstore/misc.hh \ + nix/libstore/local-store.hh \ + nix/libstore/store-api.hh + +libstore_a_CPPFLAGS = \ + $(libutil_a_CPPFLAGS) \ + -I$(top_srcdir)/nix/libstore \ + -DNIX_STORE_DIR=\"$(storedir)\" \ + -DNIX_DATA_DIR=\"$(datadir)\" \ + -DNIX_STATE_DIR=\"$(localstatedir)/nix\" \ + -DNIX_LOG_DIR=\"$(localstatedir)/log/nix\" \ + -DNIX_CONF_DIR=\"$(sysconfdir)/nix\" \ + -DNIX_LIBEXEC_DIR=\"$(libexecdir)\" \ + -DNIX_BIN_DIR=\"$(bindir)\" \ + -DOPENSSL_PATH="\"FIXME--no OpenSSL support\"" + +libstore_a_CFLAGS = \ + $(SQLITE3_CFLAGS) $(LIBGCRYPT_CFLAGS) + +bin_PROGRAMS = guix-daemon + +guix_daemon_SOURCES = \ + nix/nix-daemon/nix-daemon.cc \ + nix/nix-daemon/guix-daemon.cc + +guix_daemon_CPPFLAGS = \ + $(libutil_a_CPPFLAGS) \ + -I$(top_srcdir)/nix/libstore + +guix_daemon_LDADD = \ + libstore.a libutil.a libformat.a -lbz2 \ + $(SQLITE3_LIBS) $(LIBGCRYPT_LIBS) + + +noinst_HEADERS = \ + $(libformat_headers) $(libutil_headers) $(libstore_headers) + +nix/libstore/schema.sql.hh: nix/libstore/schema.sql + $(GUILE) --no-auto-compile -c \ + "(use-modules (rnrs io ports)) \ + (call-with-output-file \"$@\" \ + (lambda (out) \ + (call-with-input-file \"$^\" \ + (lambda (in) \ + (write (get-string-all in) out)))))" + +EXTRA_DIST += \ + nix/libstore/schema.sql \ + nix/AUTHORS \ + nix/COPYING diff --git a/m4/guix.m4 b/m4/guix.m4 index 29f928f653..9b5184ff55 100644 --- a/m4/guix.m4 +++ b/m4/guix.m4 @@ -33,3 +33,32 @@ AC_DEFUN([GUIX_ASSERT_LIBGCRYPT_USABLE], if test "x$guix_cv_libgcrypt_usable_p" != "xyes"; then AC_MSG_ERROR([GNU libgcrypt does not appear to be usable; see `--with-libgcrypt-prefix' and `README'.]) fi]) + +dnl GUIX_SYSTEM_TYPE +dnl +dnl Determine the Guix host system type, and store it in the +dnl `guix_system' variable. +AC_DEFUN([GUIX_SYSTEM_TYPE], [ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_ARG_WITH(system, AC_HELP_STRING([--with-system=SYSTEM], + [Platform identifier (e.g., `i686-linux').]), + [guix_system="$withval"], + [case "$host_cpu" in + i*86) + machine_name="i686";; + amd64) + machine_name="x86_64";; + *) + machine_name="$host_cpu";; + esac + + case "$host_os" in + linux-gnu*) + # For backward compatibility, strip the `-gnu' part. + guix_system="$machine_name-linux";; + *) + # Strip the version number from names such as `gnu0.3', + # `darwin10.2.0', etc. + guix_system="$machine_name-`echo $host_os | "$SED" -e's/@<:@0-9.@:>@*$//g'`";; + esac]) +]) diff --git a/nix/.gitignore b/nix/.gitignore new file mode 100644 index 0000000000..92d0520cc7 --- /dev/null +++ b/nix/.gitignore @@ -0,0 +1,4 @@ +*.a +*.o +.deps +.dirstamp diff --git a/nix/boost/.gitignore b/nix/boost/.gitignore new file mode 100644 index 0000000000..1f188e3b65 --- /dev/null +++ b/nix/boost/.gitignore @@ -0,0 +1,3 @@ +*.hpp +*.cpp +*.cc diff --git a/nix/libstore/.gitignore b/nix/libstore/.gitignore new file mode 100644 index 0000000000..512a0d022f --- /dev/null +++ b/nix/libstore/.gitignore @@ -0,0 +1,3 @@ +*.cc +*.hh +/schema.sql diff --git a/nix/libutil/.gitignore b/nix/libutil/.gitignore new file mode 100644 index 0000000000..e539428b1b --- /dev/null +++ b/nix/libutil/.gitignore @@ -0,0 +1,2 @@ +*.cc +*.hh diff --git a/nix/libutil/gcrypt-hash.cc b/nix/libutil/gcrypt-hash.cc new file mode 100644 index 0000000000..de7e5afc1a --- /dev/null +++ b/nix/libutil/gcrypt-hash.cc @@ -0,0 +1,50 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix 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 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +#include + +#include +#include + +extern "C" { + +void +guix_hash_init (struct guix_hash_context *ctx, gcry_md_algo_t algo) +{ + gcry_error_t err; + + err = gcry_md_open (&ctx->md_handle, algo, 0); + assert (err == GPG_ERR_NO_ERROR); +} + +void +guix_hash_update (struct guix_hash_context *ctx, const void *buffer, size_t len) +{ + gcry_md_write (ctx->md_handle, buffer, len); +} + +void +guix_hash_final (void *resbuf, struct guix_hash_context *ctx, + gcry_md_algo_t algo) +{ + memcpy (resbuf, gcry_md_read (ctx->md_handle, algo), + gcry_md_get_algo_dlen (algo)); + gcry_md_close (ctx->md_handle); +} + +} diff --git a/nix/libutil/gcrypt-hash.hh b/nix/libutil/gcrypt-hash.hh new file mode 100644 index 0000000000..1e26398540 --- /dev/null +++ b/nix/libutil/gcrypt-hash.hh @@ -0,0 +1,39 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix 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 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +/* An OpenSSL-like interface to GNU libgcrypt cryptographic hash + functions. */ + +#pragma once +#include +#include + +extern "C" { + +struct guix_hash_context +{ + gcry_md_hd_t md_handle; +}; + +extern void guix_hash_init (struct guix_hash_context *ctx, gcry_md_algo_t algo); +extern void guix_hash_update (struct guix_hash_context *ctx, const void *buffer, + size_t len); +extern void guix_hash_final (void *resbuf, struct guix_hash_context *ctx, + gcry_md_algo_t algo); + +} diff --git a/nix/libutil/md5.h b/nix/libutil/md5.h new file mode 100644 index 0000000000..c275e381f8 --- /dev/null +++ b/nix/libutil/md5.h @@ -0,0 +1,35 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix 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 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +#include + +#define MD5_CTX guix_hash_context + +static inline void +MD5_Init (struct MD5_CTX *ctx) +{ + guix_hash_init (ctx, GCRY_MD_MD5); +} + +#define MD5_Update guix_hash_update + +static inline void +MD5_Final (void *resbuf, struct MD5_CTX *ctx) +{ + guix_hash_final (ctx, ctx, GCRY_MD_MD5); +} diff --git a/nix/libutil/sha1.h b/nix/libutil/sha1.h new file mode 100644 index 0000000000..8af92725ea --- /dev/null +++ b/nix/libutil/sha1.h @@ -0,0 +1,35 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix 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 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +#include + +#define SHA_CTX guix_hash_context + +static inline void +SHA1_Init (struct SHA_CTX *ctx) +{ + guix_hash_init (ctx, GCRY_MD_SHA1); +} + +#define SHA1_Update guix_hash_update + +static inline void +SHA1_Final (void *resbuf, struct SHA_CTX *ctx) +{ + guix_hash_final (ctx, ctx, GCRY_MD_SHA1); +} diff --git a/nix/libutil/sha256.h b/nix/libutil/sha256.h new file mode 100644 index 0000000000..c436d6402c --- /dev/null +++ b/nix/libutil/sha256.h @@ -0,0 +1,35 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix 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 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +#include + +#define SHA256_CTX guix_hash_context + +static inline void +SHA256_Init (struct SHA256_CTX *ctx) +{ + guix_hash_init (ctx, GCRY_MD_SHA256); +} + +#define SHA256_Update guix_hash_update + +static inline void +SHA256_Final (void *resbuf, struct SHA256_CTX *ctx) +{ + guix_hash_final (ctx, ctx, GCRY_MD_SHA256); +} diff --git a/nix/nix-daemon/guix-daemon.cc b/nix/nix-daemon/guix-daemon.cc new file mode 100644 index 0000000000..43d4113493 --- /dev/null +++ b/nix/nix-daemon/guix-daemon.cc @@ -0,0 +1,115 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix 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 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +#include + +#include +#include "shared.hh" +#include + +#include +#include + +/* Variables used by `nix-daemon.cc'. */ +volatile ::sig_atomic_t blockInt; +char **argvSaved; + +using namespace nix; + +/* Entry point in `nix-daemon.cc'. */ +extern void run (Strings args); + + +/* Command-line options. */ + +const char *argp_program_version = + "guix-daemon (" PACKAGE_NAME ") " PACKAGE_VERSION; +const char *argp_program_bug_address = PACKAGE_BUGREPORT; + +static char doc[] = +"guix-daemon -- perform derivation builds and store accesses\ +\v\ +This program is a daemon meant to run in the background. It serves \ +requests sent over a Unix-domain socket. It accesses the store, and \ +builds derivations on behalf of its clients."; + +#define GUIX_OPT_SYSTEM 1 +#define GUIX_OPT_DISABLE_CHROOT 2 +#define GUIX_OPT_DISABLE_LOG_COMPRESSION 3 + +static const struct argp_option options[] = + { + { "system", GUIX_OPT_SYSTEM, "SYSTEM", 0, + "Assume SYSTEM as the current system type" }, + { "build-cores", 'C', "N", 0, + "Use N CPU cores to build each derivation; 0 means as many as available" }, + { "max-jobs", 'M', "N", 0, + "Allow at most N build jobs" }, + { "disable-chroot", GUIX_OPT_DISABLE_CHROOT, 0, 0, + "Disable chroot builds" }, + { "disable-log-compression", GUIX_OPT_DISABLE_LOG_COMPRESSION, 0, 0, + "Disable compression of the build logs" }, + { 0, 0, 0, 0, 0 } + }; + +/* Parse a single option. */ +static error_t +parse_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) + { + case GUIX_OPT_DISABLE_CHROOT: + settings.useChroot = false; + break; + case GUIX_OPT_DISABLE_LOG_COMPRESSION: + settings.compressLog = false; + break; + case 'C': + settings.buildCores = atoi (arg); + break; + case 'M': + settings.maxBuildJobs = atoi (arg); + break; + case GUIX_OPT_SYSTEM: + settings.thisSystem = arg; + break; + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +} + +/* Argument parsing. */ +static struct argp argp = { options, parse_opt, 0, doc }; + + + +int +main (int argc, char *argv[]) +{ + Strings nothing; + + settings.useChroot = true; + settings.processEnvironment (); + + argp_parse (&argp, argc, argv, 0, 0, 0); + + argvSaved = argv; + run (nothing); +} diff --git a/nix/nix-daemon/shared.hh b/nix/nix-daemon/shared.hh new file mode 100644 index 0000000000..a03c09c036 --- /dev/null +++ b/nix/nix-daemon/shared.hh @@ -0,0 +1,37 @@ +/* Guix --- Nix package management from Guile. -*- coding: utf-8 -*- + Copyright (C) 2012 Ludovic Courtès + + This file is part of Guix. + + Guix 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 3 of the License, or (at + your option) any later version. + + Guix is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Guix. If not, see . */ + +/* Replacement for Nix's libmain/shared.hh. */ + +#pragma once + +#include + +#include +#include + +static inline void +showManPage (const char *name) +{ + /* This idea is evil. Abort. */ + abort (); +} + +extern volatile ::sig_atomic_t blockInt; + +extern char **argvSaved;