socsvn commit: r254890 - soc2013/dpl/head/contrib/xz/src/xz
dpl at FreeBSD.org
dpl at FreeBSD.org
Wed Jul 17 17:17:16 UTC 2013
Author: dpl
Date: Wed Jul 17 17:17:16 2013
New Revision: 254890
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=254890
Log:
It works always, except when used --files/--files0 as options.
Modified:
soc2013/dpl/head/contrib/xz/src/xz/coder.c
soc2013/dpl/head/contrib/xz/src/xz/coder.h
soc2013/dpl/head/contrib/xz/src/xz/file_io.c
soc2013/dpl/head/contrib/xz/src/xz/file_io.h
soc2013/dpl/head/contrib/xz/src/xz/list.c
soc2013/dpl/head/contrib/xz/src/xz/list.h
soc2013/dpl/head/contrib/xz/src/xz/main.c
soc2013/dpl/head/contrib/xz/src/xz/main.h
soc2013/dpl/head/contrib/xz/src/xz/private.h
Modified: soc2013/dpl/head/contrib/xz/src/xz/coder.c
==============================================================================
--- soc2013/dpl/head/contrib/xz/src/xz/coder.c Wed Jul 17 14:15:00 2013 (r254889)
+++ soc2013/dpl/head/contrib/xz/src/xz/coder.c Wed Jul 17 17:17:16 2013 (r254890)
@@ -609,52 +609,51 @@
extern void
-coder_run(file_pair pairs[], int files)
+coder_run(file_pair *pair)
{
- int i;
+ if (pair == NULL )
+ return;
- for( i=0; i < files; i++) {
- // Set and possibly print the filename for the progress message.
- message_filename(pairs[i].src_name);
-
- // Assume that something goes wrong.
- bool success = false;
-
- // Read the first chunk of input data. This is needed to detect
- // the input file type (for now, only for decompression).
- strm.next_in = in_buf.u8;
- strm.avail_in = io_read(&pairs[i], &in_buf, IO_BUFFER_SIZE);
-
- if (strm.avail_in != SIZE_MAX) {
- // Initialize the coder. This will detect the file format
- // and, in decompression or testing mode, check the memory
- // usage of the first Block too. This way we don't try to
- // open the destination file if we see that coding wouldn't
- // work at all anyway. This also avoids deleting the old
- // "target" file if --force was used.
- const enum coder_init_ret init_ret = coder_init(&pairs[i]);
-
- if (init_ret != CODER_INIT_ERROR && !user_abort) {
- // Initialize the progress indicator.
- const uint64_t in_size
- = pairs[i].src_st.st_size <= 0
- ? 0 : pairs[i].src_st.st_size;
- message_progress_start(&strm, in_size);
-
- // Do the actual coding or passthru.
- if (init_ret == CODER_INIT_NORMAL)
- success = coder_normal(&pairs[i]);
- else
- success = coder_passthru(&pairs[i]);
+ // Set and possibly print the filename for the progress message.
+ message_filename(pair->src_name);
- message_progress_end(success);
- }
+ // Assume that something goes wrong.
+ bool success = false;
+
+ // Read the first chunk of input data. This is needed to detect
+ // the input file type (for now, only for decompression).
+ strm.next_in = in_buf.u8;
+ strm.avail_in = io_read(pair, &in_buf, IO_BUFFER_SIZE);
+
+ if (strm.avail_in != SIZE_MAX) {
+ // Initialize the coder. This will detect the file format
+ // and, in decompression or testing mode, check the memory
+ // usage of the first Block too. This way we don't try to
+ // open the destination file if we see that coding wouldn't
+ // work at all anyway. This also avoids deleting the old
+ // "target" file if --force was used.
+ const enum coder_init_ret init_ret = coder_init(pair);
+
+ if (init_ret != CODER_INIT_ERROR && !user_abort) {
+ // Initialize the progress indicator.
+ const uint64_t in_size
+ = pair->src_st.st_size <= 0
+ ? 0 : pair->src_st.st_size;
+ message_progress_start(&strm, in_size);
+
+ // Do the actual coding or passthru.
+ if (init_ret == CODER_INIT_NORMAL)
+ success = coder_normal(pair);
+ else
+ success = coder_passthru(pair);
+
+ message_progress_end(success);
}
-
- // Close the file pair. It needs to know if coding was successful to
- // know if the source or target file should be unlinked.
- io_close(&pairs[i], success);
}
+ // Close the file pair. It needs to know if coding was successful to
+ // know if the source or target file should be unlinked.
+ io_close(pair, success);
+
return;
}
Modified: soc2013/dpl/head/contrib/xz/src/xz/coder.h
==============================================================================
--- soc2013/dpl/head/contrib/xz/src/xz/coder.h Wed Jul 17 14:15:00 2013 (r254889)
+++ soc2013/dpl/head/contrib/xz/src/xz/coder.h Wed Jul 17 17:17:16 2013 (r254890)
@@ -58,4 +58,4 @@
extern void coder_set_compression_settings(void);
/// Compress or decompress the given file
-extern void coder_run(file_pair *pairs[], int files);
+extern void coder_run(file_pair *pairs);
Modified: soc2013/dpl/head/contrib/xz/src/xz/file_io.c
==============================================================================
--- soc2013/dpl/head/contrib/xz/src/xz/file_io.c Wed Jul 17 14:15:00 2013 (r254889)
+++ soc2013/dpl/head/contrib/xz/src/xz/file_io.c Wed Jul 17 17:17:16 2013 (r254890)
@@ -91,7 +91,7 @@
/// a small unavoidable race, but this is much better than nothing (the file
/// could have been moved/replaced even hours earlier).
static void
-io_unlink(const char *name, const struct stat *known_st)
+io_unlink(file_pair *pair, int dest)
{
#if defined(TUKLIB_DOSLIKE)
// On DOS-like systems, st_ino is meaningless, so don't bother
@@ -99,6 +99,19 @@
(void)known_st;
#else
struct stat new_st;
+ const char *name;
+ int fd;
+ struct stat *known_st;
+ //const char *name, int *fd, int *dirfd, const struct stat *known_st)
+ if (dest) {
+ name = pair->dest_name;
+ fd = &pair->dest_fd;
+ known_st = &pair->dest_st;
+ } else {
+ name = pair->src_name;
+ fd = &pair->src_fd;
+ known_st = &pair->src_st;
+ }
// If --force was used, use stat() instead of lstat(). This way
// (de)compressing symlinks works correctly. However, it also means
@@ -110,7 +123,8 @@
// Probably it's not too bad though, so this doesn't need a more
// complex fix.
const int stat_ret = opt_force
- ? stat(name, &new_st) : lstat(name, &new_st);
+ ? fstatat(pair->dir_fd, basename(name), &new_st, 0)
+ : fstatat(pair->dir_fd, basename(name), &new_st, AT_SYMLINK_NOFOLLOW);
if (stat_ret
# ifdef __VMS
@@ -140,7 +154,7 @@
#endif
// There's a race condition between lstat() and unlink()
// but at least we have tried to avoid removing wrong file.
- if (unlink(name))
+ if (unlinkat(pair->dir_fd, basename(name), 0))
message_error(_("%s: Cannot remove: %s"),
name, strerror(errno));
@@ -355,6 +369,9 @@
// doesn't hurt to have it just in case.
do {
pair->src_fd = open(pair->src_name, flags);
+#if defined(CAPSICUM)
+ pair->dir_fd = open( dirname(pair->src_name), O_DIRECTORY);
+#endif
} while (pair->src_fd == -1 && errno == EINTR && !user_abort);
if (!reg_files_only)
@@ -513,36 +530,26 @@
if (is_empty_filename(src_name))
return NULL;
- // Since we have only one file open at a time, we can use
- // a statically allocated structure.
- static file_pair pair;
-
- pair = (file_pair){
- .src_name = src_name,
- .dest_name = NULL,
- .src_fd = -1,
- .dest_fd = -1,
- .src_eof = false,
- .dest_try_sparse = false,
- .dest_pending_sparse = 0,
- };
+ file_pair *pair;
+
+ pair = (file_pair*)malloc(sizeof(file_pair));
+ pair->src_name = src_name;
+ pair->dest_name = NULL;
+ pair->dir_fd = -1;
+ pair->src_fd = -1;
+ pair->dest_fd = -1;
+ pair->src_eof = false;
+ pair->dest_try_sparse = false;
+ pair->dest_pending_sparse = 0;
-/* pair = (file_pair *)malloc(sizeof(file_pair);*/
-/* pair.src_name = src_name;*/
-/* pair.dest_name = NULL;*/
-/* pair.src_fd = -1;*/
-/* pair.dest_fd = -1;*/
-/* pair.src_eof = false;*/
-/* pair.dest_try_sparse = false;*/
-/* pair.dest_pending_sparse = 0;*/
// Block the signals, for which we have a custom signal handler, so
// that we don't need to worry about EINTR.
signals_block();
- const bool error = io_open_src_real(&pair);
+ const bool error = io_open_src_real(pair);
signals_unblock();
- return error ? NULL : &pair;
+ return error ? NULL : pair;
}
@@ -567,7 +574,7 @@
// NOTE: DOS-like systems are an exception to this, because
// they don't allow unlinking files that are open. *sigh*
if (success && !opt_keep_original)
- io_unlink(pair->src_name, &pair->src_st);
+ io_unlink(pair, 0);
#ifndef TUKLIB_DOSLIKE
(void)close(pair->src_fd);
@@ -694,7 +701,9 @@
io_open_dest(file_pair *pair)
{
signals_block();
- const bool ret = io_open_dest_real(pair);
+ bool ret = true;
+ if(pair != NULL)
+ ret = io_open_dest_real(pair);
signals_unblock();
return ret;
}
@@ -736,15 +745,15 @@
// Closing destination file failed, so we cannot trust its
// contents. Get rid of junk:
- io_unlink(pair->dest_name, &pair->dest_st);
+ io_unlink(pair, 1);
free(pair->dest_name);
return true;
}
- // If the operation using this file wasn't successful, we git rid
+ // If the operation using this file wasn't successful, we get rid
// of the junk file.
if (!success)
- io_unlink(pair->dest_name, &pair->dest_st);
+ io_unlink(pair, 1);
free(pair->dest_name);
@@ -797,6 +806,8 @@
signals_unblock();
+ free(pair);
+
return;
}
@@ -966,48 +977,36 @@
}
extern file_pair **
-io_list_open(char *filename[], int files)
+io_open_files(char *filename[], int files)
{
int i;
- file_pair *pairs[files];
+ file_pair **pairs = (file_pair **)malloc(files * sizeof(file_pair *));
- //Open files a la list_file()
- if (opt_format != FORMAT_XZ && opt_format != FORMAT_AUTO)
- message_fatal(_("--list works only on .xz files "
- "(--format=xz or --format=auto)"));
-
+ if( opt_mode == MODE_LIST)
+ if (opt_format != FORMAT_XZ && opt_format != FORMAT_AUTO)
+ message_fatal(_("--list works only on .xz files "
+ "(--format=xz or --format=auto)"));
+
for ( i = 0; i < files; i++) {
+ if (filename[i] == NULL) {
+ break;
+ }
+ // Set and possibly print the filename for the progress message.
message_filename(filename[i]);
-
- if (filename[i] == stdin_filename) {
- message_error(_("--list does not support reading from "
- "standard input"));
- continue;
- }
-
- // Unset opt_stdout so that io_open_src() won't accept special files.
- // Set opt_force so that io_open_src() will follow symlinks.
- opt_stdout = false;
- opt_force = true;
- pairs[i] = io_open_src(filename[i]);
-#if defined(CAPSICUM)
- limitfd(pairs[i]);
-#endif
- }
- return pairs;
-}
-extern file_pair **
-io_coder_open(char *filename[], int files)
-{
- int i;
- file_pair *pairs[files];
+ if (opt_mode == MODE_LIST) {
+ if (filename[i] == stdin_filename) {
+ message_error(_("--list does not support reading from "
+ "standard input"));
+ break;
+ }
+
+ // Unset opt_stdout so that io_open_src() won't accept special files.
+ // Set opt_force so that io_open_src() will follow symlinks.
+ opt_stdout = false;
+ opt_force = true;
+ }
- for ( i = 0; i < files; i++) {
- // Set and possibly print the filename for the progress message.
- message_filename(filename[i]);
-
- // Try to open the input file.
pairs[i] = io_open_src(filename[i]);
if( opt_mode != MODE_TEST )
io_open_dest(pairs[i]);
@@ -1015,7 +1014,6 @@
limitfd(pairs[i]);
#endif
}
-
return pairs;
}
@@ -1023,19 +1021,31 @@
extern void
limitfd(file_pair *pair)
{
- cap_rights_t rights = 0;
+ cap_rights_t rights;
- rights |= CAP_READ;
- if (cap_rights_limit(pair->src_fd, rights) < 0 && errno != ENOSYS){
- message_error("%s: %s", pair->src_name, strerror(errno));
- exit(E_ERROR);
+ if(pair->dir_fd != -1 ){
+ rights = CAP_FSTATAT|CAP_UNLINKAT|CAP_LOOKUP;
+ if (cap_rights_limit(pair->dir_fd, rights) < 0 && errno != ENOSYS){
+ message_error("%s: %s", pair->dest_name, strerror(errno));
+ exit(E_ERROR);
+ }
}
- rights |= CAP_WRITE|CAP_FSTAT|CAP_FCHOWN;
- rights |= CAP_FCHMOD|CAP_FUTIMES;
- if (cap_rights_limit(pair->dest_fd, rights) < 0 && errno != ENOSYS){
- message_error("%s: %s", pair->dest_name, strerror(errno));
- exit(E_ERROR);
+ if(pair->src_fd != -1 ){
+ rights = CAP_READ|CAP_SEEK;
+ if (cap_rights_limit(pair->src_fd, rights) < 0 && errno != ENOSYS){
+ message_error("%s: %s", pair->src_name, strerror(errno));
+ exit(E_ERROR);
+ }
+ }
+
+ if(pair->dest_fd != -1 ){
+ rights = CAP_WRITE|CAP_FSTAT|CAP_FCHOWN
+ |CAP_FCHMOD|CAP_FUTIMES;
+ if (cap_rights_limit(pair->dest_fd, rights) < 0 && errno != ENOSYS){
+ message_error("%s: %s", pair->dest_name, strerror(errno));
+ exit(E_ERROR);
+ }
}
return;
}
@@ -1043,29 +1053,28 @@
extern void
cap_init(void)
{
- cap_rights_t *rights;
+ cap_rights_t rights;
- if( cap_rights_get(STDIN_FILENO, rights) < 0) {
+ if( cap_rights_get(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) {
message_error("%d: %s", STDIN_FILENO, strerror(errno));
exit(E_ERROR);
- } else if (*rights == 0) {
+ } else if (rights == 0) {
if (cap_rights_limit(STDIN_FILENO, CAP_WRITE) < 0 && errno != ENOSYS){
message_error("%d: %s", STDIN_FILENO, strerror(errno));
exit(E_ERROR);
}
}
- if( cap_rights_get(STDOUT_FILENO, rights) < 0) {
+ if( cap_rights_get(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) {
message_error("%d: %s", STDOUT_FILENO, strerror(errno));
exit(E_ERROR);
- } else if (*rights == 0) {
+ } else if (rights == 0) {
if (cap_rights_limit(STDOUT_FILENO, CAP_WRITE) < 0 && errno != ENOSYS){
message_error("%d: %s", STDOUT_FILENO, strerror(errno));
exit(E_ERROR);
}
}
-
if (cap_rights_limit(STDERR_FILENO, CAP_WRITE) < 0 && errno != ENOSYS){
message_error("%d: %s", STDERR_FILENO, strerror(errno));
exit(E_ERROR);
Modified: soc2013/dpl/head/contrib/xz/src/xz/file_io.h
==============================================================================
--- soc2013/dpl/head/contrib/xz/src/xz/file_io.h Wed Jul 17 14:15:00 2013 (r254889)
+++ soc2013/dpl/head/contrib/xz/src/xz/file_io.h Wed Jul 17 17:17:16 2013 (r254890)
@@ -93,21 +93,14 @@
extern bool io_write(file_pair *pair, const io_buf *buf, size_t size);
-/// \brief Open all the files as needed in lit_file().
+/// \brief Open all the files as needed.
///
/// \param filenames Array containing all the filenames to be open.
/// \param files Number of files to open.
///
/// \return Returns an array of file_pairs.
-extern file_pair ** io_list_open(char *filenames[], int files);
+extern file_pair ** io_open_files(char *filenames[], int files);
-/// \brief Open all the files as needed in coder_run().
-///
-/// \param filenames Array containing all the filenames to be open.
-/// \param files Number of files to open.
-///
-/// \return Returns an array of file_pairs.
-extern file_pair ** io_coder_open(char *filenames[], int files);
#if defined(CAPSICUM)
/// \brief Limits fd using FreeBSD's Capsicum framework.
Modified: soc2013/dpl/head/contrib/xz/src/xz/list.c
==============================================================================
--- soc2013/dpl/head/contrib/xz/src/xz/list.c Wed Jul 17 14:15:00 2013 (r254889)
+++ soc2013/dpl/head/contrib/xz/src/xz/list.c Wed Jul 17 17:17:16 2013 (r254890)
@@ -1057,9 +1057,8 @@
extern void
-list_file(file_pair pairs[], int files)
+list_file(file_pair *pair)
{
- int i;
xz_file_info xfi = XZ_FILE_INFO_INIT;
// Unset opt_stdout so that io_open_src() won't accept special files.
@@ -1067,35 +1066,34 @@
opt_stdout = false;
opt_force = true;
- for (i = 0; i < files; i++) {
- if (pairs[i] == NULL)
- continue;
-
- if (!parse_indexes(&xfi, pairs[i])) {
- bool fail;
-
- // We have three main modes:
- // - --robot, which has submodes if --verbose is specified
- // once or twice
- // - Normal --list without --verbose
- // - --list with one or two --verbose
- if (opt_robot)
- fail = print_info_robot(&xfi, pairs[i]);
- else if (message_verbosity_get() <= V_WARNING)
- fail = print_info_basic(&xfi, pairs[i]);
- else
- fail = print_info_adv(&xfi, pairs[i]);
-
- // Update the totals that are displayed after all
- // the individual files have been listed. Don't count
- // broken files.
- if (!fail)
- update_totals(&xfi);
-
- lzma_index_end(xfi.idx, NULL);
- }
-
- io_close(pairs[i], false);
+ if (pair == NULL)
+ return;
+
+ if (!parse_indexes(&xfi, pair)) {
+ bool fail;
+
+ // We have three main modes:
+ // - --robot, which has submodes if --verbose is specified
+ // once or twice
+ // - Normal --list without --verbose
+ // - --list with one or two --verbose
+ if (opt_robot)
+ fail = print_info_robot(&xfi, pair);
+ else if (message_verbosity_get() <= V_WARNING)
+ fail = print_info_basic(&xfi, pair);
+ else
+ fail = print_info_adv(&xfi, pair);
+
+ // Update the totals that are displayed after all
+ // the individual files have been listed. Don't count
+ // broken files.
+ if (!fail)
+ update_totals(&xfi);
+
+ lzma_index_end(xfi.idx, NULL);
}
+
+ io_close(pair, false);
+
return;
}
Modified: soc2013/dpl/head/contrib/xz/src/xz/list.h
==============================================================================
--- soc2013/dpl/head/contrib/xz/src/xz/list.h Wed Jul 17 14:15:00 2013 (r254889)
+++ soc2013/dpl/head/contrib/xz/src/xz/list.h Wed Jul 17 17:17:16 2013 (r254890)
@@ -11,7 +11,7 @@
///////////////////////////////////////////////////////////////////////////////
/// \brief List information about the given .xz file
-extern void list_file(const char *filename);
+extern void list_file(file_pair *pairs);
/// \brief Show the totals after all files have been listed
Modified: soc2013/dpl/head/contrib/xz/src/xz/main.c
==============================================================================
--- soc2013/dpl/head/contrib/xz/src/xz/main.c Wed Jul 17 14:15:00 2013 (r254889)
+++ soc2013/dpl/head/contrib/xz/src/xz/main.c Wed Jul 17 17:17:16 2013 (r254890)
@@ -55,7 +55,7 @@
}
-static const char *
+static char *
read_name(const args_info *args)
{
// FIXME: Maybe we should have some kind of memory usage limit here
@@ -142,8 +142,7 @@
int
main(int argc, char **argv)
{
- int files = 0;
-
+ int forkpid, i, nfiles = 0;
#if defined(_WIN32) && !defined(__CYGWIN__)
InitializeCriticalSection(&exit_status_cs);
#endif
@@ -208,13 +207,9 @@
signals_init();
// Separate opening the files from list_file() and coder_run()
- // We have to limit both functions with Capsicum.
- file_pair * (*open)(const char **filename, int files) = opt_mode == MODE_LIST
- ? &io_list_open : &io_coder_open;
-
// coder_run() handles compression, decompression, and testing.
// list_file() is for --list.
- void (*run)(const file_pair *pairs, int files) = opt_mode == MODE_LIST
+ void (*run)(file_pair *pair) = opt_mode == MODE_LIST
? &list_file : &coder_run;
// Process the files given on the command line. Note that if no names
@@ -248,14 +243,10 @@
// string and the code still knows that it is
// handling the special case of stdin.
args.arg_names[i] = (char *)stdin_filename;
- files++;
}
+ nfiles++;
}
- file_pair pairs[files] = open(args.arg_names, files);
- cap_init();
- run(pairs, files);
-
// If --files or --files0 was used, process the filenames from the
// given file or stdin. Note that here we don't consider "-" to
// indicate stdin like we do with the command line arguments.
@@ -263,19 +254,46 @@
// read_name() checks for user_abort so we don't need to
// check it as loop termination condition.
while (true) {
- const char *name = read_name(&args);
+ char *name = read_name(&args);
+ printf("name: %s\n", name);
if (name == NULL)
break;
// read_name() doesn't return empty names.
assert(name[0] != '\0');
- run(name);
+ args.arg_count++;
+ args.arg_names[nfiles] = name;
+ nfiles++;
}
if (args.files_name != stdin_filename)
(void)fclose(args.files_file);
}
+ printf("nfiles: %d\n", nfiles);
+ for ( i = 0; (size_t)i < args.arg_count; i++)
+ printf("file: %s\n", args.arg_names[i]);
+
+ file_pair **pairs = io_open_files(args.arg_names, nfiles);
+
+ for( i = 0; i < nfiles; i++){
+#if defined(CAPSICUM)
+ if ( (forkpid = fork()) == -1 ){
+ message_error("%d: %s", STDERR_FILENO, strerror(errno));
+ exit(E_ERROR);
+ } else if ( forkpid != 0) {
+ /* Let the children compress */
+ wait(NULL);
+ } else if (forkpid == 0){
+ cap_init();
+#endif
+ run(pairs[i]);
+#if defined(CAPSICUM)
+ exit(0);
+ }
+#endif
+ }
+
// All files have now been handled. If in --list mode, display
// the totals before exiting. We don't have signal handlers
// enabled in --list mode, so we don't need to check user_abort.
Modified: soc2013/dpl/head/contrib/xz/src/xz/main.h
==============================================================================
--- soc2013/dpl/head/contrib/xz/src/xz/main.h Wed Jul 17 14:15:00 2013 (r254889)
+++ soc2013/dpl/head/contrib/xz/src/xz/main.h Wed Jul 17 17:17:16 2013 (r254890)
@@ -17,6 +17,8 @@
E_WARNING = 2,
};
+// To be used with unlinkat(), fstatat() at io_close().
+int dirfd;
/// Sets the exit status after a warning or error has occurred. If new_status
/// is E_WARNING and the old exit status was already E_ERROR, the exit
Modified: soc2013/dpl/head/contrib/xz/src/xz/private.h
==============================================================================
--- soc2013/dpl/head/contrib/xz/src/xz/private.h Wed Jul 17 14:15:00 2013 (r254889)
+++ soc2013/dpl/head/contrib/xz/src/xz/private.h Wed Jul 17 17:17:16 2013 (r254890)
@@ -32,6 +32,8 @@
# if __FreeBSD_version >= 900041
# define CAPSICUM
# include <sys/capability.h>
+# include <libgen.h>
+# include <sys/wait.h>
# endif
#endif
@@ -61,6 +63,11 @@
/// "(stdout)" when writing to standard output.
char *dest_name;
+#if defined(CAPSICUM)
+ // File descriptor of the directory where the files are.
+ int dir_fd;
+#endif
+
/// File descriptor of the source file
int src_fd;
More information about the svn-soc-all
mailing list