diff -Nru flatpak-builder-0.10.6/aclocal.m4 flatpak-builder-0.10.9/aclocal.m4 --- flatpak-builder-0.10.6/aclocal.m4 2017-12-15 13:26:49.000000000 +0000 +++ flatpak-builder-0.10.9/aclocal.m4 2018-02-19 09:37:55.000000000 +0000 @@ -1530,6 +1530,7 @@ AC_SUBST([am__untar]) ]) # _AM_PROG_TAR +m4_include([libglnx/libglnx.m4]) m4_include([m4/attributes.m4]) m4_include([m4/gettext.m4]) m4_include([m4/glibtests.m4]) diff -Nru flatpak-builder-0.10.6/config.h.in flatpak-builder-0.10.9/config.h.in --- flatpak-builder-0.10.6/config.h.in 2017-12-15 13:27:18.000000000 +0000 +++ flatpak-builder-0.10.9/config.h.in 2018-02-19 09:37:56.000000000 +0000 @@ -1,9 +1,15 @@ /* config.h.in. Generated from configure.ac by autoheader. */ +/* Define if we should avoid using O_TMPFILE */ +#undef DISABLE_OTMPFILE + /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef ENABLE_NLS +/* Define if we should be compatible with wrpseudo */ +#undef ENABLE_WRPSEUDO_COMPAT + /* Define if peer to peer support should be enabled */ #undef FLATPAK_ENABLE_P2P @@ -22,6 +28,18 @@ */ #undef HAVE_DCGETTEXT +/* Define to 1 if you have the declaration of `copy_file_range', and to 0 if + you don't. */ +#undef HAVE_DECL_COPY_FILE_RANGE + +/* Define to 1 if you have the declaration of `memfd_create', and to 0 if you + don't. */ +#undef HAVE_DECL_MEMFD_CREATE + +/* Define to 1 if you have the declaration of `renameat2', and to 0 if you + don't. */ +#undef HAVE_DECL_RENAMEAT2 + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H diff -Nru flatpak-builder-0.10.6/configure flatpak-builder-0.10.9/configure --- flatpak-builder-0.10.6/configure 2017-12-15 13:26:50.000000000 +0000 +++ flatpak-builder-0.10.9/configure 2018-02-19 09:37:56.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for flatpak-builder 0.10.6. +# Generated by GNU Autoconf 2.69 for flatpak-builder 0.10.9. # # Report bugs to . # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='flatpak-builder' PACKAGE_TARNAME='flatpak-builder' -PACKAGE_VERSION='0.10.6' -PACKAGE_STRING='flatpak-builder 0.10.6' +PACKAGE_VERSION='0.10.9' +PACKAGE_STRING='flatpak-builder 0.10.9' PACKAGE_BUGREPORT='https://github.com/flatpak/flatpak-builder/issues' PACKAGE_URL='http://flatpak.org/' @@ -809,6 +809,8 @@ ac_user_opts=' enable_option_checking enable_largefile +enable_otmpfile +enable_wrpseudo_compat enable_static enable_shared with_pic @@ -1394,7 +1396,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures flatpak-builder 0.10.6 to adapt to many kinds of systems. +\`configure' configures flatpak-builder 0.10.9 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1464,7 +1466,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of flatpak-builder 0.10.6:";; + short | recursive ) echo "Configuration of flatpak-builder 0.10.9:";; esac cat <<\_ACEOF @@ -1473,6 +1475,10 @@ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-largefile omit support for large files + --disable-otmpfile Disable use of O_TMPFILE [default=no] + --enable-wrpseudo-compat + Disable use syscall() and filesystem calls to for + compatibility with wrpseudo [default=no] --enable-static[=PKGS] build static libraries [default=no] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-fast-install[=PKGS] @@ -1612,7 +1618,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -flatpak-builder configure 0.10.6 +flatpak-builder configure 0.10.9 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1865,6 +1871,52 @@ } # ac_fn_c_check_header_compile +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. @@ -1981,7 +2033,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by flatpak-builder $as_me 0.10.6, which was +It was created by flatpak-builder $as_me 0.10.9, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3875,6 +3927,102 @@ fi +ac_fn_c_check_decl "$LINENO" "renameat2" "ac_cv_have_decl_renameat2" " +#include +#include +#include +#include +#include +#include +#include +#include + +" +if test "x$ac_cv_have_decl_renameat2" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_RENAMEAT2 $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "memfd_create" "ac_cv_have_decl_memfd_create" " +#include +#include +#include +#include +#include +#include +#include +#include + +" +if test "x$ac_cv_have_decl_memfd_create" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_MEMFD_CREATE $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "copy_file_range" "ac_cv_have_decl_copy_file_range" " +#include +#include +#include +#include +#include +#include +#include +#include + +" +if test "x$ac_cv_have_decl_copy_file_range" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_COPY_FILE_RANGE $ac_have_decl +_ACEOF + + +# Check whether --enable-otmpfile was given. +if test "${enable_otmpfile+set}" = set; then : + enableval=$enable_otmpfile; +else + enable_otmpfile=yes +fi + +if test $enable_otmpfile = yes; then : + +else + + +$as_echo "#define DISABLE_OTMPFILE 1" >>confdefs.h + +fi + +# Check whether --enable-wrpseudo-compat was given. +if test "${enable_wrpseudo_compat+set}" = set; then : + enableval=$enable_wrpseudo_compat; +else + enable_wrpseudo_compat=no +fi + +if test $enable_wrpseudo_compat = no; then : + +else + + +$as_echo "#define ENABLE_WRPSEUDO_COMPAT 1" >>confdefs.h + +fi + + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -12809,7 +12957,7 @@ # Define the identity of the package. PACKAGE='flatpak-builder' - VERSION='0.10.6' + VERSION='0.10.9' # Some tools Automake needs. @@ -16533,7 +16681,7 @@ fi -FLATPAK_BUILDER_VERSION=0.10.6 +FLATPAK_BUILDER_VERSION=0.10.9 ac_config_files="$ac_config_files Makefile doc/Makefile doc/flatpak-builder-docs.xml" @@ -17096,7 +17244,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by flatpak-builder $as_me 0.10.6, which was +This file was extended by flatpak-builder $as_me 0.10.9, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -17163,7 +17311,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -flatpak-builder config.status 0.10.6 +flatpak-builder config.status 0.10.9 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -Nru flatpak-builder-0.10.6/configure.ac flatpak-builder-0.10.9/configure.ac --- flatpak-builder-0.10.6/configure.ac 2017-12-15 13:26:32.000000000 +0000 +++ flatpak-builder-0.10.9/configure.ac 2018-02-19 09:29:25.000000000 +0000 @@ -15,7 +15,7 @@ m4_define([flatpak_builder_major_version], [0]) m4_define([flatpak_builder_minor_version], [10]) -m4_define([flatpak_builder_micro_version], [6]) +m4_define([flatpak_builder_micro_version], [9]) m4_define([flatpak_builder_version], [flatpak_builder_major_version.flatpak_builder_minor_version.flatpak_builder_micro_version]) @@ -31,6 +31,7 @@ AC_USE_SYSTEM_EXTENSIONS AC_SYS_LARGEFILE +LIBGLNX_CONFIGURE AC_PROG_CC AM_PROG_CC_C_O diff -Nru flatpak-builder-0.10.6/debian/changelog flatpak-builder-0.10.9/debian/changelog --- flatpak-builder-0.10.6/debian/changelog 2017-12-30 02:33:14.000000000 +0000 +++ flatpak-builder-0.10.9/debian/changelog 2018-03-14 10:24:44.000000000 +0000 @@ -1,9 +1,63 @@ -flatpak-builder (0.10.6-1ubuntu1~ppa1) artful; urgency=medium +flatpak-builder (0.10.9-1~bpo9+1ubuntu1~ppa1) artful; urgency=medium - * Build for Artful. - * Remove Rules-Requires-Root. + * Buil for Artful. - -- Ikuya Awashiro Sat, 30 Dec 2017 11:33:14 +0900 + -- Ikuya Awashiro Wed, 14 Mar 2018 19:24:44 +0900 + +flatpak-builder (0.10.9-1~bpo9+1) stretch-backports; urgency=medium + + * Rebuild for stretch-backports. + - debian/gbp.conf: Adjust for this branch + + -- Simon McVittie Mon, 19 Feb 2018 10:18:28 +0000 + +flatpak-builder (0.10.9-1) unstable; urgency=medium + + * New upstream release + - Includes patch from Aurelien Jarno to fix FTBFS with glibc 2.27 + (Closes: #890722) + + -- Simon McVittie Mon, 19 Feb 2018 09:56:47 +0000 + +flatpak-builder (0.10.8-1~bpo9+1) stretch-backports; urgency=medium + + * Rebuild for stretch-backports. + - debian/gbp.conf: Adjust for this branch + + -- Simon McVittie Fri, 16 Feb 2018 15:54:07 +0000 + +flatpak-builder (0.10.8-1) unstable; urgency=medium + + * New upstream release + + -- Simon McVittie Fri, 16 Feb 2018 12:41:32 +0000 + +flatpak-builder (0.10.7-1) unstable; urgency=medium + + * New upstream release + + -- Simon McVittie Wed, 14 Feb 2018 18:25:05 +0000 + +flatpak-builder (0.10.6-2~bpo9+1) stretch-backports; urgency=medium + + * Rebuild for stretch-backports. + - debian/gbp.conf: Adjust for this branch + + -- Simon McVittie Thu, 18 Jan 2018 07:42:45 +0000 + +flatpak-builder (0.10.6-2) unstable; urgency=medium + + * Set Vcs-* to salsa.debian.org + * Standards-Version: 4.1.3 (no changes required) + + -- Simon McVittie Wed, 17 Jan 2018 14:27:22 +0000 + +flatpak-builder (0.10.6-1~bpo9+1) stretch-backports; urgency=medium + + * Rebuild for stretch-backports. + - debian/gbp.conf: Adjust for this branch + + -- Simon McVittie Tue, 02 Jan 2018 16:45:45 +0000 flatpak-builder (0.10.6-1) unstable; urgency=medium @@ -13,6 +67,13 @@ -- Simon McVittie Fri, 15 Dec 2017 15:34:20 +0000 +flatpak-builder (0.10.5-1~bpo9+1) stretch-backports; urgency=medium + + * Rebuild for stretch-backports. + - debian/gbp.conf: Adjust for this branch + + -- Simon McVittie Mon, 27 Nov 2017 10:02:51 +0000 + flatpak-builder (0.10.5-1) unstable; urgency=medium * New upstream release @@ -20,12 +81,26 @@ -- Simon McVittie Mon, 27 Nov 2017 09:14:05 +0000 +flatpak-builder (0.10.4-1~bpo9+1) stretch-backports; urgency=medium + + * Rebuild for stretch-backports. + - debian/gbp.conf: Adjust for this branch + + -- Simon McVittie Thu, 23 Nov 2017 11:49:46 +0000 + flatpak-builder (0.10.4-1) unstable; urgency=medium * New upstream release -- Simon McVittie Mon, 06 Nov 2017 17:14:30 +0000 +flatpak-builder (0.10.3-1~bpo9+1) stretch-backports; urgency=medium + + * Rebuild for stretch-backports. + - debian/gbp.conf: Adjust for this branch + + -- Simon McVittie Wed, 01 Nov 2017 12:36:45 +0000 + flatpak-builder (0.10.3-1) unstable; urgency=medium * New upstream release @@ -38,6 +113,13 @@ -- Simon McVittie Tue, 31 Oct 2017 14:03:31 +0000 +flatpak-builder (0.10.1-1~bpo9+1) stretch-backports; urgency=medium + + * Rebuild for stretch-backports. + - debian/gbp.conf: Adjust for this branch + + -- Simon McVittie Fri, 27 Oct 2017 12:55:54 +0100 + flatpak-builder (0.10.1-1) unstable; urgency=medium * New upstream release @@ -57,6 +139,13 @@ -- Simon McVittie Thu, 26 Oct 2017 12:41:56 +0100 +flatpak-builder (0.9.99-1~bpo9+1) stretch-backports; urgency=medium + + * Rebuild for stretch-backports. + - debian/gbp.conf: Adjust for this branch + + -- Simon McVittie Mon, 09 Oct 2017 15:19:35 +0100 + flatpak-builder (0.9.99-1) unstable; urgency=medium * New upstream release @@ -69,6 +158,13 @@ -- Simon McVittie Mon, 09 Oct 2017 14:17:02 +0100 +flatpak-builder (0.9.98-1~bpo9+1) stretch-backports; urgency=medium + + * Rebuild for stretch-backports + - debian/gbp.conf: Adjust for this branch + + -- Simon McVittie Sun, 01 Oct 2017 12:16:57 +0100 + flatpak-builder (0.9.98-1) unstable; urgency=medium * New upstream release diff -Nru flatpak-builder-0.10.6/debian/control flatpak-builder-0.10.9/debian/control --- flatpak-builder-0.10.6/debian/control 2017-12-30 02:33:09.000000000 +0000 +++ flatpak-builder-0.10.9/debian/control 2018-02-19 10:18:28.000000000 +0000 @@ -37,10 +37,11 @@ shared-mime-info , xmlto , xsltproc , -Standards-Version: 4.1.2 +Standards-Version: 4.1.3 Homepage: http://flatpak.org/ -Vcs-Git: https://anonscm.debian.org/git/collab-maint/flatpak-builder.git -Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/flatpak-builder.git +Vcs-Git: https://salsa.debian.org/debian/flatpak-builder.git +Vcs-Browser: https://salsa.debian.org/debian/flatpak-builder +Rules-Requires-Root: no Package: flatpak-builder Architecture: linux-any diff -Nru flatpak-builder-0.10.6/debian/gbp.conf flatpak-builder-0.10.9/debian/gbp.conf --- flatpak-builder-0.10.6/debian/gbp.conf 2017-12-15 15:34:20.000000000 +0000 +++ flatpak-builder-0.10.9/debian/gbp.conf 2018-02-19 10:18:28.000000000 +0000 @@ -1,7 +1,7 @@ [DEFAULT] pristine-tar = True compression = xz -debian-branch = debian/master +debian-branch = debian/stretch-backports upstream-branch = upstream/latest patch-numbers = False upstream-vcs-tag = %(version)s diff -Nru flatpak-builder-0.10.6/doc/flatpak-manifest.xml flatpak-builder-0.10.9/doc/flatpak-manifest.xml --- flatpak-builder-0.10.6/doc/flatpak-manifest.xml 2017-12-11 10:04:15.000000000 +0000 +++ flatpak-builder-0.10.9/doc/flatpak-manifest.xml 2018-01-11 08:37:55.000000000 +0000 @@ -247,19 +247,19 @@ (string) - This is set in the environment variable CFLAGS during the build. Multiple specifications of this (in e.g. per-arch area) are concatinated with spaces inbetween. + This is set in the environment variable CFLAGS during the build. Multiple specifications of this (in e.g. per-arch area) are concatenated, separated by spaces. (string) - This is set in the environment variable CPPFLAGS during the build. Multiple specifications of this (in e.g. per-arch area) are concatinated with spaces inbetween. + This is set in the environment variable CPPFLAGS during the build. Multiple specifications of this (in e.g. per-arch area) are concatenated, separated by spaces. (string) - This is set in the environment variable CXXFLAGS during the build. Multiple specifications of this (in e.g. per-arch area) are concatinated with spaces inbetween. + This is set in the environment variable CXXFLAGS during the build. Multiple specifications of this (in e.g. per-arch area) are concatenated, separated by spaces. (string) - This is set in the environment variable LDFLAGS during the build. Multiple specifications of this (in e.g. per-arch area) are concatinated with spaces inbetween. + This is set in the environment variable LDFLAGS during the build. Multiple specifications of this (in e.g. per-arch area) are concatenated, separated by spaces. (string) diff -Nru flatpak-builder-0.10.6/doc/Makefile.in flatpak-builder-0.10.9/doc/Makefile.in --- flatpak-builder-0.10.6/doc/Makefile.in 2017-12-15 13:26:50.000000000 +0000 +++ flatpak-builder-0.10.9/doc/Makefile.in 2018-02-19 09:37:56.000000000 +0000 @@ -91,16 +91,16 @@ @DOCBOOK_DOCS_ENABLED_TRUE@am__append_1 = flatpak-builder-docs.html subdir = doc ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibtests.m4 \ - $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/libglnx/libglnx.m4 \ + $(top_srcdir)/m4/attributes.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/glibtests.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) diff -Nru flatpak-builder-0.10.6/libglnx/glnx-console.c flatpak-builder-0.10.9/libglnx/glnx-console.c --- flatpak-builder-0.10.6/libglnx/glnx-console.c 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-console.c 2018-02-14 17:35:37.000000000 +0000 @@ -29,12 +29,25 @@ #include #include -static char *current_text = NULL; -static gint current_percent = -1; +/* For people with widescreen monitors and maximized terminals, it looks pretty + * bad to have an enormous progress bar. For much the same reason as web pages + * tend to have a maximum width; + * https://ux.stackexchange.com/questions/48982/suggest-good-max-width-for-fluid-width-design + */ +#define MAX_PROGRESSBAR_COLUMNS 20 + +/* Max updates output per second. On a tty there's no point to rendering + * extremely fast; and for a non-tty we're probably in a Jenkins job + * or whatever and having percentages spam multiple lines there is annoying. + */ +#define MAX_TTY_UPDATE_HZ (5) +#define MAX_NONTTY_UPDATE_HZ (1) + static gboolean locked; +static guint64 last_update_ms; /* monotonic time in millis we last updated */ -static gboolean -stdout_is_tty (void) +gboolean +glnx_stdout_is_tty (void) { static gsize initialized = 0; static gboolean stdout_is_tty_v; @@ -143,12 +156,10 @@ g_return_if_fail (!locked); g_return_if_fail (!console->locked); - console->is_tty = stdout_is_tty (); + console->is_tty = glnx_stdout_is_tty (); locked = console->locked = TRUE; - current_percent = 0; - if (console->is_tty) { if (g_once_init_enter (&sigwinch_initialized)) @@ -181,6 +192,26 @@ text_percent_internal (const char *text, int percentage) { + /* Check whether we're trying to render too fast; unless percentage is 100, in + * which case we assume this is the last call, so we always render it. + */ + const guint64 current_ms = g_get_monotonic_time () / 1000; + if (percentage != 100) + { + const guint64 diff_ms = current_ms - last_update_ms; + if (glnx_stdout_is_tty ()) + { + if (diff_ms < (1000/MAX_TTY_UPDATE_HZ)) + return; + } + else + { + if (diff_ms < (1000/MAX_NONTTY_UPDATE_HZ)) + return; + } + } + last_update_ms = current_ms; + static const char equals[] = "===================="; const guint n_equals = sizeof (equals) - 1; static const char spaces[] = " "; @@ -193,11 +224,7 @@ const guint input_textlen = text ? strlen (text) : 0; - if (percentage == current_percent - && g_strcmp0 (text, current_text) == 0) - return; - - if (!stdout_is_tty ()) + if (!glnx_stdout_is_tty ()) { if (text) fprintf (stdout, "%s", text); @@ -232,7 +259,7 @@ else { const guint textlen = MIN (input_textlen, ncolumns - bar_min); - const guint barlen = ncolumns - (textlen + 1);; + const guint barlen = MIN (MAX_PROGRESSBAR_COLUMNS, ncolumns - (textlen + 1)); if (textlen > 0) { @@ -245,7 +272,7 @@ const guint textpercent_len = 5; const guint bar_internal_len = barlen - nbraces - textpercent_len; const guint eqlen = bar_internal_len * (percentage / 100.0); - const guint spacelen = bar_internal_len - eqlen; + const guint spacelen = bar_internal_len - eqlen; fputc ('[', stdout); printpad (equals, n_equals, eqlen); @@ -280,6 +307,32 @@ text_percent_internal (text, percentage); } +/** + * glnx_console_progress_n_items: + * @text: Show this text before the progress bar + * @current: An integer for how many items have been processed + * @total: An integer for how many items there are total + * + * On a tty, print to the console @text followed by [@current/@total], + * then an ASCII art progress bar, like glnx_console_progress_text_percent(). + * + * You must have called glnx_console_lock() before invoking this + * function. + */ +void +glnx_console_progress_n_items (const char *text, + guint current, + guint total) +{ + g_return_if_fail (current <= total); + g_return_if_fail (total > 0); + + g_autofree char *newtext = g_strdup_printf ("%s (%u/%u)", text, current, total); + /* Special case current == total to ensure we end at 100% */ + int percentage = (current == total) ? 100 : (((double)current) / total * 100); + glnx_console_progress_text_percent (newtext, percentage); +} + void glnx_console_text (const char *text) { @@ -299,9 +352,6 @@ g_return_if_fail (locked); g_return_if_fail (console->locked); - current_percent = -1; - g_clear_pointer (¤t_text, g_free); - if (console->is_tty) fputc ('\n', stdout); diff -Nru flatpak-builder-0.10.6/libglnx/glnx-console.h flatpak-builder-0.10.9/libglnx/glnx-console.h --- flatpak-builder-0.10.6/libglnx/glnx-console.h 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-console.h 2018-02-14 17:35:37.000000000 +0000 @@ -31,12 +31,18 @@ typedef struct GLnxConsoleRef GLnxConsoleRef; +gboolean glnx_stdout_is_tty (void); + void glnx_console_lock (GLnxConsoleRef *ref); void glnx_console_text (const char *text); void glnx_console_progress_text_percent (const char *text, - guint percentage); + guint percentage); + +void glnx_console_progress_n_items (const char *text, + guint current, + guint total); void glnx_console_unlock (GLnxConsoleRef *ref); diff -Nru flatpak-builder-0.10.6/libglnx/glnx-dirfd.c flatpak-builder-0.10.9/libglnx/glnx-dirfd.c --- flatpak-builder-0.10.6/libglnx/glnx-dirfd.c 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-dirfd.c 2018-02-14 17:35:37.000000000 +0000 @@ -23,8 +23,10 @@ #include #include +#include #include #include +#include /** * glnx_opendirat_with_errno: @@ -97,7 +99,7 @@ GLnxDirFdIterator *out_dfd_iter, GError **error) { - glnx_fd_close int fd = -1; + glnx_autofd int fd = -1; if (!glnx_opendirat (dfd, path, follow, &fd, error)) return FALSE; @@ -188,23 +190,20 @@ GCancellable *cancellable, GError **error) { - struct dirent *ret_dent; - g_return_val_if_fail (out_dent, FALSE); if (!glnx_dirfd_iterator_next_dent (dfd_iter, out_dent, cancellable, error)) return FALSE; - ret_dent = *out_dent; - + struct dirent *ret_dent = *out_dent; if (ret_dent) { if (ret_dent->d_type == DT_UNKNOWN) { struct stat stbuf; - if (TEMP_FAILURE_RETRY (fstatat (dfd_iter->fd, ret_dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW)) != 0) - return glnx_throw_errno (error); + if (!glnx_fstatat (dfd_iter->fd, ret_dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return FALSE; ret_dent->d_type = IFTODT (stbuf.st_mode); } } @@ -263,47 +262,52 @@ void glnx_gen_temp_name (gchar *tmpl) { - size_t len; - char *XXXXXX; - int i; - static const char letters[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - static const int NLETTERS = sizeof (letters) - 1; - g_return_if_fail (tmpl != NULL); - len = strlen (tmpl); + const size_t len = strlen (tmpl); g_return_if_fail (len >= 6); - XXXXXX = tmpl + (len - 6); + static const char letters[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + static const int NLETTERS = sizeof (letters) - 1; - for (i = 0; i < 6; i++) + char *XXXXXX = tmpl + (len - 6); + for (int i = 0; i < 6; i++) XXXXXX[i] = letters[g_random_int_range(0, NLETTERS)]; } /** * glnx_mkdtempat: * @dfd: Directory fd - * @tmpl: (type filename): template directory name, last 6 characters will be replaced - * @mode: permissions to create the temporary directory with + * @tmpl: (type filename): Initial template directory name, last 6 characters will be replaced + * @mode: permissions with which to create the temporary directory + * @out_tmpdir: (out caller-allocates): Initialized tempdir structure * @error: Error * - * Similar to g_mkdtemp_full, but using openat. + * Somewhat similar to g_mkdtemp_full(), but fd-relative, and returns a + * structure that uses autocleanups. Note that the supplied @dfd lifetime + * must match or exceed that of @out_tmpdir in order to remove the directory. */ gboolean -glnx_mkdtempat (int dfd, - gchar *tmpl, - int mode, - GError **error) +glnx_mkdtempat (int dfd, const char *tmpl, int mode, + GLnxTmpDir *out_tmpdir, GError **error) { - int count; + g_return_val_if_fail (tmpl != NULL, FALSE); + g_return_val_if_fail (out_tmpdir != NULL, FALSE); + g_return_val_if_fail (!out_tmpdir->initialized, FALSE); - g_return_val_if_fail (tmpl != NULL, -1); + dfd = glnx_dirfd_canonicalize (dfd); - for (count = 0; count < 100; count++) + g_autofree char *path = g_strdup (tmpl); + for (int count = 0; count < 100; count++) { - glnx_gen_temp_name (tmpl); + glnx_gen_temp_name (path); - if (mkdirat (dfd, tmpl, mode) == -1) + /* Ideally we could use openat(O_DIRECTORY | O_CREAT | O_EXCL) here + * to create and open the directory atomically, but that’s not supported by + * current kernel versions: http://www.openwall.com/lists/oss-security/2014/11/26/14 + * (Tested on kernel 4.10.10-200.fc25.x86_64). For the moment, accept a + * TOCTTOU race here. */ + if (mkdirat (dfd, path, mode) == -1) { if (errno == EEXIST) continue; @@ -314,77 +318,108 @@ return glnx_throw_errno_prefix (error, "mkdirat"); } + /* And open it */ + glnx_autofd int ret_dfd = -1; + if (!glnx_opendirat (dfd, path, FALSE, &ret_dfd, error)) + { + /* If we fail to open, let's try to clean up */ + (void)unlinkat (dfd, path, AT_REMOVEDIR); + return FALSE; + } + + /* Return the initialized directory struct */ + out_tmpdir->initialized = TRUE; + out_tmpdir->src_dfd = dfd; /* referenced; see above docs */ + out_tmpdir->fd = glnx_steal_fd (&ret_dfd); + out_tmpdir->path = g_steal_pointer (&path); return TRUE; } + /* Failure */ g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS, - "mkstempat ran out of combinations to try."); + "glnx_mkdtempat ran out of combinations to try"); return FALSE; } /** - * glnx_mkdtempat_open: - * @dfd: Directory FD - * @tmpl: (type filename): template directory name, last 6 characters will be replaced + * glnx_mkdtemp: + * @tmpl: (type filename): Source template directory name, last 6 characters will be replaced * @mode: permissions to create the temporary directory with - * @out_dfd: (out caller-allocates): Return location for an FD for the new - * temporary directory, or `-1` on error + * @out_tmpdir: (out caller-allocates): Return location for tmpdir data * @error: Return location for a #GError, or %NULL * - * Similar to glnx_mkdtempat(), except it will open the resulting temporary - * directory and return a directory FD to it. + * Similar to glnx_mkdtempat(), but will use g_get_tmp_dir() as the parent + * directory to @tmpl. * * Returns: %TRUE on success, %FALSE otherwise * Since: UNRELEASED */ gboolean -glnx_mkdtempat_open (int dfd, - gchar *tmpl, - int mode, - int *out_dfd, - GError **error) -{ - /* FIXME: Ideally we could use openat(O_DIRECTORY | O_CREAT | O_EXCL) here - * to create and open the directory atomically, but that’s not supported by - * current kernel versions: http://www.openwall.com/lists/oss-security/2014/11/26/14 - * (Tested on kernel 4.10.10-200.fc25.x86_64). For the moment, accept a - * TOCTTOU race here. */ - *out_dfd = -1; - - if (!glnx_mkdtempat (dfd, tmpl, mode, error)) - return FALSE; - - return glnx_opendirat (dfd, tmpl, FALSE, out_dfd, error); +glnx_mkdtemp (const gchar *tmpl, + int mode, + GLnxTmpDir *out_tmpdir, + GError **error) +{ + g_autofree char *path = g_build_filename (g_get_tmp_dir (), tmpl, NULL); + return glnx_mkdtempat (AT_FDCWD, path, mode, + out_tmpdir, error); +} + +static gboolean +_glnx_tmpdir_free (GLnxTmpDir *tmpd, + gboolean delete_dir, + GCancellable *cancellable, + GError **error) +{ + /* Support being passed NULL so we work nicely in a GPtrArray */ + if (!(tmpd && tmpd->initialized)) + return TRUE; + g_assert_cmpint (tmpd->fd, !=, -1); + glnx_close_fd (&tmpd->fd); + g_assert (tmpd->path); + g_assert_cmpint (tmpd->src_dfd, !=, -1); + g_autofree char *path = tmpd->path; /* Take ownership */ + tmpd->initialized = FALSE; + if (delete_dir) + { + if (!glnx_shutil_rm_rf_at (tmpd->src_dfd, path, cancellable, error)) + return FALSE; + } + return TRUE; } /** - * glnx_mkdtempat_open_in_system: - * @tmpl: (type filename): template directory name, last 6 characters will be replaced - * @mode: permissions to create the temporary directory with - * @out_dfd: (out caller-allocates): Return location for an FD for the new - * temporary directory, or `-1` on error - * @error: Return location for a #GError, or %NULL + * glnx_tmpdir_delete: + * @tmpf: Temporary dir + * @cancellable: Cancellable + * @error: Error * - * Similar to glnx_mkdtempat_open(), except it will use the system temporary - * directory (from g_get_tmp_dir()) as the parent directory to @tmpl. + * Deallocate a tmpdir, closing the fd and recursively deleting the path. This + * is normally called indirectly via glnx_tmpdir_cleanup() by the autocleanup + * attribute, but you can also invoke this directly. * - * Returns: %TRUE on success, %FALSE otherwise - * Since: UNRELEASED + * If an error occurs while deleting the filesystem path, @tmpf will still have + * been deallocated and should not be reused. + * + * See also `glnx_tmpdir_unset` to avoid deleting the path. */ gboolean -glnx_mkdtempat_open_in_system (gchar *tmpl, - int mode, - int *out_dfd, - GError **error) +glnx_tmpdir_delete (GLnxTmpDir *tmpf, GCancellable *cancellable, GError **error) { - glnx_fd_close int tmp_dfd = -1; - - *out_dfd = -1; - - if (!glnx_opendirat (-1, g_get_tmp_dir (), TRUE, &tmp_dfd, error)) - return FALSE; - - return glnx_mkdtempat_open (tmp_dfd, tmpl, mode, out_dfd, error); + return _glnx_tmpdir_free (tmpf, TRUE, cancellable, error); } - +/** + * glnx_tmpdir_unset: + * @tmpf: Temporary dir + * @cancellable: Cancellable + * @error: Error + * + * Deallocate a tmpdir, but do not delete the filesystem path. See also + * `glnx_tmpdir_delete()`. + */ +void +glnx_tmpdir_unset (GLnxTmpDir *tmpf) +{ + (void) _glnx_tmpdir_free (tmpf, FALSE, NULL, NULL); +} diff -Nru flatpak-builder-0.10.6/libglnx/glnx-dirfd.h flatpak-builder-0.10.9/libglnx/glnx-dirfd.h --- flatpak-builder-0.10.6/libglnx/glnx-dirfd.h 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-dirfd.h 2018-02-14 17:35:37.000000000 +0000 @@ -92,7 +92,7 @@ * @mode: Mode * @error: Return location for a #GError, or %NULL * - * Wrapper around mkdirat() which ignores adds #GError support, ensures that + * Wrapper around mkdirat() which adds #GError support, ensures that * it retries on %EINTR, and also ignores `EEXIST`. * * See also `glnx_shutil_mkdir_p_at()` for recursive handling. @@ -113,20 +113,25 @@ return TRUE; } -gboolean glnx_mkdtempat (int dfd, - gchar *tmpl, - int mode, - GError **error); +typedef struct { + gboolean initialized; + int src_dfd; + int fd; + char *path; +} GLnxTmpDir; +gboolean glnx_tmpdir_delete (GLnxTmpDir *tmpf, GCancellable *cancellable, GError **error); +void glnx_tmpdir_unset (GLnxTmpDir *tmpf); +static inline void +glnx_tmpdir_cleanup (GLnxTmpDir *tmpf) +{ + (void)glnx_tmpdir_delete (tmpf, NULL, NULL); +} +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxTmpDir, glnx_tmpdir_cleanup) -gboolean glnx_mkdtempat_open (int dfd, - gchar *tmpl, - int mode, - int *out_dfd, - GError **error); +gboolean glnx_mkdtempat (int dfd, const char *tmpl, int mode, + GLnxTmpDir *out_tmpdir, GError **error); -gboolean glnx_mkdtempat_open_in_system (gchar *tmpl, - int mode, - int *out_dfd, - GError **error); +gboolean glnx_mkdtemp (const char *tmpl, int mode, + GLnxTmpDir *out_tmpdir, GError **error); G_END_DECLS diff -Nru flatpak-builder-0.10.6/libglnx/glnx-errors.c flatpak-builder-0.10.9/libglnx/glnx-errors.c --- flatpak-builder-0.10.6/libglnx/glnx-errors.c 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-errors.c 2018-02-14 17:35:37.000000000 +0000 @@ -23,6 +23,32 @@ #include #include +/* Set @error with G_IO_ERROR/G_IO_ERROR_FAILED. + * + * This function returns %FALSE so it can be used conveniently in a single + * statement: + * + * ``` + * if (strcmp (foo, "somevalue") != 0) + * return glnx_throw (error, "key must be somevalue, not '%s'", foo); + * ``` + */ +gboolean +glnx_throw (GError **error, + const char *fmt, + ...) +{ + if (error == NULL) + return FALSE; + + va_list args; + va_start (args, fmt); + GError *new = g_error_new_valist (G_IO_ERROR, G_IO_ERROR_FAILED, fmt, args); + va_end (args); + g_propagate_error (error, g_steal_pointer (&new)); + return FALSE; +} + void glnx_real_set_prefix_error_va (GError *error, const char *format, @@ -39,6 +65,30 @@ error->message = g_string_free (g_steal_pointer (&buf), FALSE); } +/* Prepend to @error's message by `$prefix: ` where `$prefix` is computed via + * printf @fmt. Returns %FALSE so it can be used conveniently in a single + * statement: + * + * ``` + * if (!function_that_fails (s, error)) + * return glnx_throw_prefix (error, "while handling '%s'", s); + * ``` + * */ +gboolean +glnx_prefix_error (GError **error, + const char *fmt, + ...) +{ + if (error == NULL) + return FALSE; + + va_list args; + va_start (args, fmt); + glnx_real_set_prefix_error_va (*error, fmt, args); + va_end (args); + return FALSE; +} + void glnx_real_set_prefix_error_from_errno_va (GError **error, gint errsv, @@ -54,3 +104,28 @@ g_strerror (errsv)); glnx_real_set_prefix_error_va (*error, format, args); } + +/* Set @error using the value of `$prefix: g_strerror (errno)` where `$prefix` + * is computed via printf @fmt. + * + * This function returns %FALSE so it can be used conveniently in a single + * statement: + * + * ``` + * return glnx_throw_errno_prefix (error, "unlinking %s", pathname); + * ``` + */ +gboolean +glnx_throw_errno_prefix (GError **error, + const char *fmt, + ...) +{ + int errsv = errno; + va_list args; + va_start (args, fmt); + glnx_real_set_prefix_error_from_errno_va (error, errsv, fmt, args); + va_end (args); + /* See comment in glnx_throw_errno() about preserving errno */ + errno = errsv; + return FALSE; +} diff -Nru flatpak-builder-0.10.6/libglnx/glnx-errors.h flatpak-builder-0.10.9/libglnx/glnx-errors.h --- flatpak-builder-0.10.6/libglnx/glnx-errors.h 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-errors.h 2018-02-14 17:35:37.000000000 +0000 @@ -25,29 +25,7 @@ G_BEGIN_DECLS -/* Set @error with G_IO_ERROR/G_IO_ERROR_FAILED. - * - * This function returns %FALSE so it can be used conveniently in a single - * statement: - * - * ``` - * if (strcmp (foo, "somevalue") != 0) - * return glnx_throw (error, "key must be somevalue, not '%s'", foo); - * ``` - */ -static inline gboolean G_GNUC_PRINTF (2,3) -glnx_throw (GError **error, const char *fmt, ...) -{ - if (error == NULL) - return FALSE; - - va_list args; - va_start (args, fmt); - GError *new = g_error_new_valist (G_IO_ERROR, G_IO_ERROR_FAILED, fmt, args); - va_end (args); - g_propagate_error (error, g_steal_pointer (&new)); - return FALSE; -} +gboolean glnx_throw (GError **error, const char *fmt, ...) G_GNUC_PRINTF (2,3); /* Like `glnx_throw ()`, but returns %NULL. */ #define glnx_null_throw(error, args...) \ @@ -58,27 +36,7 @@ const char *format, va_list args) G_GNUC_PRINTF (2,0); -/* Prepend to @error's message by `$prefix: ` where `$prefix` is computed via - * printf @fmt. Returns %FALSE so it can be used conveniently in a single - * statement: - * - * ``` - * if (!function_that_fails (s, error)) - * return glnx_throw_prefix (error, "while handling '%s'", s); - * ``` - * */ -static inline gboolean G_GNUC_PRINTF (2,3) -glnx_prefix_error (GError **error, const char *fmt, ...) -{ - if (error == NULL) - return FALSE; - - va_list args; - va_start (args, fmt); - glnx_real_set_prefix_error_va (*error, fmt, args); - va_end (args); - return FALSE; -} +gboolean glnx_prefix_error (GError **error, const char *fmt, ...) G_GNUC_PRINTF (2,3); /* Like `glnx_prefix_error ()`, but returns %NULL. */ #define glnx_prefix_error_null(error, args...) \ @@ -155,28 +113,7 @@ const char *format, va_list args) G_GNUC_PRINTF (3,0); -/* Set @error using the value of `$prefix: g_strerror (errno)` where `$prefix` - * is computed via printf @fmt. - * - * This function returns %FALSE so it can be used conveniently in a single - * statement: - * - * ``` - * return glnx_throw_errno_prefix (error, "unlinking %s", pathname); - * ``` - */ -static inline gboolean G_GNUC_PRINTF (2,3) -glnx_throw_errno_prefix (GError **error, const char *fmt, ...) -{ - int errsv = errno; - va_list args; - va_start (args, fmt); - glnx_real_set_prefix_error_from_errno_va (error, errsv, fmt, args); - va_end (args); - /* See comment above about preserving errno */ - errno = errsv; - return FALSE; -} +gboolean glnx_throw_errno_prefix (GError **error, const char *fmt, ...) G_GNUC_PRINTF (2,3); /* Like glnx_throw_errno_prefix(), but yields a NULL pointer. */ #define glnx_null_throw_errno_prefix(error, args...) \ diff -Nru flatpak-builder-0.10.6/libglnx/glnx-fdio.c flatpak-builder-0.10.9/libglnx/glnx-fdio.c --- flatpak-builder-0.10.6/libglnx/glnx-fdio.c 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-fdio.c 2018-02-14 17:35:37.000000000 +0000 @@ -112,7 +112,7 @@ return TRUE; } else - return glnx_throw_errno (error); + return glnx_throw_errno_prefix (error, "renameat"); } return TRUE; } @@ -141,7 +141,14 @@ #endif /* Fallback */ - { const char *old_tmp_name = glnx_strjoina (oldpath, ".XXXXXX"); + { char *old_tmp_name_buf = glnx_strjoina (oldpath, ".XXXXXX"); + /* This obviously isn't race-free, but doing better gets tricky, since if + * we're here the kernel isn't likely to support RENAME_NOREPLACE either. + * Anyways, upgrade the kernel. Failing that, avoid use of this function in + * shared subdirectories like /tmp. + */ + glnx_gen_temp_name (old_tmp_name_buf); + const char *old_tmp_name = old_tmp_name_buf; /* Move old out of the way */ if (renameat (olddirfd, oldpath, olddirfd, old_tmp_name) < 0) @@ -168,9 +175,7 @@ return; if (!tmpf->initialized) return; - if (tmpf->fd == -1) - return; - (void) close (tmpf->fd); + glnx_close_fd (&tmpf->fd); /* If ->path is set, we're likely aborting due to an error. Clean it up */ if (tmpf->path) { @@ -180,30 +185,17 @@ tmpf->initialized = FALSE; } -/* Allocate a temporary file, using Linux O_TMPFILE if available. The file mode - * will be 0600. - * - * The result will be stored in @out_tmpf, which is caller allocated - * so you can store it on the stack in common scenarios. - * - * The directory fd @dfd must live at least as long as the output @out_tmpf. - */ -gboolean -glnx_open_tmpfile_linkable_at (int dfd, - const char *subpath, - int flags, - GLnxTmpfile *out_tmpf, - GError **error) +static gboolean +open_tmpfile_core (int dfd, const char *subpath, + int flags, + GLnxTmpfile *out_tmpf, + GError **error) { + /* Picked this to match mkstemp() */ const guint mode = 0600; - glnx_fd_close int fd = -1; - int count; dfd = glnx_dirfd_canonicalize (dfd); - /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */ - g_return_val_if_fail ((flags & O_EXCL) == 0, FALSE); - /* Creates a temporary file, that shall be renamed to "target" * later. If possible, this uses O_TMPFILE – in which case * "ret_path" will be returned as NULL. If not possible a the @@ -211,33 +203,35 @@ * link_tmpfile() below to rename the result after writing the file * in full. */ #if defined(O_TMPFILE) && !defined(DISABLE_OTMPFILE) && !defined(ENABLE_WRPSEUDO_COMPAT) - fd = openat (dfd, subpath, O_TMPFILE|flags, mode); - if (fd == -1 && !(G_IN_SET(errno, ENOSYS, EISDIR, EOPNOTSUPP))) - return glnx_throw_errno_prefix (error, "open(O_TMPFILE)"); - if (fd != -1) - { - /* Workaround for https://sourceware.org/bugzilla/show_bug.cgi?id=17523 - * See also https://github.com/ostreedev/ostree/issues/991 - */ - if (fchmod (fd, mode) < 0) - return glnx_throw_errno_prefix (error, "fchmod"); - out_tmpf->initialized = TRUE; - out_tmpf->src_dfd = dfd; /* Copied; caller must keep open */ - out_tmpf->fd = glnx_steal_fd (&fd); - out_tmpf->path = NULL; - return TRUE; - } + { + glnx_autofd int fd = openat (dfd, subpath, O_TMPFILE|flags, mode); + if (fd == -1 && !(G_IN_SET(errno, ENOSYS, EISDIR, EOPNOTSUPP))) + return glnx_throw_errno_prefix (error, "open(O_TMPFILE)"); + if (fd != -1) + { + /* Workaround for https://sourceware.org/bugzilla/show_bug.cgi?id=17523 + * See also https://github.com/ostreedev/ostree/issues/991 + */ + if (fchmod (fd, mode) < 0) + return glnx_throw_errno_prefix (error, "fchmod"); + out_tmpf->initialized = TRUE; + out_tmpf->src_dfd = dfd; /* Copied; caller must keep open */ + out_tmpf->fd = glnx_steal_fd (&fd); + out_tmpf->path = NULL; + return TRUE; + } + } /* Fallthrough */ #endif + const guint count_max = 100; { g_autofree char *tmp = g_strconcat (subpath, "/tmp.XXXXXX", NULL); - const guint count_max = 100; - for (count = 0; count < count_max; count++) + for (int count = 0; count < count_max; count++) { glnx_gen_temp_name (tmp); - fd = openat (dfd, tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, mode); + glnx_autofd int fd = openat (dfd, tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, mode); if (fd < 0) { if (errno == EEXIST) @@ -256,10 +250,33 @@ } } g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS, - "Exhausted %u attempts to create temporary file", count); + "Exhausted %u attempts to create temporary file", count_max); return FALSE; } +/* Allocate a temporary file, using Linux O_TMPFILE if available. The file mode + * will be 0600. + * + * The result will be stored in @out_tmpf, which is caller allocated + * so you can store it on the stack in common scenarios. + * + * The directory fd @dfd must live at least as long as the output @out_tmpf. + */ +gboolean +glnx_open_tmpfile_linkable_at (int dfd, + const char *subpath, + int flags, + GLnxTmpfile *out_tmpf, + GError **error) +{ + /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE; + * it's used for glnx_open_anonymous_tmpfile(). + */ + g_return_val_if_fail ((flags & O_EXCL) == 0, FALSE); + + return open_tmpfile_core (dfd, subpath, flags, out_tmpf, error); +} + /* A variant of `glnx_open_tmpfile_linkable_at()` which doesn't support linking. * Useful for true temporary storage. The fd will be allocated in /var/tmp to * ensure maximum storage space. @@ -269,7 +286,8 @@ GLnxTmpfile *out_tmpf, GError **error) { - if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, "/var/tmp", flags, out_tmpf, error)) + /* Add in O_EXCL */ + if (!open_tmpfile_core (AT_FDCWD, "/var/tmp", flags | O_EXCL, out_tmpf, error)) return FALSE; if (out_tmpf->path) { @@ -342,9 +360,9 @@ char *dnbuf = strdupa (target); const char *dn = dirname (dnbuf); char *tmpname_buf = glnx_strjoina (dn, "/tmp.XXXXXX"); - guint count; - const guint count_max = 100; + const guint count_max = 100; + guint count; for (count = 0; count < count_max; count++) { glnx_gen_temp_name (tmpname_buf); @@ -428,8 +446,8 @@ const guint maxreadlen = 4096; struct stat stbuf; - if (TEMP_FAILURE_RETRY (fstat (fd, &stbuf)) < 0) - return glnx_null_throw_errno (error); + if (!glnx_fstat (fd, &stbuf, error)) + return FALSE; gsize buf_allocated; if (S_ISREG (stbuf.st_mode) && stbuf.st_size > 0) @@ -555,7 +573,7 @@ { dfd = glnx_dirfd_canonicalize (dfd); - glnx_fd_close int fd = -1; + glnx_autofd int fd = -1; if (!glnx_openat_rdonly (dfd, subpath, TRUE, &fd, error)) return NULL; @@ -585,19 +603,15 @@ GCancellable *cancellable, GError **error) { - size_t l = 100; - dfd = glnx_dirfd_canonicalize (dfd); + size_t l = 100; for (;;) { - g_autofree char *c = NULL; - ssize_t n; - - c = g_malloc (l); - n = TEMP_FAILURE_RETRY (readlinkat (dfd, subpath, c, l-1)); + g_autofree char *c = g_malloc (l); + ssize_t n = TEMP_FAILURE_RETRY (readlinkat (dfd, subpath, c, l-1)); if (n < 0) - return glnx_null_throw_errno (error); + return glnx_null_throw_errno_prefix (error, "readlinkat"); if ((size_t) n < l-1) { @@ -644,7 +658,7 @@ if (TEMP_FAILURE_RETRY (fchownat (dest_dfd, dest_subpath, src_stbuf->st_uid, src_stbuf->st_gid, AT_SYMLINK_NOFOLLOW)) != 0) - return glnx_throw_errno (error); + return glnx_throw_errno_prefix (error, "fchownat"); return TRUE; } @@ -665,18 +679,15 @@ int glnx_loop_write(int fd, const void *buf, size_t nbytes) { - const uint8_t *p = buf; - - g_return_val_if_fail(fd >= 0, -1); - g_return_val_if_fail(buf, -1); + g_return_val_if_fail (fd >= 0, -1); + g_return_val_if_fail (buf, -1); errno = 0; + const uint8_t *p = buf; while (nbytes > 0) { - ssize_t k; - - k = write(fd, p, nbytes); + ssize_t k = write(fd, p, nbytes); if (k < 0) { if (errno == EINTR) @@ -852,17 +863,22 @@ * glnx_file_copy_at: * @src_dfd: Source directory fd * @src_subpath: Subpath relative to @src_dfd + * @src_stbuf: (allow-none): Optional stat buffer for source; if a stat() has already been done * @dest_dfd: Target directory fd * @dest_subpath: Destination name * @copyflags: Flags * @cancellable: cancellable * @error: Error * - * Perform a full copy of the regular file or - * symbolic link from @src_subpath to @dest_subpath. - * - * If @src_subpath is anything other than a regular - * file or symbolic link, an error will be returned. + * Perform a full copy of the regular file or symbolic link from @src_subpath to + * @dest_subpath; if @src_subpath is anything other than a regular file or + * symbolic link, an error will be returned. + * + * If the source is a regular file and the destination exists as a symbolic + * link, the symbolic link will not be followed; rather the link itself will be + * replaced. Related to this: for regular files, when `GLNX_FILE_COPY_OVERWRITE` + * is specified, this function always uses `O_TMPFILE` (if available) and does a + * rename-into-place rather than `open(O_TRUNC)`. */ gboolean glnx_file_copy_at (int src_dfd, @@ -874,31 +890,23 @@ GCancellable *cancellable, GError **error) { - gboolean ret = FALSE; - int r; - int dest_open_flags; - struct timespec ts[2]; - glnx_fd_close int src_fd = -1; - glnx_fd_close int dest_fd = -1; - struct stat local_stbuf; - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) - goto out; - + /* Canonicalize dfds */ src_dfd = glnx_dirfd_canonicalize (src_dfd); dest_dfd = glnx_dirfd_canonicalize (dest_dfd); + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + /* Automatically do stat() if no stat buffer was supplied */ + struct stat local_stbuf; if (!src_stbuf) { - if (fstatat (src_dfd, src_subpath, &local_stbuf, AT_SYMLINK_NOFOLLOW) != 0) - { - glnx_set_error_from_errno (error); - goto out; - } + if (!glnx_fstatat (src_dfd, src_subpath, &local_stbuf, AT_SYMLINK_NOFOLLOW, error)) + return FALSE; src_stbuf = &local_stbuf; } + /* For symlinks, defer entirely to copy_symlink_at() */ if (S_ISLNK (src_stbuf->st_mode)) { return copy_symlink_at (src_dfd, src_subpath, src_stbuf, @@ -910,47 +918,31 @@ { g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Cannot copy non-regular/non-symlink file: %s", src_subpath); - goto out; + return FALSE; } - if (!glnx_openat_rdonly (src_dfd, src_subpath, FALSE, &src_fd, error)) - goto out; - - dest_open_flags = O_WRONLY | O_CREAT | O_CLOEXEC | O_NOCTTY; - if (!(copyflags & GLNX_FILE_COPY_OVERWRITE)) - dest_open_flags |= O_EXCL; - else - dest_open_flags |= O_TRUNC; - - dest_fd = TEMP_FAILURE_RETRY (openat (dest_dfd, dest_subpath, dest_open_flags, src_stbuf->st_mode)); - if (dest_fd == -1) - { - glnx_set_error_from_errno (error); - goto out; - } + /* Regular file path below here */ - r = glnx_regfile_copy_bytes (src_fd, dest_fd, (off_t) -1); - if (r < 0) - { - glnx_set_error_from_errno (error); - goto out; - } + glnx_autofd int src_fd = -1; + if (!glnx_openat_rdonly (src_dfd, src_subpath, FALSE, &src_fd, error)) + return FALSE; - if (fchown (dest_fd, src_stbuf->st_uid, src_stbuf->st_gid) != 0) - { - glnx_set_error_from_errno (error); - goto out; - } + /* Open a tmpfile for dest. Particularly for AT_FDCWD calls, we really want to + * open in the target directory, otherwise we may not be able to link. + */ + g_auto(GLnxTmpfile) tmp_dest = { 0, }; + { char *dnbuf = strdupa (dest_subpath); + const char *dn = dirname (dnbuf); + if (!glnx_open_tmpfile_linkable_at (dest_dfd, dn, O_WRONLY | O_CLOEXEC, + &tmp_dest, error)) + return FALSE; + } - if (fchmod (dest_fd, src_stbuf->st_mode & 07777) != 0) - { - glnx_set_error_from_errno (error); - goto out; - } + if (glnx_regfile_copy_bytes (src_fd, tmp_dest.fd, (off_t) -1) < 0) + return glnx_throw_errno_prefix (error, "regfile copy"); - ts[0] = src_stbuf->st_atim; - ts[1] = src_stbuf->st_mtim; - (void) futimens (dest_fd, ts); + if (fchown (tmp_dest.fd, src_stbuf->st_uid, src_stbuf->st_gid) != 0) + return glnx_throw_errno_prefix (error, "fchown"); if (!(copyflags & GLNX_FILE_COPY_NOXATTRS)) { @@ -958,35 +950,40 @@ if (!glnx_fd_get_all_xattrs (src_fd, &xattrs, cancellable, error)) - goto out; + return FALSE; - if (!glnx_fd_set_all_xattrs (dest_fd, xattrs, + if (!glnx_fd_set_all_xattrs (tmp_dest.fd, xattrs, cancellable, error)) - goto out; + return FALSE; } + /* Always chmod after setting xattrs, in case the file has mode 0400 or less, + * like /etc/shadow. Linux currently allows write() on non-writable open files + * but not fsetxattr(). + */ + if (fchmod (tmp_dest.fd, src_stbuf->st_mode & 07777) != 0) + return glnx_throw_errno_prefix (error, "fchmod"); + + struct timespec ts[2]; + ts[0] = src_stbuf->st_atim; + ts[1] = src_stbuf->st_mtim; + (void) futimens (tmp_dest.fd, ts); + if (copyflags & GLNX_FILE_COPY_DATASYNC) { - if (fdatasync (dest_fd) < 0) - { - glnx_set_error_from_errno (error); - goto out; - } - } - - r = close (dest_fd); - dest_fd = -1; - if (r < 0) - { - glnx_set_error_from_errno (error); - goto out; + if (fdatasync (tmp_dest.fd) < 0) + return glnx_throw_errno_prefix (error, "fdatasync"); } - ret = TRUE; - out: - if (!ret) - (void) unlinkat (dest_dfd, dest_subpath, 0); - return ret; + const GLnxLinkTmpfileReplaceMode replacemode = + (copyflags & GLNX_FILE_COPY_OVERWRITE) ? + GLNX_LINK_TMPFILE_REPLACE : + GLNX_LINK_TMPFILE_NOREPLACE; + + if (!glnx_link_tmpfile_at (&tmp_dest, replacemode, dest_dfd, dest_subpath, error)) + return FALSE; + + return TRUE; } /** @@ -1071,19 +1068,17 @@ return FALSE; if (glnx_loop_write (tmpf.fd, buf, len) < 0) - return glnx_throw_errno (error); + return glnx_throw_errno_prefix (error, "write"); if (!(flags & GLNX_FILE_REPLACE_NODATASYNC)) { struct stat stbuf; gboolean do_sync; - if (fstatat (dfd, subpath, &stbuf, AT_SYMLINK_NOFOLLOW) != 0) - { - if (errno != ENOENT) - return glnx_throw_errno (error); - do_sync = (flags & GLNX_FILE_REPLACE_DATASYNC_NEW) > 0; - } + if (!glnx_fstatat_allow_noent (dfd, subpath, &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return FALSE; + if (errno == ENOENT) + do_sync = (flags & GLNX_FILE_REPLACE_DATASYNC_NEW) > 0; else do_sync = TRUE; @@ -1097,11 +1092,11 @@ if (uid != (uid_t) -1) { if (fchown (tmpf.fd, uid, gid) != 0) - return glnx_throw_errno (error); + return glnx_throw_errno_prefix (error, "fchown"); } if (fchmod (tmpf.fd, mode) != 0) - return glnx_throw_errno (error); + return glnx_throw_errno_prefix (error, "fchmod"); if (!glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_REPLACE, dfd, subpath, error)) diff -Nru flatpak-builder-0.10.6/libglnx/glnx-fdio.h flatpak-builder-0.10.9/libglnx/glnx-fdio.h --- flatpak-builder-0.10.6/libglnx/glnx-fdio.h 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-fdio.h 2018-02-14 17:35:37.000000000 +0000 @@ -29,12 +29,8 @@ #include #include #include -/* From systemd/src/shared/util.h */ -/* When we include libgen.h because we need dirname() we immediately - * undefine basename() since libgen.h defines it as a macro to the XDG - * version which is really broken. */ +// For dirname(), and previously basename() #include -#undef basename #include #include @@ -47,7 +43,12 @@ static inline const char *glnx_basename (const char *path) { - return (basename) (path); + gchar *base = strrchr (path, G_DIR_SEPARATOR); + + if (base) + return base + 1; + + return path; } /* Utilities for standard FILE* */ @@ -295,6 +296,41 @@ return TRUE; } +/** + * glnx_fstatat_allow_noent: + * @dfd: Directory FD to stat beneath + * @path: Path to stat beneath @dfd + * @buf: (out caller-allocates) (allow-none): Return location for stat details + * @flags: Flags to pass to fstatat() + * @error: Return location for a #GError, or %NULL + * + * Like glnx_fstatat(), but handles `ENOENT` in a non-error way. Instead, + * on success `errno` will be zero, otherwise it will be preserved. Hence + * you can test `if (errno == 0)` to conditionalize on the file existing, + * or `if (errno == ENOENT)` for non-existence. + * + * Returns: %TRUE on success, %FALSE otherwise (errno is preserved) + * Since: UNRELEASED + */ +static inline gboolean +glnx_fstatat_allow_noent (int dfd, + const char *path, + struct stat *out_buf, + int flags, + GError **error) +{ + G_GNUC_UNUSED struct stat unused_stbuf; + if (TEMP_FAILURE_RETRY (fstatat (dfd, path, out_buf ? out_buf : &unused_stbuf, flags)) != 0) + { + if (errno != ENOENT) + return glnx_throw_errno_prefix (error, "fstatat(%s)", path); + /* Note we preserve errno as ENOENT */ + } + else + errno = 0; + return TRUE; +} + /** * glnx_renameat: * diff -Nru flatpak-builder-0.10.6/libglnx/glnx-local-alloc.h flatpak-builder-0.10.9/libglnx/glnx-local-alloc.h --- flatpak-builder-0.10.6/libglnx/glnx-local-alloc.h 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-local-alloc.h 2018-02-14 17:35:37.000000000 +0000 @@ -42,14 +42,30 @@ } #define glnx_unref_object __attribute__ ((cleanup(glnx_local_obj_unref))) +static inline int +glnx_steal_fd (int *fdp) +{ + int fd = *fdp; + *fdp = -1; + return fd; +} + +/** + * glnx_close_fd: + * @fdp: Pointer to fd + * + * Effectively `close (glnx_steal_fd (&fd))`. Also + * asserts that `close()` did not raise `EBADF` - encountering + * that error is usually a critical bug in the program. + */ static inline void -glnx_cleanup_close_fdp (int *fdp) +glnx_close_fd (int *fdp) { - int fd, errsv; + int errsv; g_assert (fdp); - fd = *fdp; + int fd = glnx_steal_fd (fdp); if (fd >= 0) { errsv = errno; @@ -62,16 +78,14 @@ /** * glnx_fd_close: * + * Deprecated in favor of `glnx_autofd`. + */ +#define glnx_fd_close __attribute__((cleanup(glnx_close_fd))) +/** + * glnx_autofd: + * * Call close() on a variable location when it goes out of scope. */ -#define glnx_fd_close __attribute__((cleanup(glnx_cleanup_close_fdp))) - -static inline int -glnx_steal_fd (int *fdp) -{ - int fd = *fdp; - *fdp = -1; - return fd; -} +#define glnx_autofd __attribute__((cleanup(glnx_close_fd))) G_END_DECLS diff -Nru flatpak-builder-0.10.6/libglnx/glnx-lockfile.c flatpak-builder-0.10.9/libglnx/glnx-lockfile.c --- flatpak-builder-0.10.6/libglnx/glnx-lockfile.c 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-lockfile.c 2018-02-14 17:35:37.000000000 +0000 @@ -61,7 +61,7 @@ */ gboolean glnx_make_lock_file(int dfd, const char *p, int operation, GLnxLockFile *out_lock, GError **error) { - glnx_fd_close int fd = -1; + glnx_autofd int fd = -1; g_autofree char *t = NULL; int r; @@ -105,7 +105,7 @@ r = flock(fd, operation); if (r < 0) - return glnx_throw_errno(error); + return glnx_throw_errno_prefix (error, "flock"); } /* If we acquired the lock, let's check if the file @@ -114,34 +114,29 @@ * it. In such a case our acquired lock is worthless, * hence try again. */ - r = fstat(fd, &st); - if (r < 0) - return glnx_throw_errno(error); + if (!glnx_fstat (fd, &st, error)) + return FALSE; if (st.st_nlink > 0) break; - (void) close(fd); - fd = -1; + glnx_close_fd (&fd); } /* Note that if this is not AT_FDCWD, the caller takes responsibility * for the fd's lifetime being >= that of the lock. */ + out_lock->initialized = TRUE; out_lock->dfd = dfd; - out_lock->path = t; - out_lock->fd = fd; + out_lock->path = g_steal_pointer (&t); + out_lock->fd = glnx_steal_fd (&fd); out_lock->operation = operation; - - fd = -1; - t = NULL; - return TRUE; } void glnx_release_lock_file(GLnxLockFile *f) { int r; - if (!f) + if (!(f && f->initialized)) return; if (f->path) { @@ -178,8 +173,7 @@ f->path = NULL; } - if (f->fd != -1) - (void) close (f->fd); - f->fd = -1; + glnx_close_fd (&f->fd); f->operation = 0; + f->initialized = FALSE; } diff -Nru flatpak-builder-0.10.6/libglnx/glnx-lockfile.h flatpak-builder-0.10.9/libglnx/glnx-lockfile.h --- flatpak-builder-0.10.6/libglnx/glnx-lockfile.h 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-lockfile.h 2018-02-14 17:35:37.000000000 +0000 @@ -27,6 +27,7 @@ #include "glnx-backport-autoptr.h" typedef struct GLnxLockFile { + gboolean initialized; int dfd; char *path; int fd; @@ -37,5 +38,3 @@ void glnx_release_lock_file(GLnxLockFile *f); G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxLockFile, glnx_release_lock_file) - -#define GLNX_LOCK_FILE_INIT { .fd = -1, .dfd = AT_FDCWD, .path = NULL } diff -Nru flatpak-builder-0.10.6/libglnx/glnx-macros.h flatpak-builder-0.10.9/libglnx/glnx-macros.h --- flatpak-builder-0.10.6/libglnx/glnx-macros.h 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-macros.h 2018-02-14 17:35:37.000000000 +0000 @@ -38,7 +38,7 @@ ({ \ const char *_appendees_[] = { a, __VA_ARGS__ }; \ char *_d_, *_p_; \ - int _len_ = 0; \ + size_t _len_ = 0; \ unsigned _i_; \ for (_i_ = 0; _i_ < G_N_ELEMENTS(_appendees_) && _appendees_[_i_]; _i_++) \ _len_ += strlen(_appendees_[_i_]); \ diff -Nru flatpak-builder-0.10.6/libglnx/glnx-missing.h flatpak-builder-0.10.9/libglnx/glnx-missing.h --- flatpak-builder-0.10.6/libglnx/glnx-missing.h 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-missing.h 2018-02-14 17:35:37.000000000 +0000 @@ -19,7 +19,17 @@ along with systemd; If not, see . ***/ -/* Missing glibc definitions to access certain kernel APIs */ +/* Missing glibc definitions to access certain kernel APIs. + This file is last updated from systemd git: + + commit 71e5200f94b22589922704aa4abdf95d4fe2e528 + Author: Daniel Mack + AuthorDate: Tue Oct 18 17:57:10 2016 +0200 + Commit: Lennart Poettering + CommitDate: Fri Sep 22 15:24:54 2017 +0200 + + Add abstraction model for BPF programs +*/ #include #include @@ -29,22 +39,30 @@ #include #include -#if defined(__i386__) || defined(__x86_64__) - -/* The precise definition of __O_TMPFILE is arch specific, so let's - * just define this on x86 where we know the value. */ +/* The precise definition of __O_TMPFILE is arch specific; use the + * values defined by the kernel (note: some are hexa, some are octal, + * duplicated as-is from the kernel definitions): + * - alpha, parisc, sparc: each has a specific value; + * - others: they use the "generic" value. + */ #ifndef __O_TMPFILE +#if defined(__alpha__) +#define __O_TMPFILE 0100000000 +#elif defined(__parisc__) || defined(__hppa__) +#define __O_TMPFILE 0400000000 +#elif defined(__sparc__) || defined(__sparc64__) +#define __O_TMPFILE 0x2000000 +#else #define __O_TMPFILE 020000000 #endif +#endif /* a horrid kludge trying to make sure that this will fail on old kernels */ #ifndef O_TMPFILE #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY) #endif -#endif - #ifndef RENAME_NOREPLACE #define RENAME_NOREPLACE (1 << 0) #endif @@ -52,4 +70,26 @@ #define RENAME_EXCHANGE (1 << 1) #endif +#ifndef F_LINUX_SPECIFIC_BASE +#define F_LINUX_SPECIFIC_BASE 1024 +#endif + +#ifndef F_ADD_SEALS +#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9) +#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10) + +#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */ +#define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */ +#define F_SEAL_GROW 0x0004 /* prevent file from growing */ +#define F_SEAL_WRITE 0x0008 /* prevent writes */ +#endif + +#ifndef MFD_ALLOW_SEALING +#define MFD_ALLOW_SEALING 0x0002U +#endif + +#ifndef MFD_CLOEXEC +#define MFD_CLOEXEC 0x0001U +#endif + #include "glnx-missing-syscall.h" diff -Nru flatpak-builder-0.10.6/libglnx/glnx-missing-syscall.h flatpak-builder-0.10.9/libglnx/glnx-missing-syscall.h --- flatpak-builder-0.10.6/libglnx/glnx-missing-syscall.h 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-missing-syscall.h 2018-02-14 17:35:37.000000000 +0000 @@ -18,7 +18,19 @@ along with systemd; If not, see . ***/ -/* Missing glibc definitions to access certain kernel APIs */ +/* Missing glibc definitions to access certain kernel APIs. + This file is last updated from systemd git: + + commit 71e5200f94b22589922704aa4abdf95d4fe2e528 + Author: Daniel Mack + AuthorDate: Tue Oct 18 17:57:10 2016 +0200 + Commit: Lennart Poettering + CommitDate: Fri Sep 22 15:24:54 2017 +0200 + + Add abstraction model for BPF programs +*/ + +#include "config.h" #if !HAVE_DECL_RENAMEAT2 # ifndef __NR_renameat2 @@ -26,6 +38,8 @@ # define __NR_renameat2 316 # elif defined __arm__ # define __NR_renameat2 382 +# elif defined __aarch64__ +# define __NR_renameat2 276 # elif defined _MIPS_SIM # if _MIPS_SIM == _MIPS_SIM_ABI32 # define __NR_renameat2 4351 @@ -38,6 +52,12 @@ # endif # elif defined __i386__ # define __NR_renameat2 353 +# elif defined __powerpc64__ +# define __NR_renameat2 357 +# elif defined __s390__ || defined __s390x__ +# define __NR_renameat2 347 +# elif defined __arc__ +# define __NR_renameat2 276 # else # warning "__NR_renameat2 unknown for your architecture" # endif @@ -49,6 +69,45 @@ # else errno = ENOSYS; return -1; +# endif +} +#endif + +#if !HAVE_DECL_MEMFD_CREATE +# ifndef __NR_memfd_create +# if defined __x86_64__ +# define __NR_memfd_create 319 +# elif defined __arm__ +# define __NR_memfd_create 385 +# elif defined __aarch64__ +# define __NR_memfd_create 279 +# elif defined __s390__ +# define __NR_memfd_create 350 +# elif defined _MIPS_SIM +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define __NR_memfd_create 4354 +# endif +# if _MIPS_SIM == _MIPS_SIM_NABI32 +# define __NR_memfd_create 6318 +# endif +# if _MIPS_SIM == _MIPS_SIM_ABI64 +# define __NR_memfd_create 5314 +# endif +# elif defined __i386__ +# define __NR_memfd_create 356 +# elif defined __arc__ +# define __NR_memfd_create 279 +# else +# warning "__NR_memfd_create unknown for your architecture" +# endif +# endif + +static inline int memfd_create(const char *name, unsigned int flags) { +# ifdef __NR_memfd_create + return syscall(__NR_memfd_create, name, flags); +# else + errno = ENOSYS; + return -1; # endif } #endif diff -Nru flatpak-builder-0.10.6/libglnx/glnx-shutil.c flatpak-builder-0.10.9/libglnx/glnx-shutil.c --- flatpak-builder-0.10.6/libglnx/glnx-shutil.c 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/glnx-shutil.c 2018-02-14 17:35:37.000000000 +0000 @@ -84,14 +84,12 @@ GCancellable *cancellable, GError **error) { - glnx_fd_close int target_dfd = -1; - g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; - dfd = glnx_dirfd_canonicalize (dfd); + /* With O_NOFOLLOW first */ - target_dfd = openat (dfd, path, - O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW); + glnx_autofd int target_dfd = + openat (dfd, path, O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW); if (target_dfd == -1) { @@ -110,6 +108,7 @@ } else { + g_auto(GLnxDirFdIterator) dfd_iter = { 0, }; if (!glnx_dirfd_iterator_init_take_fd (&target_dfd, &dfd_iter, error)) return FALSE; @@ -148,7 +147,13 @@ g_assert (!did_recurse); lastslash = strrchr (path, '/'); - g_assert (lastslash != NULL); + if (lastslash == NULL) + { + /* This can happen if @dfd was deleted between being opened and + * passed to mkdir_p_at_internal(). */ + return glnx_throw_errno_prefix (error, "mkdir(%s)", path); + } + /* Note we can mutate the buffer as we dup'd it */ *lastslash = '\0'; @@ -187,6 +192,9 @@ * directory fd @dfd. * * See also glnx_ensure_dir() for a non-recursive version. + * + * This will return %G_IO_ERROR_NOT_FOUND if @dfd has been deleted since being + * opened. It may return other errors from mkdirat() in other situations. */ gboolean glnx_shutil_mkdir_p_at (int dfd, diff -Nru flatpak-builder-0.10.6/libglnx/libglnx.h flatpak-builder-0.10.9/libglnx/libglnx.h --- flatpak-builder-0.10.6/libglnx/libglnx.h 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/libglnx.h 2018-02-14 17:35:37.000000000 +0000 @@ -25,6 +25,7 @@ G_BEGIN_DECLS #include +#include #include #include #include diff -Nru flatpak-builder-0.10.6/libglnx/libglnx.m4 flatpak-builder-0.10.9/libglnx/libglnx.m4 --- flatpak-builder-0.10.6/libglnx/libglnx.m4 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/libglnx.m4 2018-02-19 09:35:46.000000000 +0000 @@ -2,7 +2,8 @@ [ AC_CHECK_DECLS([ renameat2, - ], + memfd_create, + copy_file_range], [], [], [[ #include #include @@ -11,6 +12,7 @@ #include #include #include +#include ]]) AC_ARG_ENABLE(otmpfile, diff -Nru flatpak-builder-0.10.6/libglnx/Makefile-libglnx.am.inc flatpak-builder-0.10.9/libglnx/Makefile-libglnx.am.inc --- flatpak-builder-0.10.6/libglnx/Makefile-libglnx.am.inc 2017-08-29 14:48:04.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/Makefile-libglnx.am.inc 2018-02-19 09:37:46.000000000 +0000 @@ -46,13 +46,14 @@ libglnx/glnx-shutil.h \ libglnx/glnx-shutil.c \ libglnx/libglnx.h \ + libglnx/tests/libglnx-testlib.h \ $(NULL) libglnx_la_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags) libglnx_la_LDFLAGS = -avoid-version -Bsymbolic-functions -export-symbols-regex "^glnx_" -no-undefined -export-dynamic libglnx_la_LIBADD = $(libglnx_libs) -libglnx_tests = test-libglnx-xattrs test-libglnx-fdio test-libglnx-errors test-libglnx-macros +libglnx_tests = test-libglnx-xattrs test-libglnx-fdio test-libglnx-errors test-libglnx-macros test-libglnx-shutil TESTS += $(libglnx_tests) check_PROGRAMS += $(libglnx_tests) @@ -71,3 +72,7 @@ test_libglnx_macros_SOURCES = libglnx/tests/test-libglnx-macros.c test_libglnx_macros_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags) test_libglnx_macros_LDADD = $(libglnx_libs) libglnx.la + +test_libglnx_shutil_SOURCES = libglnx/tests/test-libglnx-shutil.c +test_libglnx_shutil_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags) +test_libglnx_shutil_LDADD = $(libglnx_libs) libglnx.la diff -Nru flatpak-builder-0.10.6/libglnx/README.md flatpak-builder-0.10.9/libglnx/README.md --- flatpak-builder-0.10.6/libglnx/README.md 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/README.md 2018-02-14 17:35:37.000000000 +0000 @@ -37,7 +37,7 @@ For local allocation macros, you should start using the `g_auto` macros from GLib. A backport is included in libglnx. There are a few -APIs not defined in GLib yet, such as `glnx_fd_close`. +APIs not defined in GLib yet, such as `glnx_autofd`. `gs_transfer_out_value` is replaced by `g_steal_pointer`. diff -Nru flatpak-builder-0.10.6/libglnx/tests/libglnx-testlib.h flatpak-builder-0.10.9/libglnx/tests/libglnx-testlib.h --- flatpak-builder-0.10.6/libglnx/tests/libglnx-testlib.h 1970-01-01 00:00:00.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/tests/libglnx-testlib.h 2018-02-14 17:35:37.000000000 +0000 @@ -0,0 +1,34 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#pragma once + +typedef GError _GLnxTestAutoError; +static inline void +_glnx_test_auto_error_cleanup (_GLnxTestAutoError *autoerror) +{ + g_assert_no_error (autoerror); + /* We could add a clear call here, but no point...we'll have aborted */ +} +G_DEFINE_AUTOPTR_CLEANUP_FUNC(_GLnxTestAutoError, _glnx_test_auto_error_cleanup); + +#define _GLNX_TEST_DECLARE_ERROR(local_error, error) \ + g_autoptr(_GLnxTestAutoError) local_error = NULL; \ + GError **error = &local_error diff -Nru flatpak-builder-0.10.6/libglnx/tests/test-libglnx-fdio.c flatpak-builder-0.10.9/libglnx/tests/test-libglnx-fdio.c --- flatpak-builder-0.10.6/libglnx/tests/test-libglnx-fdio.c 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/tests/test-libglnx-fdio.c 2018-02-14 17:35:37.000000000 +0000 @@ -26,12 +26,14 @@ #include #include +#include "libglnx-testlib.h" + static gboolean renameat_test_setup (int *out_srcfd, int *out_destfd, GError **error) { - glnx_fd_close int srcfd = -1; - glnx_fd_close int destfd = -1; + glnx_autofd int srcfd = -1; + glnx_autofd int destfd = -1; (void) glnx_shutil_rm_rf_at (AT_FDCWD, "srcdir", NULL, NULL); if (mkdir ("srcdir", 0755) < 0) @@ -59,14 +61,13 @@ static void test_renameat2_noreplace (void) { - g_autoptr(GError) local_error = NULL; - GError **error = &local_error; - glnx_fd_close int srcfd = -1; - glnx_fd_close int destfd = -1; + _GLNX_TEST_DECLARE_ERROR(local_error, error); + glnx_autofd int srcfd = -1; + glnx_autofd int destfd = -1; struct stat stbuf; if (!renameat_test_setup (&srcfd, &destfd, error)) - goto out; + return; if (glnx_renameat2_noreplace (srcfd, "foo", destfd, "bar") == 0) g_assert_not_reached (); @@ -76,117 +77,162 @@ } if (glnx_renameat2_noreplace (srcfd, "foo", destfd, "baz") < 0) - { - glnx_set_error_from_errno (error); - goto out; - } + return (void)glnx_throw_errno_prefix (error, "renameat"); if (!glnx_fstatat (destfd, "bar", &stbuf, AT_SYMLINK_NOFOLLOW, error)) - goto out; + return; if (fstatat (srcfd, "foo", &stbuf, AT_SYMLINK_NOFOLLOW) == 0) g_assert_not_reached (); else g_assert_cmpint (errno, ==, ENOENT); - - out: - g_assert_no_error (local_error); } static void test_renameat2_exchange (void) { - g_autoptr(GError) local_error = NULL; - GError **error = &local_error; - glnx_fd_close int srcfd = -1; - glnx_fd_close int destfd = -1; - struct stat stbuf; + _GLNX_TEST_DECLARE_ERROR(local_error, error); + glnx_autofd int srcfd = -1; + glnx_autofd int destfd = -1; if (!renameat_test_setup (&srcfd, &destfd, error)) - goto out; + return; if (glnx_renameat2_exchange (AT_FDCWD, "srcdir", AT_FDCWD, "destdir") < 0) - { - glnx_set_error_from_errno (error); - goto out; - } + return (void)glnx_throw_errno_prefix (error, "renameat"); /* Ensure the dir fds are the same */ - if (fstatat (srcfd, "foo", &stbuf, AT_SYMLINK_NOFOLLOW) < 0) - { - glnx_set_error_from_errno (error); - goto out; - } - if (fstatat (destfd, "bar", &stbuf, AT_SYMLINK_NOFOLLOW) < 0) - { - glnx_set_error_from_errno (error); - goto out; - } + struct stat stbuf; + if (!glnx_fstatat (srcfd, "foo", &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return; + if (!glnx_fstatat (destfd, "bar", &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return; /* But the dirs should be swapped */ - if (fstatat (AT_FDCWD, "destdir/foo", &stbuf, AT_SYMLINK_NOFOLLOW) < 0) - { - glnx_set_error_from_errno (error); - goto out; - } - if (fstatat (AT_FDCWD, "srcdir/bar", &stbuf, AT_SYMLINK_NOFOLLOW) < 0) - { - glnx_set_error_from_errno (error); - goto out; - } - - out: - g_assert_no_error (local_error); + if (!glnx_fstatat (AT_FDCWD, "destdir/foo", &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return; + if (!glnx_fstatat (AT_FDCWD, "srcdir/bar", &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return; } static void test_tmpfile (void) { - g_autoptr(GError) local_error = NULL; - GError **error = &local_error; - g_auto(GLnxTmpfile) tmpf = { 0, }; + _GLNX_TEST_DECLARE_ERROR(local_error, error); + g_auto(GLnxTmpfile) tmpf = { 0, }; if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, ".", O_WRONLY|O_CLOEXEC, &tmpf, error)) - goto out; - + return; if (glnx_loop_write (tmpf.fd, "foo", strlen ("foo")) < 0) - { - (void)glnx_throw_errno_prefix (error, "write"); - goto out; - } - + return (void)glnx_throw_errno_prefix (error, "write"); if (glnx_link_tmpfile_at (&tmpf, GLNX_LINK_TMPFILE_NOREPLACE, AT_FDCWD, "foo", error)) - goto out; - - out: - g_assert_no_error (local_error); + return; } static void test_stdio_file (void) { - g_autoptr(GError) local_error = NULL; - GError **error = &local_error; + _GLNX_TEST_DECLARE_ERROR(local_error, error); g_auto(GLnxTmpfile) tmpf = { 0, }; g_autoptr(FILE) f = NULL; if (!glnx_open_anonymous_tmpfile (O_RDWR|O_CLOEXEC, &tmpf, error)) - goto out; + return; f = fdopen (tmpf.fd, "w"); + tmpf.fd = -1; /* Ownership was transferred via fdopen() */ if (!f) - { - (void)glnx_throw_errno_prefix (error, "fdopen"); - goto out; - } - + return (void)glnx_throw_errno_prefix (error, "fdopen"); if (fwrite ("hello", 1, strlen ("hello"), f) != strlen ("hello")) - { - (void)glnx_throw_errno_prefix (error, "fwrite"); - goto out; - } + return (void)glnx_throw_errno_prefix (error, "fwrite"); if (!glnx_stdio_file_flush (f, error)) - goto out; + return; +} + +static void +test_fstatat (void) +{ + _GLNX_TEST_DECLARE_ERROR(local_error, error); + struct stat stbuf = { 0, }; + + if (!glnx_fstatat_allow_noent (AT_FDCWD, ".", &stbuf, 0, error)) + return; + g_assert_cmpint (errno, ==, 0); + g_assert_no_error (local_error); + g_assert (S_ISDIR (stbuf.st_mode)); + if (!glnx_fstatat_allow_noent (AT_FDCWD, "nosuchfile", &stbuf, 0, error)) + return; + g_assert_cmpint (errno, ==, ENOENT); + g_assert_no_error (local_error); + + /* test NULL parameter for stat */ + if (!glnx_fstatat_allow_noent (AT_FDCWD, ".", NULL, 0, error)) + return; + g_assert_cmpint (errno, ==, 0); + g_assert_no_error (local_error); + if (!glnx_fstatat_allow_noent (AT_FDCWD, "nosuchfile", NULL, 0, error)) + return; + g_assert_cmpint (errno, ==, ENOENT); + g_assert_no_error (local_error); +} + +static void +test_filecopy (void) +{ + _GLNX_TEST_DECLARE_ERROR(local_error, error); + const char foo[] = "foo"; + struct stat stbuf; + + if (!glnx_ensure_dir (AT_FDCWD, "subdir", 0755, error)) + return; + + if (!glnx_file_replace_contents_at (AT_FDCWD, foo, (guint8*)foo, sizeof (foo), + GLNX_FILE_REPLACE_NODATASYNC, NULL, error)) + return; + + /* Copy it into both the same dir and a subdir */ + if (!glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "bar", + GLNX_FILE_COPY_NOXATTRS, NULL, error)) + return; + if (!glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "subdir/bar", + GLNX_FILE_COPY_NOXATTRS, NULL, error)) + return; + if (!glnx_fstatat (AT_FDCWD, "subdir/bar", &stbuf, 0, error)) + return; + + if (glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "bar", + GLNX_FILE_COPY_NOXATTRS, NULL, error)) + g_assert_not_reached (); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS); + g_clear_error (&local_error); - out: + if (!glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "bar", + GLNX_FILE_COPY_NOXATTRS | GLNX_FILE_COPY_OVERWRITE, + NULL, error)) + return; + + if (symlinkat ("nosuchtarget", AT_FDCWD, "link") < 0) + return (void) glnx_throw_errno_prefix (error, "symlinkat"); + + /* Shouldn't be able to overwrite a symlink without GLNX_FILE_COPY_OVERWRITE */ + if (glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "link", + GLNX_FILE_COPY_NOXATTRS, + NULL, error)) + g_assert_not_reached (); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS); + g_clear_error (&local_error); + + /* Test overwriting symlink */ + if (!glnx_file_copy_at (AT_FDCWD, foo, NULL, AT_FDCWD, "link", + GLNX_FILE_COPY_NOXATTRS | GLNX_FILE_COPY_OVERWRITE, + NULL, error)) + return; + + if (!glnx_fstatat_allow_noent (AT_FDCWD, "nosuchtarget", &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return; + g_assert_cmpint (errno, ==, ENOENT); g_assert_no_error (local_error); + + if (!glnx_fstatat (AT_FDCWD, "link", &stbuf, AT_SYMLINK_NOFOLLOW, error)) + return; + g_assert (S_ISREG (stbuf.st_mode)); } int main (int argc, char **argv) @@ -197,8 +243,10 @@ g_test_add_func ("/tmpfile", test_tmpfile); g_test_add_func ("/stdio-file", test_stdio_file); + g_test_add_func ("/filecopy", test_filecopy); g_test_add_func ("/renameat2-noreplace", test_renameat2_noreplace); g_test_add_func ("/renameat2-exchange", test_renameat2_exchange); + g_test_add_func ("/fstat", test_fstatat); ret = g_test_run(); diff -Nru flatpak-builder-0.10.6/libglnx/tests/test-libglnx-shutil.c flatpak-builder-0.10.9/libglnx/tests/test-libglnx-shutil.c --- flatpak-builder-0.10.6/libglnx/tests/test-libglnx-shutil.c 1970-01-01 00:00:00.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/tests/test-libglnx-shutil.c 2018-02-14 17:35:37.000000000 +0000 @@ -0,0 +1,63 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright © 2017 Endless Mobile, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" +#include "libglnx.h" +#include +#include +#include +#include +#include + +#include "libglnx-testlib.h" + +static void +test_mkdir_p_enoent (void) +{ + _GLNX_TEST_DECLARE_ERROR(local_error, error); + glnx_autofd int dfd = -1; + + if (!glnx_ensure_dir (AT_FDCWD, "test", 0755, error)) + return; + if (!glnx_opendirat (AT_FDCWD, "test", FALSE, &dfd, error)) + return; + if (rmdir ("test") < 0) + return (void) glnx_throw_errno_prefix (error, "rmdir(%s)", "test"); + + /* This should fail with ENOENT. */ + glnx_shutil_mkdir_p_at (dfd, "blah/baz", 0755, NULL, error); + g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND); + g_clear_error (&local_error); +} + +int +main (int argc, + char **argv) +{ + int ret; + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/mkdir-p/enoent", test_mkdir_p_enoent); + + ret = g_test_run(); + + return ret; +} diff -Nru flatpak-builder-0.10.6/libglnx/tests/test-libglnx-xattrs.c flatpak-builder-0.10.9/libglnx/tests/test-libglnx-xattrs.c --- flatpak-builder-0.10.6/libglnx/tests/test-libglnx-xattrs.c 2017-08-24 13:49:12.000000000 +0000 +++ flatpak-builder-0.10.9/libglnx/tests/test-libglnx-xattrs.c 2018-02-14 17:35:37.000000000 +0000 @@ -82,7 +82,7 @@ { guint32 randname_v = g_random_int (); g_autofree char *randname = g_strdup_printf ("file%u", randname_v); - glnx_fd_close int fd = -1; + glnx_autofd int fd = -1; again: fd = openat (dfd_iter->fd, randname, O_CREAT | O_EXCL, 0644); @@ -113,7 +113,7 @@ if (!dent) break; - glnx_fd_close int fd = -1; + glnx_autofd int fd = -1; if (!glnx_openat_rdonly (dfd_iter->fd, dent->d_name, FALSE, &fd, error)) return FALSE; @@ -157,7 +157,7 @@ if (!dent) break; - glnx_fd_close int fd = -1; + glnx_autofd int fd = -1; if (!glnx_openat_rdonly (dfd_iter->fd, dent->d_name, FALSE, &fd, error)) return FALSE; @@ -223,19 +223,17 @@ GThread *threads[nprocs]; g_autoptr(GError) local_error = NULL; GError **error = &local_error; - glnx_fd_close int dfd = -1; - g_autofree char *tmpdir = g_strdup_printf ("%s/libglnx-xattrs-XXXXXX", - getenv ("TMPDIR") ?: "/var/tmp"); + g_auto(GLnxTmpDir) tmpdir = { 0, }; + g_autofree char *tmpdir_path = g_strdup_printf ("%s/libglnx-xattrs-XXXXXX", + getenv ("TMPDIR") ?: "/var/tmp"); guint nread = 0; - if (!glnx_mkdtempat (AT_FDCWD, tmpdir, 0700, error)) - goto out; - - if (!glnx_opendirat (AT_FDCWD, tmpdir, TRUE, &dfd, error)) + if (!glnx_mkdtempat (AT_FDCWD, tmpdir_path, 0700, + &tmpdir, error)) goto out; /* Support people building/testing on tmpfs https://github.com/flatpak/flatpak/issues/686 */ - if (fsetxattr (dfd, "user.test", "novalue", strlen ("novalue"), 0) < 0) + if (fsetxattr (tmpdir.fd, "user.test", "novalue", strlen ("novalue"), 0) < 0) { if (errno == EOPNOTSUPP) { @@ -252,7 +250,7 @@ for (guint i = 0; i < nprocs; i++) { struct XattrWorker *worker = &wdata[i]; - worker->dfd = dfd; + worker->dfd = tmpdir.fd; worker->is_writer = i % 2 == 0; threads[i] = g_thread_new (NULL, xattr_thread, worker); } @@ -267,8 +265,6 @@ g_print ("Read %u xattrs race free!\n", nread); - (void) glnx_shutil_rm_rf_at (AT_FDCWD, tmpdir, NULL, NULL); - out: g_assert_no_error (local_error); } diff -Nru flatpak-builder-0.10.6/Makefile.am flatpak-builder-0.10.9/Makefile.am --- flatpak-builder-0.10.6/Makefile.am 2017-08-25 07:33:46.000000000 +0000 +++ flatpak-builder-0.10.9/Makefile.am 2018-02-14 17:46:23.000000000 +0000 @@ -21,7 +21,7 @@ endif FLATPAK_BINDIR=$(bindir) - +ACLOCAL_AMFLAGS = -I m4 -I libglnx ${ACLOCAL_FLAGS} AM_CPPFLAGS = \ -DFLATPAK_BINDIR=\"$(FLATPAK_BINDIR)\" \ -DFLATPAK_BASEDIR=\"$(pkgdatadir)\" \ diff -Nru flatpak-builder-0.10.6/Makefile.in flatpak-builder-0.10.9/Makefile.in --- flatpak-builder-0.10.6/Makefile.in 2017-12-15 13:26:50.000000000 +0000 +++ flatpak-builder-0.10.9/Makefile.in 2018-02-19 09:37:56.000000000 +0000 @@ -145,16 +145,16 @@ @BUILD_DOCUMENTATION_TRUE@am__append_14 = . doc subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/attributes.m4 \ - $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/glibtests.m4 \ - $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac +am__aclocal_m4_deps = $(top_srcdir)/libglnx/libglnx.m4 \ + $(top_srcdir)/m4/attributes.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/glibtests.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/intlmacosx.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ @@ -231,7 +231,8 @@ am__EXEEXT_1 = @ENABLE_ALWAYS_BUILD_TESTS_FALSE@am__EXEEXT_2 = $(am__EXEEXT_1) am__EXEEXT_3 = test-libglnx-xattrs$(EXEEXT) test-libglnx-fdio$(EXEEXT) \ - test-libglnx-errors$(EXEEXT) test-libglnx-macros$(EXEEXT) + test-libglnx-errors$(EXEEXT) test-libglnx-macros$(EXEEXT) \ + test-libglnx-shutil$(EXEEXT) @ENABLE_ALWAYS_BUILD_TESTS_TRUE@am__EXEEXT_4 = $(am__EXEEXT_1) PROGRAMS = $(bin_PROGRAMS) $(installed_test_PROGRAMS) \ $(libexec_PROGRAMS) $(noinst_PROGRAMS) @@ -285,6 +286,13 @@ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_libglnx_macros_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ +am_test_libglnx_shutil_OBJECTS = libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.$(OBJEXT) +test_libglnx_shutil_OBJECTS = $(am_test_libglnx_shutil_OBJECTS) +test_libglnx_shutil_DEPENDENCIES = $(am__DEPENDENCIES_2) libglnx.la +test_libglnx_shutil_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(test_libglnx_shutil_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ am_test_libglnx_xattrs_OBJECTS = libglnx/tests/test_libglnx_xattrs-test-libglnx-xattrs.$(OBJEXT) test_libglnx_xattrs_OBJECTS = $(am_test_libglnx_xattrs_OBJECTS) test_libglnx_xattrs_DEPENDENCIES = $(am__DEPENDENCIES_2) libglnx.la @@ -329,10 +337,12 @@ am__v_CCLD_1 = SOURCES = $(libglnx_la_SOURCES) $(flatpak_builder_SOURCES) \ $(test_libglnx_errors_SOURCES) $(test_libglnx_fdio_SOURCES) \ - $(test_libglnx_macros_SOURCES) $(test_libglnx_xattrs_SOURCES) + $(test_libglnx_macros_SOURCES) $(test_libglnx_shutil_SOURCES) \ + $(test_libglnx_xattrs_SOURCES) DIST_SOURCES = $(libglnx_la_SOURCES) $(flatpak_builder_SOURCES) \ $(test_libglnx_errors_SOURCES) $(test_libglnx_fdio_SOURCES) \ - $(test_libglnx_macros_SOURCES) $(test_libglnx_xattrs_SOURCES) + $(test_libglnx_macros_SOURCES) $(test_libglnx_shutil_SOURCES) \ + $(test_libglnx_xattrs_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ @@ -824,6 +834,7 @@ @ENABLE_INSTALLED_TESTS_TRUE@installed_test_meta_DATA = $(installed_testcases:=.test) SUBDIRS = $(am__append_14) FLATPAK_BINDIR = $(bindir) +ACLOCAL_AMFLAGS = -I m4 -I libglnx ${ACLOCAL_FLAGS} AM_CPPFLAGS = \ -DFLATPAK_BINDIR=\"$(FLATPAK_BINDIR)\" \ -DFLATPAK_BASEDIR=\"$(pkgdatadir)\" \ @@ -868,12 +879,13 @@ libglnx/glnx-shutil.h \ libglnx/glnx-shutil.c \ libglnx/libglnx.h \ + libglnx/tests/libglnx-testlib.h \ $(NULL) libglnx_la_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags) libglnx_la_LDFLAGS = -avoid-version -Bsymbolic-functions -export-symbols-regex "^glnx_" -no-undefined -export-dynamic libglnx_la_LIBADD = $(libglnx_libs) -libglnx_tests = test-libglnx-xattrs test-libglnx-fdio test-libglnx-errors test-libglnx-macros +libglnx_tests = test-libglnx-xattrs test-libglnx-fdio test-libglnx-errors test-libglnx-macros test-libglnx-shutil test_libglnx_xattrs_SOURCES = libglnx/tests/test-libglnx-xattrs.c test_libglnx_xattrs_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags) test_libglnx_xattrs_LDADD = $(libglnx_libs) libglnx.la @@ -886,6 +898,9 @@ test_libglnx_macros_SOURCES = libglnx/tests/test-libglnx-macros.c test_libglnx_macros_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags) test_libglnx_macros_LDADD = $(libglnx_libs) libglnx.la +test_libglnx_shutil_SOURCES = libglnx/tests/test-libglnx-shutil.c +test_libglnx_shutil_CFLAGS = $(AM_CFLAGS) $(libglnx_cflags) +test_libglnx_shutil_LDADD = $(libglnx_libs) libglnx.la flatpak_builder_SOURCES = \ src/builder-main.c \ src/builder-manifest.c \ @@ -1395,6 +1410,13 @@ test-libglnx-macros$(EXEEXT): $(test_libglnx_macros_OBJECTS) $(test_libglnx_macros_DEPENDENCIES) $(EXTRA_test_libglnx_macros_DEPENDENCIES) @rm -f test-libglnx-macros$(EXEEXT) $(AM_V_CCLD)$(test_libglnx_macros_LINK) $(test_libglnx_macros_OBJECTS) $(test_libglnx_macros_LDADD) $(LIBS) +libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.$(OBJEXT): \ + libglnx/tests/$(am__dirstamp) \ + libglnx/tests/$(DEPDIR)/$(am__dirstamp) + +test-libglnx-shutil$(EXEEXT): $(test_libglnx_shutil_OBJECTS) $(test_libglnx_shutil_DEPENDENCIES) $(EXTRA_test_libglnx_shutil_DEPENDENCIES) + @rm -f test-libglnx-shutil$(EXEEXT) + $(AM_V_CCLD)$(test_libglnx_shutil_LINK) $(test_libglnx_shutil_OBJECTS) $(test_libglnx_shutil_LDADD) $(LIBS) libglnx/tests/test_libglnx_xattrs-test-libglnx-xattrs.$(OBJEXT): \ libglnx/tests/$(am__dirstamp) \ libglnx/tests/$(DEPDIR)/$(am__dirstamp) @@ -1460,6 +1482,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@libglnx/tests/$(DEPDIR)/test_libglnx_errors-test-libglnx-errors.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libglnx/tests/$(DEPDIR)/test_libglnx_fdio-test-libglnx-fdio.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libglnx/tests/$(DEPDIR)/test_libglnx_macros-test-libglnx-macros.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@libglnx/tests/$(DEPDIR)/test_libglnx_shutil-test-libglnx-shutil.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@libglnx/tests/$(DEPDIR)/test_libglnx_xattrs-test-libglnx-xattrs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/flatpak_builder-builder-cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/flatpak_builder-builder-context.Po@am__quote@ @@ -1891,6 +1914,20 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_libglnx_macros_CFLAGS) $(CFLAGS) -c -o libglnx/tests/test_libglnx_macros-test-libglnx-macros.obj `if test -f 'libglnx/tests/test-libglnx-macros.c'; then $(CYGPATH_W) 'libglnx/tests/test-libglnx-macros.c'; else $(CYGPATH_W) '$(srcdir)/libglnx/tests/test-libglnx-macros.c'; fi` +libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.o: libglnx/tests/test-libglnx-shutil.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_libglnx_shutil_CFLAGS) $(CFLAGS) -MT libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.o -MD -MP -MF libglnx/tests/$(DEPDIR)/test_libglnx_shutil-test-libglnx-shutil.Tpo -c -o libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.o `test -f 'libglnx/tests/test-libglnx-shutil.c' || echo '$(srcdir)/'`libglnx/tests/test-libglnx-shutil.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libglnx/tests/$(DEPDIR)/test_libglnx_shutil-test-libglnx-shutil.Tpo libglnx/tests/$(DEPDIR)/test_libglnx_shutil-test-libglnx-shutil.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libglnx/tests/test-libglnx-shutil.c' object='libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_libglnx_shutil_CFLAGS) $(CFLAGS) -c -o libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.o `test -f 'libglnx/tests/test-libglnx-shutil.c' || echo '$(srcdir)/'`libglnx/tests/test-libglnx-shutil.c + +libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.obj: libglnx/tests/test-libglnx-shutil.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_libglnx_shutil_CFLAGS) $(CFLAGS) -MT libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.obj -MD -MP -MF libglnx/tests/$(DEPDIR)/test_libglnx_shutil-test-libglnx-shutil.Tpo -c -o libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.obj `if test -f 'libglnx/tests/test-libglnx-shutil.c'; then $(CYGPATH_W) 'libglnx/tests/test-libglnx-shutil.c'; else $(CYGPATH_W) '$(srcdir)/libglnx/tests/test-libglnx-shutil.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libglnx/tests/$(DEPDIR)/test_libglnx_shutil-test-libglnx-shutil.Tpo libglnx/tests/$(DEPDIR)/test_libglnx_shutil-test-libglnx-shutil.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libglnx/tests/test-libglnx-shutil.c' object='libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_libglnx_shutil_CFLAGS) $(CFLAGS) -c -o libglnx/tests/test_libglnx_shutil-test-libglnx-shutil.obj `if test -f 'libglnx/tests/test-libglnx-shutil.c'; then $(CYGPATH_W) 'libglnx/tests/test-libglnx-shutil.c'; else $(CYGPATH_W) '$(srcdir)/libglnx/tests/test-libglnx-shutil.c'; fi` + libglnx/tests/test_libglnx_xattrs-test-libglnx-xattrs.o: libglnx/tests/test-libglnx-xattrs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_libglnx_xattrs_CFLAGS) $(CFLAGS) -MT libglnx/tests/test_libglnx_xattrs-test-libglnx-xattrs.o -MD -MP -MF libglnx/tests/$(DEPDIR)/test_libglnx_xattrs-test-libglnx-xattrs.Tpo -c -o libglnx/tests/test_libglnx_xattrs-test-libglnx-xattrs.o `test -f 'libglnx/tests/test-libglnx-xattrs.c' || echo '$(srcdir)/'`libglnx/tests/test-libglnx-xattrs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libglnx/tests/$(DEPDIR)/test_libglnx_xattrs-test-libglnx-xattrs.Tpo libglnx/tests/$(DEPDIR)/test_libglnx_xattrs-test-libglnx-xattrs.Po @@ -2311,6 +2348,13 @@ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +test-libglnx-shutil.log: test-libglnx-shutil$(EXEEXT) + @p='test-libglnx-shutil$(EXEEXT)'; \ + b='test-libglnx-shutil'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ diff -Nru flatpak-builder-0.10.6/NEWS flatpak-builder-0.10.9/NEWS --- flatpak-builder-0.10.6/NEWS 2017-12-15 13:32:25.000000000 +0000 +++ flatpak-builder-0.10.9/NEWS 2018-02-19 09:37:03.000000000 +0000 @@ -1,3 +1,23 @@ +Major changes in 0.10.9 +======================= + + * Support -y argument, which passes it on to flatpak install, etc + * Fix build on glibc 2.27 + +Major changes in 0.10.8 +======================= + + * Fix build on recent glibc + +Major changes in 0.10.7 +======================= + + * Add support for --socket=fallback-x11 + * Fix assert in --install + * Fix --disable-updates for git sources + * When mirroring git repos, use a temporary download dir + * Support running flatpak-builder inside a flatpak sandbox + Major changes in 0.10.6 ======================= diff -Nru flatpak-builder-0.10.6/README.md flatpak-builder-0.10.9/README.md --- flatpak-builder-0.10.6/README.md 2017-09-28 11:47:45.000000000 +0000 +++ flatpak-builder-0.10.9/README.md 2018-02-16 07:14:58.000000000 +0000 @@ -6,7 +6,7 @@ See http://flatpak.org/ for more information. -Read documentation for the flatpak-builder [commandline tools](http://flatpak.org/flatpak/flatpak-docs.html). +Read documentation for the flatpak-builder [commandline tools](http://docs.flatpak.org/en/latest/flatpak-builder-command-reference.html). # INSTALLATION diff -Nru flatpak-builder-0.10.6/src/builder-context.c flatpak-builder-0.10.9/src/builder-context.c --- flatpak-builder-0.10.6/src/builder-context.c 2017-12-07 14:40:32.000000000 +0000 +++ flatpak-builder-0.10.9/src/builder-context.c 2018-02-16 11:05:31.000000000 +0000 @@ -229,7 +229,7 @@ static void builder_context_init (BuilderContext *self) { - GLnxLockFile init = GLNX_LOCK_FILE_INIT; + GLnxLockFile init = { 0, }; g_autofree char *path = NULL; self->rofiles_file_lock = init; diff -Nru flatpak-builder-0.10.6/src/builder-flatpak-utils.c flatpak-builder-0.10.9/src/builder-flatpak-utils.c --- flatpak-builder-0.10.6/src/builder-flatpak-utils.c 2017-12-14 09:29:35.000000000 +0000 +++ flatpak-builder-0.10.9/src/builder-flatpak-utils.c 2018-02-14 17:46:20.000000000 +0000 @@ -897,6 +897,23 @@ cancellable, error); } +gboolean flatpak_file_rename (GFile *from, + GFile *to, + GCancellable *cancellable, + GError **error) +{ + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + if (rename (flatpak_file_get_path_cached (from), + flatpak_file_get_path_cached (to)) < 0) + { + glnx_set_error_from_errno (error); + return FALSE; + } + + return TRUE; +} #define OSTREE_GIO_FAST_QUERYINFO ("standard::name,standard::type,standard::size,standard::is-symlink,standard::symlink-target," \ "unix::device,unix::inode,unix::mode,unix::uid,unix::gid,unix::rdev") @@ -991,20 +1008,17 @@ while (tmpdir_name == NULL) { g_autofree char *tmpdir_name_template = g_strconcat (tmpdir_prefix, "XXXXXX", NULL); - glnx_fd_close int new_tmpdir_fd = -1; g_autoptr(GError) local_error = NULL; g_autofree char *lock_name = NULL; + g_auto(GLnxTmpDir) new_tmpdir = { 0, }; /* No existing tmpdir found, create a new */ - if (!glnx_mkdtempat (dfd_iter.fd, tmpdir_name_template, 0777, error)) - return FALSE; - - if (!glnx_opendirat (dfd_iter.fd, tmpdir_name_template, FALSE, - &new_tmpdir_fd, error)) + if (!glnx_mkdtempat (dfd_iter.fd, tmpdir_name_template, 0777, + &new_tmpdir, error)) return FALSE; - lock_name = g_strconcat (tmpdir_name_template, "-lock", NULL); + lock_name = g_strconcat (new_tmpdir.path, "-lock", NULL); /* Note, at this point we can race with another process that picks up this * new directory. If that happens we need to retry, making a new directory. */ @@ -1013,6 +1027,7 @@ { if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { + glnx_tmpdir_unset (&new_tmpdir); /* Don't delete */ continue; } else @@ -1022,8 +1037,9 @@ } } - tmpdir_name = g_steal_pointer (&tmpdir_name_template); - tmpdir_fd = glnx_steal_fd (&new_tmpdir_fd); + tmpdir_name = g_strdup (new_tmpdir.path); + tmpdir_fd = dup (new_tmpdir.fd); + glnx_tmpdir_unset (&new_tmpdir); /* Don't delete */ } if (tmpdir_name_out) @@ -1277,6 +1293,7 @@ FLATPAK_CONTEXT_SOCKET_PULSEAUDIO = 1 << 2, FLATPAK_CONTEXT_SOCKET_SESSION_BUS = 1 << 3, FLATPAK_CONTEXT_SOCKET_SYSTEM_BUS = 1 << 4, + FLATPAK_CONTEXT_SOCKET_FALLBACK_X11 = 1 << 5, /* For backwards compat, also set SOCKET_X11 */ } FlatpakContextSockets; /* Same order as enum */ @@ -1286,6 +1303,7 @@ "pulseaudio", "session-bus", "system-bus", + "fallback-x11", NULL }; @@ -1924,6 +1942,9 @@ if (socket == 0) return FALSE; + if (socket == FLATPAK_CONTEXT_SOCKET_FALLBACK_X11) + socket |= FLATPAK_CONTEXT_SOCKET_X11; + flatpak_context_add_sockets (context, socket); return TRUE; @@ -1942,6 +1963,9 @@ if (socket == 0) return FALSE; + if (socket == FLATPAK_CONTEXT_SOCKET_FALLBACK_X11) + socket |= FLATPAK_CONTEXT_SOCKET_X11; + flatpak_context_remove_sockets (context, socket); return TRUE; diff -Nru flatpak-builder-0.10.6/src/builder-flatpak-utils.h flatpak-builder-0.10.9/src/builder-flatpak-utils.h --- flatpak-builder-0.10.6/src/builder-flatpak-utils.h 2017-12-14 09:29:35.000000000 +0000 +++ flatpak-builder-0.10.9/src/builder-flatpak-utils.h 2018-01-11 08:37:55.000000000 +0000 @@ -221,6 +221,11 @@ va_list args); GFile *flatpak_build_file (GFile *base, ...) G_GNUC_NULL_TERMINATED; +gboolean flatpak_file_rename (GFile *from, + GFile *to, + GCancellable *cancellable, + GError **error); + gboolean flatpak_openat_noatime (int dfd, const char *name, int *ret_fd, diff -Nru flatpak-builder-0.10.6/src/builder-git.c flatpak-builder-0.10.9/src/builder-git.c --- flatpak-builder-0.10.6/src/builder-git.c 2017-12-07 10:16:32.000000000 +0000 +++ flatpak-builder-0.10.9/src/builder-git.c 2018-02-16 11:05:31.000000000 +0000 @@ -440,6 +440,8 @@ { g_autoptr(GFile) cache_mirror_dir = NULL; g_autoptr(GFile) mirror_dir = NULL; + g_autoptr(GFile) real_mirror_dir = NULL; + g_autoptr(FlatpakTempDir) tmp_mirror_dir = NULL; g_autofree char *current_commit = NULL; g_autoptr(GHashTable) refs = NULL; gboolean already_exists = FALSE; @@ -466,6 +468,15 @@ if (!g_file_query_exists (mirror_dir, NULL)) { + g_autofree char *tmpdir = g_strconcat (flatpak_file_get_path_cached (mirror_dir), "-XXXXXX", NULL); + + if (g_mkdtemp_full (tmpdir, 0755) == NULL) + return flatpak_fail (error, "Can't create temporary directory"); + + tmp_mirror_dir = g_file_new_for_path (tmpdir); + real_mirror_dir = g_steal_pointer (&mirror_dir); + mirror_dir = g_object_ref (tmp_mirror_dir); + if (!git (NULL, NULL, 0, error, "init", "--bare", (char *)flatpak_file_get_path_cached (mirror_dir), NULL)) @@ -507,18 +518,29 @@ g_autoptr(GFile) cached_git_dir = NULL; g_autofree char *origin = NULL; g_autoptr(GFile) alternates = NULL; - g_autofree char *filename = g_file_get_basename (mirror_dir); + g_autofree char *cache_filename = NULL; + + if (real_mirror_dir) + cache_filename = g_file_get_basename (real_mirror_dir); + else + cache_filename = g_file_get_basename (mirror_dir); /* If we're doing a regular download, look for cache sources */ if (destination_path == NULL) - cached_git_dir = builder_context_find_in_sources_dirs (context, "git", filename, NULL); + cached_git_dir = builder_context_find_in_sources_dirs (context, "git", cache_filename, NULL); else cached_git_dir = g_object_ref (cache_mirror_dir); /* If we're not updating, only pull from cache to avoid network i/o */ - if (!update && cached_git_dir) - origin = g_file_get_uri (cached_git_dir); - else + if (!update) + { + if (cached_git_dir) + origin = g_file_get_uri (cached_git_dir); + else if (!created) + return TRUE; + } + + if (origin == NULL) origin = g_strdup ("origin"); refs = git_ls_remote (mirror_dir, origin, error); @@ -599,6 +621,14 @@ } } + if (real_mirror_dir) + { + if (!flatpak_file_rename (mirror_dir, real_mirror_dir, NULL, error)) + return FALSE; + g_clear_object (&mirror_dir); + mirror_dir = g_steal_pointer (&real_mirror_dir); + } + if (flags & FLATPAK_GIT_MIRROR_FLAGS_MIRROR_SUBMODULES) { current_commit = git_get_current_commit (mirror_dir, ref, FALSE, context, error); diff -Nru flatpak-builder-0.10.6/src/builder-main.c flatpak-builder-0.10.9/src/builder-main.c --- flatpak-builder-0.10.6/src/builder-main.c 2017-12-15 13:24:27.000000000 +0000 +++ flatpak-builder-0.10.9/src/builder-main.c 2018-02-16 10:37:25.000000000 +0000 @@ -81,6 +81,7 @@ static char *opt_installation; static gboolean opt_log_session_bus; static gboolean opt_log_system_bus; +static gboolean opt_yes; static GOptionEntry entries[] = { { "verbose", 'v', 0, G_OPTION_ARG_NONE, &opt_verbose, "Print debug information during command processing", NULL }, @@ -131,6 +132,7 @@ { "system", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_user, "Install dependencies in system-wide installations (default)", NULL }, { "installation", 0, 0, G_OPTION_ARG_STRING, &opt_installation, "Install dependencies in a specific system-wide installation", "NAME" }, { "state-dir", 0, 0, G_OPTION_ARG_FILENAME, &opt_state_dir, "Use this directory for state instead of .flatpak-builder", "PATH" }, + { "assumeyes", 'y', 0, G_OPTION_ARG_NONE, &opt_yes, N_("Automatically answer yes for all questions"), NULL }, { NULL } }; @@ -273,6 +275,9 @@ else g_ptr_array_add (args, g_strdup ("--system")); + if (opt_user) + g_ptr_array_add (args, g_strdup ("-y")); + g_ptr_array_add (args, g_strdup ("--reinstall")); g_ptr_array_add (args, g_strdup ("--subpath=")); @@ -591,7 +596,8 @@ if (opt_install_deps_from != NULL) { - if (!builder_manifest_install_deps (manifest, build_context, opt_install_deps_from, opt_user, opt_installation, &error)) + if (!builder_manifest_install_deps (manifest, build_context, opt_install_deps_from, opt_user, opt_installation, + opt_yes, &error)) { g_printerr ("Error running %s: %s\n", argv[3], error->message); return 1; @@ -830,6 +836,7 @@ { if (!builder_maybe_host_spawnv (NULL, NULL, + 0, &error, argv)) { @@ -850,9 +857,10 @@ g_auto(GStrv) exclude_dirs = builder_manifest_get_exclude_dirs (manifest); GList *l; - export_repo = g_file_new_for_path (opt_repo); - if (opt_install && export_repo == NULL) - export_repo = builder_context_get_cache_dir (build_context); + if (opt_repo) + export_repo = g_file_new_for_path (opt_repo); + else if (opt_install) + export_repo = g_object_ref (builder_context_get_cache_dir (build_context)); g_print ("Exporting %s to repo\n", builder_manifest_get_id (manifest)); builder_set_term_title (_("Exporting to repository")); diff -Nru flatpak-builder-0.10.6/src/builder-manifest.c flatpak-builder-0.10.9/src/builder-manifest.c --- flatpak-builder-0.10.6/src/builder-manifest.c 2017-12-14 09:29:35.000000000 +0000 +++ flatpak-builder-0.10.9/src/builder-manifest.c 2018-02-16 10:37:25.000000000 +0000 @@ -1308,23 +1308,36 @@ return self->base_version ? self->base_version : builder_manifest_get_branch (self); } +G_GNUC_NULL_TERMINATED static char * flatpak (GError **error, ...) { gboolean res; g_autofree char *output = NULL; + g_autoptr(GPtrArray) ar = g_ptr_array_new (); va_list ap; va_start (ap, error); - res = flatpak_spawn (NULL, &output, 0, error, "flatpak", ap); + g_ptr_array_add (ar, "flatpak"); + while (TRUE) + { + gchar *param = va_arg (ap, gchar *); + g_ptr_array_add (ar, param); + if (param == NULL) + break; + } va_end (ap); + res = builder_maybe_host_spawnv (NULL, &output, 0, error, + (const gchar * const *)ar->pdata); + if (res) { g_strchomp (output); return g_steal_pointer (&output); } + return NULL; } @@ -1361,7 +1374,7 @@ g_ptr_array_add (args, g_strdup (ref)); g_ptr_array_add (args, NULL); - res = flatpak_spawnv (NULL, &output, G_SUBPROCESS_FLAGS_STDERR_SILENCE, error, (const char * const *)args->pdata); + res = builder_maybe_host_spawnv (NULL, &output, G_SUBPROCESS_FLAGS_STDERR_SILENCE, error, (const char * const *)args->pdata); if (res) { @@ -1867,7 +1880,7 @@ g_ptr_array_add (args, g_strdup (commandline)); g_ptr_array_add (args, NULL); - return builder_maybe_host_spawnv (NULL, NULL, error, (const char * const *)args->pdata); + return builder_maybe_host_spawnv (NULL, NULL, 0, error, (const char * const *)args->pdata); } typedef gboolean (*ForeachFileFunc) (BuilderManifest *self, @@ -2037,7 +2050,7 @@ g_ptr_array_add (args, NULL); va_end (ap); - if (!builder_maybe_host_spawnv (NULL, NULL, error, (const char * const *)args->pdata)) + if (!builder_maybe_host_spawnv (NULL, NULL, 0, error, (const char * const *)args->pdata)) { g_prefix_error (error, "ERROR: appstream-compose failed: "); return FALSE; @@ -3261,6 +3274,7 @@ const char *opt_installation, const char *runtime, const char *version, + gboolean opt_yes, GError **error) { g_autofree char *ref = NULL; @@ -3292,10 +3306,13 @@ g_ptr_array_add (args, g_strdup (remote)); } + if (opt_yes) + g_ptr_array_add (args, "-y"); + g_ptr_array_add (args, g_strdup (ref)); g_ptr_array_add (args, NULL); - if (!flatpak_spawnv (NULL, NULL, 0, error, (const char * const *)args->pdata)) + if (!builder_maybe_host_spawnv (NULL, NULL, 0, error, (const char * const *)args->pdata)) return FALSE; return TRUE; @@ -3309,6 +3326,7 @@ const char *remote, gboolean opt_user, const char *opt_installation, + gboolean opt_yes, GError **error) { g_autofree char *runtime_ref = flatpak_build_runtime_ref (runtime, builder_manifest_get_runtime_version (self), @@ -3355,6 +3373,7 @@ g_print ("Dependency Extension: %s %s\n", runtime_extensions[i], extension_version); if (!builder_manifest_install_dep (self, context, remote, opt_user, opt_installation, runtime_extensions[i], extension_version, + opt_yes, error)) return FALSE; } @@ -3368,12 +3387,14 @@ const char *remote, gboolean opt_user, const char *opt_installation, + gboolean opt_yes, GError **error) { /* Sdk */ g_print ("Dependency Sdk: %s %s\n", self->sdk, builder_manifest_get_runtime_version (self)); if (!builder_manifest_install_dep (self, context, remote, opt_user, opt_installation, self->sdk, builder_manifest_get_runtime_version (self), + opt_yes, error)) return FALSE; @@ -3381,6 +3402,7 @@ g_print ("Dependency Runtime: %s %s\n", self->runtime, builder_manifest_get_runtime_version (self)); if (!builder_manifest_install_dep (self, context, remote, opt_user, opt_installation, self->runtime, builder_manifest_get_runtime_version (self), + opt_yes, error)) return FALSE; @@ -3389,6 +3411,7 @@ g_print ("Dependency Base: %s %s\n", self->base, builder_manifest_get_base_version (self)); if (!builder_manifest_install_dep (self, context, remote, opt_user, opt_installation, self->base, builder_manifest_get_base_version (self), + opt_yes, error)) return FALSE; } @@ -3396,12 +3419,14 @@ if (!builder_manifest_install_extension_deps (self, context, self->sdk, self->sdk_extensions, remote,opt_user, opt_installation, + opt_yes, error)) return FALSE; if (!builder_manifest_install_extension_deps (self, context, self->runtime, self->platform_extensions, remote, opt_user, opt_installation, + opt_yes, error)) return FALSE; diff -Nru flatpak-builder-0.10.6/src/builder-manifest.h flatpak-builder-0.10.9/src/builder-manifest.h --- flatpak-builder-0.10.6/src/builder-manifest.h 2017-12-14 09:08:50.000000000 +0000 +++ flatpak-builder-0.10.9/src/builder-manifest.h 2018-02-16 10:37:25.000000000 +0000 @@ -94,6 +94,7 @@ const char *remote, gboolean opt_user, const char *opt_installation, + gboolean opt_yes, GError **error); gboolean builder_manifest_run (BuilderManifest *self, BuilderContext *context, diff -Nru flatpak-builder-0.10.6/src/builder-module.c flatpak-builder-0.10.9/src/builder-module.c --- flatpak-builder-0.10.6/src/builder-module.c 2017-12-11 10:04:15.000000000 +0000 +++ flatpak-builder-0.10.9/src/builder-module.c 2018-02-14 10:46:32.000000000 +0000 @@ -1279,7 +1279,7 @@ g_ptr_array_add (args, NULL); - if (!builder_maybe_host_spawnv (cwd_file, NULL, error, (const char * const *)args->pdata)) + if (!builder_maybe_host_spawnv (cwd_file, NULL, 0, error, (const char * const *)args->pdata)) { g_prefix_error (error, "module %s: ", module_name); return FALSE; diff -Nru flatpak-builder-0.10.6/src/builder-source-shell.c flatpak-builder-0.10.9/src/builder-source-shell.c --- flatpak-builder-0.10.6/src/builder-source-shell.c 2017-09-06 17:13:55.000000000 +0000 +++ flatpak-builder-0.10.9/src/builder-source-shell.c 2018-02-14 10:46:32.000000000 +0000 @@ -160,7 +160,7 @@ source_dir_path_canonical_file = g_file_new_for_path (source_dir_path_canonical); - return builder_maybe_host_spawnv (source_dir_path_canonical_file, NULL, error, (const char * const *)args->pdata); + return builder_maybe_host_spawnv (source_dir_path_canonical_file, NULL, 0, error, (const char * const *)args->pdata); } diff -Nru flatpak-builder-0.10.6/src/builder-utils.c flatpak-builder-0.10.9/src/builder-utils.c --- flatpak-builder-0.10.6/src/builder-utils.c 2017-12-07 14:40:32.000000000 +0000 +++ flatpak-builder-0.10.9/src/builder-utils.c 2018-02-14 10:46:32.000000000 +0000 @@ -1409,7 +1409,7 @@ if (client_pid == data->client_pid) { - g_print ("host_command_exited_cb %d %d\n", client_pid, exit_status); + g_debug ("host_command_exited_cb %d %d\n", client_pid, exit_status); data->exit_status = exit_status; host_command_call_exit (data); } @@ -1456,6 +1456,7 @@ gboolean builder_host_spawnv (GFile *dir, char **output, + GSubprocessFlags flags, GError **error, const gchar * const *argv) { @@ -1463,7 +1464,7 @@ GVariantBuilder *fd_builder = g_variant_builder_new (G_VARIANT_TYPE("a{uh}")); GVariantBuilder *env_builder = g_variant_builder_new (G_VARIANT_TYPE("a{ss}")); g_autoptr(GUnixFDList) fd_list = g_unix_fd_list_new (); - gint stdout_handle, stdin_handle, stderr_handle; + gint stdout_handle, stdin_handle, stderr_handle = -1; g_autoptr(GDBusConnection) connection = NULL; g_autoptr(GVariant) ret = NULL; g_autoptr(GMainLoop) loop = NULL; @@ -1534,13 +1535,16 @@ return FALSE; } - stderr_handle = g_unix_fd_list_append (fd_list, 2, error); - if (stderr_handle == -1) - return FALSE; - g_variant_builder_add (fd_builder, "{uh}", 0, stdin_handle); g_variant_builder_add (fd_builder, "{uh}", 1, stdout_handle); - g_variant_builder_add (fd_builder, "{uh}", 2, stderr_handle); + + if ((flags & G_SUBPROCESS_FLAGS_STDERR_SILENCE) == 0) + { + stderr_handle = g_unix_fd_list_append (fd_list, 2, error); + if (stderr_handle == -1) + return FALSE; + g_variant_builder_add (fd_builder, "{uh}", 2, stderr_handle); + } env_vars = g_listenv (); for (i = 0; env_vars[i] != NULL; i++) @@ -1575,6 +1579,11 @@ g_variant_get (ret, "(u)", &client_pid); data.client_pid = client_pid; + /* Drop the FDList immediately or splice_async() may not + * complete when the peer process exists, causing us to hang. + */ + g_clear_object (&fd_list); + g_main_loop_run (loop); g_source_remove (sigterm_id); @@ -1606,13 +1615,14 @@ gboolean builder_maybe_host_spawnv (GFile *dir, char **output, + GSubprocessFlags flags, GError **error, const gchar * const *argv) { if (flatpak_is_in_sandbox ()) - return builder_host_spawnv (dir, output, error, argv); + return builder_host_spawnv (dir, output, 0, error, argv); - return flatpak_spawnv (dir, output, 0, error, argv); + return flatpak_spawnv (dir, output, flags, error, argv); } /** diff -Nru flatpak-builder-0.10.6/src/builder-utils.h flatpak-builder-0.10.9/src/builder-utils.h --- flatpak-builder-0.10.6/src/builder-utils.h 2017-12-07 14:40:32.000000000 +0000 +++ flatpak-builder-0.10.9/src/builder-utils.h 2018-02-14 10:46:32.000000000 +0000 @@ -63,10 +63,12 @@ gboolean builder_host_spawnv (GFile *dir, char **output, + GSubprocessFlags flags, GError **error, const gchar * const *argv); gboolean builder_maybe_host_spawnv (GFile *dir, char **output, + GSubprocessFlags flags, GError **error, const gchar * const *argv);