> From: Gavin Smith <[email protected]>
> Date: Thu, 15 Jan 2026 18:58:38 +0000
> Cc: [email protected], [email protected]
>
> On Thu, Jan 15, 2026 at 08:25:14PM +0200, Eli Zaretskii wrote:
> > I guess I'm missing something, then, because the test script does
> > this:
> >
> > srcdir=${srcdir:-.}
> > . $srcdir/t/Init-test.inc
> >
> > # Follow an reference to "file-menu" in dir without matching label exactly
> > $ginfo --output - FiLe-M | grep "^File: file-menu,"
> >
> > I understand that the Info file it uses is infodir/dir, is that
> > correct (even this was something it took a lot of time to understand)?
> > But then what is "FiLe-M" in the above command?
> >
> > Thanks.
>
> Yes, it loads infodir/dir initially.
>
> The "FiLe-M" should use the following entry in that file:
>
> * file-menu: (file-menu).
>
> The test is to check if it can still find that dir entry even though the
> case of the letters does not match.
>
> It could be related to multibyte support as the comparison is done
> with the mbscasecmp function from gnulib.
No, it's much simpler and sillier: the problem was with
manual-not-found hook. That file is a Unix shell script, which
MS-Windows 'popen' cannot run, because the Windows shell cmd.exe
doesn't know how to run Unix shell scripts.
So we need to have a Windows variant of manual-not-found hook, and
we need to look for it when running on Windows.
In addition, the !PIPE_USE_FORK branch of get_output_from_program had
a few problems: it failed to use the FILENAME argument when
constructing the command line for popen, used the null
formatter_args[2] in sprintf, and had a few other minor issues.
Here's the patch to fix all that, after which all Info tests pass. I
will see about writing a Windows batch file that works like
info/info-hooks-default/manual-not-found, so that "make install" could
install it.
--- info/info.c~0 2026-01-01 21:06:26.000000000 +0200
+++ info/info.c 2026-01-16 17:57:37.648516700 +0200
@@ -323,7 +323,11 @@ get_initial_file (int *argc, char ***arg
/* Run "manual not found" hook. */
{
+#ifdef __MINGW32__
+ char *hook_name = "manual-not-found.cmd";
+#else
char *hook_name = "manual-not-found";
+#endif
char *hook_output;
/* Create argument array. */
--- info/run-external.c~0 2026-01-01 20:44:32.000000000 +0200
+++ info/run-external.c 2026-01-16 17:40:33.599793200 +0200
@@ -88,12 +88,21 @@ get_output_from_program (char *filename,
{
FILE *fpipe;
char *cmdline;
- size_t cmdlen = 0;
int save_stderr = dup (fileno (stderr));
int fd_err = open (NULL_DEVICE, O_WRONLY, 0666);
+ size_t cmdlen = strlen (filename);
int i;
- for (i = 0; formatter_args[i]; i++)
+#ifdef __MINGW32__
+ /* Mirror all forward slashes in FILENAME to backslashes, since
+ otherwise the Windows shell might fail to run the script. */
+ filename = xstrdup (filename);
+ for (i = 0; i < cmdlen; i++)
+ if (filename[i] == '/')
+ filename[i] = '\\';
+#endif
+
+ for (i = 1; formatter_args[i]; i++)
cmdlen += strlen (formatter_args[i]);
/* Add-ons: 2 blanks, 2 quotes for the formatter program, 1
terminating null character. */
@@ -102,10 +111,12 @@ get_output_from_program (char *filename,
if (fd_err > 2)
dup2 (fd_err, fileno (stderr)); /* Don't print errors. */
- sprintf (cmdline, "\"%s\" %s %s",
- formatter_args[0], formatter_args[1], formatter_args[2]);
+ sprintf (cmdline, "\"%s\" %s %s", filename,
+ formatter_args[1], formatter_args[2] ? formatter_args[2] : "");
+#ifdef __MINGW32__
+ free (filename);
+#endif
fpipe = popen (cmdline, "r");
- free (cmdline);
if (fd_err > 2)
close (fd_err);
dup2 (save_stderr, fileno (stderr));
@@ -113,6 +124,7 @@ get_output_from_program (char *filename,
return 127;
output = read_from_fd (fileno (fpipe));
int pclose_status = pclose (fpipe);
+ free (cmdline);
if (pclose_status != -1)
exit_status = pclose_status;
else
--- /dev/null 1970-01-01 02:00:00.000000000 +0200
+++ info/t/config/texinfo/info-hooks/manual-not-found.cmd 2026-01-16
17:34:37.235683500 +0200
@@ -0,0 +1,2 @@
+@echo off
+exit 1
--- doc/info-stnd.texi~0 2026-01-06 23:22:00.000000000 +0200
+++ doc/info-stnd.texi 2026-01-16 17:52:23.431100600 +0200
@@ -2603,6 +2603,7 @@
Currently, Info has the following hook:
+@cindex @file{manual-not-found} script
@table @code
@item manual-not-found [--interactive] @var{manual}
This hook runs if a manual is not found. The program is
@@ -2677,7 +2678,9 @@
this to be useful in practice.)
Texinfo installs a default sample @code{manual-not-found} hook program
-and data file in its compile-time data directory.
+and data file in its compile-time data directory. It's a shell script
+whose name is @file{manual-not-found.cmd} on MS-Windows and
+@file{manual-not-found} on other systems.
@end table
Hooks are run with the full file name used to run them in the