summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2016-02-16 15:55:08 +0100
committerAlexander Larsson <alexl@redhat.com>2016-02-16 15:55:08 +0100
commitf5b006ff0ca206b3f760253baf73bd0a00ff71cd (patch)
tree984d8efd67e84d4910889046cad2fb5d74d31aa9
parent0bf9bc3d0b9833f3441f5e53ed35b2589f90c487 (diff)
downloadbubblewrap-f5b006ff0ca206b3f760253baf73bd0a00ff71cd.tar.gz
Support --make-file
-rw-r--r--build-root.c39
-rw-r--r--utils.c65
-rw-r--r--utils.h5
3 files changed, 109 insertions, 0 deletions
diff --git a/build-root.c b/build-root.c
index ac7ff31..dcea2d6 100644
--- a/build-root.c
+++ b/build-root.c
@@ -63,6 +63,7 @@ usage ()
" --mount-proc DEST Mount procfs on DEST in the sandbox\n"
" --mount-dev DEST Mount new dev on DEST in the sandbox\n"
" --make-dir DEST Create dir at DEST in the sandbox\n"
+ " --make-file FD DEST Copy from FD to dest DEST in the sandbox\n"
" --make-symlink SRC DEST Create symlink at DEST in the sandbox with target SRC\n"
" --make-passwd DEST Create trivial /etc/passwd file at DEST in the sandbox\n"
" --make-group DEST Create trivial /etc/group file at DEST in the sandbox\n"
@@ -296,6 +297,7 @@ typedef enum {
SETUP_MOUNT_PROC,
SETUP_MOUNT_DEV,
SETUP_MAKE_DIR,
+ SETUP_MAKE_FILE,
SETUP_MAKE_SYMLINK,
SETUP_MAKE_PASSWD,
SETUP_MAKE_GROUP,
@@ -307,6 +309,7 @@ struct _SetupOp {
SetupOpType type;
const char *source;
const char *dest;
+ int fd;
SetupOp *next;
};
@@ -319,6 +322,7 @@ setup_op_new (SetupOpType type)
SetupOp *op = xcalloc (sizeof (SetupOp));
op->type = type;
+ op->fd = -1;
if (last_op != NULL)
last_op->next = op;
else
@@ -518,6 +522,26 @@ main (int argc,
argv += 1;
argc -= 1;
}
+ else if (strcmp (arg, "--make-file") == 0)
+ {
+ SetupOp *op;
+ int file_fd;
+ char *endptr;
+
+ if (argc < 3)
+ die ("--make-file takes two arguments");
+
+ file_fd = strtol (argv[1], &endptr, 10);
+ if (argv[1][0] == 0 || endptr[0] != 0 || file_fd < 0)
+ die ("Invalid fd: %s", argv[1]);
+
+ op = setup_op_new (SETUP_MAKE_FILE);
+ op->fd = file_fd;
+ op->dest = argv[2];
+
+ argv += 2;
+ argc -= 2;
+ }
else if (strcmp (arg, "--make-symlink") == 0)
{
SetupOp *op;
@@ -840,6 +864,21 @@ main (int argc,
break;
+ case SETUP_MAKE_FILE:
+ {
+ cleanup_fd int dest_fd = -1;
+
+ dest_fd = creat (dest, 0666);
+ if (dest_fd == -1)
+ die_with_error ("Can't create file %s", op->dest);
+
+ if (copy_file_data (op->fd, dest_fd) != 0)
+ die_with_error ("Can't write data to file %s", op->dest);
+
+ close (op->fd);
+ }
+ break;
+
case SETUP_MAKE_SYMLINK:
if (symlink (op->source, dest) != 0)
die_with_error ("Can't make symlink at %s", op->dest);
diff --git a/utils.c b/utils.c
index f14857f..21c7fd7 100644
--- a/utils.c
+++ b/utils.c
@@ -330,6 +330,71 @@ create_file (const char *path,
return res;
}
+#define BUFSIZE 8192
+/* Sets errno on error (!= 0), ENOSPC on short write */
+int
+copy_file_data (int sfd,
+ int dfd)
+{
+ char buffer[BUFSIZE];
+ ssize_t bytes_read;
+
+ while (TRUE)
+ {
+ bytes_read = read (sfd, buffer, BUFSIZE);
+ if (bytes_read == -1)
+ {
+ if (errno == EINTR)
+ continue;
+
+ return -1;
+ }
+
+ if (bytes_read == 0)
+ break;
+
+ if (write_to_fd (dfd, buffer, bytes_read) != 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Sets errno on error (!= 0), ENOSPC on short write */
+int
+copy_file (const char *src_path,
+ const char *dst_path,
+ mode_t mode)
+{
+ int sfd;
+ int dfd;
+ int res;
+ int errsv;
+
+ sfd = open (src_path, O_CLOEXEC | O_RDONLY);
+ if (sfd == -1)
+ return -1;
+
+ dfd = creat (dst_path, mode);
+ if (dfd == -1)
+ {
+ errsv = errno;
+ close (sfd);
+ errno = errsv;
+ return -1;
+ }
+
+ res = copy_file_data (sfd, dfd);
+
+ errsv = errno;
+ close (sfd);
+ close (dfd);
+ errno = errsv;
+
+ return res;
+}
+
+
/* Sets errno on error (== NULL) */
char *
load_file_at (int dirfd,
diff --git a/utils.h b/utils.h
index 59fb3bc..435fb2c 100644
--- a/utils.h
+++ b/utils.h
@@ -81,6 +81,11 @@ int write_file_at (int dirfd,
int write_to_fd (int fd,
const char *content,
ssize_t len);
+int copy_file_data (int sfd,
+ int dfd);
+int copy_file (const char *src_path,
+ const char *dst_path,
+ mode_t mode);
int create_file (const char *path,
mode_t mode,
const char *content);