aboutsummaryrefslogtreecommitdiff
path: root/contrib/less/edit.c
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2017-11-20 08:52:33 +0000
committerXin LI <delphij@FreeBSD.org>2017-11-20 08:52:33 +0000
commitb2ea244070ff84eab79e04befb7aa30c982fc84d (patch)
tree28b5fe8762e1d749bf704ba80f01774532fb120f /contrib/less/edit.c
parent727ca2fdfd341222314f96e7075d153f6009ee9e (diff)
parentee3dcfe98fdc32918e3476f437b9603983d6d0be (diff)
downloadsrc-b2ea244070ff84eab79e04befb7aa30c982fc84d.tar.gz
src-b2ea244070ff84eab79e04befb7aa30c982fc84d.zip
MFV r326007: less v529.
MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=326010
Diffstat (limited to 'contrib/less/edit.c')
-rw-r--r--contrib/less/edit.c255
1 files changed, 152 insertions, 103 deletions
diff --git a/contrib/less/edit.c b/contrib/less/edit.c
index f2a74a049200..7dc80bbd6453 100644
--- a/contrib/less/edit.c
+++ b/contrib/less/edit.c
@@ -9,9 +9,13 @@
#include "less.h"
+#include "position.h"
#if HAVE_STAT
#include <sys/stat.h>
#endif
+#if OS2
+#include <signal.h>
+#endif
public int fd0 = 0;
@@ -43,9 +47,6 @@ public dev_t curr_dev;
public ino_t curr_ino;
#endif
-char *curr_altfilename = NULL;
-static void *curr_altpipe;
-
/*
* Textlist functions deal with a list of words separated by spaces.
@@ -149,12 +150,33 @@ back_textlist(tlist, prev)
}
/*
+ * Close a pipe opened via popen.
+ */
+ static void
+close_pipe(FILE *pipefd)
+{
+ if (pipefd == NULL)
+ return;
+#if OS2
+ /*
+ * The pclose function of OS/2 emx sometimes fails.
+ * Send SIGINT to the piped process before closing it.
+ */
+ kill(pipefd->_pid, SIGINT);
+#endif
+ pclose(pipefd);
+}
+
+/*
* Close the current input file.
*/
static void
close_file()
{
struct scrpos scrpos;
+ int chflags;
+ FILE *altpipe;
+ char *altfilename;
if (curr_ifile == NULL_IFILE)
return;
@@ -163,7 +185,7 @@ close_file()
* Save the current position so that we can return to
* the same position if we edit this file again.
*/
- get_scrpos(&scrpos);
+ get_scrpos(&scrpos, TOP);
if (scrpos.pos != NULL_POSITION)
{
store_pos(curr_ifile, &scrpos);
@@ -172,17 +194,23 @@ close_file()
/*
* Close the file descriptor, unless it is a pipe.
*/
+ chflags = ch_getflags();
ch_close();
/*
* If we opened a file using an alternate name,
* do special stuff to close it.
*/
- if (curr_altfilename != NULL)
+ altfilename = get_altfilename(curr_ifile);
+ if (altfilename != NULL)
{
- close_altfile(curr_altfilename, get_filename(curr_ifile),
- curr_altpipe);
- free(curr_altfilename);
- curr_altfilename = NULL;
+ altpipe = get_altpipe(curr_ifile);
+ if (altpipe != NULL && !(chflags & CH_KEEPOPEN))
+ {
+ close_pipe(altpipe);
+ set_altpipe(curr_ifile, NULL);
+ }
+ close_altfile(altfilename, get_filename(curr_ifile));
+ set_altfilename(curr_ifile, NULL);
}
curr_ifile = NULL_IFILE;
#if HAVE_STAT_INO
@@ -218,9 +246,8 @@ edit_ifile(ifile)
int chflags;
char *filename;
char *open_filename;
- char *qopen_filename;
char *alt_filename;
- void *alt_pipe;
+ void *altpipe;
IFILE was_curr_ifile;
PARG parg;
@@ -270,107 +297,129 @@ edit_ifile(ifile)
}
filename = save(get_filename(ifile));
+
/*
* See if LESSOPEN specifies an "alternate" file to open.
*/
- alt_pipe = NULL;
- alt_filename = open_altfile(filename, &f, &alt_pipe);
- open_filename = (alt_filename != NULL) ? alt_filename : filename;
- qopen_filename = shell_unquote(open_filename);
-
- chflags = 0;
- if (alt_pipe != NULL)
+ altpipe = get_altpipe(ifile);
+ 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.
+ * File is already open.
+ * chflags and f are not used by ch_init if ifile has
+ * filestate which should be the case if we're here.
+ * Set them here to avoid uninitialized variable warnings.
*/
- chflags |= CH_POPENED;
- } else if (strcmp(open_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);
-#endif
- } else if (strcmp(open_filename, FAKE_EMPTYFILE) == 0)
- {
+ chflags = 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)
+ alt_filename = get_altfilename(ifile);
+ open_filename = (alt_filename != NULL) ? alt_filename : filename;
+ } else
{
- /*
- * It looks like a bad file. Don't try to open it.
- */
- error("%s", &parg);
- free(parg.p_string);
- err1:
- if (alt_filename != 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)
{
- close_altfile(alt_filename, filename, alt_pipe);
- free(alt_filename);
- }
- del_ifile(ifile);
- free(qopen_filename);
- free(filename);
- /*
- * Re-open the current file.
- */
- if (was_curr_ifile == 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.
+ */
+ 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;
/*
- * Whoops. The "current" ifile is the one we just deleted.
- * Just give up.
+ * Must switch stdin to BINARY mode.
*/
- quit(QUIT_ERROR);
- }
- reedit_ifile(was_curr_ifile);
- return (1);
- } else if ((f = open(qopen_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))
+ 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);
+#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)
{
/*
- * Looks like a binary file.
- * Ask user if we should proceed.
+ * It looks like a bad file. Don't try to open it.
*/
- parg.p_string = filename;
- answer = query("\"%s\" may be a binary file. See it anyway? ",
- &parg);
- if (answer != 'y' && answer != 'Y')
+ error("%s", &parg);
+ free(parg.p_string);
+ err1:
+ if (alt_filename != NULL)
{
- close(f);
+ 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)
+ {
+ /*
+ * 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;
+ }
}
}
}
@@ -385,8 +434,8 @@ edit_ifile(ifile)
unsave_ifile(was_curr_ifile);
}
curr_ifile = ifile;
- curr_altfilename = alt_filename;
- curr_altpipe = alt_pipe;
+ set_altfilename(curr_ifile, alt_filename);
+ set_altpipe(curr_ifile, altpipe);
set_open(curr_ifile); /* File has been opened */
get_pos(curr_ifile, &initial_scrpos);
new_file = TRUE;
@@ -400,9 +449,10 @@ 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(qopen_filename, &statbuf);
+ int r = stat(open_filename, &statbuf);
if (r == 0)
{
curr_ino = statbuf.st_ino;
@@ -417,7 +467,6 @@ edit_ifile(ifile)
}
}
- free(qopen_filename);
no_display = !any_display;
flush();
any_display = TRUE;
@@ -468,6 +517,7 @@ edit_list(filelist)
char *filename;
char *gfilelist;
char *gfilename;
+ char *qfilename;
struct textlist tl_files;
struct textlist tl_gfiles;
@@ -489,8 +539,10 @@ edit_list(filelist)
gfilename = NULL;
while ((gfilename = forw_textlist(&tl_gfiles, gfilename)) != NULL)
{
- if (edit(gfilename) == 0 && good_filename == NULL)
+ qfilename = shell_unquote(gfilename);
+ if (edit(qfilename) == 0 && good_filename == NULL)
good_filename = get_filename(curr_ifile);
+ free(qfilename);
}
free(gfilelist);
}
@@ -747,7 +799,6 @@ use_logfile(filename)
/*
* {{ We could use access() here. }}
*/
- filename = shell_unquote(filename);
exists = open(filename, OPEN_READ);
if (exists >= 0)
close(exists);
@@ -816,10 +867,8 @@ loop:
*/
parg.p_string = filename;
error("Cannot write to \"%s\"", &parg);
- free(filename);
return;
}
- free(filename);
SET_BINARY(logfile);
}