Subject: Re: lseek() continued! DOH!
To: None <tooleym@douglas.bc.ca>
From: Todd Vierling <tv@NetBSD.ORG>
List: netbsd-help
Date: 02/04/1998 09:34:17
On Wed, 4 Feb 1998 tooleym@douglas.bc.ca wrote:
: > It still sounds like you're treating the offset parameter and return
: > value of lseek() as 32-bit values... they're 64-bit values. When you
: > printf lseek's return value, you have to use a %qd, not %ld or %d. And
: > make sure you #include <unistd.h>
: pos = 1L;
: if ((datafile=open("player.records",O_RDWR))>=0) {
:
: status=lseek(datafile, (off_t)(-(sizeof(struct record))), SEEK_END);
: printf("lseeked to %d\n", status);
: while(pos != -1L) {
: status=lseek(datafile, (off_t)(-(sizeof(struct record)*pos)), SEEK_END);
: if (status < 0) break;
: if ((status=read (datafile, &myrec, sizeof (struct record)))<0) {
: pos = -1L;
: } else {
: printf("status: %d\n", status);
: printf("name field:%s\n", myrec.name);
: if (!strncmp(myrec.name,who,strlen(who))) {
: printf("found an entry with name: %s\n", myrec.name);
: printf("fiddling with entry..\n");
: strcpy(myrec.status, "clean");
: status=lseek(datafile,(off_t)(-( (sizeof(struct record)) * pos),SEEK_END));
: write (datafile, &myrec, sizeof (record));
: pos = -1L;
: } else { pos += 1L; printf("pos:%d\n", pos);}
: }
: }
: close(f);
Let me give you a shot in the dark rewrite.
#include <unistd.h>
/* ... */
off_t status;
long pos;
/* ... */
pos = 1;
if ((datafile=open("player.records",O_RDWR))>=0) {
status=lseek(datafile, (off_t)(-(sizeof(struct record))), SEEK_END);
printf("lseeked to %d\n", status);
while(pos != -1) {
status=lseek(datafile, -((off_t)(sizeof(struct record)*pos)), SEEK_END);
if (status < 0) break;
if ((status=read (datafile, &myrec, sizeof(struct record)))<0) {
pos = -1;
} else {
printf("status: %d\n", status);
printf("name field:%s\n", myrec.name);
if (!strncmp(myrec.name,who,strlen(who))) {
printf("found an entry with name: %s\n", myrec.name);
printf("fiddling with entry..\n");
strcpy(myrec.status, "clean");
status=lseek(datafile,-((off_t)(sizeof(struct record) * pos)),SEEK_END));
write (datafile, &myrec, sizeof(struct record));
/* ^^^^^^^^^^^^^ */
pos = -1;
} else { pos += 1; printf("pos:%d\n", pos);}
}
}
close(f);
You'll note four changes:
- status is an off_t (that's the return value of lseek(), though
conceivably `long' would work if the rest of the code worked ;).
- the removal of `L' from constants assigned to pos (if `pos' is long,
that's overkill, it's just a cleanup).
- a sizeof(record) is changed to a sizeof(struct record), at the `^^^^^'.
Perhaps this was a typo, or you `typedef struct record record'?
- casting to off_t is done after all calculations EXCEPT NEGATING is done.
(From memory:) When you evaluate a sizeof expression, its type is
`unsigned int'. Negating it keeps it an `unsigned int', even though you
negated it properly in 32-bit math. If you cast first, it becomes off_t
(`signed long long'), which should work.
The last change is what I think will fix this code as per the problem you
have.
=====
===== Todd Vierling (Personal tv@pobox.com) =====
== "There's a myth that there is a scarcity of justice to go around, so
== that if we extend justice to 'those people,' it will somehow erode the
== quality of justice everyone else receives." -- Maria Price