Menu

#1912 Include strnlen

WSL
pending
Feature
later
Feature_in_WSL_4.1
False
2014-01-12
2012-03-17
No

strnlen is not included in the official builds of MinGW. It should be included.

Discussion

  • Rodney Beede

    Rodney Beede - 2012-03-17

    Microsoft has this available via Visual C++:

    MSDN ref

     

    Last edit: Earnie Boyd 2013-02-21
  • Earnie Boyd

    Earnie Boyd - 2012-03-17

    WFFM. What makes you think that it isn't available. See /mingw/bin/string.h.

     
  • Earnie Boyd

    Earnie Boyd - 2012-03-17
    • labels: 1166413 -->
    • status: open --> pending
     
  • Rodney Beede

    Rodney Beede - 2012-03-17

    #include <string.h>

    void main(void) {
    char * test = "Testing";

    strnlen\(test, 8\);
    

    }

    gcc test.c
    C:\Users\user\AppData\Local\Temp\ccwJLof4.o:test.c:(.text+0x26): undefined reference to `strnlen'
    collect2: ld returned 1 exit status

    C:\Users\user\Desktop>gcc --version
    gcc (GCC) 4.6.2
    Copyright (C) 2011 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    Using MinGW version published 2011-11-13 (latest binary for Windows).

     
  • Rodney Beede

    Rodney Beede - 2012-03-17
    • status: pending --> open
     
  • Earnie Boyd

    Earnie Boyd - 2012-03-17
    • labels: --> 104601
    • assigned_to: nobody --> ir0nh34d
     
  • Earnie Boyd

    Earnie Boyd - 2012-03-17

    Duh!! Sorry, I should have used -Wall in my simple test.

     
  • Keith Marshall

    Keith Marshall - 2012-03-21

    /mingw/bin/string.h ? I guess you mean /mingw/include/string.h, but I don't see any strnlen() prototype within it. This minimal autoconf script

    AC_INIT
    AC_PROG_CC
    AC_CHECK_FUNC([strnlen])

    says we don't have it. FWIW, I don't see it listed in the output from

    $ pexports msvcrt.dll

    either, (which is likely the reason it has been omitted), but

    HMODULE dll = LoadLibrary( "msvcrt.dll" );
    void *fp = GetProcAddress( dll, "strnlen" );

    returns a non-NULL function pointer, indicating that it is present therein.

    To be pedantic, I wouldn't classify this omission as a bug -- there are a number of justifiable omissions from MinGW, so it is a stretch for the OP to assert that strnlen() should be included; this is a feature request, not a bug report. That said, I see no reason why this request shouldn't be accommodated; it will entail:

    - adding the appropriate function prototype (from MSDN) to string.h
    - adding the missing symbol to the various msvcr*.def.in files, and regenerating the import libraries.

     
  • Keith Marshall

    Keith Marshall - 2012-03-21
    • labels: 104601 -->
     
  • Earnie Boyd

    Earnie Boyd - 2013-02-15

    Ticket moved from /p/mingw/feature-requests/105/

     
  • Earnie Boyd

    Earnie Boyd - 2013-02-15
    • status: open --> pending
    • assigned_to: Chris Sutcliffe --> Earnie Boyd
    • milestone: --> WSL
    • type: --> Feature
    • resolution: --> later
    • category: --> Unknown
    • patch_attached: --> False
     
  • Earnie Boyd

    Earnie Boyd - 2013-02-21
    • labels: --> needs review, needs test
    • category: Unknown --> Feature_in_WSL_4.1
     
  • Carlo Bramini

    Carlo Bramini - 2013-12-31

    I would like to report that by running this version of the tool:

    PExports 0.46; Originally written 1998, Anders Norlander
    Updated 1999, Paul Sokolovsky, 2008, Tor Lillqvist, 2013, Keith Marshall
    Copyright (C) 1998, 1999, 2008, 2013, MinGW.org Project
    

    the strnlen() is actually listed with all other functions... perhaps its absence was caused by a bug in this tool but nowadays it seems to be fixed.

    EDIT: Keith, you are right. I forgot to mention that I did the test on Windows Seven Home Premium.

     

    Last edit: Carlo Bramini 2013-12-31
    • Keith Marshall

      Keith Marshall - 2013-12-31

      the strnlen() is actually listed with all other functions

      Hmm. Not sure if it was a peculiarity of pexports, before I hacked on it earlier this year, or dependent on the source of the MSVCRT.DLL analysed; I see strnlen in the list, from the MSVCRT.DLL on my Win7 Home Premium VM, but not from that on my WinXP Pro VM. (I don't have anything in between, to check). Furthermore, a GetProcAddress() probe confirms absence of the strnlen() function from the WinXP MSVCRT.DLL.

      As a consequence, while I still see no reason for not adding strnlen() to WSL, visibility would need, at the very least, to be conditional on a minimum WINNT_VERSION -- what should that be? Certainly not the current WinXP default -- or preferably, wrapped in a __mingw_strnlen() implementation, (either performing a DLL probe, or providing a free-standing implementation which could be WINNT_VERSION agnostic).

       
  • Keith Marshall

    Keith Marshall - 2013-12-31

    FWIW, here's a sample free-standing implementation, which we could adopt as a __CRT_ALIAS (say), to keep us WINNT_VERSION agnostic, (ignoring MSVCRT.DLL implementations altogether).

    static __inline__
    size_t strnlen( const char *start, size_t maxlen )
    {
      /* Determine the length of a NUL terminated string, subject
       * to a maximum permitted length constraint.
       */
      const char *stop = start;
    
      /* Scan at most maxlen bytes, seeking a NUL terminator;
       * note that we MUST enforce the length check, BEFORE the
       * terminator check, otherwise we could scan maxlen + 1
       * bytes, which POSIX forbids.
       */
      while( ((stop - start) < maxlen) && *stop )
        ++stop;
    
      /* Result is the number of non-NUL bytes actually scanned.
       */
      return stop - start;
    }
    

    Obviously, this could also be adapted to provide other MS variants on the theme. Equally obviously, the MS strnlen_s() variant is utterly pointless.

     

    Last edit: Keith Marshall 2013-12-31
  • Carlo Bramini

    Carlo Bramini - 2014-01-12

    Perhaps the strnlen() function and its variants could be implemented directly with less efforts, by using already existing functions, for example like this:

    ~~~~static inline
    size_t strnlen( const char start, size_t maxlen )
    {
    const char
    end = (const char *)memchr(start, '\0', maxlen);

    return (end) ? (size_t)(end - start) : maxlen;
    

    }
    ~~~~