From cdf94949a4a12b0f99d855dcfb113905ac8a90f4 Mon Sep 17 00:00:00 2001 From: pommicket Date: Sun, 24 Sep 2023 10:16:17 -0400 Subject: don't truncate log on startup --- main.c | 9 ++++++++- os-posix.c | 10 +++++++++- os-win.c | 17 +++++++++++++++++ os.h | 64 +++++++++++++++++++++++++++++++------------------------------- 4 files changed, 66 insertions(+), 34 deletions(-) diff --git a/main.c b/main.c index 930d6da..8cdba9d 100644 --- a/main.c +++ b/main.c @@ -397,9 +397,16 @@ int main(int argc, char **argv) { // open log file FILE *log = NULL; char log_filename[TED_PATH_MAX]; + char log1_filename[TED_PATH_MAX]; strbuf_printf(log_filename, "%s/log.txt", ted->local_data_dir); - log = fopen(log_filename, "w"); + strbuf_printf(log1_filename, "%s/log.1.txt", ted->local_data_dir); + if (fs_file_size(log_filename) > 500000) { + remove(log1_filename); + rename(log_filename, log1_filename); + } + log = fopen(log_filename, "a"); setbuf(log, NULL); + fprintf(log, "---- (starting ted, pid = %d) ----\n", process_get_id()); ted->log = log; } diff --git a/os-posix.c b/os-posix.c index 6b274fb..fa14584 100644 --- a/os-posix.c +++ b/os-posix.c @@ -41,6 +41,14 @@ bool fs_file_exists(const char *path) { return fs_path_type(path) == FS_FILE; } +int64_t fs_file_size(const char *path) { + struct stat statbuf = {0}; + if (stat(path, &statbuf) == 0) + return statbuf.st_size; + else + return -1; +} + FsDirectoryEntry **fs_list_directory(const char *dirname) { FsDirectoryEntry **entries = NULL; DIR *dir = opendir(dirname); @@ -51,7 +59,7 @@ FsDirectoryEntry **fs_list_directory(const char *dirname) { if (fd != -1) { while (readdir(dir)) ++nentries; rewinddir(dir); - entries = (FsDirectoryEntry **)calloc(nentries+1, sizeof *entries); + entries = (FsDirectoryEntry **)calloc(nentries+1, sizeof (FsDirectoryEntry *)); if (entries) { size_t idx = 0; while ((ent = readdir(dir))) { diff --git a/os-win.c b/os-win.c index 6a50122..1ee6fd6 100644 --- a/os-win.c +++ b/os-win.c @@ -36,6 +36,23 @@ bool fs_file_exists(const char *path) { return fs_path_type(path) == FS_FILE; } +int64_t fs_file_size(const char *path) { + WCHAR wide_path[4100]; + if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wide_path, arr_count(wide_path)) == 0) + return -1; + HANDLE file = CreateFileW(wide_path, GENERIC_READ, + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) + return -1; + int64_t size = -1; + LARGE_INTEGER large = {0}; + if (GetFileSizeEx(file, &large)) { + size = large.QuadPart; + } + CloseHandle(file); +} + FsDirectoryEntry **fs_list_directory(const char *dirname) { char file_pattern[4100]; FsDirectoryEntry **files = NULL; diff --git a/os.h b/os.h index 4769063..23e94f2 100644 --- a/os.h +++ b/os.h @@ -16,6 +16,7 @@ enum { FS_PERMISSION_READ = 0x01, FS_PERMISSION_WRITE = 0x02, }; +/// permission bits typedef u8 FsPermission; typedef struct { @@ -25,43 +26,52 @@ typedef struct { /// returns what kind of thing this is. FsType fs_path_type(const char *path); +/// get which permissions user has for file FsPermission fs_path_permission(const char *path); /// Does this file exist? Returns false for directories. bool fs_file_exists(const char *path); -/// Returns a NULL-terminated array of the files/directories in this directory, or NULL if the directory does not exist/out of memory. -/// When you're done with the entries, call fs_dir_entries_free (or call free on each entry, then on the whole array). +/// returns size of file or -1 on error +int64_t fs_file_size(const char *path); +/// Returns a `NULL`-terminated array of the files/directories in this directory, or `NULL` on error. +/// +/// When you're done with the entries, call \ref fs_dir_entries_free (or call free on each entry, then on the whole array). /// NOTE: The files/directories aren't returned in any particular order! FsDirectoryEntry **fs_list_directory(const char *dirname); -/// Create the directory specified by `path`\n -/// Returns:\n +/// Create the directory specified by `path` +/// +/// \returns /// 1 if the directory was created successfully\n /// 0 if the directory already exists\n -/// -1 if the path already exists, but it's not a directory, or if there's another error (e.g. don't have permission to create directory).\n +/// -1 if the path already exists, but it's not a directory, or if there's another error (e.g. don't have permission to create directory). int fs_mkdir(const char *path); -// Puts the current working directory into buf, including a null-terminator, writing at most buflen bytes.\n -// Returns:\n -// 1 if the working directory was inserted into buf successfully\n -// 0 if buf is too short to hold the cwd\n -// -1 if we can't get the cwd for whatever reason.\n +/// Puts the current working directory into `buf`, including a null-terminator, writing at most `buflen` bytes. +/// +/// \returns +/// 1 if the working directory was inserted into buf successfully\n +/// 0 if buf is too short to hold the cwd\n +/// -1 if we can't get the cwd for whatever reason. int os_get_cwd(char *buf, size_t buflen); -// Unlike ISO C rename() function, this will overwrite `newname` if it exists.\n -// Returns:\n -// >= 0 if successful\n -// < 0 on error\n +/// Unlike ISO C rename() function, this will overwrite `newname` if it exists. +/// +/// \returns +/// >= 0 if successful\n +/// < 0 on error int os_rename_overwrite(const char *oldname, const char *newname); +/// get last modification time of file struct timespec time_last_modified(const char *filename); +/// get time since some arbitrary point struct timespec time_get(void); /// sleep for a certain number of nanoseconds void time_sleep_ns(u64 ns); /// runs xdg-open or equivalent on the given path, which can be a URL. /// -/// returns `true` on success. +/// \returns `true` on success. bool open_with_default_application(const char *path); -/// equivalent to POSIX function chdir, but returns `true` on success and `false` on failure. +/// equivalent to POSIX function `chdir`, but returns `true` on success and `false` on failure. bool change_directory(const char *path); -/// free the entries generated by fs_list_directory. +/// free the entries generated by \ref fs_list_directory. static void fs_dir_entries_free(FsDirectoryEntry **entries) { for (int i = 0; entries[i]; ++i) free(entries[i]); @@ -75,21 +85,10 @@ static double time_get_seconds(void) { + (double)t.tv_nsec * 1e-9; } - - -/// sleep for microseconds -static void time_sleep_us(u64 us) { - time_sleep_ns(us * 1000); -} - -/// sleep for milliseconds -static void time_sleep_ms(u64 ms) { - time_sleep_ns(ms * 1000000); -} - /// sleep for seconds -static void time_sleep_s(u64 s) { - time_sleep_ns(s * 1000000000); +static void time_sleep_seconds(double s) { + if (s <= 0) return; + time_sleep_ns((u64)(s * 1000000000)); } /// a process @@ -179,7 +178,8 @@ const char *socket_get_error(Socket *socket); /// -2 on error\n /// -1 on end of file\n /// 0 if no data is available right now\n -/// or a positive number indicating the number of bytes read to `data` (at most `size`)\n +/// or a positive number indicating the number of bytes read to `data` (at most `size`) +/// /// This does a nonblocking read. long long socket_read(Socket *socket, char *data, size_t size); /// write to socket -- cgit v1.2.3