delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2006/01/19/21:34:45

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 <sds AT gnu DOT org>
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: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
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 <unistd.h>.

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/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019