From 5118355732d380968122994651469c5ca4af5bf5 Mon Sep 17 00:00:00 2001 From: cpq Date: Tue, 26 Jan 2021 17:43:31 +0000 Subject: [PATCH] Use 64bit file ops even on 32bit systems --- mongoose.c | 21 +++++++++++---------- mongoose.h | 17 +++++++++++++++++ src/arch_esp32.h | 1 + src/arch_esp8266.h | 1 + src/arch_freertos.h | 1 + src/arch_unix.h | 2 ++ src/arch_win32.h | 2 ++ src/http.c | 20 ++++++++++---------- src/util.h | 10 ++++++++++ test/unit_test.c | 6 +++--- 10 files changed, 58 insertions(+), 23 deletions(-) diff --git a/mongoose.c b/mongoose.c index d75ecd65..e029e40e 100644 --- a/mongoose.c +++ b/mongoose.c @@ -671,9 +671,9 @@ static void restore_http_cb(struct mg_connection *c) { free(d); } -char *mg_http_etag(char *buf, size_t len, struct stat *st) { - snprintf(buf, len, "\"%lx.%lu\"", (unsigned long) st->st_mtime, - (unsigned long) st->st_size); +char *mg_http_etag(char *buf, size_t len, mg_stat_t *st) { + snprintf(buf, len, "\"%lx." MG_INT64_FMT "\"", (unsigned long) st->st_mtime, + (int64_t) st->st_size); return buf; } @@ -785,10 +785,10 @@ static const char *guess_content_type(const char *filename) { void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm, const char *path, const char *mime, const char *hdrs) { struct mg_str *inm = mg_http_get_header(hm, "If-None-Match"); - struct stat st; + mg_stat_t st; FILE *fp = fopen(path, "rb"); char etag[64]; - if (fp == NULL || stat(path, &st) != 0 || + if (fp == NULL || mg_stat(path, &st) != 0 || mg_http_etag(etag, sizeof(etag), &st) != etag) { mg_http_reply(c, 404, "", "%s", "Not found\n"); } else if (inm != NULL && mg_vcasecmp(inm, etag) == 0) { @@ -797,8 +797,8 @@ void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm, } else { mg_printf(c, "HTTP/1.1 200 OK\r\nContent-Type: %s\r\n" - "Etag: %s\r\nContent-Length: %lu\r\n%s\r\n", - mime, etag, (unsigned long) st.st_size, hdrs ? hdrs : ""); + "Etag: %s\r\nContent-Length: " MG_INT64_FMT "\r\n%s\r\n", + mime, etag, (int64_t) st.st_size, hdrs ? hdrs : ""); if (mg_vcasecmp(&hm->method, "HEAD") == 0) { fclose(fp); } else { @@ -949,7 +949,7 @@ struct dirent *readdir(DIR *d) { #endif static void printdirentry(struct mg_connection *c, struct mg_http_message *hm, - const char *name, struct stat *stp) { + const char *name, mg_stat_t *stp) { char size[64], mod[64]; //, path[PATH_MAX]; int is_dir = S_ISDIR(stp->st_mode); const char *slash = is_dir ? "/" : ""; @@ -997,11 +997,11 @@ static void listdir(struct mg_connection *c, struct mg_http_message *hm, "
\n", (int) hm->uri.len, hm->uri.ptr, (int) hm->uri.len, hm->uri.ptr); while ((dp = readdir(dirp)) != NULL) { - struct stat st; + mg_stat_t st; // Do not show current dir and hidden files if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; snprintf(path, sizeof(path), "%s/%s", dir, dp->d_name); - if (stat(path, &st) != 0) { + if (mg_stat(path, &st) != 0) { LOG(LL_ERROR, ("%lu stat(%s): %d", c->id, path, errno)); continue; } @@ -3711,6 +3711,7 @@ struct mg_str mg_url_pass(const char *url) { #endif + #if MG_ENABLE_FS size_t mg_file_size(const char *path) { #if MG_ARCH == MG_ARCH_FREERTOS diff --git a/mongoose.h b/mongoose.h index 9e9da925..61114449 100644 --- a/mongoose.h +++ b/mongoose.h @@ -121,6 +121,7 @@ #include #include #define MG_DIRSEP '/' +#define MG_INT64_FMT "%lld" #endif @@ -133,6 +134,7 @@ #include #include #define MG_DIRSEP '/' +#define MG_INT64_FMT "%lld" #endif @@ -146,6 +148,7 @@ #include #include +#define MG_INT64_FMT "%lld" #define MG_DIRSEP '/' #define IPPROTO_TCP FREERTOS_IPPROTO_TCP #define IPPROTO_UDP FREERTOS_IPPROTO_UDP @@ -206,6 +209,7 @@ static inline int ff_vfprintf(FF_FILE *fp, const char *fmt, va_list ap) { #include #include +#include #include #include #include @@ -217,6 +221,7 @@ static inline int ff_vfprintf(FF_FILE *fp, const char *fmt, va_list ap) { #include #define MG_DIRSEP '/' #define MG_ENABLE_POSIX 1 +#define MG_INT64_FMT "%" PRId64 #endif @@ -273,6 +278,8 @@ typedef int socklen_t; #define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR) #endif +#define MG_INT64_FMT "%I64d" + #endif @@ -432,6 +439,16 @@ double mg_time(void); unsigned long mg_millis(void); void mg_usleep(unsigned long usecs); +#if MG_ENABLE_FS +#ifdef _WIN32 +typedef struct _stati64 mg_stat_t; +#define mg_stat(a, b) _stati64((a), (b)) +#else +typedef struct stat mg_stat_t; +#define mg_stat(a, b) stat((a), (b)) +#endif +#endif + #define mg_htons(x) mg_ntohs(x) #define mg_htonl(x) mg_ntohl(x) diff --git a/src/arch_esp32.h b/src/arch_esp32.h index ea503313..a50711b3 100644 --- a/src/arch_esp32.h +++ b/src/arch_esp32.h @@ -5,5 +5,6 @@ #include #include #define MG_DIRSEP '/' +#define MG_INT64_FMT "%lld" #endif diff --git a/src/arch_esp8266.h b/src/arch_esp8266.h index 243b5831..18834717 100644 --- a/src/arch_esp8266.h +++ b/src/arch_esp8266.h @@ -8,5 +8,6 @@ #include #include #define MG_DIRSEP '/' +#define MG_INT64_FMT "%lld" #endif diff --git a/src/arch_freertos.h b/src/arch_freertos.h index f4ec5bed..64fbb9ac 100644 --- a/src/arch_freertos.h +++ b/src/arch_freertos.h @@ -9,6 +9,7 @@ #include #include +#define MG_INT64_FMT "%lld" #define MG_DIRSEP '/' #define IPPROTO_TCP FREERTOS_IPPROTO_TCP #define IPPROTO_UDP FREERTOS_IPPROTO_UDP diff --git a/src/arch_unix.h b/src/arch_unix.h index 81f11dae..b3dbb352 100644 --- a/src/arch_unix.h +++ b/src/arch_unix.h @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -17,5 +18,6 @@ #include #define MG_DIRSEP '/' #define MG_ENABLE_POSIX 1 +#define MG_INT64_FMT "%" PRId64 #endif diff --git a/src/arch_win32.h b/src/arch_win32.h index 648f2cab..c78ebd4a 100644 --- a/src/arch_win32.h +++ b/src/arch_win32.h @@ -52,4 +52,6 @@ typedef int socklen_t; #define S_ISDIR(x) (((x) &_S_IFMT) == _S_IFDIR) #endif +#define MG_INT64_FMT "%I64d" + #endif diff --git a/src/http.c b/src/http.c index 4851ad10..a2efca6d 100644 --- a/src/http.c +++ b/src/http.c @@ -251,9 +251,9 @@ static void restore_http_cb(struct mg_connection *c) { free(d); } -char *mg_http_etag(char *buf, size_t len, struct stat *st) { - snprintf(buf, len, "\"%lx.%lu\"", (unsigned long) st->st_mtime, - (unsigned long) st->st_size); +char *mg_http_etag(char *buf, size_t len, mg_stat_t *st) { + snprintf(buf, len, "\"%lx." MG_INT64_FMT "\"", (unsigned long) st->st_mtime, + (int64_t) st->st_size); return buf; } @@ -365,10 +365,10 @@ static const char *guess_content_type(const char *filename) { void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm, const char *path, const char *mime, const char *hdrs) { struct mg_str *inm = mg_http_get_header(hm, "If-None-Match"); - struct stat st; + mg_stat_t st; FILE *fp = fopen(path, "rb"); char etag[64]; - if (fp == NULL || stat(path, &st) != 0 || + if (fp == NULL || mg_stat(path, &st) != 0 || mg_http_etag(etag, sizeof(etag), &st) != etag) { mg_http_reply(c, 404, "", "%s", "Not found\n"); } else if (inm != NULL && mg_vcasecmp(inm, etag) == 0) { @@ -377,8 +377,8 @@ void mg_http_serve_file(struct mg_connection *c, struct mg_http_message *hm, } else { mg_printf(c, "HTTP/1.1 200 OK\r\nContent-Type: %s\r\n" - "Etag: %s\r\nContent-Length: %lu\r\n%s\r\n", - mime, etag, (unsigned long) st.st_size, hdrs ? hdrs : ""); + "Etag: %s\r\nContent-Length: " MG_INT64_FMT "\r\n%s\r\n", + mime, etag, (int64_t) st.st_size, hdrs ? hdrs : ""); if (mg_vcasecmp(&hm->method, "HEAD") == 0) { fclose(fp); } else { @@ -529,7 +529,7 @@ struct dirent *readdir(DIR *d) { #endif static void printdirentry(struct mg_connection *c, struct mg_http_message *hm, - const char *name, struct stat *stp) { + const char *name, mg_stat_t *stp) { char size[64], mod[64]; //, path[PATH_MAX]; int is_dir = S_ISDIR(stp->st_mode); const char *slash = is_dir ? "/" : ""; @@ -577,11 +577,11 @@ static void listdir(struct mg_connection *c, struct mg_http_message *hm, "
\n", (int) hm->uri.len, hm->uri.ptr, (int) hm->uri.len, hm->uri.ptr); while ((dp = readdir(dirp)) != NULL) { - struct stat st; + mg_stat_t st; // Do not show current dir and hidden files if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) continue; snprintf(path, sizeof(path), "%s/%s", dir, dp->d_name); - if (stat(path, &st) != 0) { + if (mg_stat(path, &st) != 0) { LOG(LL_ERROR, ("%lu stat(%s): %d", c->id, path, errno)); continue; } diff --git a/src/util.h b/src/util.h index 9e837e18..fe4ecf24 100644 --- a/src/util.h +++ b/src/util.h @@ -23,6 +23,16 @@ double mg_time(void); unsigned long mg_millis(void); void mg_usleep(unsigned long usecs); +#if MG_ENABLE_FS +#ifdef _WIN32 +typedef struct _stati64 mg_stat_t; +#define mg_stat(a, b) _stati64((a), (b)) +#else +typedef struct stat mg_stat_t; +#define mg_stat(a, b) stat((a), (b)) +#endif +#endif + #define mg_htons(x) mg_ntohs(x) #define mg_htonl(x) mg_ntohl(x) diff --git a/test/unit_test.c b/test/unit_test.c index 5db4ea35..b88db0dc 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -451,7 +451,7 @@ static void test_http_server(void) { struct mg_mgr mgr; const char *url = "http://127.0.0.1:12346"; char buf[FETCH_BUF_SIZE]; - struct stat st; + mg_stat_t st; mg_mgr_init(&mgr); mg_http_listen(&mgr, url, eh1, NULL); @@ -463,9 +463,9 @@ static void test_http_server(void) { ASSERT(cmpbody(buf, "hello\n") == 0); { - extern char *mg_http_etag(char *, size_t, struct stat *); + extern char *mg_http_etag(char *, size_t, mg_stat_t *); char etag[100]; - ASSERT(stat("./test/data/a.txt", &st) == 0); + ASSERT(mg_stat("./test/data/a.txt", &st) == 0); ASSERT(mg_http_etag(etag, sizeof(etag), &st) == etag); ASSERT(fetch(&mgr, buf, url, "GET /a.txt HTTP/1.0\nIf-None-Match: %s\n\n", etag) == 304);