write() on 64 bit platform sometimes returns 32bit -1 as error indicator
netbsdrat@gmail.com
netbsdrat@gmail.com
Thu Apr 23 19:36:24 GMT 2020
write() on 64 bit platform sometimes returns 32bit -1 as error indicator:
Using 64 bit cygwin on 64 bit platform. Doing direct read() / write of
disks,
this example is using the /dev/floppy device.
Opening for writing floppy device using open() succeeds.
2 cases:
CaseA) write() a 512 byte buffer to the floppy, succeeds with return
value of 512, errno = 0. This works.
CaseB) write() a 5120 byte buffer to the floppy. This fails if we have
recently
formatted the floppy with windows. Perhaps windows still has some file
descriptor to the floppy open? But this is not the point.
The point is that the return value from the write() is 4294967295
(0xffffffff).
This value is a 32 bit -1. When we compare the return value to -1 (64 bit),
the compare fails, which indicates that the write succeeded, and implies
that
4294967295 bytes were written.
The write did not succeed though. No data was written to the floppy.
Errno is set indicating an error (13 'Permission denied'), but the return
value from write() is not correct for this situation. Thus the write
failure cannot
be detected (except by looking at errno)! BTW, return value in this
case == -1U, but not == -1.
CaseC) As a third control case to make sure that I was understanding all the
data
widths, I tried opening a fake file, and doing the same write to it,
expecting an error. The error propagated correctly... the return value
of writing to a bad file descriptor was 64 bit -1 (0xffffffffffffffff)
and can be compared to -1 directly to detect the error. Errno is set
correctly.
So I think that somewhere in the myriad of pathways between 32 / 64 bit
way down in the depths of cygwin, this unusual write error triggers a return
value of 32 bit -1 instead of 64 bit -1.
Is this cygwin issue? gcc issue? libc issue??
Thanks,
John Refling
PS: Equally odd is the errno of 13, 'permission denied' with a different
buffer size. You can write 512 bytes after getting the permission denied,
and then after that, write as many bytes as you want without 'permission
denied'. Some strange things in windows, cygwin, or the interaction of the
two.
Output of attached sample programs:
/* CaseA OUTPUT, here we test 512 which works.
open floppy, which is OK
fno = 3, errno = 0 'No error'
ie: fopen() OK
try write() 512 which is OK
RV = 0x200 or 512, errno = 0 'No error'
Write OK!
*/
/* CaseB OUTPUT: this case triggers bad return value
open floppy, which is OK
fno = 3, errno = 0 'No error'
ie: fopen() OK
try write() 5120 which is NOT ok, sometimes.
RV = 0xffffffff or 4294967295, errno = 13 'Permission denied'
but nothing actually written
RV IS NOT == 0
RV IS NOT < 0
RV IS NOT == -1
RV IS NOT == -1L
RV IS == -1U !!! 32 bit -1 !!!
no way to detect this write() failure!
*/
/* CaseC OUTPUT: this case shows usual correct return value for fail
open fake file, which fails, as expected
fno = -1, errno = 2 'No such file or directory'
try write() 512 to bad file, expect fail
RV = 0xffffffffffffffff or -1, errno = 9 'Bad file descriptor'
RV IS NOT == 0
RV IS < 0
RV IS == -1
RV IS == -1L
RV IS NOT == -1U
can detect this failure.
*/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: caseA.c
Type: application/octet-stream
Size: 1483 bytes
Desc: not available
URL: <https://cygwin.com/pipermail/cygwin/attachments/20200423/6b919dff/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: caseC.c
Type: application/octet-stream
Size: 1620 bytes
Desc: not available
URL: <https://cygwin.com/pipermail/cygwin/attachments/20200423/6b919dff/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: caseB.c
Type: application/octet-stream
Size: 1940 bytes
Desc: not available
URL: <https://cygwin.com/pipermail/cygwin/attachments/20200423/6b919dff/attachment-0002.obj>
More information about the Cygwin
mailing list