New upstream version 2017.13

This commit is contained in:
Simon McVittie committed 2017-11-04 11:55:24 +00:00
commit 8f7f43a65b
174 files changed
+5474 -2244

No files matched your search

+5 -1
View File
@@ -53,7 +53,7 @@ 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)
@@ -72,3 +72,7 @@ test_libglnx_errors_LDADD = $(libglnx_libs) libglnx.la
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
+1 -1
View File
@@ -37,7 +37,7 @@ applicable.
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`.
+10 -18
View File
@@ -99,7 +99,7 @@ glnx_dirfd_iterator_init_at (int dfd,
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;
@@ -190,15 +190,12 @@ glnx_dirfd_iterator_next_dent_ensure_dtype (GLnxDirFdIterator *dfd_iter,
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)
{
@@ -265,20 +262,16 @@ glnx_fdrel_abspath (int dfd,
void
glnx_gen_temp_name (gchar *tmpl)
{
size_t len;
char *XXXXXX;
int i;
g_return_if_fail (tmpl != NULL);
const size_t len = strlen (tmpl);
g_return_if_fail (len >= 6);
static const char letters[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
static const int NLETTERS = sizeof (letters) - 1;
g_return_if_fail (tmpl != NULL);
len = strlen (tmpl);
g_return_if_fail (len >= 6);
XXXXXX = tmpl + (len - 6);
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)];
}
@@ -326,7 +319,7 @@ glnx_mkdtempat (int dfd, const char *tmpl, int mode,
}
/* And open it */
glnx_fd_close int ret_dfd = -1;
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 */
@@ -382,8 +375,7 @@ _glnx_tmpdir_free (GLnxTmpDir *tmpd,
if (!(tmpd && tmpd->initialized))
return TRUE;
g_assert_cmpint (tmpd->fd, !=, -1);
(void) close (tmpd->fd);
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 */
+43 -46
View File
@@ -141,7 +141,14 @@ glnx_renameat2_exchange (int olddirfd, const char *oldpath,
#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,11 +175,7 @@ glnx_tmpfile_clear (GLnxTmpfile *tmpf)
return;
if (!tmpf->initialized)
return;
if (tmpf->fd != -1)
{
if (close (tmpf->fd) < 0)
g_assert (errno != EBADF);
}
glnx_close_fd (&tmpf->fd);
/* If ->path is set, we're likely aborting due to an error. Clean it up */
if (tmpf->path)
{
@@ -188,9 +191,8 @@ open_tmpfile_core (int dfd, const char *subpath,
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);
@@ -201,33 +203,35 @@ open_tmpfile_core (int dfd, const char *subpath,
* 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)
@@ -246,7 +250,7 @@ open_tmpfile_core (int dfd, const char *subpath,
}
}
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;
}
@@ -356,9 +360,9 @@ glnx_link_tmpfile_at (GLnxTmpfile *tmpf,
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);
@@ -569,7 +573,7 @@ glnx_file_get_contents_utf8_at (int dfd,
{
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;
@@ -599,17 +603,13 @@ glnx_readlinkat_malloc (int dfd,
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_prefix (error, "readlinkat");
@@ -679,18 +679,15 @@ copy_symlink_at (int src_dfd,
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)
@@ -926,7 +923,7 @@ glnx_file_copy_at (int src_dfd,
/* Regular file path below here */
glnx_fd_close int src_fd = -1;
glnx_autofd int src_fd = -1;
if (!glnx_openat_rdonly (src_dfd, src_subpath, FALSE, &src_fd, error))
return FALSE;
+5 -8
View File
@@ -299,7 +299,7 @@ glnx_fstatat (int dfd,
* glnx_fstatat_allow_noent:
* @dfd: Directory FD to stat beneath
* @path: Path to stat beneath @dfd
* @buf: (out caller-allocates): Return location for stat details
* @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
*
@@ -318,15 +318,12 @@ glnx_fstatat_allow_noent (int dfd,
int flags,
GError **error)
{
if (TEMP_FAILURE_RETRY (fstatat (dfd, path, out_buf, flags)) != 0)
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)
{
int errsv = errno;
(void) glnx_throw_errno_prefix (error, "fstatat(%s)", path);
errno = errsv;
return FALSE;
}
return glnx_throw_errno_prefix (error, "fstatat(%s)", path);
/* Note we preserve errno as ENOENT */
}
else
errno = 0;
+27 -13
View File
@@ -42,14 +42,30 @@ glnx_local_obj_unref (void *v)
}
#define glnx_unref_object __attribute__ ((cleanup(glnx_local_obj_unref)))
static inline void
glnx_cleanup_close_fdp (int *fdp)
static inline int
glnx_steal_fd (int *fdp)
{
int fd, errsv;
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_close_fd (int *fdp)
{
int errsv;
g_assert (fdp);
fd = *fdp;
int fd = glnx_steal_fd (fdp);
if (fd >= 0)
{
errsv = errno;
@@ -62,16 +78,14 @@ glnx_cleanup_close_fdp (int *fdp)
/**
* 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
+3 -6
View File
@@ -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;
@@ -119,8 +119,7 @@ glnx_make_lock_file(int dfd, const char *p, int operation, GLnxLockFile *out_loc
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
@@ -174,9 +173,7 @@ void glnx_release_lock_file(GLnxLockFile *f) {
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;
}
+59 -1
View File
@@ -18,7 +18,18 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
/* 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 <daniel@zonque.org>
AuthorDate: Tue Oct 18 17:57:10 2016 +0200
Commit: Lennart Poettering <lennart@poettering.net>
CommitDate: Fri Sep 22 15:24:54 2017 +0200
Add abstraction model for BPF programs
*/
#if !HAVE_DECL_RENAMEAT2
# ifndef __NR_renameat2
@@ -26,6 +37,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 +51,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
@@ -53,6 +72,45 @@ static inline int renameat2(int oldfd, const char *oldname, int newfd, const cha
}
#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
/* Copied from systemd git:
commit 6bda23dd6aaba50cf8e3e6024248cf736cc443ca
Author: Yu Watanabe <watanabe.yu+github@gmail.com>
+47 -7
View File
@@ -19,7 +19,17 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
/* 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 <daniel@zonque.org>
AuthorDate: Tue Oct 18 17:57:10 2016 +0200
Commit: Lennart Poettering <lennart@poettering.net>
CommitDate: Fri Sep 22 15:24:54 2017 +0200
Add abstraction model for BPF programs
*/
#include <errno.h>
#include <fcntl.h>
@@ -29,22 +39,30 @@
#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. */
/* 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"
+4 -5
View File
@@ -84,14 +84,12 @@ glnx_shutil_rm_rf_at (int dfd,
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 @@ glnx_shutil_rm_rf_at (int dfd,
}
else
{
g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
if (!glnx_dirfd_iterator_init_take_fd (&target_dfd, &dfd_iter, error))
return FALSE;
+1
View File
@@ -25,6 +25,7 @@
G_BEGIN_DECLS
#include <glnx-macros.h>
#include <glnx-missing.h>
#include <glnx-local-alloc.h>
#include <glnx-backport-autocleanups.h>
#include <glnx-backports.h>
+1 -3
View File
@@ -1,8 +1,6 @@
AC_DEFUN([LIBGLNX_CONFIGURE],
[
AC_CHECK_DECLS([
renameat2,
],
AC_CHECK_DECLS([renameat2, memfd_create],
[], [], [[
#include <sys/types.h>
#include <unistd.h>
+16 -7
View File
@@ -32,8 +32,8 @@ 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)
@@ -62,8 +62,8 @@ static void
test_renameat2_noreplace (void)
{
_GLNX_TEST_DECLARE_ERROR(local_error, error);
glnx_fd_close int srcfd = -1;
glnx_fd_close int destfd = -1;
glnx_autofd int srcfd = -1;
glnx_autofd int destfd = -1;
struct stat stbuf;
if (!renameat_test_setup (&srcfd, &destfd, error))
@@ -92,8 +92,8 @@ test_renameat2_exchange (void)
{
_GLNX_TEST_DECLARE_ERROR(local_error, error);
glnx_fd_close int srcfd = -1;
glnx_fd_close int destfd = -1;
glnx_autofd int srcfd = -1;
glnx_autofd int destfd = -1;
if (!renameat_test_setup (&srcfd, &destfd, error))
return;
@@ -161,13 +161,22 @@ test_fstatat (void)
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);
g_auto(GLnxTmpfile) tmpf = { 0, };
const char foo[] = "foo";
struct stat stbuf;
+63
View File
@@ -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 <glib.h>
#include <stdlib.h>
#include <gio/gio.h>
#include <err.h>
#include <string.h>
#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;
}
+3 -3
View File
@@ -82,7 +82,7 @@ do_write_run (GLnxDirFdIterator *dfd_iter, GError **error)
{
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 @@ do_write_run (GLnxDirFdIterator *dfd_iter, GError **error)
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 @@ do_read_run (GLnxDirFdIterator *dfd_iter,
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;