From dbba40b5a3722e4acb0cc043f0be1bebff872f27 Mon Sep 17 00:00:00 2001 From: Michael Vrable Date: Thu, 16 Aug 2007 15:53:29 -0700 Subject: [PATCH] Cleanup of the tar-store code. - Make spawn_filter generic, not part of Tarfile, so that it can be used by other parts of the code. (Specifically, it should be used later when writing out a segment descriptor, so that the descriptor can be filtered through gpg for signing.) - Drop internal_write_object. It had only one caller, so simply inline the code. --- store.cc | 23 ++++++++++------------- store.h | 12 ++++++++---- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/store.cc b/store.cc index 930794d..caec347 100644 --- a/store.cc +++ b/store.cc @@ -56,7 +56,7 @@ Tarfile::Tarfile(const string &path, const string &segment) if (real_fd < 0) throw IOException("Error opening output file"); - filter_fd = spawn_filter(real_fd); + filter_fd = spawn_filter(real_fd, filter_program, &filter_pid); } Tarfile::~Tarfile() @@ -86,9 +86,10 @@ Tarfile::~Tarfile() * on the TAR output. The file descriptor to which output should be written * must be specified; the return value is the file descriptor which will be * attached to the standard input of the filter program. */ -int Tarfile::spawn_filter(int fd_out) +int spawn_filter(int fd_out, const char *program, pid_t *filter_pid) { int fds[2]; + pid_t pid; /* Create a pipe for communicating with the filter process. */ if (pipe(fds) < 0) { @@ -96,7 +97,7 @@ int Tarfile::spawn_filter(int fd_out) } /* Create a child process which can exec() the filter program. */ - filter_pid = fork(); + pid = fork(); if (filter_pid < 0) throw IOException("Unable to fork filter process"); @@ -104,6 +105,8 @@ int Tarfile::spawn_filter(int fd_out) /* Parent process */ close(fds[0]); cloexec(fds[1]); + if (filter_pid != NULL) + *filter_pid = pid; } else { /* Child process. Rearrange file descriptors. stdin is fds[0], stdout * is fd_out, stderr is unchanged. */ @@ -118,7 +121,7 @@ int Tarfile::spawn_filter(int fd_out) close(fd_out); /* Exec the filter program. */ - execlp("/bin/sh", "/bin/sh", "-c", filter_program, NULL); + execlp("/bin/sh", "/bin/sh", "-c", program, NULL); /* Should not reach here except for error cases. */ fprintf(stderr, "Could not exec filter: %m\n"); @@ -149,19 +152,13 @@ void Tarfile::tar_write(const char *data, size_t len) void Tarfile::write_object(int id, const char *data, size_t len) { + struct tar_header header; + memset(&header, 0, sizeof(header)); + char buf[64]; sprintf(buf, "%08x", id); string path = segment_name + "/" + buf; - internal_write_object(path, data, len); -} - -void Tarfile::internal_write_object(const string &path, - const char *data, size_t len) -{ - struct tar_header header; - memset(&header, 0, sizeof(header)); - assert(path.size() < 100); memcpy(header.name, path.data(), path.size()); sprintf(header.mode, "%07o", 0600); diff --git a/store.h b/store.h index a959cce..956a1b5 100644 --- a/store.h +++ b/store.h @@ -72,15 +72,11 @@ public: Tarfile(const std::string &path, const std::string &segment); ~Tarfile(); - int spawn_filter(int fd_out); void write_object(int id, const char *data, size_t len); // Return an estimate of the size of the file. size_t size_estimate(); - void internal_write_object(const std::string &path, - const char *data, size_t len); - private: size_t size; std::string segment_name; @@ -184,4 +180,12 @@ extern const char *filter_program; * included; this adds to it) */ extern const char *filter_extension; +/* Launch a process to filter data written to a file descriptor. fd_out is the + * file descriptor where the filtered data should be written. program is the + * filter program to execute (a single string which will be interpreted by + * /bin/sh). The return value is a file descriptor to which the data to be + * filtered should be written. The process ID of the filter process is stored + * at address filter_pid if non-NULL. */ +int spawn_filter(int fd_out, const char *program, pid_t *filter_pid); + #endif // _LBS_STORE_H -- 2.20.1