haunted85
haunted85

Reputation: 1671

lseek issues

I'm having a hard time figuring out why lseek doesn't work properly. Basically all I need to do is take input from the standard input, store it into a file named "log.txt" and let the program stop as the "STOP" word is encountered.

My problem is as I try to run the program I get an lseek error: illegal seek and I don't know why. I thought the issue was the call to lseek but if I substitute lseek(fd, 0, SEEK_END) with lseek(fd, atol(0), SEEK_END) I get a segmentation fault.

I'm just so confused, I don't know how to proceed in order to fix this, I hope you could give your advice.

int fd;
char buffer[SIZE];
int n, cur;

if (fd = open("log.txt", O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO) < 0)
{
    perror("Error: open");
    return 1;
}

if ((cur = lseek(fd, 0, SEEK_END)) < 0)
{
    printf("Offset corrente: %d\n", (int) lseek(fd, SIZE, SEEK_CUR));
    perror("Error: lseek");
    return 2;
}

while ((n = read(fd, buffer, SIZE)) > 0 && (strncmp(buffer, "STOP", 4) != 0))
{
    write(fd, buffer, SIZE);
}

Upvotes: 1

Views: 6580

Answers (4)

TreeFrogHoldsLeaf
TreeFrogHoldsLeaf

Reputation: 21

if ((cur = lseek(fd, 0, SEEK_END)) < 0)

should be changed to:

if ((cur = lseek(fd, 0, SEEK_END)) == -1)

In certain situations it is possible for lseek to provide a negative offset. As a result when testing for an error, only x == -1 should be used, instead of x < 0.

Upvotes: 2

Gilbert
Gilbert

Reputation: 3776

Not only are you reading the same file, read() reads SIZE bytes. Unless your input is fixed length records of SIZE bytes you will read multiple lines, completely missing the STOP which is now in the middle of the buffer.

while ( fgets( buffer, sizeof(buffer), stdin) && (strncmp(buffer, "STOP", 4) != 0))

Reads a line at a time.

Upvotes: 1

Matthew Slattery
Matthew Slattery

Reputation: 47058

if (fd = open("log.txt", O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO) < 0)

should be

if ((fd = open("log.txt", O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO)) < 0)

otherwise it will be parsed as

if (fd = (open("log.txt", O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO) < 0))

(because < has a higher operator precedence than =); if the open() succeeds, it will return a value that is >= 0, so the expression open(...) < 0 will be false, so fd will be set to 0.

File descriptor 0 represents the standard input for your process. Unless you've redirected it, this will be a terminal device, for which seeking is illegal.

Upvotes: 4

Hogan
Hogan

Reputation: 70538

You are reading and writing to the same file

 read(fd, buffer, SIZE)

Is wrong. You want to read from stdin.

Upvotes: 3

Related Questions