X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/eb61be192de5bb899bedb851f69981e191ba1853..4034cb3f71473271e4c5768c4bb3cdb3c8cf6d61:/util.c?ds=sidebyside diff --git a/util.c b/util.c index e6420646..fe81f2ad 100644 --- a/util.c +++ b/util.c @@ -197,12 +197,10 @@ static int full_write(int desc, char *ptr, size_t len) total_written = 0; while (len > 0) { - int written = write (desc, ptr, len); + int written = write(desc, ptr, len); if (written < 0) { -#ifdef EINTR if (errno == EINTR) continue; -#endif return written; } total_written += written; @@ -231,13 +229,9 @@ static int safe_read(int desc, char *ptr, size_t len) if (len == 0) return len; -#ifdef EINTR do { n_chars = read(desc, ptr, len); } while (n_chars < 0 && errno == EINTR); -#else - n_chars = read(desc, ptr, len); -#endif return n_chars; } @@ -559,12 +553,57 @@ void strlower(char *s) } } -void *Realloc(void *p, int size) +/* Join strings p1 & p2 into "dest" with a guaranteed '/' between them. (If + * p1 ends with a '/', no extra '/' is inserted.) Returns the length of both + * strings + 1 (if '/' was inserted), regardless of whether the whole thing + * fits into destsize (including the terminating '\0'). */ +size_t pathjoin(char *dest, size_t destsize, const char *p1, const char *p2) { - if (!p) return (void *)malloc(size); - return (void *)realloc(p, size); + size_t len = strlcpy(dest, p1, destsize); + if (len < destsize - 1) { + if (!len || dest[len-1] != '/') + dest[len++] = '/'; + if (len < destsize - 1) + len += strlcpy(dest + len, p2, destsize - len); + else { + dest[len] = '\0'; + len += strlen(p2); + } + } + else + len += strlen(p2) + 1; /* Assume we'd insert a '/'. */ + return len; } +/* Join any number of strings together, putting them in "dest". The return + * value is the length of all the strings, regardless of whether they fit in + * destsize (including the terminating '\0'). Your list of string pointers + * should end with a NULL to indicate the end of the list. */ +size_t stringjoin(char *dest, size_t destsize, ...) +{ + va_list ap; + size_t len, ret = 0; + const char *src; + + va_start(ap, destsize); + while (1) { + if (!(src = va_arg(ap, const char *))) + break; + len = strlen(src); + ret += len; + if (destsize > 1) { + if (len >= destsize) + len = destsize - 1; + memcpy(dest, src, len); + destsize -= len; + dest += len; + } + } + *dest = '\0'; + va_end(ap); + + return ret; +} void clean_fname(char *name) { @@ -1008,3 +1047,23 @@ int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6) return ret; } #endif + + +#define MALLOC_MAX 0x40000000 + +void *_new_array(unsigned int size, unsigned long num) +{ + if (num >= MALLOC_MAX/size) + return NULL; + return malloc(size * num); +} + +void *_realloc_array(void *ptr, unsigned int size, unsigned long num) +{ + if (num >= MALLOC_MAX/size) + return NULL; + /* No realloc should need this, but just in case... */ + if (!ptr) + return malloc(size * num); + return realloc(ptr, size * num); +}