> 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

Reply via email to