From: Bruno Haible Date: Mon, 5 May 2025 09:37:16 +0000 (+0200) Subject: New module windows-cygpath. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d5452f03346280bb2b604f6cc04b3fda4fafe360;p=thirdparty%2Fgnulib.git New module windows-cygpath. * lib/windows-cygpath.h: New file, based on lib/cygpath.h. * lib/windows-cygpath.c: New file, based on lib/cygpath.c. * modules/windows-cygpath: New file. --- diff --git a/ChangeLog b/ChangeLog index 29a66a4b76..7c790cdff3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2025-05-05 Bruno Haible + + New module windows-cygpath. + * lib/windows-cygpath.h: New file, based on lib/cygpath.h. + * lib/windows-cygpath.c: New file, based on lib/cygpath.c. + * modules/windows-cygpath: New file. + 2025-05-05 Bruno Haible obstack: Relicense under LGPLv2+. diff --git a/lib/windows-cygpath.c b/lib/windows-cygpath.c new file mode 100644 index 0000000000..f0f1a887ce --- /dev/null +++ b/lib/windows-cygpath.c @@ -0,0 +1,137 @@ +/* Convert file names between Cygwin syntax and Windows syntax. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2024. */ + +#include + +/* Specification. */ +#include "windows-cygpath.h" + +#include "xalloc.h" +#include "gettext.h" + +#define _(msgid) dgettext ("gnulib", msgid) + +#if defined _WIN32 && !defined __CYGWIN__ + +/* Since Cygwin has its own notion of mount points (which can be defined by the + user), it would be wrong to blindly convert '/cygdrive/c/foo' to 'C:\foo'. + We really need to use the Cygwin API or the 'cygpath' program. + Since under native Windows, the Cygwin API is not available, we need to + invoke the 'cygpath' program. */ + +/* Documentation: + https://cygwin.com/cygwin-ug-net/cygpath.html */ + +# include +# include +# include +# include + +# include "spawn-pipe.h" +# include "wait-process.h" + +/* Executes a program. + Returns the first line of its output, as a freshly allocated string, or + NULL. */ +static char * +execute_and_read_line (const char *progname, + const char *prog_path, const char * const *prog_argv) +{ + pid_t child; + int fd[1]; + FILE *fp; + char *line; + size_t linesize; + size_t linelen; + + /* Open a pipe to the program. */ + child = create_pipe_in (progname, prog_path, prog_argv, NULL, NULL, + DEV_NULL, false, true, false, fd); + + if (child == -1) + return NULL; + + /* Retrieve its result. */ + fp = fdopen (fd[0], "r"); + if (fp == NULL) + error (EXIT_FAILURE, errno, _("fdopen() failed")); + + line = NULL; linesize = 0; + linelen = getline (&line, &linesize, fp); + if (linelen == (size_t)(-1)) + { + error (0, 0, _("%s subprocess I/O error"), progname); + fclose (fp); + wait_subprocess (child, progname, true, false, true, false, NULL); + } + else + { + int exitstatus; + + if (linelen > 0 && line[linelen - 1] == '\n') + line[linelen - 1] = '\0'; + + /* Read until EOF (otherwise the child process may get a SIGPIPE signal). */ + while (getc (fp) != EOF) + ; + + fclose (fp); + + /* Remove zombie process from process list, and retrieve exit status. */ + exitstatus = + wait_subprocess (child, progname, true, false, true, false, NULL); + if (exitstatus == 0) + return line; + } + free (line); + return NULL; +} + +char * +windows_cygpath_w (const char *filename) +{ + if (filename[0] == '/') + { + /* It's an absolute POSIX-style file name. */ + const char *argv[4]; + + argv[0] = "cygpath"; + argv[1] = "-w"; + argv[2] = filename; + argv[3] = NULL; + + char *line = execute_and_read_line ("cygpath", "cygpath", argv); + if (line == NULL || line[0] == '\0') + error (EXIT_FAILURE, 0, _("%s invocation failed"), "cygpath"); + return line; + } + else + /* It's a relative file name, or an absolute native Windows file name. + No conversion is needed. */ + return xstrdup (filename); +} + +#else + +char * +windows_cygpath_w (const char *filename) +{ + return xstrdup (filename); +} + +#endif diff --git a/lib/windows-cygpath.h b/lib/windows-cygpath.h new file mode 100644 index 0000000000..eb870d29fa --- /dev/null +++ b/lib/windows-cygpath.h @@ -0,0 +1,37 @@ +/* Convert file names between Cygwin syntax and Windows syntax. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2024. */ + +#ifndef _WINDOWS_CYGPATH_H +#define _WINDOWS_CYGPATH_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* On native Windows, this function converts a file name from Cygwin syntax to + native Windows syntax, like 'cygpath -w' does (if available). + Returns a freshly allocated file name. + On the other platforms, it returns a freshly allocated copy of the + argument file name. */ +extern char *windows_cygpath_w (const char *filename); + +#ifdef __cplusplus +} +#endif + +#endif /* _WINDOWS_CYGPATH_H */ diff --git a/modules/windows-cygpath b/modules/windows-cygpath new file mode 100644 index 0000000000..6575f49a62 --- /dev/null +++ b/modules/windows-cygpath @@ -0,0 +1,29 @@ +Description: +Convert file names between Cygwin syntax and Windows syntax. + +Files: +lib/windows-cygpath.h +lib/windows-cygpath.c + +Depends-on: +spawn-pipe +wait-process +getline +xalloc +free-posix +gettext-h +gnulib-i18n + +configure.ac: + +Makefile.am: +lib_SOURCES += windows-cygpath.c + +Include: +"windows-cygpath.h" + +License: +GPL + +Maintainer: +all