delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2000/11/09/18:28:42

Sender: richdawe AT bigfoot DOT com
Message-ID: <3A0B329F.D33F7737@bigfoot.com>
Date: Thu, 09 Nov 2000 23:26:23 +0000
From: Richard Dawe <richdawe AT bigfoot DOT com>
X-Mailer: Mozilla 4.51 [en] (X11; I; Linux 2.2.17 i586)
X-Accept-Language: de,fr
MIME-Version: 1.0
To: djgpp-workers AT delorie DOT com
Subject: Re: Summary of the snprintf() situation
References: <3A09EAB9 DOT 6924045A AT bigfoot DOT com>
Reply-To: djgpp-workers AT delorie DOT com

This is a cryptographically signed message in MIME format.

--------------ms041EB3D80A1E385366206CBB
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello.

Having summarised the whole thing, maybe I can comment on it. ;) Most of
the snprintf() code seems to be agreed. AFAICT the only contentious point
is the return code of the modified __putc_raw(). I found a couple more
mails that add a little to the discussion.

Richard Dawe wrote:
> static __inline__ int __putc_raw(int const x,FILE *const p)
> {
>    if(p->_cnt>0)
>    {
>       p->_cnt--;
>       return((unsigned char)(*(p->_ptr++)=(unsigned char)x));
>    } else if (p->_flag & _IOSTR)
>    {
>       /* For String stream never flush.  And we also mimic the
>        * GNU libc by keep on counting.
>        */
>       p->cnt--;
>       return 0;
>    }
>    return(_flsbuf(x,p));
> }
> 
> (Rich: It seems that between this version and the current version, the
> 'p->cnt--;' line for string streams has been lost.)

This change is because negative cnt has a special meaning. From a mail I
just found (quotation mine):

Eli Zareskii wrote:
>
> Richard Dawe wrote:
> > Am I correct in thinking that you can't a negative value for p->cnt
> > has some special meaning?
>
> Yes.
>
> > IIRC for my brief look, it's used to simulate
> > non-buffered output (i.e. character-by-character output).
>
> No, the main reason is line-buffered streams.

So the "p->_cnt--;" was removed.

Now for some (hopefully) clarifying comments about what __putc_raw()
should return when the end of the buffer has been reached:

Alain Magloire wrote (& I quoted):
> With regard to returning EOF on overflow: "Each function snprintf,
> printf, sprintf, returns and a negative value when an error occured,
> obviously overflow is an error, IMO."

Eli said that __putc_raw() should return the character 'x', even when the
buffer was full, to be consistent with the (previous) semantics of
__putc_raw(). Part of the concern seemed to be that the library expects
certain behaviour and modifying that behaviour would cause subtle
problems.

(Again, quotation mine, from other mails.)

Eli Zaretskii wrote: 
>
> Richard Dawe wrote:
> > Eli, you seem concerned that _doprnt() will not be able to cope with
> > __putc_raw() returning EOF (via putc()), if someone changes _doprnt()
> > in the future. Surely the solution here is to make _doprnt() aware
> > that __putc_raw() can return EOF for streams with _IOSTRG flag set?
>
> I don't want _doprnt to know about _IOSTRG.  It's not a good idea to
> have too many functions know about these flags, it complicates
> maintenance.

The motivation for returning EOF was also discussed:

Eli Zaretskii wrote:
>
> Richard Dawe wrote:
>
> > From Alain's example, I get the impression the main motivation for
> > returning EOF is to avoid looping when the range of negative values
> > of "cnt" is used up.
>
> Why do we need to get to negative values of _cnt at all?  We could
> simply leave alone the _cnt member of the FILE object for _IOSTRG
> ``streams''.

I have to admit, reading this again, I am confused by what you say, Eli.
If you don't track the position in the buffer using _cnt, what do you use?
Would you add another field?

Maybe I have an idea that will work. The intention of returning EOF is to
stop _cnt wrapping round. _cnt is an int, whereas snprintf()'s buffer size
is a size_t. Firstly, change _cnt to a ssize_t. Then place a restriction
on the maximum buffer size, namely the maximum (positive) number that can
be stored in both a size_t and ssize_t. Now, what error to return, when
the buffer size is bigger than this?

Unix98 has the following error:

"[EFBIG]
    The file is a regular file and an attempt was made to write at or
    beyond the offset maximum associated with the corresponding stream."

(See the page for fputc() - this is referenced from the fprintf() page.)

So you'd have:

...
#include <limits.h>

...
snprintf (...)
{
    ...

    if (n > SSIZE_MAX) {
        errno = EFBIG;
        return(-1);
    }
}

Now you can preserve __putc_raw() semantics and avoid the buffer
wrap-around problem. Could someone please check that this is allowed by
C99 spec?

Pardon the long mail, but I wanted to clarify things / make a suggestion
based on finding more mail.

Thanks, bye, Rich =]

