summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cleanup.c4
-rw-r--r--configure.ac2
-rw-r--r--lib/compat.c85
-rw-r--r--log.c10
-rw-r--r--options.c10
-rw-r--r--rsync.1.md21
-rw-r--r--util2.c18
7 files changed, 65 insertions, 85 deletions
diff --git a/cleanup.c b/cleanup.c
index a2d6b384..f9a5d76b 100644
--- a/cleanup.c
+++ b/cleanup.c
@@ -222,10 +222,6 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
* we don't want to output a duplicate error. */
if ((exit_code && line > 0)
|| am_daemon || (logfile_name && (am_server || !INFO_GTE(STATS, 1)))) {
-#ifdef HAVE_USLEEP /* A tiny delay just in case both sender & receiver are sending a msg at the same time. */
- if (am_server && exit_code)
- usleep(50);
-#endif
log_exit(exit_code, exit_file, exit_line);
}
diff --git a/configure.ac b/configure.ac
index a49e6add..69c8f933 100644
--- a/configure.ac
+++ b/configure.ac
@@ -820,7 +820,7 @@ dnl AC_FUNC_MEMCMP
AC_FUNC_UTIME_NULL
AC_FUNC_ALLOCA
-AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
+AC_CHECK_FUNCS(waitpid wait4 getcwd chown chmod lchmod mknod mkfifo \
fchmod fstat ftruncate strchr readlink link utime utimes lutimes strftime \
chflags getattrlist \
memmove lchown vsnprintf snprintf vasprintf asprintf setsid strpbrk \
diff --git a/lib/compat.c b/lib/compat.c
index 26a2aa60..513d79b2 100644
--- a/lib/compat.c
+++ b/lib/compat.c
@@ -24,16 +24,24 @@
static char number_separator;
-#ifndef HAVE_STRDUP
- char *strdup(char *s)
+char get_number_separator(void)
{
- int len = strlen(s) + 1;
- char *ret = (char *)malloc(len);
- if (ret)
- memcpy(ret, s, len);
- return ret;
+ if (!number_separator) {
+ char buf[32];
+ snprintf(buf, sizeof buf, "%f", 3.14);
+ if (strchr(buf, '.') != NULL)
+ number_separator = ',';
+ else
+ number_separator = '.';
+ }
+
+ return number_separator;
+}
+
+char get_decimal_point(void)
+{
+ return get_number_separator() == ',' ? '.' : ',';
}
-#endif
#ifndef HAVE_GETCWD
char *getcwd(char *buf, int size)
@@ -155,30 +163,6 @@ int sys_gettimeofday(struct timeval *tv)
#endif
}
-#define HUMANIFY(mult) \
- do { \
- if (num >= mult || num <= -mult) { \
- double dnum = (double)num / mult; \
- char units; \
- if (num < 0) \
- dnum = -dnum; \
- if (dnum < mult) \
- units = 'K'; \
- else if ((dnum /= mult) < mult) \
- units = 'M'; \
- else if ((dnum /= mult) < mult) \
- units = 'G'; \
- else { \
- dnum /= mult; \
- units = 'T'; \
- } \
- if (num < 0) \
- dnum = -dnum; \
- snprintf(bufs[n], sizeof bufs[0], "%.2f%c", dnum, units); \
- return bufs[n]; \
- } \
- } while (0)
-
/* Return the int64 number as a string. If the human_flag arg is non-zero,
* we may output the number in K, M, G, or T units. If we don't add a unit
* suffix, we will append the fract string, if it is non-NULL. We can
@@ -190,22 +174,35 @@ char *do_big_num(int64 num, int human_flag, const char *fract)
char *s;
int len, negated;
- if (human_flag && !number_separator) {
- char buf[32];
- snprintf(buf, sizeof buf, "%f", 3.14);
- if (strchr(buf, '.') != NULL)
- number_separator = ',';
- else
- number_separator = '.';
- }
+ if (human_flag && !number_separator)
+ (void)get_number_separator();
n = (n + 1) % (sizeof bufs / sizeof bufs[0]);
if (human_flag > 1) {
- if (human_flag == 2)
- HUMANIFY(1000);
- else
- HUMANIFY(1024);
+ int mult = human_flag == 2 ? 1000 : 1024;
+ if (num >= mult || num <= -mult) {
+ double dnum = (double)num / mult;
+ char units;
+ if (num < 0)
+ dnum = -dnum;
+ if (dnum < mult)
+ units = 'K';
+ else if ((dnum /= mult) < mult)
+ units = 'M';
+ else if ((dnum /= mult) < mult)
+ units = 'G';
+ else if ((dnum /= mult) < mult)
+ units = 'T';
+ else {
+ dnum /= mult;
+ units = 'P';
+ }
+ if (num < 0)
+ dnum = -dnum;
+ snprintf(bufs[n], sizeof bufs[0], "%.2f%c", dnum, units);
+ return bufs[n];
+ }
}
s = bufs[n] + sizeof bufs[0] - 1;
diff --git a/log.c b/log.c
index 73428d31..633bcdbc 100644
--- a/log.c
+++ b/log.c
@@ -350,8 +350,7 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
output_needs_newline = 0;
}
- trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r')
- ? buf[--len] : 0;
+ trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r') ? buf[--len] : '\0';
if (len && buf[0] == '\r') {
fputc('\r', f);
@@ -372,7 +371,12 @@ void rwrite(enum logcode code, const char *buf, int len, int is_utf8)
iconvbufs(ic, &inbuf, &outbuf, inbuf.pos ? 0 : ICB_INIT);
ierrno = errno;
if (outbuf.len) {
- filtered_fwrite(f, convbuf, outbuf.len, 0, 0);
+ char trailing = inbuf.len ? '\0' : trailing_CR_or_NL;
+ filtered_fwrite(f, convbuf, outbuf.len, 0, trailing);
+ if (trailing) {
+ trailing_CR_or_NL = '\0';
+ fflush(f);
+ }
outbuf.len = 0;
}
/* Log one byte of illegal/incomplete sequence and continue with
diff --git a/options.c b/options.c
index eab64b61..1e438fb1 100644
--- a/options.c
+++ b/options.c
@@ -1261,7 +1261,7 @@ static ssize_t parse_size_arg(const char *size_arg, char def_suf, const char *op
ssize_t limit = -1, size = 1;
for (arg = size_arg; isDigit(arg); arg++) {}
- if (*arg == '.')
+ if (*arg == '.' || *arg == get_decimal_point()) /* backward compatibility: always allow '.' */
for (arg++; isDigit(arg); arg++) {}
switch (*arg && *arg != '+' && *arg != '-' ? *arg++ : def_suf) {
case 'b': case 'B':
@@ -1714,20 +1714,20 @@ int parse_arguments(int *argc_p, const char ***argv_p)
case OPT_MAX_SIZE:
if ((max_size = parse_size_arg(max_size_arg, 'b', "max-size", 0, -1, False)) < 0)
return 0;
- max_size_arg = num_to_byte_string(max_size);
+ max_size_arg = strdup(do_big_num(max_size, 0, NULL));
break;
case OPT_MIN_SIZE:
if ((min_size = parse_size_arg(min_size_arg, 'b', "min-size", 0, -1, False)) < 0)
return 0;
- min_size_arg = num_to_byte_string(min_size);
+ min_size_arg = strdup(do_big_num(min_size, 0, NULL));
break;
case OPT_BWLIMIT: {
ssize_t size = parse_size_arg(bwlimit_arg, 'K', "bwlimit", 512, -1, True);
if (size < 0)
return 0;
- bwlimit_arg = num_to_byte_string(size);
+ bwlimit_arg = strdup(do_big_num(size, 0, NULL));
bwlimit = (size + 512) / 1024;
break;
}
@@ -2691,7 +2691,7 @@ void server_options(char **args, int *argc_p)
}
if (block_size) {
- if (asprintf(&arg, "-B%u", block_size) < 0)
+ if (asprintf(&arg, "-B%u", (int)block_size) < 0)
goto oom;
args[ac++] = arg;
}
diff --git a/rsync.1.md b/rsync.1.md
index 8bca5e33..685c5c37 100644
--- a/rsync.1.md
+++ b/rsync.1.md
@@ -1726,19 +1726,18 @@ your home directory (remove the '=' for that).
This tells rsync to avoid transferring any file that is larger than the
specified SIZE. A numeric value can be suffixed with a string to indicate
- a size multiplier or left unqualified to specify bytes. Feel free to use a
- fractional value along with a suffix, such as `--max-size=1.5m`.
+ the numeric units or left unqualified to specify bytes. Feel free to use a
+ fractional value along with the units, such as `--max-size=1.5m`.
This option is a transfer rule, not an exclude, so it doesn't affect the
data that goes into the file-lists, and thus it doesn't affect deletions.
It just limits the files that the receiver requests to be transferred.
- The accepted suffix letters are: `B`, `K`, `M`, `G`, `T`, and `P` for
- bytes, kilobytes/kibibytes, megabytes/mebibytes, gigabytes/gibibytes,
- terabytes/tebibytes, and petabytes/pebibytes. If you use a single-char
- suffix or add-on "ib" to it (e.g. "G" or "GiB") then you get units that are
+ The first letter of a units string can be `B` (bytes), `K` (kilo), `M`
+ (mega), `G` (giga), `T` (tera), or `P` (peta). If the string is a single
+ char or has "ib" added to it (e.g. "G" or "GiB") then the units are
multiples of 1024. If you use a two-letter suffix that ends with a "B"
- (e.g. "kb") then you get units that are multiples of 1000. The suffix
+ (e.g. "kb") then you get units that are multiples of 1000. The string's
letters can be any mix of upper and lower-case that you want to use.
Finally, if the string ends with either "+1" or "-1", it is offset by one
@@ -2814,10 +2813,10 @@ your home directory (remove the '=' for that).
level by one. You can take the level down to 0 (to output numbers as pure
digits) by specifying the `--no-human-readable` (`--no-h`) option.
- The unit letters that are appended in levels 2 and 3 are: K (kilo), M
- (mega), G (giga), or T (tera). For example, a 1234567-byte file would
- output as 1.23M in level-2 (assuming that a period is your local decimal
- point).
+ The unit letters that are appended in levels 2 and 3 are: `K` (kilo), `M`
+ (mega), `G` (giga), `T` (tera), or `P` (peta). For example, a 1234567-byte
+ file would output as 1.23M in level-2 (assuming that a period is your local
+ decimal point).
Backward compatibility note: versions of rsync prior to 3.1.0 do not
support human-readable level 1, and they default to level 0. Thus,
diff --git a/util2.c b/util2.c
index 9566b8db..6ea6981d 100644
--- a/util2.c
+++ b/util2.c
@@ -21,7 +21,6 @@
*/
#include "rsync.h"
-#include "ifuncs.h"
#include "itypes.h"
#include "inums.h"
@@ -71,28 +70,13 @@ int msleep(int t)
return True;
}
-/* Convert a num manually because the needed %lld precision is not a portable sprintf() escape. */
-char *num_to_byte_string(ssize_t num)
-{
- char buf[128], *s = buf + sizeof buf - 1;
-
- *s = '\0';
- if (!num)
- *--s = '0';
- while (num) {
- *--s = (char)(num % 10) + '0';
- num /= 10;
- }
- return strdup(s);
-}
-
void *my_alloc(void *ptr, size_t num, size_t size, const char *file, int line)
{
if (max_alloc && num >= max_alloc/size) {
if (!file)
return NULL;
rprintf(FERROR, "[%s] exceeded --max-alloc=%s setting (file=%s, line=%d)\n",
- who_am_i(), num_to_byte_string(max_alloc), file, line);
+ who_am_i(), do_big_num(max_alloc, 0, NULL), file, line);
exit_cleanup(RERR_MALLOC);
}
if (!ptr)