#include <h/addrsbr.h>
#include <h/fmt_scan.h>
#include <h/tws.h>
+#include "h/done.h"
#include <h/utils.h>
#include "sbr/m_popen.h"
#include <setjmp.h>
static char *ignores[MAXARGS];
static jmp_buf env;
-static jmp_buf mhlenv;
static char delim3[] = /* from forw.c */
"\n----------------------------------------------------------------------\n\n";
static char delim4[] = "\n------------------------------\n\n";
-static FILE *(*mhl_action)(char *);
-
/*
* prototypes
*/
static char *oneline (char *, unsigned long);
static void putstr (char *, unsigned long);
static void putch (char, unsigned long);
+static bool linefeed_typed(void);
static void intrser (int);
static void pipeser (int);
static void quitser (int);
if (isatty (fileno (stdout))) {
if (!nomore && moreproc && *moreproc != '\0') {
- if (mhl_action) {
- SIGNAL (SIGINT, SIG_IGN);
- SIGNAL2 (SIGQUIT, quitser);
- }
SIGNAL2 (SIGPIPE, pipeser);
- m_popen (moreproc, mhl_action != NULL);
+ m_popen(moreproc, false);
ontty = PITTY;
} else {
SIGNAL (SIGINT, SIG_IGN);
if (!strcasecmp (name, "length"))
return ptoi (name, &c1->c_length);
if (!strcasecmp (name, "nodashstuffing"))
- return (dashstuff = -1);
+ return dashstuff = -1;
for (ap = triples; ap->t_name; ap++)
if (!strcasecmp (ap->t_name, name)) {
switch (setjmp (env)) {
case OK:
if (fname) {
- fp = mhl_action ? (*mhl_action) (fname) : fopen (fname, "r");
+ fp = fopen(fname, "r");
if (fp == NULL) {
advise (fname, "unable to open");
exitstat++;
default:
if (ontty != PITTY)
SIGNAL (SIGINT, SIG_IGN);
- if (mhl_action == NULL && fp != stdin && fp != NULL)
+ if (fp != stdin && fp != NULL)
fclose (fp);
- mh_xfree(holder.c_text);
+ free(holder.c_text);
holder.c_text = NULL;
free_queue (&msghd, &msgtl);
for (c1 = fmthd; c1; c1 = c1->c_next)
break;
case ISTTY:
- strncpy (buf, "\n", sizeof(buf));
if (ofilec > 1) {
if (SOprintf ("Press <return> to list \"%s\"...", mname)) {
if (ofilen > 1)
printf ("Press <return> to list \"%s\"...", mname);
}
fflush (stdout);
- buf[0] = 0;
- if (read (fileno (stdout), buf, sizeof(buf)) < 0) {
- advise ("stdout", "read");
- }
}
- if (strchr(buf, '\n')) {
+ if (ofilec == 1 || linefeed_typed()) {
if ((global.c_flags & CLEARSCR))
nmh_clear_screen ();
}
for (ap = pairs; ap->p_name; ap++)
if (!strcasecmp (ap->p_name, name))
- return (ap->p_flags);
+ return ap->p_flags;
return 0;
}
}
charstring_free (scanl);
- mh_xfree(p->pq_text);
- mh_xfree(p->pq_error);
+ free(p->pq_text);
+ free(p->pq_error);
q = p->pq_next;
free(p);
}
for (c1 = *head; c1; c1 = c2) {
c2 = c1->c_next;
- mh_xfree(c1->c_name);
- mh_xfree(c1->c_text);
- mh_xfree(c1->c_ovtxt);
- mh_xfree(c1->c_nfs);
+ free(c1->c_name);
+ free(c1->c_text);
+ free(c1->c_ovtxt);
+ free(c1->c_nfs);
if (c1->c_fmt)
fmt_free (c1->c_fmt, 0);
free(c1);
if (onelp == NULL)
onelp = stuff;
if (*onelp == 0)
- return (onelp = NULL);
+ return onelp = NULL;
ret = onelp;
term = 0;
static void
putch (char ch, unsigned long flags)
{
- char buf[BUFSIZ];
-
if (llim == 0)
return;
if (global.c_flags & BELL)
putchar ('\007');
fflush (stdout);
- buf[0] = 0;
- if (read (fileno (stdout), buf, sizeof(buf)) < 0) {
- advise ("stdout", "read");
- }
- if (strchr(buf, '\n')) {
+ if (linefeed_typed()) {
if (global.c_flags & CLEARSCR)
nmh_clear_screen ();
row = 0;
}
}
+/* linefeed_typed() makes a single read(2) from stdin and returns true
+ * if a linefeed character is amongst the characters read.
+ * A read error is treated as if linefeed wasn't typed.
+ *
+ * Typing on a TTY can cause read() to return data without typing Enter
+ * by using the TTY's EOF character instead, normally ASCII EOT, Ctrl-D.
+ * The linefeed can also be escaped with the TTY's LNEXT character,
+ * normally ASCII SYN, Ctrl-V, by typing Ctrl-V Ctrl-J.
+ * It's not possible to distinguish between the user typing a buffer's
+ * worth of characters and then EOT, or more than the buffer can hold.
+ * Either way, the result depends on ASCII LF, either from typing Enter
+ * or an escaped Ctrl-J, being amongst the read characters.
+ */
+static bool linefeed_typed(void)
+{
+ char buf[128];
+ ssize_t n;
+
+ n = read(0, buf, sizeof buf);
+ if (n == -1) {
+ advise("stdin", "read");
+ return false; /* Treat as EOF. */
+ }
+
+ return memchr(buf, '\n', n);
+}
+
static void
intrser (int i)
mhldone (int status)
{
exitstat = status;
- if (mhl_action)
- longjmp (mhlenv, DONE);
done (exitstat);
}