ledit

Text editor (WIP)
git clone git://lumidify.org/ledit.git (fast, but not encrypted)
git clone https://lumidify.org/git/ledit.git (encrypted, but very slow)
Log | Files | Refs | README | LICENSE

commit fcb4dcfe38932c8c4550b3f6b007d467ee5b7042
parent bab18b62da4d443665698fa3e8bc0e28fc9bbfe0
Author: lumidify <nobody@lumidify.org>
Date:   Sat,  4 Nov 2023 21:18:29 +0100

Don't attempt to open non-regular files

Diffstat:
Mledit.c | 50+++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/ledit.c b/ledit.c @@ -600,42 +600,59 @@ setup(int argc, char *argv[]) { clock_gettime(CLOCK_MONOTONIC, &last); #endif + /* FIXME: Technically, there's a race condition between checking stat and actually + opening the files. This is mainly important when checking if the file is not a regular + file because that is not an error for functions like fopen, so bad things will happen + if a non-regular file (e.g. a directory) is given to one of the file reading + functions. However, I don't know of any portable way to have one of the open functions + check that, so this is the best I can do. */ char *stat_errstr = NULL, *load_errstr = NULL, *load_default_errstr = NULL; char *cfgfile = NULL; if (!opt_filename) { uid_t uid = getuid(); struct passwd *pw = getpwuid(uid); if (!pw) { - fprintf(stderr, "Unable to determine home directory\n"); + stat_errstr = ledit_strdup("Unable to determine home directory to load default configuration file."); } else { cfgfile = ledit_strcat(pw->pw_dir, "/.leditrc"); struct stat cfgst; - /* FIXME: maybe only when ENOENT? */ if (stat(cfgfile, &cfgst)) { free(cfgfile); cfgfile = NULL; + if (errno != ENOENT) { + stat_errstr = print_fmt("Unable to load configuration file '~/.leditrc': %s", strerror(errno)); + } + } else if (!S_ISREG(cfgst.st_mode)) { + stat_errstr = ledit_strdup("Unable to load configuration file '~/.leditrc': Is not a regular file."); + free(cfgfile); + cfgfile = NULL; } } } else { struct stat cfgst; if (stat(opt_filename, &cfgst)) { - stat_errstr = print_fmt("Unable to load configuration file '%s'", opt_filename); - fprintf(stderr, "%s\n", stat_errstr); + stat_errstr = print_fmt("Unable to load configuration file '%s': %s", opt_filename, strerror(errno)); + } else if (!S_ISREG(cfgst.st_mode)) { + stat_errstr = print_fmt("Unable to load configuration file '%s': Is not a regular file.", opt_filename); } else { cfgfile = ledit_strdup(opt_filename); } } + if (stat_errstr) + fprintf(stderr, "%s\n", stat_errstr); if (config_loadfile(&common, cfgfile, &load_errstr)) { fprintf(stderr, "%s\n", load_errstr); + fprintf(stderr, "Unable to load configuration '%s'\n", cfgfile ? cfgfile : "default config"); int failure = 1; if (cfgfile) { /* retry with default config */ failure = config_loadfile(&common, NULL, &load_default_errstr); } if (failure) { - fprintf(stderr, "Unable to load configuration: %s\n", load_errstr); - if (load_default_errstr) - fprintf(stderr, "Also unable to load default configuration: %s\n", load_default_errstr); + if (load_default_errstr) { + fprintf(stderr, "%s\n", load_default_errstr); + fprintf(stderr, "Also unable to load default configuration\n"); + } free(stat_errstr); free(load_errstr); free(load_default_errstr); @@ -683,6 +700,8 @@ setup(int argc, char *argv[]) { int readonly = 0; int error = 0; /* FIXME: maybe copy vi and open file in /tmp by default? */ + /* FIXME: when other methods of opening files (:r, etc.) are supported, + all this checking needs to be moved to a place where it can be reused */ if (stat(argv[0], &sb)) { if (errno == ENOENT) { /* note that there may still be a failure @@ -690,18 +709,32 @@ setup(int argc, char *argv[]) { the path does not exist */ newfile = 1; } else { + fprintf( + stderr, "Error opening file '%s': %s\n", + argv[0], strerror(errno) + ); window_show_message_fmt( view->window, "Error opening file '%s': %s", argv[0], strerror(errno) ); error = 1; } + } else if (!S_ISREG(sb.st_mode)) { + fprintf(stderr, "Error opening file '%s': Is not a regular file\n", argv[0]); + window_show_message_fmt( + view->window, "Error opening file '%s': Is not a regular file", argv[0] + ); + error = 1; } if (access(argv[0], W_OK)) { readonly = 1; } - if (!newfile) { + if (!newfile && !error) { if (buffer_load_file(buffer, argv[0], 0, &load_err)) { + fprintf( + stderr, "Error opening file '%s': %s\n", + argv[0], load_err + ); window_show_message_fmt( view->window, "Error opening file '%s': %s", argv[0], load_err @@ -712,7 +745,6 @@ setup(int argc, char *argv[]) { } if (!error) { buffer->filename = ledit_strdup(argv[0]); - /* FIXME: show this *in addition* to error */ if (!show_error) { if (newfile) { window_show_message_fmt(view->window, "%s: new file", argv[0]);