X-Spam-Check-By: sourceware.org Message-ID: <43D035FC.7000101@hones.org.uk> Date: Fri, 20 Jan 2006 00:59:40 +0000 From: Cliff Hones User-Agent: Mozilla Thunderbird 1.0 (Windows/20041206) MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Re: lseek + read = ENOENT References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-IsSubscribed: yes 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 Sam Steingold wrote: > 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? This seems to be a bug in gcc. The off_t argument to lseek is a 64-bit type, but instead of being sign-extended to 64 bits, the value passed (-sizeof(data)) passed is only extended to 32-bits, so is actually +4294967292. If you write: int n = -sizeof(data); lseek(fd, n, SEEK_END); it works as expected. -- Cliff -- 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/