X-Spam-Check-By: sourceware.org From: ericblake AT comcast DOT net (Eric Blake) To: sds AT gnu DOT org, cygwin AT cygwin DOT com Cc: Sam Steingold Subject: Re: lseek + read = ENOENT Date: Fri, 20 Jan 2006 02:34:35 +0000 Message-Id: <012020060234.23454.43D04C3B000B5DD000005B9E22007510900A050E040D0C079D0A@comcast.net> Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com > I cannot read the last 4-byte word in a file using lseek + read: > > /* file "foo" exists and is large enough - say, 4 MB */ > int fd = open("foo",O_RDONLY|O_BINARY); > uint32 data; > /* this succeeds and correctly returns the size of file "foo" minus 4 */ > lseek(fd,-sizeof(data),SEEK_END); > /* this returns 0 -- instead of the expected 4 -- and sets errno to ENOENT */ > read(fd,&data,sizeof(data)); > > if I run this under gdb and type > lseek(fd,-sizeof(data),SEEK_END); > read(fd,&data,sizeof(data)); > several times, eventually read() starts to return 4 and set data to the > value I actually wrote into "foo" last. > > I observe this on linux, cygwin and solaris -- what am I doing wrong? It would have been nicer if you had provided a small example that would compile out of the box; that would show whether you remembered to #include . One thing you did wrong was not checking the return value of lseek. For all you know, the system might have been trying to tell you your lseek was invalid, but you ignored it and proceeded on with the read anyway. The other thing you did wrong: on cygwin, off_t is a 64-bit signed type, but the sizeof operator is of type size_t, which is only a 32-bit unsigned type. The unary - on an unsigned 32-bit number is an unsigned 32-bit number, then you promote that argument to off_t (32-bit unsigned to 64-bit signed promotion is 0-extended). So you were calling lseek(fd, 0x00000000fffffffcLL, SEEK_END), which is certainly different than the intended lseek(fd, 0xfffffffffffffffcLL, SEEK_END). -- Eric Blake -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/