-- 
Richard Dawe
[ mailto:richdawe AT bigfoot DOT com | http://www.bigfoot.com/~richdawe/ ]
--------------ms041EB3D80A1E385366206CBB
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
Content-Description: S/MIME Cryptographic Signature

MIIHFQYJKoZIhvcNAQcCoIIHBjCCBwICAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHAaCC
BY0wggLMMIICNaADAgECAhB2D2twnX9wqhegGKLtJkJmMA0GCSqGSIb3DQEBBAUAMFgxJzAl
BgNVBAoTHkJyaXRpc2ggVGVsZWNvbW11bmljYXRpb25zIHBsYzEtMCsGA1UECxMkQlQgVHJ1
c3R3aXNlIC0gQ2xhc3MgMSBJbmRpdmlkdWFsIENBMB4XDTAwMTAxNTAwMDAwMFoXDTAxMTAx
NTIzNTk1OVowggERMScwJQYDVQQKEx5Ccml0aXNoIFRlbGVjb21tdW5pY2F0aW9ucyBwbGMx
LTArBgNVBAsTJEJUIFRydXN0d2lzZSAtIENsYXNzIDEgSW5kaXZpZHVhbCBDQTFGMEQGA1UE
CxM9d3d3LnRydXN0d2lzZS5jb20vcmVwb3NpdG9yeS9SUCBJbmNvcnAuIGJ5IFJlZi4sTElB
Qi5MVEQoYyk5ODEzMDEGA1UECxMqRGlnaXRhbCBJRCBDbGFzcyAxIC0gTmV0c2NhcGUgRnVs
bCBTZXJ2aWNlMRUwEwYDVQQDEwxSaWNoYXJkIERhd2UxIzAhBgkqhkiG9w0BCQEWFHJpY2hk
YXdlQGJpZ2Zvb3QuY29tMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMJ3LQ1fxlYpzsChuJ16
J9dwyZIkhexC8uW2RGyxJVOG6643weIDoATk515qu8G91CS85rLDRFIB0u2N4ezCUCkCAwEA
AaMgMB4wCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCB4AwDQYJKoZIhvcNAQEEBQADgYEA
llCoL5Afa66m9bxGh/gMgwUCCCOb6DdKHmJw9Q5h0xoEHuHOcEEjNPqQug5ZQaKioEIJM7DS
gsuSPrEy5Z521OzNWxN8nRv9YAlV3fVHQxcNlsjaAZru6zJxZ0+0uAKKFKOjJLTdfXFUqdcH
kcY2syIZo6DRSIap9pCqC+HYOoIwggK5MIICIqADAgECAhEA0zBJnvKZLVDb03kHStQNPTAN
BgkqhkiG9w0BAQIFADBfMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4x
NzA1BgNVBAsTLkNsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkwHhcNOTgwMjEyMDAwMDAwWhcNMDMwMjEyMjM1OTU5WjBYMScwJQYDVQQKEx5Ccml0aXNo
IFRlbGVjb21tdW5pY2F0aW9ucyBwbGMxLTArBgNVBAsTJEJUIFRydXN0d2lzZSAtIENsYXNz
IDEgSW5kaXZpZHVhbCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0QG30oEW28L0
Z/5fC03tfZ+a2ahBQYehZ6hrcb1PW6ZIXuqm5y8KpzYJ9rLhRkMA3BzH8eACTVhkn/qAJmqC
m2GTDa7eueV8q6A/0I/p9KwahkjEgG4exysZ9svlo21+HWn0yFtrHAraKuNoZOPpFnNP5dOp
AuObV5lKytU5AlkCAwEAAaN8MHowEQYJYIZIAYb4QgEBBAQDAgEGMEcGA1UdIARAMD4wPAYL
YIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNvbS9yZXBvc2l0b3J5
L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQIFAAOBgQBS
Acma9vqkvYS4miXj6t5jPDVao9pIjdxWTjRoiRPRRi7wz0On9jUzqVK8sVcrPIpwxmvnlOyv
jM8KpZaJVXECrgclfNlGR58eSiyTSHyBO0XUK4XLJkwkBXyBmiHc+32l5gvC+QXuGccUEdg8
WZ/OOeoRMbCdGuw1+LeE55h4JzGCAVAwggFMAgEBMGwwWDEnMCUGA1UEChMeQnJpdGlzaCBU
ZWxlY29tbXVuaWNhdGlvbnMgcGxjMS0wKwYDVQQLEyRCVCBUcnVzdHdpc2UgLSBDbGFzcyAx
IEluZGl2aWR1YWwgQ0ECEHYPa3Cdf3CqF6AYou0mQmYwCQYFKw4DAhoFAKB9MBgGCSqGSIb3
DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTAwMTEwOTIzMjYyM1owHgYJKoZI
hvcNAQkPMREwDzANBggqhkiG9w0DAgIBKDAjBgkqhkiG9w0BCQQxFgQUyo4gHbtmuL4TdiuE
2TBqifLCgBkwDQYJKoZIhvcNAQEBBQAEQFqifDUly4BZlDV+5K6TYiUNkj5P+ogjMsFujSd2
2hvjiApVJ6/k1zrYNJVSxab6qJSk9GK1vN5nW6QvrmpUzLA=
--------------ms041EB3D80A1E385366206CBB--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019