lseek + read = ENOENT
Web Server forum
Back To The Forum Home!Search!Private Messaging System

Web Server Talk Web Server Talk > Unix and Linux reviews > Free Unix support > Unix Programming > lseek + read = ENOENT




  Last Thread   Next Thread Next
  Show Printable Version Email this Page Subscribe to this Thread      Post New Thread    Post A Reply      

    lseek + read = ENOENT  
Sam Steingold


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
01-19-06 11:24 PM

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 return the size of "foo" minus 4 */
lseek(fd,-sizeof(data),SEEK_END);
/* this returns 0 -- instead of 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?

--
Sam Steingold (http://www.podval.org/~sds) running w2k
http://www.camera.org http://www.openvotingconsortium.org http://pmw.org.il
http://ffii.org http://www.jihadwatch.org http://www.memri.org
Vegetarians eat Vegetables, Humanitarians are scary.





[ Post a follow-up to this message ]



    Re: lseek + read = ENOENT  
Casper H.S. Dik


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
01-19-06 11:24 PM

Sam Steingold <sds@gnu.org> writes:

>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 return the size of "foo" minus 4 */
>  lseek(fd,-sizeof(data),SEEK_END);
>/* this returns 0 -- instead of 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?


Run the code under strace/truss and you may be enlightened.

BTW, checking errno when read returns 0 is *wrong*; it gives no
useful information.

Possible clues:

sizeof(data) is unsigned
-sizeof(data) is ?
what's the 2nd argument to lseek in your compilation
environment?  (what size is off_t?)
what's the size of size_t?

Casper
--
Expressed in this posting are my opinions.  They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.





[ Post a follow-up to this message ]



    Re: lseek + read = ENOENT  
Pascal Bourguignon


View Ip Address Report This Message To A Moderator Edit/Delete Message


 
01-19-06 11:24 PM

Sam Steingold <sds@gnu.org> writes:

> 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 return the size of "foo" minus 4 */
>   lseek(fd,-sizeof(data),SEEK_END);
> /* this returns 0 -- instead of 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?

Since you don't say us what uint32 is, or O_BINARY (which is not in
SUSv3 AFAIK), it's hard to say.  But the following works perfectly on
Linux 2.6 on ix86:


-*- mode: compilation; default-directory: "/tmp/" -*-
cat last-long.c;make -k last-long  CFLAGS=-g ; ls -l  /tmp/asfgXDwZ9 ; od -x
  /tmp/asfgXDwZ9 | tail -3 ; ./last-long /tmp/asfgXDwZ9
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

typedef unsigned long uint32;
const int O_BINARY=0;

int main(int argc,char** argv){
/* file "foo" exists and is large enough - say, 4 MB */
int fd = open(argv[1],O_RDONLY|O_BINARY);
uint32 data;
/* this succeeds and correctly return the size of "foo" minus 4 */
printf("lseek(%d,%d,%d)=%d\n",fd,-sizeof(data),SEEK_END,
lseek(fd,-sizeof(data),SEEK_END));
/* this returns 0 -- instead of expected 4 -- and sets errno to ENOENT */
printf("read(%d,&data,%d)=%d\n",fd,sizeof(data),read(fd,&data,sizeof(data)))
;
printf("data=%lu\n",data);
return(0);
}


make: `last-long' is up to date.
-rw-------    1 pjb      pjb      45473136 2006-01-18 20:54 /tmp/asfgXDwZ9
255356520 f72e 0be6 a903 e425 59c0 00a7 02c0 442c
255356540 09c0 c902 b483 d6d1 2559 925d 0069 0000
255356560
lseek(3,-4,2)=45473132
read(3,&data,4)=4
data=105

Compilation finished at Thu Jan 19 22:36:48

--
__Pascal Bourguignon__                     http://www.informatimago.com/

What is this talk of 'release'? Klingons do not make software 'releases'.
Our software 'escapes' leaving a bloody trail of designers and quality
assurance people in it's wake.





[ Post a follow-up to this message ]



    Sponsored Links  




 





   All times are GMT. The time now is 07:19 PM.      Post New Thread    Post A Reply      
  Last Thread   Next Thread Next


Most Popular forums 

Forum Jump:
Rate This Thread:

Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is OFF
vB code is ON
Smilies are ON
[IMG] code is OFF
 
Medical and Health forum | Computer Games Reviews | Graphics design forum

Back To The Top
Home | Usercp | Faq | Register