deploy: Port file copying code to GLnxDirFdIterator

It handles ownership of the `DIR*` for us more cleanly, and
is just a better API.

This is in preparation for further changes to this code to do SELinux
labeling while copying.

Closes: #428
Approved by: jlebon
This commit is contained in:
Colin Walters 2016-08-03 21:24:09 -04:00 committed by Atomic Bot
parent 8dab17f6db
commit 686d0352e1
1 changed files with 21 additions and 37 deletions

View File

@ -171,76 +171,60 @@ copy_dir_recurse (int src_parent_dfd,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
gboolean ret = FALSE; g_auto(GLnxDirFdIterator) src_dfd_iter = { 0, };
glnx_fd_close int src_dfd = -1;
glnx_fd_close int dest_dfd = -1; glnx_fd_close int dest_dfd = -1;
DIR *srcd = NULL;
struct dirent *dent; struct dirent *dent;
if (!ot_gopendirat (src_parent_dfd, name, TRUE, &src_dfd, error)) if (!glnx_dirfd_iterator_init_at (src_parent_dfd, name, TRUE, &src_dfd_iter, error))
goto out; return FALSE;
/* Create with mode 0700, we'll fchmod/fchown later */ /* Create with mode 0700, we'll fchmod/fchown later */
if (mkdirat (dest_parent_dfd, name, 0700) != 0) if (mkdirat (dest_parent_dfd, name, 0700) != 0)
{ {
glnx_set_error_from_errno (error); glnx_set_error_from_errno (error);
goto out; return FALSE;
} }
if (!ot_gopendirat (dest_parent_dfd, name, TRUE, &dest_dfd, error)) if (!glnx_opendirat (dest_parent_dfd, name, TRUE, &dest_dfd, error))
goto out; return FALSE;
if (!dirfd_copy_attributes_and_xattrs (src_parent_dfd, name, src_dfd, dest_dfd, if (!dirfd_copy_attributes_and_xattrs (src_parent_dfd, name, src_dfd_iter.fd, dest_dfd,
cancellable, error)) cancellable, error))
goto out; return FALSE;
srcd = fdopendir (src_dfd); while (TRUE)
if (!srcd)
{ {
glnx_set_error_from_errno (error);
goto out;
}
while ((dent = readdir (srcd)) != NULL)
{
const char *name = dent->d_name;
struct stat child_stbuf; struct stat child_stbuf;
if (strcmp (name, ".") == 0 || if (!glnx_dirfd_iterator_next_dent (&src_dfd_iter, &dent, cancellable, error))
strcmp (name, "..") == 0) return FALSE;
continue; if (dent == NULL)
break;
if (fstatat (src_dfd, name, &child_stbuf, if (fstatat (src_dfd_iter.fd, dent->d_name, &child_stbuf,
AT_SYMLINK_NOFOLLOW) != 0) AT_SYMLINK_NOFOLLOW) != 0)
{ {
glnx_set_error_from_errno (error); glnx_set_error_from_errno (error);
goto out; return FALSE;
} }
if (S_ISDIR (child_stbuf.st_mode)) if (S_ISDIR (child_stbuf.st_mode))
{ {
if (!copy_dir_recurse (src_dfd, dest_dfd, name, if (!copy_dir_recurse (src_dfd_iter.fd, dest_dfd, dent->d_name,
cancellable, error)) cancellable, error))
goto out; return FALSE;
} }
else else
{ {
if (!glnx_file_copy_at (src_dfd, name, &child_stbuf, dest_dfd, name, if (!glnx_file_copy_at (src_dfd_iter.fd, dent->d_name, &child_stbuf,
dest_dfd, dent->d_name,
GLNX_FILE_COPY_OVERWRITE, GLNX_FILE_COPY_OVERWRITE,
cancellable, error)) cancellable, error))
goto out; return FALSE;
} }
} }
ret = TRUE; return TRUE;
out:
if (srcd)
{
(void) closedir (srcd);
/* Note the srcd owns src_dfd */
src_dfd = -1;
}
return ret;
} }
static gboolean static gboolean