aboutsummaryrefslogtreecommitdiff
path: root/src/xzdec/xzdec.c
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2010-08-07 20:45:18 +0300
committerLasse Collin <lasse.collin@tukaani.org>2010-08-07 20:45:18 +0300
commit792331bdee706aa852a78b171040ebf814c6f3ae (patch)
tree255e92da193003ad47eb29ccf47ab353d93cafa5 /src/xzdec/xzdec.c
parentAdd missing const to a global constant in xz. (diff)
downloadxz-792331bdee706aa852a78b171040ebf814c6f3ae.tar.xz
Disable the memory usage limiter by default.
For several people, the limiter causes bigger problems that it solves, so it is better to have it disabled by default. Those who want to have a limiter by default need to enable it via the environment variable XZ_DEFAULTS. Support for environment variable XZ_DEFAULTS was added. It is parsed before XZ_OPT and technically identical with it. The intended uses differ quite a bit though; see the man page. The memory usage limit can now be set separately for compression and decompression using --memlimit-compress and --memlimit-decompress. To set both at once, -M or --memlimit can be used. --memory was retained as a legacy alias for --memlimit for backwards compatibility. The semantics of --info-memory were changed in backwards incompatible way. Compatibility wasn't meaningful due to changes in the memory usage limiter functionality. The memory usage limiter info is no longer shown at the bottom of xz --long -help. The memory usage limiter support for removed completely from xzdec. xz's man page was updated to match the above changes. Various unrelated fixes were also made to the man page.
Diffstat (limited to '')
-rw-r--r--src/xzdec/xzdec.c176
1 files changed, 4 insertions, 172 deletions
diff --git a/src/xzdec/xzdec.c b/src/xzdec/xzdec.c
index 7f2e0fdc..fd015076 100644
--- a/src/xzdec/xzdec.c
+++ b/src/xzdec/xzdec.c
@@ -35,12 +35,6 @@
#endif
-/// Number of bytes to use memory at maximum
-static uint64_t memlimit;
-
-/// Total amount of physical RAM
-static uint64_t total_ram;
-
/// Error messages are suppressed if this is zero, which is the case when
/// --quiet has been given at least twice.
static unsigned int display_errors = 2;
@@ -66,10 +60,6 @@ my_errorf(const char *fmt, ...)
static void lzma_attribute((noreturn))
help(void)
{
- // Round up to the next MiB and do it correctly also with UINT64_MAX.
- const uint64_t mem_mib = (memlimit >> 20)
- + ((memlimit & ((UINT32_C(1) << 20) - 1)) != 0);
-
printf(
"Usage: %s [OPTION]... [FILE]...\n"
"Uncompress files in the ." TOOL_FORMAT " format to the standard output.\n"
@@ -77,7 +67,6 @@ help(void)
" -c, --stdout (ignored)\n"
" -d, --decompress (ignored)\n"
" -k, --keep (ignored)\n"
-" -M, --memory=NUM use NUM bytes of memory at maximum (0 means default)\n"
" -q, --quiet specify *twice* to suppress errors\n"
" -Q, --no-warn (ignored)\n"
" -h, --help display this help and exit\n"
@@ -85,11 +74,9 @@ help(void)
"\n"
"With no FILE, or when FILE is -, read standard input.\n"
"\n"
-"On this system and configuration, this program will use a maximum of roughly\n"
-"%" PRIu64 " MiB RAM.\n"
-"\n"
"Report bugs to <" PACKAGE_BUGREPORT "> (in English or Finnish).\n"
-PACKAGE_NAME " home page: <" PACKAGE_URL ">\n", progname, mem_mib);
+PACKAGE_NAME " home page: <" PACKAGE_URL ">\n", progname);
+
tuklib_exit(EXIT_SUCCESS, EXIT_FAILURE, display_errors);
}
@@ -104,126 +91,6 @@ version(void)
}
-/// Find out the amount of physical memory (RAM) in the system, and set
-/// the memory usage limit to the given percentage of RAM.
-static void
-memlimit_set_percentage(uint32_t percentage)
-{
- memlimit = percentage * total_ram / 100;
- return;
-}
-
-
-/// Set the memory usage limit to give number of bytes. Zero is a special
-/// value to indicate the default limit.
-static void
-memlimit_set(uint64_t new_memlimit)
-{
- if (new_memlimit != 0) {
- memlimit = new_memlimit;
- } else {
- memlimit = 40 * total_ram / 100;
- if (memlimit < UINT64_C(80) * 1024 * 1024) {
- memlimit = 80 * total_ram / 100;
- if (memlimit > UINT64_C(80) * 1024 * 1024)
- memlimit = UINT64_C(80) * 1024 * 1024;
- }
- }
-
- return;
-}
-
-
-/// Get the total amount of physical RAM and set the memory usage limit
-/// to the default value.
-static void
-memlimit_init(void)
-{
- // If we cannot determine the amount of RAM, use the assumption
- // defined by the configure script.
- total_ram = lzma_physmem();
- if (total_ram == 0)
- total_ram = (uint64_t)(ASSUME_RAM) * 1024 * 1024;
-
- memlimit_set(0);
- return;
-}
-
-
-/// \brief Convert a string to uint64_t
-///
-/// This is rudely copied from src/xz/util.c and modified a little. :-(
-/// Since this function is used only for parsing the memory usage limit,
-/// this cheats a little and saturates too big values to UINT64_MAX instead
-/// of giving an error.
-///
-/// \param max Return value when the string "max" was specified.
-///
-static uint64_t
-str_to_uint64(const char *value, uint64_t max)
-{
- uint64_t result = 0;
-
- // Accept special value "max".
- if (strcmp(value, "max") == 0)
- return max;
-
- if (*value < '0' || *value > '9') {
- my_errorf("%s: Value is not a non-negative decimal integer",
- value);
- exit(EXIT_FAILURE);
- }
-
- do {
- // Don't overflow.
- if (result > UINT64_MAX / 10)
- return UINT64_MAX;
-
- result *= 10;
-
- // Another overflow check
- const uint32_t add = *value - '0';
- if (UINT64_MAX - add < result)
- return UINT64_MAX;
-
- result += add;
- ++value;
- } while (*value >= '0' && *value <= '9');
-
- if (*value != '\0') {
- // Look for suffix.
- uint64_t multiplier = 0;
- if (*value == 'k' || *value == 'K')
- multiplier = UINT64_C(1) << 10;
- else if (*value == 'm' || *value == 'M')
- multiplier = UINT64_C(1) << 20;
- else if (*value == 'g' || *value == 'G')
- multiplier = UINT64_C(1) << 30;
-
- ++value;
-
- // Allow also e.g. Ki, KiB, and KB.
- if (*value != '\0' && strcmp(value, "i") != 0
- && strcmp(value, "iB") != 0
- && strcmp(value, "B") != 0)
- multiplier = 0;
-
- if (multiplier == 0) {
- my_errorf("%s: Invalid suffix", value - 1);
- exit(EXIT_FAILURE);
- }
-
- // Don't overflow here either.
- if (result > UINT64_MAX / multiplier)
- result = UINT64_MAX;
- else
- result *= multiplier;
- }
-
- return result;
-}
-
-
/// Parses command line options.
static void
parse_options(int argc, char **argv)
@@ -235,7 +102,6 @@ parse_options(int argc, char **argv)
{ "decompress", no_argument, NULL, 'd' },
{ "uncompress", no_argument, NULL, 'd' },
{ "keep", no_argument, NULL, 'k' },
- { "memory", required_argument, NULL, 'M' },
{ "quiet", no_argument, NULL, 'q' },
{ "no-warn", no_argument, NULL, 'Q' },
{ "help", no_argument, NULL, 'h' },
@@ -254,31 +120,6 @@ parse_options(int argc, char **argv)
case 'Q':
break;
- case 'M': {
- // Support specifying the limit as a percentage of
- // installed physical RAM.
- const size_t len = strlen(optarg);
- if (len > 0 && optarg[len - 1] == '%') {
- // Memory limit is a percentage of total
- // installed RAM.
- optarg[len - 1] = '\0';
- const uint64_t percentage
- = str_to_uint64(optarg, 100);
- if (percentage < 1 || percentage > 100) {
- my_errorf("Percentage must be in "
- "the range [1, 100]");
- exit(EXIT_FAILURE);
- }
-
- memlimit_set_percentage(percentage);
- } else {
- memlimit_set(str_to_uint64(
- optarg, UINT64_MAX));
- }
-
- break;
- }
-
case 'q':
if (display_errors > 0)
--display_errors;
@@ -307,13 +148,12 @@ uncompress(lzma_stream *strm, FILE *file, const char *filename)
// Initialize the decoder
#ifdef LZMADEC
- ret = lzma_alone_decoder(strm, memlimit);
+ ret = lzma_alone_decoder(strm, UINT64_MAX);
#else
- ret = lzma_stream_decoder(strm, memlimit, LZMA_CONCATENATED);
+ ret = lzma_stream_decoder(strm, UINT64_MAX, LZMA_CONCATENATED);
#endif
// The only reasonable error here is LZMA_MEM_ERROR.
- // FIXME: Maybe also LZMA_MEMLIMIT_ERROR in future?
if (ret != LZMA_OK) {
my_errorf("%s", ret == LZMA_MEM_ERROR ? strerror(ENOMEM)
: "Internal error (bug)");
@@ -401,10 +241,6 @@ uncompress(lzma_stream *strm, FILE *file, const char *filename)
msg = strerror(ENOMEM);
break;
- case LZMA_MEMLIMIT_ERROR:
- msg = "Memory usage limit reached";
- break;
-
case LZMA_FORMAT_ERROR:
msg = "File format not recognized";
break;
@@ -440,10 +276,6 @@ main(int argc, char **argv)
// Initialize progname which we will be used in error messages.
tuklib_progname_init(argv);
- // Set the default memory usage limit. This is needed before parsing
- // the command line arguments.
- memlimit_init();
-
// Parse the command line options.
parse_options(argc, argv);