Clang builds use getopt.c in librte_eal while MinGW provides
implementation as part of the toolchain. Statically linking librte_eal
to an application that depends on getopt results in undefined reference
errors with MinGW. There are no such errors with Clang, because with
Clang librte_eal actually defines getopt functions.

Use getopt.c in EAL with Clang and MinGW to get identical behavior.
Adjust code for MinGW. Incidentally, this removes a bug when free() is
called on uninitialized memory.

Fixes: 5e373e456e6 ("eal/windows: add getopt implementation")
Cc: sta...@dpdk.org

Signed-off-by: Dmitry Kozlyuk <dmitry.kozl...@gmail.com>
Reported-by: Khoa To <k...@microsoft.com>
Reported-by: Tal Shnaiderman <tal...@nvidia.com>
---

This patch probably supesedes http://patchwork.dpdk.org/patch/78574/.

 lib/librte_eal/meson.build      | 3 ---
 lib/librte_eal/windows/getopt.c | 9 ++++-----
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/lib/librte_eal/meson.build b/lib/librte_eal/meson.build
index 8d492897d..7d6222e78 100644
--- a/lib/librte_eal/meson.build
+++ b/lib/librte_eal/meson.build
@@ -25,6 +25,3 @@ endif
 if cc.has_function('getentropy', prefix : '#include <unistd.h>')
        cflags += '-DRTE_LIBEAL_USE_GETENTROPY'
 endif
-if cc.has_header('getopt.h')
-       cflags += ['-DHAVE_GETOPT_H', '-DHAVE_GETOPT', '-DHAVE_GETOPT_LONG']
-endif
diff --git a/lib/librte_eal/windows/getopt.c b/lib/librte_eal/windows/getopt.c
index a08f7c109..a1f51c6c2 100644
--- a/lib/librte_eal/windows/getopt.c
+++ b/lib/librte_eal/windows/getopt.c
@@ -242,7 +242,6 @@ getopt_internal(int nargc, char **nargv, const char 
*options,
        char *oli;                              /* option letter list index */
        int optchar, short_too;
        static int posixly_correct = -1;
-       char *buf;
        size_t len;
        int optreset = 0;
 
@@ -253,16 +252,16 @@ getopt_internal(int nargc, char **nargv, const char 
*options,
         * Disable GNU extensions if POSIXLY_CORRECT is set or options
         * string begins with a '+'.
         */
-       if (posixly_correct == -1)
-               posixly_correct = _dupenv_s(&buf, &len, "POSIXLY_CORRECT");
+       if (posixly_correct == -1) {
+               errno_t err = _wgetenv_s(&len, NULL, 0, L"POSIXLY_CORRECT");
+               posixly_correct = (err == 0) && (len > 0);
+       }
        if (!posixly_correct || *options == '+')
                flags &= ~FLAG_PERMUTE;
        else if (*options == '-')
                flags |= FLAG_ALLARGS;
        if (*options == '+' || *options == '-')
                options++;
-       if (!posixly_correct)
-               free(buf);
        /*
         * reset if requested
         */
-- 
2.25.4

Reply via email to