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 */
> 

Reply via email to