New upstream version 2016.8
This commit is contained in:
commit
ba02f3eb2f
250 files changed
+80671
-11685
No files matched your search
@@ -1,16 +0,0 @@
|
||||
# A path ostree writes to work around automake bug with
|
||||
# subdir-objects
|
||||
Makefile-libglnx.am.inc
|
||||
|
||||
# Some standard bits
|
||||
.deps
|
||||
.libs
|
||||
.dirstamp
|
||||
*.typelib
|
||||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
*.pyc
|
||||
*.stamp
|
||||
*~
|
||||
|
||||
@@ -37,6 +37,8 @@ libglnx_la_SOURCES = \
|
||||
$(libglnx_srcpath)/glnx-lockfile.c \
|
||||
$(libglnx_srcpath)/glnx-libcontainer.h \
|
||||
$(libglnx_srcpath)/glnx-libcontainer.c \
|
||||
$(libglnx_srcpath)/glnx-missing-syscall.h \
|
||||
$(libglnx_srcpath)/glnx-missing.h \
|
||||
$(libglnx_srcpath)/glnx-xattrs.h \
|
||||
$(libglnx_srcpath)/glnx-xattrs.c \
|
||||
$(libglnx_srcpath)/glnx-shutil.h \
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# Copyright (C) 2015 Colin Walters <walters@verbum.org>
|
||||
#
|
||||
# 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.
|
||||
|
||||
EXTRA_DIST += libglnx/README.md libglnx/COPYING
|
||||
|
||||
libglnx_la_SOURCES = \
|
||||
libglnx/glnx-alloca.h \
|
||||
libglnx/glnx-backport-autocleanups.h \
|
||||
libglnx/glnx-backport-autoptr.h \
|
||||
libglnx/glnx-backports.h \
|
||||
libglnx/glnx-backports.c \
|
||||
libglnx/glnx-local-alloc.h \
|
||||
libglnx/glnx-local-alloc.c \
|
||||
libglnx/glnx-errors.h \
|
||||
libglnx/glnx-errors.c \
|
||||
libglnx/glnx-console.h \
|
||||
libglnx/glnx-console.c \
|
||||
libglnx/glnx-dirfd.h \
|
||||
libglnx/glnx-dirfd.c \
|
||||
libglnx/glnx-fdio.h \
|
||||
libglnx/glnx-fdio.c \
|
||||
libglnx/glnx-lockfile.h \
|
||||
libglnx/glnx-lockfile.c \
|
||||
libglnx/glnx-libcontainer.h \
|
||||
libglnx/glnx-libcontainer.c \
|
||||
libglnx/glnx-missing-syscall.h \
|
||||
libglnx/glnx-missing.h \
|
||||
libglnx/glnx-xattrs.h \
|
||||
libglnx/glnx-xattrs.c \
|
||||
libglnx/glnx-shutil.h \
|
||||
libglnx/glnx-shutil.c \
|
||||
libglnx/libglnx.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)
|
||||
@@ -221,9 +221,11 @@ text_percent_internal (const char *text,
|
||||
|
||||
if (percentage == -1)
|
||||
{
|
||||
const guint spacelen = ncolumns - input_textlen;
|
||||
fwrite (text, 1, input_textlen, stdout);
|
||||
printpad (spaces, n_spaces, spacelen);
|
||||
|
||||
/* Overwrite remaining space, if any */
|
||||
if (ncolumns > input_textlen)
|
||||
printpad (spaces, n_spaces, ncolumns - input_textlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+277
-35
@@ -37,10 +37,255 @@
|
||||
|
||||
#include <glnx-fdio.h>
|
||||
#include <glnx-dirfd.h>
|
||||
#include <glnx-alloca.h>
|
||||
#include <glnx-errors.h>
|
||||
#include <glnx-xattrs.h>
|
||||
#include <glnx-backport-autoptr.h>
|
||||
#include <glnx-local-alloc.h>
|
||||
#include <glnx-missing.h>
|
||||
|
||||
/* Returns the number of chars needed to format variables of the
|
||||
* specified type as a decimal string. Adds in extra space for a
|
||||
* negative '-' prefix (hence works correctly on signed
|
||||
* types). Includes space for the trailing NUL. */
|
||||
#define DECIMAL_STR_MAX(type) \
|
||||
(2+(sizeof(type) <= 1 ? 3 : \
|
||||
sizeof(type) <= 2 ? 5 : \
|
||||
sizeof(type) <= 4 ? 10 : \
|
||||
sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)])))
|
||||
|
||||
static gboolean
|
||||
rename_file_noreplace_at (int olddirfd, const char *oldpath,
|
||||
int newdirfd, const char *newpath,
|
||||
gboolean ignore_eexist,
|
||||
GError **error)
|
||||
{
|
||||
if (renameat2 (olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE) < 0)
|
||||
{
|
||||
if (errno == EINVAL || errno == ENOSYS)
|
||||
{
|
||||
/* Fall through */
|
||||
;
|
||||
}
|
||||
else if (errno == EEXIST && ignore_eexist)
|
||||
{
|
||||
(void) unlinkat (olddirfd, oldpath, 0);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
|
||||
if (linkat (olddirfd, oldpath, newdirfd, newpath, 0) < 0)
|
||||
{
|
||||
if (errno == EEXIST && ignore_eexist)
|
||||
/* Fall through */
|
||||
;
|
||||
else
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (unlinkat (olddirfd, oldpath, 0) < 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
glnx_open_tmpfile_linkable_at (int dfd,
|
||||
const char *subpath,
|
||||
int flags,
|
||||
int *out_fd,
|
||||
char **out_path,
|
||||
GError **error)
|
||||
{
|
||||
glnx_fd_close int fd = -1;
|
||||
int count;
|
||||
|
||||
/* 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
|
||||
* tempoary path name used is returned in "ret_path". Use
|
||||
* link_tmpfile() below to rename the result after writing the file
|
||||
* in full. */
|
||||
#if defined(O_TMPFILE) && !defined(DISABLE_OTMPFILE)
|
||||
fd = openat (dfd, subpath, O_TMPFILE|flags, 0600);
|
||||
if (fd == -1 && !(errno == ENOSYS || errno == EISDIR || errno == EOPNOTSUPP))
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "%s", "open(O_TMPFILE)");
|
||||
return FALSE;
|
||||
}
|
||||
if (fd != -1)
|
||||
{
|
||||
*out_fd = fd;
|
||||
fd = -1;
|
||||
*out_path = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
/* Fallthrough */
|
||||
#endif
|
||||
|
||||
{ g_autofree char *tmp = g_strconcat (subpath, "/tmp.XXXXXX", NULL);
|
||||
const guint count_max = 100;
|
||||
|
||||
for (count = 0; count < count_max; count++)
|
||||
{
|
||||
glnx_gen_temp_name (tmp);
|
||||
|
||||
fd = openat (dfd, tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0600);
|
||||
if (fd < 0)
|
||||
{
|
||||
if (errno == EEXIST)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
glnx_set_prefix_error_from_errno (error, "%s", "Creating temp file");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*out_fd = fd;
|
||||
fd = -1;
|
||||
*out_path = g_steal_pointer (&tmp);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
|
||||
"Exhausted %u attempts to create temporary file", count);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
glnx_link_tmpfile_at (int dfd,
|
||||
GLnxLinkTmpfileReplaceMode mode,
|
||||
int fd,
|
||||
const char *tmpfile_path,
|
||||
int target_dfd,
|
||||
const char *target,
|
||||
GError **error)
|
||||
{
|
||||
const gboolean replace = (mode == GLNX_LINK_TMPFILE_REPLACE);
|
||||
const gboolean ignore_eexist = (mode == GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST);
|
||||
|
||||
g_return_val_if_fail (fd >= 0, FALSE);
|
||||
|
||||
/* Unlike the original systemd code, this function also supports
|
||||
* replacing existing files.
|
||||
*/
|
||||
|
||||
/* We have `tmpfile_path` for old systems without O_TMPFILE. */
|
||||
if (tmpfile_path)
|
||||
{
|
||||
if (replace)
|
||||
{
|
||||
/* We have a regular tempfile, we're overwriting - this is a
|
||||
* simple renameat().
|
||||
*/
|
||||
if (renameat (dfd, tmpfile_path, target_dfd, target) < 0)
|
||||
{
|
||||
(void) unlinkat (dfd, tmpfile_path, 0);
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We need to use renameat2(..., NOREPLACE) or emulate it */
|
||||
if (!rename_file_noreplace_at (dfd, tmpfile_path, target_dfd, target,
|
||||
ignore_eexist,
|
||||
error))
|
||||
{
|
||||
(void) unlinkat (dfd, tmpfile_path, 0);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This case we have O_TMPFILE, so our reference to it is via /proc/self/fd */
|
||||
char proc_fd_path[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
|
||||
|
||||
sprintf (proc_fd_path, "/proc/self/fd/%i", fd);
|
||||
|
||||
if (replace)
|
||||
{
|
||||
/* In this case, we had our temp file atomically hidden, but now
|
||||
* we need to make it visible in the FS so we can do a rename.
|
||||
* Ideally, linkat() would gain AT_REPLACE or so.
|
||||
*/
|
||||
/* TODO - avoid double alloca, we can just alloca a copy of
|
||||
* the pathname plus space for tmp.XXXXX */
|
||||
char *dnbuf = strdupa (target);
|
||||
const char *dn = dirname (dnbuf);
|
||||
char *tmpname_buf = glnx_strjoina (dn, "/tmp.XXXXXX");
|
||||
guint count;
|
||||
const guint count_max = 100;
|
||||
|
||||
for (count = 0; count < count_max; count++)
|
||||
{
|
||||
glnx_gen_temp_name (tmpname_buf);
|
||||
|
||||
if (linkat (AT_FDCWD, proc_fd_path, target_dfd, tmpname_buf, AT_SYMLINK_FOLLOW) < 0)
|
||||
{
|
||||
if (errno == EEXIST)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (count == count_max)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
|
||||
"Exhausted %u attempts to create temporary file", count);
|
||||
}
|
||||
if (renameat (target_dfd, tmpname_buf, target_dfd, target) < 0)
|
||||
{
|
||||
/* This is currently the only case where we need to have
|
||||
* a cleanup unlinkat() still with O_TMPFILE.
|
||||
*/
|
||||
(void) unlinkat (target_dfd, tmpname_buf, 0);
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (linkat (AT_FDCWD, proc_fd_path, target_dfd, target, AT_SYMLINK_FOLLOW) < 0)
|
||||
{
|
||||
if (errno == EEXIST && mode == GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST)
|
||||
;
|
||||
else
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guint8*
|
||||
glnx_fd_readall_malloc (int fd,
|
||||
@@ -658,38 +903,45 @@ glnx_file_replace_contents_with_perms_at (int dfd,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
int r;
|
||||
/* We use the /proc/self trick as there's no mkostemp_at() yet */
|
||||
g_autofree char *tmppath = g_strdup_printf ("/proc/self/fd/%d/.tmpXXXXXX", dfd);
|
||||
char *dnbuf = strdupa (subpath);
|
||||
const char *dn = dirname (dnbuf);
|
||||
g_autofree char *tmpfile_path = NULL;
|
||||
glnx_fd_close int fd = -1;
|
||||
|
||||
dfd = glnx_dirfd_canonicalize (dfd);
|
||||
|
||||
if ((fd = g_mkstemp_full (tmppath, O_WRONLY | O_CLOEXEC,
|
||||
mode == (mode_t) -1 ? 0666 : mode)) == -1)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
/* With O_TMPFILE we can't use umask, and we can't sanely query the
|
||||
* umask...let's assume something relatively standard.
|
||||
*/
|
||||
if (mode == (mode_t) -1)
|
||||
mode = 0644;
|
||||
|
||||
if (!glnx_open_tmpfile_linkable_at (dfd, dn, O_WRONLY | O_CLOEXEC,
|
||||
&fd, &tmpfile_path,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
if (len == -1)
|
||||
len = strlen ((char*)buf);
|
||||
|
||||
/* Note that posix_fallocate does *not* set errno but returns it. */
|
||||
r = posix_fallocate (fd, 0, len);
|
||||
if (r != 0)
|
||||
if (len > 0)
|
||||
{
|
||||
errno = r;
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
r = posix_fallocate (fd, 0, len);
|
||||
if (r != 0)
|
||||
{
|
||||
errno = r;
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((r = glnx_loop_write (fd, buf, len)) != 0)
|
||||
{
|
||||
errno = -r;
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!(flags & GLNX_FILE_REPLACE_NODATASYNC))
|
||||
@@ -702,7 +954,7 @@ glnx_file_replace_contents_with_perms_at (int dfd,
|
||||
if (errno != ENOENT)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
return FALSE;
|
||||
}
|
||||
do_sync = (flags & GLNX_FILE_REPLACE_DATASYNC_NEW) > 0;
|
||||
}
|
||||
@@ -714,7 +966,7 @@ glnx_file_replace_contents_with_perms_at (int dfd,
|
||||
if (fdatasync (fd) != 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -724,31 +976,21 @@ glnx_file_replace_contents_with_perms_at (int dfd,
|
||||
if (fchown (fd, uid, gid) != 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If a mode was forced, override umask */
|
||||
if (mode != (mode_t) -1)
|
||||
{
|
||||
if (fchmod (fd, mode) != 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (renameat (dfd, tmppath, dfd, subpath) != 0)
|
||||
if (fchmod (fd, mode) != 0)
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
if (!ret)
|
||||
(void) unlink (tmppath);
|
||||
return ret;
|
||||
if (!glnx_link_tmpfile_at (dfd, GLNX_LINK_TMPFILE_REPLACE,
|
||||
fd, tmpfile_path, dfd, subpath, error))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -46,6 +46,29 @@ const char *glnx_basename (const char *path)
|
||||
return (basename) (path);
|
||||
}
|
||||
|
||||
gboolean
|
||||
glnx_open_tmpfile_linkable_at (int dfd,
|
||||
const char *subpath,
|
||||
int flags,
|
||||
int *out_fd,
|
||||
char **out_path,
|
||||
GError **error);
|
||||
|
||||
typedef enum {
|
||||
GLNX_LINK_TMPFILE_REPLACE,
|
||||
GLNX_LINK_TMPFILE_NOREPLACE,
|
||||
GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST
|
||||
} GLnxLinkTmpfileReplaceMode;
|
||||
|
||||
gboolean
|
||||
glnx_link_tmpfile_at (int dfd,
|
||||
GLnxLinkTmpfileReplaceMode flags,
|
||||
int fd,
|
||||
const char *tmpfile_path,
|
||||
int target_dfd,
|
||||
const char *target,
|
||||
GError **error);
|
||||
|
||||
GBytes *
|
||||
glnx_fd_readall_bytes (int fd,
|
||||
GCancellable *cancellable,
|
||||
|
||||
+27
-11
@@ -33,6 +33,7 @@
|
||||
#include <gio/gunixoutputstream.h>
|
||||
|
||||
#include "glnx-libcontainer.h"
|
||||
#include "glnx-dirfd.h"
|
||||
|
||||
#include "glnx-backport-autocleanups.h"
|
||||
#include "glnx-local-alloc.h"
|
||||
@@ -104,9 +105,9 @@ glnx_libcontainer_bind_mount_readonly (const char *path, GError **error)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Based on code from nspawn.c */
|
||||
/* Based on code from nspawn.c; assumes process cwd is the target */
|
||||
static int
|
||||
glnx_libcontainer_make_api_mounts (const char *dest)
|
||||
glnx_libcontainer_make_api_mounts (void)
|
||||
{
|
||||
typedef struct MountPoint {
|
||||
const char *what;
|
||||
@@ -134,10 +135,11 @@ glnx_libcontainer_make_api_mounts (const char *dest)
|
||||
|
||||
for (k = 0; k < G_N_ELEMENTS(mount_table); k++)
|
||||
{
|
||||
g_autofree char *where = NULL;
|
||||
const char *where = mount_table[k].where;
|
||||
int t;
|
||||
|
||||
where = g_build_filename (dest, mount_table[k].where, NULL);
|
||||
g_assert (where[0] == '/');
|
||||
where++;
|
||||
|
||||
t = mkdir (where, 0755);
|
||||
if (t < 0 && errno != EEXIST)
|
||||
@@ -201,9 +203,9 @@ glnx_libcontainer_prep_dev (const char *dest_devdir)
|
||||
}
|
||||
|
||||
pid_t
|
||||
glnx_libcontainer_run_chroot_private (const char *dest,
|
||||
const char *binary,
|
||||
char **argv)
|
||||
glnx_libcontainer_run_chroot_at_private (int dfd,
|
||||
const char *binary,
|
||||
char **argv)
|
||||
{
|
||||
/* Make most new namespaces; note our use of CLONE_NEWNET means we
|
||||
* have no networking in the container root.
|
||||
@@ -250,12 +252,12 @@ glnx_libcontainer_run_chroot_private (const char *dest,
|
||||
}
|
||||
}
|
||||
|
||||
if (chdir (dest) != 0)
|
||||
_perror_fatal ("chdir: ");
|
||||
if (fchdir (dfd) != 0)
|
||||
_perror_fatal ("fchdir: ");
|
||||
|
||||
if (!in_container)
|
||||
{
|
||||
if (glnx_libcontainer_make_api_mounts (dest) != 0)
|
||||
if (glnx_libcontainer_make_api_mounts () != 0)
|
||||
_perror_fatal ("preparing api mounts: ");
|
||||
|
||||
if (glnx_libcontainer_prep_dev ("dev") != 0)
|
||||
@@ -264,7 +266,7 @@ glnx_libcontainer_run_chroot_private (const char *dest,
|
||||
if (mount (".", ".", NULL, MS_BIND | MS_PRIVATE, NULL) != 0)
|
||||
_perror_fatal ("mount (MS_BIND)");
|
||||
|
||||
if (mount (dest, "/", NULL, MS_MOVE, NULL) != 0)
|
||||
if (mount (".", "/", NULL, MS_MOVE, NULL) != 0)
|
||||
_perror_fatal ("mount (MS_MOVE)");
|
||||
}
|
||||
|
||||
@@ -295,3 +297,17 @@ glnx_libcontainer_run_chroot_private (const char *dest,
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
pid_t
|
||||
glnx_libcontainer_run_chroot_private (const char *dest,
|
||||
const char *binary,
|
||||
char **argv)
|
||||
{
|
||||
glnx_fd_close int dfd = -1;
|
||||
|
||||
dfd = glnx_opendirat_with_errno (AT_FDCWD, dest, TRUE);
|
||||
if (dfd < 0)
|
||||
return -1;
|
||||
|
||||
return glnx_libcontainer_run_chroot_at_private (dfd, binary, argv);
|
||||
}
|
||||
@@ -31,6 +31,10 @@
|
||||
#include <sys/capability.h>
|
||||
#include <sched.h>
|
||||
|
||||
pid_t glnx_libcontainer_run_chroot_at_private (int root_dfd,
|
||||
const char *binary,
|
||||
char **argv);
|
||||
|
||||
pid_t glnx_libcontainer_run_chroot_private (const char *dest,
|
||||
const char *binary,
|
||||
char **argv);
|
||||
@@ -187,7 +187,8 @@ void glnx_release_lock_file(GLnxLockFile *f) {
|
||||
f->path = NULL;
|
||||
}
|
||||
|
||||
(void) close (f->fd);
|
||||
if (f->fd != -1)
|
||||
(void) close (f->fd);
|
||||
f->fd = -1;
|
||||
f->operation = 0;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/***
|
||||
This file was originally part of systemd.
|
||||
|
||||
Copyright 2010 Lennart Poettering
|
||||
Copyright 2016 Zbigniew Jędrzejewski-Szmek
|
||||
|
||||
systemd 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.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
/* Missing glibc definitions to access certain kernel APIs */
|
||||
|
||||
#if !HAVE_DECL_RENAMEAT2
|
||||
# ifndef __NR_renameat2
|
||||
# if defined __x86_64__
|
||||
# define __NR_renameat2 316
|
||||
# elif defined __arm__
|
||||
# define __NR_renameat2 382
|
||||
# elif defined _MIPS_SIM
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI32
|
||||
# define __NR_renameat2 4351
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_NABI32
|
||||
# define __NR_renameat2 6315
|
||||
# endif
|
||||
# if _MIPS_SIM == _MIPS_SIM_ABI64
|
||||
# define __NR_renameat2 5311
|
||||
# endif
|
||||
# elif defined __i386__
|
||||
# define __NR_renameat2 353
|
||||
# else
|
||||
# warning "__NR_renameat2 unknown for your architecture"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
static inline int renameat2(int oldfd, const char *oldname, int newfd, const char *newname, unsigned flags) {
|
||||
# ifdef __NR_renameat2
|
||||
return syscall(__NR_renameat2, oldfd, oldname, newfd, newname, flags);
|
||||
# else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
This file was originally part of systemd.
|
||||
|
||||
Copyright 2010 Lennart Poettering
|
||||
|
||||
systemd 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.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd 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 systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
/* Missing glibc definitions to access certain kernel APIs */
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <uchar.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#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. */
|
||||
|
||||
#ifndef __O_TMPFILE
|
||||
#define __O_TMPFILE 020000000
|
||||
#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
|
||||
|
||||
#include "glnx-missing-syscall.h"
|
||||
+1
-40
@@ -26,26 +26,6 @@
|
||||
#include <glnx-errors.h>
|
||||
#include <glnx-local-alloc.h>
|
||||
|
||||
static unsigned char
|
||||
struct_stat_to_dt (struct stat *stbuf)
|
||||
{
|
||||
if (S_ISDIR (stbuf->st_mode))
|
||||
return DT_DIR;
|
||||
if (S_ISREG (stbuf->st_mode))
|
||||
return DT_REG;
|
||||
if (S_ISCHR (stbuf->st_mode))
|
||||
return DT_CHR;
|
||||
if (S_ISBLK (stbuf->st_mode))
|
||||
return DT_BLK;
|
||||
if (S_ISFIFO (stbuf->st_mode))
|
||||
return DT_FIFO;
|
||||
if (S_ISLNK (stbuf->st_mode))
|
||||
return DT_LNK;
|
||||
if (S_ISSOCK (stbuf->st_mode))
|
||||
return DT_SOCK;
|
||||
return DT_UNKNOWN;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
glnx_shutil_rm_rf_children (GLnxDirFdIterator *dfd_iter,
|
||||
GCancellable *cancellable,
|
||||
@@ -56,31 +36,12 @@ glnx_shutil_rm_rf_children (GLnxDirFdIterator *dfd_iter,
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (!glnx_dirfd_iterator_next_dent (dfd_iter, &dent, cancellable, error))
|
||||
if (!glnx_dirfd_iterator_next_dent_ensure_dtype (dfd_iter, &dent, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (dent == NULL)
|
||||
break;
|
||||
|
||||
if (dent->d_type == DT_UNKNOWN)
|
||||
{
|
||||
struct stat stbuf;
|
||||
if (fstatat (dfd_iter->fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
dent->d_type = struct_stat_to_dt (&stbuf);
|
||||
/* Assume unknown types are just treated like regular files */
|
||||
if (dent->d_type == DT_UNKNOWN)
|
||||
dent->d_type = DT_REG;
|
||||
}
|
||||
|
||||
if (dent->d_type == DT_DIR)
|
||||
{
|
||||
g_auto(GLnxDirFdIterator) child_dfd_iter = { 0, };
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
|
||||
xmlns:foaf="http://xmlns.com/foaf/0.1/"
|
||||
xmlns:gnome="http://api.gnome.org/doap-extensions#"
|
||||
xmlns="http://usefulinc.com/ns/doap#">
|
||||
|
||||
<name>libglnx</name>
|
||||
<shortname>libglnx</shortname>
|
||||
|
||||
<shortdesc xml:lang="en">"Copylib" for system service modules using GLib with Linux</shortdesc>
|
||||
|
||||
<description xml:lang="en">This module is intended for use by
|
||||
infrastructure code using GLib that is also Linux specific, such as
|
||||
ostree, NetworkManager, and others.
|
||||
</description>
|
||||
|
||||
<license rdf:resource="http://usefulinc.com/doap/licenses/lgpl" />
|
||||
<mailing-list rdf:resource="mailto:desktop-devel-list@gnome.org" />
|
||||
|
||||
<programming-language>C</programming-language>
|
||||
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Colin Walters</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:walters@verbum.org"/>
|
||||
<gnome:userid>walters</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
|
||||
</Project>
|
||||
Reference in new issue
Block a user