Sender: richdawe AT bigfoot DOT com Message-ID: <3A0B329F.D33F7737@bigfoot.com> Date: Thu, 09 Nov 2000 23:26:23 +0000 From: Richard Dawe 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> Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="------------ms041EB3D80A1E385366206CBB" 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 ... 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--