From 2195072f4676dc847e240ae476e2826f60cb817f Mon Sep 17 00:00:00 2001 From: Mark Nudelman Date: Wed, 19 Jul 2017 16:24:32 -0700 Subject: [PATCH] Don't reopen an ifile that is already open. --- edit.c | 193 ++++++++++++++++++++++++++++------------------------- filename.c | 50 +++++++------- 2 files changed, 126 insertions(+), 117 deletions(-) diff --git a/edit.c b/edit.c index 7f616cf5..c51f48a4 100644 --- a/edit.c +++ b/edit.c @@ -293,110 +293,122 @@ edit_ifile(ifile) /* * See if LESSOPEN specifies an "alternate" file to open. */ - altpipe = NULL; - if (strcmp(filename, FAKE_HELPFILE) == 0 || - strcmp(filename, FAKE_EMPTYFILE) == 0) - alt_filename = NULL; - else - alt_filename = open_altfile(filename, !opened(ifile), &f, &altpipe); - - open_filename = (alt_filename != NULL) ? alt_filename : filename; - - chflags = 0; - if (altpipe != NULL) + if (opened(ifile)) { /* - * The alternate "file" is actually a pipe. - * f has already been set to the file descriptor of the pipe - * in the call to open_altfile above. - * Keep the file descriptor open because it was opened - * via popen(), and pclose() wants to close it. + * File is already open. */ - chflags |= CH_POPENED; - if (strcmp(filename, "-") == 0) - chflags |= CH_KEEPOPEN; - } else if (strcmp(filename, "-") == 0) + chflags = 0; /* not used by ch_init if ifile has filestate */ + altpipe = get_altpipe(ifile); + alt_filename = get_altfilename(ifile); + open_filename = (alt_filename != NULL) ? alt_filename : filename; + } else { - /* - * Use standard input. - * Keep the file descriptor open because we can't reopen it. - */ - f = fd0; - chflags |= CH_KEEPOPEN; - /* - * Must switch stdin to BINARY mode. - */ - SET_BINARY(f); + altpipe = NULL; + if (strcmp(filename, FAKE_HELPFILE) == 0 || + strcmp(filename, FAKE_EMPTYFILE) == 0) + alt_filename = NULL; + else + alt_filename = open_altfile(filename, &f, &altpipe); + + open_filename = (alt_filename != NULL) ? alt_filename : filename; + + chflags = 0; + if (altpipe != NULL) + { + /* + * The alternate "file" is actually a pipe. + * f has already been set to the file descriptor of the pipe + * in the call to open_altfile above. + * Keep the file descriptor open because it was opened + * via popen(), and pclose() wants to close it. + */ + chflags |= CH_POPENED; + if (strcmp(filename, "-") == 0) + chflags |= CH_KEEPOPEN; + } else if (strcmp(filename, "-") == 0) + { + /* + * Use standard input. + * Keep the file descriptor open because we can't reopen it. + */ + f = fd0; + chflags |= CH_KEEPOPEN; + /* + * Must switch stdin to BINARY mode. + */ + SET_BINARY(f); #if MSDOS_COMPILER==DJGPPC - /* - * Setting stdin to binary by default causes - * Ctrl-C to not raise SIGINT. We must undo - * that side-effect. - */ - __djgpp_set_ctrl_c(1); + /* + * Setting stdin to binary by default causes + * Ctrl-C to not raise SIGINT. We must undo + * that side-effect. + */ + __djgpp_set_ctrl_c(1); #endif - } else if (strcmp(open_filename, FAKE_EMPTYFILE) == 0) - { - f = -1; - chflags |= CH_NODATA; - } else if (strcmp(open_filename, FAKE_HELPFILE) == 0) - { - f = -1; - chflags |= CH_HELPFILE; - } else if ((parg.p_string = bad_file(open_filename)) != NULL) - { - /* - * It looks like a bad file. Don't try to open it. - */ - error("%s", &parg); - free(parg.p_string); - err1: - if (alt_filename != NULL) + } else if (strcmp(open_filename, FAKE_EMPTYFILE) == 0) { - close_pipe(altpipe); - close_altfile(alt_filename, filename); - free(alt_filename); - } - del_ifile(ifile); - free(filename); - /* - * Re-open the current file. - */ - if (was_curr_ifile == ifile) + f = -1; + chflags |= CH_NODATA; + } else if (strcmp(open_filename, FAKE_HELPFILE) == 0) + { + f = -1; + chflags |= CH_HELPFILE; + } else if ((parg.p_string = bad_file(open_filename)) != NULL) { /* - * Whoops. The "current" ifile is the one we just deleted. - * Just give up. + * It looks like a bad file. Don't try to open it. */ - quit(QUIT_ERROR); - } - reedit_ifile(was_curr_ifile); - return (1); - } else if ((f = open(open_filename, OPEN_READ)) < 0) - { - /* - * Got an error trying to open it. - */ - parg.p_string = errno_message(filename); - error("%s", &parg); - free(parg.p_string); - goto err1; - } else - { - chflags |= CH_CANSEEK; - if (!force_open && !opened(ifile) && bin_file(f)) - { + error("%s", &parg); + free(parg.p_string); + err1: + if (alt_filename != NULL) + { + close_pipe(altpipe); + close_altfile(alt_filename, filename); + free(alt_filename); + } + del_ifile(ifile); + free(filename); /* - * Looks like a binary file. - * Ask user if we should proceed. + * Re-open the current file. */ - parg.p_string = filename; - answer = query("\"%s\" may be a binary file. See it anyway? ", - &parg); - if (answer != 'y' && answer != 'Y') + if (was_curr_ifile == ifile) { - close(f); + /* + * Whoops. The "current" ifile is the one we just deleted. + * Just give up. + */ + quit(QUIT_ERROR); + } + reedit_ifile(was_curr_ifile); + return (1); + } else if ((f = open(open_filename, OPEN_READ)) < 0) + { + /* + * Got an error trying to open it. + */ + parg.p_string = errno_message(filename); + error("%s", &parg); + free(parg.p_string); goto err1; + } else + { + chflags |= CH_CANSEEK; + if (!force_open && !opened(ifile) && bin_file(f)) + { + /* + * Looks like a binary file. + * Ask user if we should proceed. + */ + parg.p_string = filename; + answer = query("\"%s\" may be a binary file. See it anyway? ", + &parg); + if (answer != 'y' && answer != 'Y') + { + close(f); + goto err1; + } } } } @@ -426,6 +438,7 @@ edit_ifile(ifile) #endif #if HAVE_STAT_INO /* Remember the i-number and device of the opened file. */ + if (strcmp(open_filename, "-") != 0) { struct stat statbuf; int r = stat(open_filename, &statbuf); diff --git a/filename.c b/filename.c index cad25a84..35fe6153 100644 --- a/filename.c +++ b/filename.c @@ -820,9 +820,8 @@ num_pct_s(lessopen) * instead of the file we're about to open. */ public char * -open_altfile(filename, first_open, pf, pfd) +open_altfile(filename, pf, pfd) char *filename; - int first_open; int *pf; void **pfd; { @@ -888,37 +887,34 @@ open_altfile(filename, first_open, pf, pfd) #if HAVE_FILENO if (returnfd) { - int f = fileno(fd); - SET_BINARY(f); + char c; + int f; - if (first_open) + /* + * The first time we open the file, read one char + * to see if the pipe will produce any data. + * If it does, push the char back on the pipe. + */ + f = fileno(fd); + SET_BINARY(f); + if (read(f, &c, 1) != 1) { - char c; - /* - * The first time we open the file, read one char - * to see if the pipe will produce any data. - * If it does, push the char back on the pipe. + * Pipe is empty. + * If more than 1 pipe char was specified, + * the exit status tells whether the file itself + * is empty, or if there is no alt file. + * If only one pipe char, just assume no alt file. */ - if (read(f, &c, 1) != 1) - { - /* - * Pipe is empty. - * If more than 1 pipe char was specified, - * the exit status tells whether the file itself - * is empty, or if there is no alt file. - * If only one pipe char, just assume no alt file. - */ - int status = pclose(fd); - if (returnfd > 1 && status == 0) { - *pfd = NULL; - *pf = -1; - return (save(FAKE_EMPTYFILE)); - } - return (NULL); + int status = pclose(fd); + if (returnfd > 1 && status == 0) { + *pfd = NULL; + *pf = -1; + return (save(FAKE_EMPTYFILE)); } - ch_ungetchar(c); + return (NULL); } + ch_ungetchar(c); *pfd = (void *) fd; *pf = f; return (save("-"));