diff --git a/include/ucore/read_file.h b/include/ucore/read_file.h index 9e1ea10..26e4987 100644 --- a/include/ucore/read_file.h +++ b/include/ucore/read_file.h @@ -21,6 +21,14 @@ extern "C" { char * uc_read_file(const char *file_name, size_t *length, size_t max); +/** Read the content of a file descriptor as a stream. + * @see uc_read_file + * This is similar but reads from a file descriptor, + * of any type as long as it supports the read() call. + */ +char * +uc_read_fd(int fd, size_t *length, size_t max); + #ifdef __cplusplus } #endif diff --git a/include/ucore/utils.h b/include/ucore/utils.h index e2b6592..70e5ca9 100644 --- a/include/ucore/utils.h +++ b/include/ucore/utils.h @@ -6,9 +6,8 @@ //Gnerate a compiler error if the compile time //constant expression fails -#define UC_STATIC_ASSERT(expr) \ - enum { assert_static__ = 1/(expr) }; - +#define UC_STATIC_ASSERT(expr)\ + typedef int STATIC_ASSERT_FAILED[(expr) ? 1 : -1] //MAX of a and b #define UC_MAX(a,b) \ diff --git a/src/rate_limit.c b/src/rate_limit.c index 2facdc1..a2ad6ef 100644 --- a/src/rate_limit.c +++ b/src/rate_limit.c @@ -32,9 +32,9 @@ static void uc_ratelimit_refill(struct RateLimit *r, long current_ts) //Find elapsed time diff_period = current_ts - r->last_refill_ts; - if (diff_period > r->period + 1) { - //help prevent overflow when calculating available_tickets below - diff_period = r->period + 1; + if (diff_period > r->period) { + //help prevent overflow when calculating available tickets below + diff_period = r->period; } else if (diff_period < 0) { //time went backwards, skip this round diff_period = 0; diff --git a/src/read_file.c b/src/read_file.c index cf6c3f5..2bdb9e5 100644 --- a/src/read_file.c +++ b/src/read_file.c @@ -1,17 +1,17 @@ -#include -#include -#include -#include -#include -#include -#include "ucore/read_file.h" +#include +#include +#include +#include +#include +#include +#include +#include "ucore/read_file.h" #define CHUNK_SZ 1024 char * -uc_read_file(const char *f, size_t *length, size_t max) +uc_read_fd(int fd, size_t *length, size_t max) { - int fd; char *s = NULL; char *p; struct stat statb; @@ -19,25 +19,26 @@ uc_read_file(const char *f, size_t *length, size_t max) *length = 0; - if ((fd = open(f, O_RDONLY)) == -1) - return NULL; - if (fstat(fd, &statb) == -1) { goto out_close; } if ((statb.st_mode & S_IFMT) == S_IFREG) { - if ((size_t)statb.st_size > max) { + if (statb.st_size > (off_t)max) { errno = EMSGSIZE; goto out_close; } - alloc_sz = (size_t) statb.st_size + 1; // + 1 to avoid one realloc - s = malloc((size_t) alloc_sz + 1); //+1 for nul terminator + if (statb.st_size > SSIZE_MAX) { + //otherwise we cannot detect the return value of read() + alloc_sz = SSIZE_MAX; + } else { + alloc_sz = statb.st_size; + } } else { alloc_sz = CHUNK_SZ; - s = malloc(alloc_sz + 1); //+1 for nul terminator } + s = malloc(alloc_sz + 1); //+1 for nul terminator if (s == NULL) { goto out_close; } @@ -80,3 +81,15 @@ out_close: return s; } +char * +uc_read_file(const char *f, size_t *length, size_t max) +{ + int fd; + + if ((fd = open(f, O_RDONLY)) == -1) { + *length = 0; + return NULL; + } + + return uc_read_fd(fd, length, max); +} diff --git a/test/test_read_file.c b/test/test_read_file.c index 5bef1f4..dcd8d68 100644 --- a/test/test_read_file.c +++ b/test/test_read_file.c @@ -13,6 +13,7 @@ START_TEST (test_read_file_non_existing_file) size_t len; int saved_errno; + errno = 0; content = uc_read_file("non existing file 123765", &len, 1000000000); saved_errno = errno;