On Thu, Mar 30, 2023 at 03:47:24PM +0200, Omar Polo wrote: > There's this "pattern" in mg where it first access(2) a path, then > does a buch of other things and finally opens it. It can do better. > > Diff below removes the access() calls for conffile handling. > startupfile() now does an ffropen() (fopen() wrapper) instead of > access() and returns the file via parameter; callers will pass it to > load() and then close it. > > There's one more subtle fix in here that may not be obvious on first > look. I've moved the adjustname() call from load() to evalfile() to > avoid doing a double tilde expansion. All call to load(), except > evalfile(), have a path that's been constructed by mg itself or it has > been passed by the user via -b/-u, thus not need to be "adjusted". > Consider: > % mkdir \~ ; mv ~/.mg \~/ ; mg -u \~/.mg > which admittedly is a very corner case but shows the problem in doing > an extra adjustname(). > > evalfile() -- aka M-x load -- prompts the user for a path so it's not > unreasonable to call adjustname() on it. > > ok?
I have a nit and a comment below. > > Index: def.h > =================================================================== > RCS file: /home/cvs/src/usr.bin/mg/def.h,v > retrieving revision 1.177 > diff -u -p -r1.177 def.h > --- def.h 20 Oct 2022 18:59:24 -0000 1.177 > +++ def.h 30 Mar 2023 11:04:59 -0000 > @@ -486,7 +486,7 @@ int ffputbuf(FILE *, struct buffer *, > int ffgetline(FILE *, char *, int, int *); > int fbackupfile(const char *); > char *adjustname(const char *, int); > -char *startupfile(char *, char *); > +char *startupfile(FILE **, char *, char *); > int copy(char *, char *); > struct list *make_file_list(char *); > int fisdir(const char *); > @@ -594,7 +594,7 @@ int extend(int, int); > int evalexpr(int, int); > int evalbuffer(int, int); > int evalfile(int, int); > -int load(const char *); > +int load(FILE *, const char *); > int excline(char *, int, int); > char *skipwhite(char *); > > Index: extend.c > =================================================================== > RCS file: /home/cvs/src/usr.bin/mg/extend.c,v > retrieving revision 1.77 > diff -u -p -r1.77 extend.c > --- extend.c 8 Mar 2023 04:43:11 -0000 1.77 > +++ extend.c 30 Mar 2023 11:04:59 -0000 > @@ -620,37 +620,37 @@ evalbuffer(int f, int n) > int > evalfile(int f, int n) > { > + FILE *ffp; > char fname[NFILEN], *bufp; > + int ret; > > if ((bufp = eread("Load file: ", fname, NFILEN, > EFNEW | EFCR)) == NULL) > return (ABORT); > - else if (bufp[0] == '\0') > + if (bufp[0] == '\0') > return (FALSE); > - return (load(fname)); > + if ((bufp = adjustname(fname, TRUE)) == NULL) > + return (FALSE); > + ret = ffropen(&ffp, bufp, NULL); Nit: I'd avoid the nesting (I know that you just moved the code): if (ret == FIODIR) (void)ffclose(ffp, NULL); if (ret != FIOSUC) return (FALSE); > + if (ret != FIOSUC) { > + if (ret == FIODIR) > + (void)ffclose(ffp, NULL); > + return (FALSE); > + } > + ret = load(ffp, bufp); > + (void)ffclose(ffp, NULL); > + return (ret); > } > > /* > * load - go load the file name we got passed. > */ > int > -load(const char *fname) > +load(FILE *ffp, const char *fname) > { > - int s = TRUE, line, ret; > + int s = TRUE, line; > int nbytes = 0; > char excbuf[BUFSIZE], fncpy[NFILEN]; > - FILE *ffp; > - > - if ((fname = adjustname(fname, TRUE)) == NULL) > - /* just to be careful */ > - return (FALSE); > - > - ret = ffropen(&ffp, fname, NULL); > - if (ret != FIOSUC) { > - if (ret == FIODIR) > - (void)ffclose(ffp, NULL); > - return (FALSE); > - } > > /* keep a note of fname in case of errors in loaded file. */ > (void)strlcpy(fncpy, fname, sizeof(fncpy)); > @@ -666,7 +666,6 @@ load(const char *fname) > break; > } > } > - (void)ffclose(ffp, NULL); > excbuf[nbytes] = '\0'; > if (s != FIOEOF || (nbytes && excline(excbuf, nbytes, ++line) != TRUE)) > return (FALSE); > Index: fileio.c > =================================================================== > RCS file: /home/cvs/src/usr.bin/mg/fileio.c,v > retrieving revision 1.110 > diff -u -p -r1.110 fileio.c > --- fileio.c 30 Mar 2023 07:26:15 -0000 1.110 > +++ fileio.c 30 Mar 2023 11:04:59 -0000 > @@ -329,7 +329,7 @@ adjustname(const char *fn, int slashslas > * to the startup file name. > */ > char * > -startupfile(char *suffix, char *conffile) > +startupfile(FILE **ffp, char *suffix, char *conffile) > { > static char file[NFILEN]; > char *home; > @@ -350,8 +350,13 @@ startupfile(char *suffix, char *conffile > return (NULL); > } > > - if (access(file, R_OK) == 0) > + ret = ffropen(ffp, file, NULL); > + if (ret == FIOSUC) > return (file); > + if (ret == FIODIR) > + (void)ffclose(*ffp, NULL); > + *ffp = NULL; > + > nohome: > #ifdef STARTUPFILE > if (suffix == NULL) { > @@ -365,8 +370,12 @@ nohome: > return (NULL); > } > > - if (access(file, R_OK) == 0) > + ret = ffropen(ffp, file, NULL); > + if (ret == FIOSUC) > return (file); > + if (ret == FIODIR) > + (void)ffclose(*ffp, NULL); > + *ffp = NULL; > #endif /* STARTUPFILE */ > return (NULL); > } > Index: main.c > =================================================================== > RCS file: /home/cvs/src/usr.bin/mg/main.c,v > retrieving revision 1.92 > diff -u -p -r1.92 main.c > --- main.c 30 Mar 2023 08:07:07 -0000 1.92 > +++ main.c 30 Mar 2023 13:26:13 -0000 > @@ -62,6 +62,7 @@ usage() > int > main(int argc, char **argv) > { > + FILE *ffp; > char *cp, *conffile = NULL, *init_fcn_name = NULL; > char *batchfile = NULL; > PF init_fcn = NULL; > @@ -107,7 +108,7 @@ main(int argc, char **argv) > pty_init(); > conffile = batchfile; > } > - if (conffile != NULL && access(conffile, R_OK) != 0) { > + if ((cp = startupfile(&ffp, NULL, conffile)) != NULL && conffile) { This doesn't look right. I'd have expected if ((cp = startupfile(&ffp, NULL, conffile)) == NULL && conffile) { (and indeed, your patch breaks -u). > fprintf(stderr, "%s: Problem with file: %s\n", __progname, > conffile); > exit(1); > @@ -159,8 +160,10 @@ main(int argc, char **argv) > update(CMODE); > > /* user startup file. */ > - if ((cp = startupfile(NULL, conffile)) != NULL) > - (void)load(cp); > + if (cp) { > + (void)load(ffp, cp); > + ffclose(ffp, NULL); > + } > > if (batch) > return (0); > Index: ttykbd.c > =================================================================== > RCS file: /home/cvs/src/usr.bin/mg/ttykbd.c,v > retrieving revision 1.21 > diff -u -p -r1.21 ttykbd.c > --- ttykbd.c 30 Mar 2023 08:07:07 -0000 1.21 > +++ ttykbd.c 30 Mar 2023 11:04:59 -0000 > @@ -31,6 +31,7 @@ char *keystrings[] = {NULL}; > void > ttykeymapinit(void) > { > + FILE *ffp; > char *cp; > > /* Bind keypad function keys. */ > @@ -57,10 +58,11 @@ ttykeymapinit(void) > if (key_dc) > dobindkey(fundamental_map, "delete-char", key_dc); > > - if ((cp = getenv("TERM"))) { > - if (((cp = startupfile(cp, NULL)) != NULL) && > - (load(cp) != TRUE)) > + if ((cp = getenv("TERM")) != NULL && > + (cp = startupfile(&ffp, cp, NULL)) != NULL) { > + if (load(ffp, cp) != TRUE) > ewprintf("Error reading key initialization file"); > + (void)ffclose(ffp, NULL); > } > if (keypad_xmit) > /* turn on keypad */ >