From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by sourceware.org (Postfix) with ESMTPS id CF9C63959C26 for ; Thu, 23 Apr 2020 19:36:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org CF9C63959C26 Received: by mail-pj1-x1030.google.com with SMTP id a7so2928731pju.2 for ; Thu, 23 Apr 2020 12:36:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :thread-index; bh=30nIeF6cnwCBlxu9jH++FcLrwf8niQSb/eTRjzzYiAE=; b=ShHCYHzjWk4cbQlNtU+Gjxgftw4j4q4nMFZPmomEmJPEKpSN1gk2KSr/mUzCcZ+Ml6 rAOVnBcjCquxfC5qF4hrQ06xg9tnSsARbiWOBqj2jtIljVKsnkT5zA/BngGI/dfi4GmN pz4VrkZcKo4GJb2/yrE7wRSAIQr8YqWbBjBSHed32ca9R7fVns7+jChvKfdmVES3V5/3 VTtZM9zmDBgvzaFvJPRG+tpeK07uHK/BFCig17YcR5sB9S1hRme6QAMvUZ+QG3Ya+ele iq8LNa2SuMPHiP1+aIyR1RKZ/MkFM3rJ2dzMoVVnlxFB+TmzXboJDDwJemS5xDGNd1gQ EmfQ== X-Gm-Message-State: AGi0PuZGnN8OTAYHgop+n2l69zOqw4w9/DQnR8HCFkW3EMLQMMz/z72Z 4qQap5+kIePEBIDQgl5/PXE+uLM= X-Google-Smtp-Source: APiQypJ160fvVQ2Vy1XITgFx+ADgCHfY1M3BKzZspzr9x0VlQJeDZHXhNiwIXS/73DIr8HuO3XjG0w== X-Received: by 2002:a17:90a:db91:: with SMTP id h17mr2479931pjv.10.1587670588367; Thu, 23 Apr 2020 12:36:28 -0700 (PDT) Received: from DAD325 (cpe-23-240-48-237.socal.res.rr.com. [23.240.48.237]) by smtp.gmail.com with ESMTPSA id g27sm2860973pgn.52.2020.04.23.12.36.26 for (version=TLS1 cipher=ECDHE-ECDSA-AES128-SHA bits=128/128); Thu, 23 Apr 2020 12:36:27 -0700 (PDT) From: To: Subject: write() on 64 bit platform sometimes returns 32bit -1 as error indicator Date: Thu, 23 Apr 2020 12:36:24 -0700 Message-ID: <8FBD9FC4F4994493AE1DA1DDBBAFB6B9@DAD325> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_059A_01D6196B.CDEE2620" X-Mailer: Microsoft Office Outlook 11 Thread-Index: AdYZpnk4p8az+0dERxG/nvdbl3R37Q== X-MimeOLE: Produced By Microsoft MimeOLE V6.1.7601.23403 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: cygwin@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: General Cygwin discussions and problem reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 23 Apr 2020 19:36:31 -0000 This is a multi-part message in MIME format. ------=_NextPart_000_059A_01D6196B.CDEE2620 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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. */ ------=_NextPart_000_059A_01D6196B.CDEE2620 Content-Type: application/octet-stream; name="caseA.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="caseA.c" #define BUFSIZZ 512 // caseA: 512 works always, more causes an error SOMETIMES, see caseB. // john refling. caseA.c /* OUTPUT, here we test 512 which works. open floppy, which is OK fno =3D 3, errno =3D 0 'No error' ie: fopen() OK try write() 512 which is OK RV =3D 0x200 or 512, errno =3D 0 'No error' Write OK! */ #include #include #include #include #include #include #include int main(int argc, char *argv[]) { char *buf =3D calloc(1, BUFSIZZ); printf("\nopen floppy, which is OK\n"); int fno =3D open("/dev/floppy", O_RDWR, 0777); printf("fno =3D %d, errno =3D %d '%s'\n", fno, errno, strerror(errno)); printf("ie: fopen() OK\n\n"); // write some data to the floppy, when this fails, // it seems to put a "32 bit -1" in return value, // not a 64 bit -1 !!! printf("try write() 512 which is OK\n"); errno =3D 0; ssize_t RV =3D write(fno, buf, BUFSIZZ); // print out the RV, it is a ssize_t, use %ld printf("RV =3D 0x%lx or %ld, errno =3D %d '%s'\n\nWrite OK!\n", (long = unsigned)RV, RV, errno, strerror(errno)); if (512 =3D=3D RV) return(0); // see what constants RV matches: fprintf(stderr, "RV %s =3D=3D 0\n", (RV =3D=3D 0)?"IS":"IS NOT"); fprintf(stderr, "RV %s < 0\n", (RV < 0)?"IS":"IS NOT"); fprintf(stderr, "RV %s =3D=3D -1\n", (RV =3D=3D -1)?"IS":"IS NOT"); fprintf(stderr, "RV %s =3D=3D -1L\n", (RV =3D=3D -1L)?"IS":"IS NOT"); fprintf(stderr, "RV %s =3D=3D -1U\n\n", (RV =3D=3D -1U)?"IS":"IS NOT"); return 0; } ------=_NextPart_000_059A_01D6196B.CDEE2620 Content-Type: application/octet-stream; name="caseC.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="caseC.c" #define BUFSIZZ 512 // caseC: do something that we know returns -1 // failure to make sure we understand data sizes. // john refling. caseC.c /* OUTPUT: this case shows correct return value for fail open fake file, which fails, as expected fno =3D -1, errno =3D 2 'No such file or directory' try write() 512 to bad file, expect fail RV =3D 0xffffffffffffffff or -1, errno =3D 9 'Bad file descriptor' RV IS NOT =3D=3D 0 RV IS < 0 RV IS =3D=3D -1 RV IS =3D=3D -1L RV IS NOT =3D=3D -1U can detect this failure. */ #include #include #include #include #include #include #include int main(int argc, char *argv[]) { char *buf =3D calloc(1, BUFSIZZ); printf("\nopen fake file, which fails, as expected\n"); int fno =3D open("/dev/flopZpy", O_RDWR, 0777); printf("fno =3D %d, errno =3D %d '%s'\n", fno, errno, strerror(errno)); // write some data to bad file number printf("\ntry write() 512 to bad file, expect fail\n"); errno =3D 0; ssize_t RV =3D write(fno, buf, BUFSIZZ); // print out the RV, it is a ssize_t, use %ld printf("RV =3D 0x%lx or %ld, errno =3D %d '%s'\n\n", (long unsigned)RV, = RV, errno, strerror(errno)); if (512 =3D=3D RV) return(0); // see what constants RV matches: fprintf(stderr, "RV %s =3D=3D 0\n", (RV =3D=3D 0)?"IS":"IS NOT"); fprintf(stderr, "RV %s < 0\n", (RV < 0)?"IS":"IS NOT"); fprintf(stderr, "RV %s =3D=3D -1\n", (RV =3D=3D -1)?"IS":"IS NOT"); fprintf(stderr, "RV %s =3D=3D -1L\n", (RV =3D=3D -1L)?"IS":"IS NOT"); fprintf(stderr, "RV %s =3D=3D -1U\n\n", (RV =3D=3D -1U)?"IS":"IS NOT"); fprintf(stderr, "can detect this failure.\n"); return 0; } ------=_NextPart_000_059A_01D6196B.CDEE2620 Content-Type: application/octet-stream; name="caseB.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="caseB.c" #define BUFSIZZ 5120 // caseB: 5120 fails soon after a windows format a: // maybe there is an error or not, from windows. // hard to tell, but in any case, the return value // is not correct. If it works once then you // can use any size after that point. // john refling. caseB.c /* OUTPUT: this case triggers bad return value open floppy, which is OK fno =3D 3, errno =3D 0 'No error' ie: fopen() OK try write() 5120 which is NOT ok, sometimes. RV =3D 0xffffffff or 4294967295, errno =3D 13 'Permission denied' but nothing actually written RV IS NOT =3D=3D 0 RV IS NOT < 0 RV IS NOT =3D=3D -1 RV IS NOT =3D=3D -1L RV IS =3D=3D -1U !!! 32 bit -1 !!! no way to detect this write() failure! */ #include #include #include #include #include #include #include int main(int argc, char *argv[]) { char *buf =3D calloc(1, BUFSIZZ); printf("\nopen floppy, which is OK\n"); int fno =3D open("/dev/floppy", O_RDWR, 0777); printf("fno =3D %d, errno =3D %d '%s'\n", fno, errno, strerror(errno)); printf("ie: fopen() OK\n\n"); // write some data to the floppy, when this fails, // it seems to put a "32 bit -1" in return value, // not a 64 bit -1 !!! printf("try write() 5120 which is NOT ok\n"); errno =3D 0; ssize_t RV =3D write(fno, buf, BUFSIZZ); // print out the RV, it is a ssize_t, use %ld printf("RV =3D 0x%lx or %ld, errno =3D %d '%s'\n\nbut nothing actually = written\n", (long unsigned)RV, RV, errno, strerror(errno)); if (512 =3D=3D RV) return(0); // see what constants RV matches: fprintf(stderr, "RV %s =3D=3D 0\n", (RV =3D=3D 0)?"IS":"IS NOT"); fprintf(stderr, "RV %s < 0\n", (RV < 0)?"IS":"IS NOT"); fprintf(stderr, "RV %s =3D=3D -1\n", (RV =3D=3D -1)?"IS":"IS NOT"); fprintf(stderr, "RV %s =3D=3D -1L\n", (RV =3D=3D -1L)?"IS":"IS NOT"); fprintf(stderr, "RV %s =3D=3D -1U\n\n", (RV =3D=3D -1U)?"IS":"IS NOT"); fprintf(stderr, "\nno way to detect this failure!\n"); return 0; } ------=_NextPart_000_059A_01D6196B.CDEE2620--