Web lists-archives.com

Re: [Mingw-users] errno_t and strerror_s




-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 01/12/16 23:04, Keith Marshall wrote:
> On 01/12/16 21:22, DAVENPORT, MARC wrote:
>> What should I use instead?
> 
> As described in ISO-C11 Annex-K, strerror() and strncpy() would
> yield a better match for the behaviour of strerror_s().

On further reflection, maybe snprintf() combined with strerror()
would be better still; strncpy() really isn't well suited to the
job of copying limited length initial sub-strings from a source
to a (possibly shorter) destination buffer, (because it doesn't
guarantee NUL termination, and it carries a possibly substantial
overhead, by always padding any string which does fit, with NULs,
until the destination buffer is completely filled).

Here's a tentative implementation for the strerror_r() function,
(as required by POSIX.1-2008), which, IMO offers a much better
interface design than Microsoft's strerror_s(), (because it doesn't
arbitrarily terminate your process via some overly generalized
invalid parameter handler, if you are careless about checking the
parameters you pass):

  #define _POSIX_C_SOURCE 200809L

  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <errno.h>

  int strerror_r( int errnum, char *buf, size_t len )
  {
    if( buf == NULL )
      return errno = ERANGE;

    if( (0 > errnum) || (errnum >= sys_nerr) )
    { snprintf( buf, len, "Unknown error: %d", errnum );
      return errno = EINVAL;
    }
    if( snprintf( buf, len, "%s", strerror( errnum )) >= len )
      return errno = ERANGE;

    return 0;
  }

Do note that, as it stands, this implementation may not be thread
safe, (as it is required to be); it will be, if the pointer returned
by strerror() refers to thread-local storage, (which it may do, but I
have been unable to find any authoritative confirmation, one way or
the other); if not, then that

  snprintf( buf, len, "%s", strerror( errnum ))

call would need to be wrapped in a critical section, mutex, or some
other synchronization construct.

All that said, your idea of using strdup(), together with strerror(),
(with any synchronization construct which may be necessary), could
actually represent an even better design than either POSIX.1-2008's
strerror_r(), or Microsoft's strerror_s(); it will never truncate the
returned copy of the error message because you failed to provide a
large enough buffer; of course, you would still need to check for
failure to allocate a buffer, and when one is allocated, you should
free it when you have finished with it.

- -- 
Regards,
Keith.

Public key available from keys.gnupg.net
Key fingerprint: C19E C018 1547 DE50 E1D4 8F53 C0AD 36C6 347E 5A3F
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.20 (GNU/Linux)

iQIcBAEBAgAGBQJYQf0vAAoJEMCtNsY0flo/+FEQALB/rpNTwxipUCuzx95bYy1V
KD7CUr3/ZIFFwcbr7a+Pfr6Ap0iCuzdptCdaGgePMjaTy14Wd21JOkhl1M4KbkoK
asRgnorn4R2lcgyeQDN7ztjRQ0EgaDtU5loz771h/2cWNyNekXwD0QuAqH3lOxIo
1NlqS1PnrCTZlo4C6fp5XhJRXvTaXb/xbh6z0/SCCY2+CD5tPKSbNFQTKKXC+8bw
+PYURZ8F072vo6iSgo0ukZnd+UfjFwt1l9NLY/2H18oOpuMuzJFHlhRaetmHsOuc
h/A+QojzOWz2YLJU/FhJuWGHvGNdgKAvQ0JN4bukupr4aW4CbdJJZR1ayGeX5d6e
W7LkufcGBkJbI1jg3xNo6LDwgggQegA2w/OvWn+6lc07WabV2BD8jo3BVS28dYcL
4duHWnfmqS+34Ta+Ehe7xP4maBQk5Enc3FkRnuwjnsVRMXkfS/YLxYXvfP6F0BDI
m88th1eJhHoHpoROQ/b+9Ctn2c3aOt7rkWs/of6kZfCBvslp92bTEU2SnH8VHeR+
PwilSbYFH65r4C2C2ZMGBW6n/pEx97xEWuFkfgElEtdSIcS2ycFOy5qKinvh7sCl
baAWHCE11kr5lturh7yptTCWsF8eKULr7P9XEaFce9On/YzKpIEawqMBQYPB9Dsv
B1pKor1CbmjOgHwLOXz5
=B/yz
-----END PGP SIGNATURE-----

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-users mailing list
MinGW-users@xxxxxxxxxxxxxxxxxxxxx

This list observes the Etiquette found at 
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.  Disregard for the list etiquette may cause your account to be moderated.

_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Also: mailto:mingw-users-request@xxxxxxxxxxxxxxxxxxxxx?subject=unsubscribe