2 * Utility routines used in rsync.
4 * Copyright (C) 1996-2000 Andrew Tridgell
5 * Copyright (C) 1996 Paul Mackerras
6 * Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
7 * Copyright (C) 2003-2024 Wayne Davison
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, visit the http://fsf.org website.
27 extern size_t max_alloc
;
29 char *do_calloc
= "42";
32 * Sleep for a specified number of milliseconds.
34 * Always returns True.
42 ts
.tv_nsec
= (t
% 1000) * 1000000L;
44 while (nanosleep(&ts
, &ts
) < 0 && errno
== EINTR
) {}
46 #elif defined HAVE_USLEEP
51 struct timeval tval
, t1
, t2
;
53 gettimeofday(&t1
, NULL
);
56 tval
.tv_sec
= (t
-tdiff
)/1000;
57 tval
.tv_usec
= 1000*((t
-tdiff
)%1000);
60 select(0,NULL
,NULL
, NULL
, &tval
);
62 gettimeofday(&t2
, NULL
);
63 tdiff
= (t2
.tv_sec
- t1
.tv_sec
)*1000 +
64 (t2
.tv_usec
- t1
.tv_usec
)/1000;
66 t1
= t2
; /* Time went backwards, so start over. */
73 void *my_alloc(void *ptr
, size_t num
, size_t size
, const char *file
, int line
)
75 if (num
>= max_alloc
/size
) {
78 rprintf(FERROR
, "[%s] exceeded --max-alloc=%s setting (file=%s, line=%d)\n",
79 who_am_i(), do_big_num(max_alloc
, 0, NULL
), src_file(file
), line
);
80 exit_cleanup(RERR_MALLOC
);
83 ptr
= malloc(num
* size
);
84 else if (ptr
== do_calloc
)
85 ptr
= calloc(num
, size
);
87 ptr
= realloc(ptr
, num
* size
);
89 _out_of_memory("my_alloc caller", file
, line
);
93 const char *sum_as_hex(int csum_type
, const char *sum
, int flist_csum
)
95 static char buf
[MAX_DIGEST_LEN
*2+1];
97 int canonical
= canonical_checksum(csum_type
);
98 int sum_len
= csum_len_for_type(csum_type
, flist_csum
);
104 assert(sum_len
*2 < (int)sizeof buf
);
106 for (i
= sum_len
, c
= buf
; --i
>= 0; ) {
107 int ndx
= canonical
< 0 ? sum_len
- i
- 1 : i
;
111 *c
++ = x1
<= 9 ? x1
+ '0' : x1
+ 'a' - 10;
112 *c
++ = x2
<= 9 ? x2
+ '0' : x2
+ 'a' - 10;
120 NORETURN
void _out_of_memory(const char *msg
, const char *file
, int line
)
122 rprintf(FERROR
, "[%s] out of memory: %s (file=%s, line=%d)\n", who_am_i(), msg
, src_file(file
), line
);
123 exit_cleanup(RERR_MALLOC
);
126 NORETURN
void _overflow_exit(const char *msg
, const char *file
, int line
)
128 rprintf(FERROR
, "[%s] buffer overflow: %s (file=%s, line=%d)\n", who_am_i(), msg
, src_file(file
), line
);
129 exit_cleanup(RERR_MALLOC
);
132 const char *src_file(const char *file
)
134 static const char *util2
= __FILE__
;
135 static int prefix
= -1;
138 const char *cp
= strrchr(util2
, '/');
139 prefix
= cp
? cp
- util2
+ 1 : 0;
142 if (prefix
&& strncmp(file
, util2
, prefix
) == 0)
143 return file
+ prefix
;