[comp.unix.wizards] question on lseek behavior

marshall@software.org (Eric Marshall) (07/05/90)

	I was trying to use lseek to rewind to the beginning
of input (a file), but I ran into difficulties.  When I run
the program below, it outputs the file missing the first 3 characters,
as if the lseek didn't do anything, then it outputs the entire
file.  Could someone please explain why this occurs.  I eventually
found the rewind(3S) call, and it works fine.  I am running
on SunOS 4.1.

	Thanks in advance.

	seek_test.c:

		#include <stdio.h>
		#include <sys/types.h>
		#include <sys/file.h>
		
		main()
		{
		  int c;
		  FILE *infile = fopen( "seek_test.c", "r" );
		
		  c = getc( infile );
		  c = getc( infile );
		  c = getc( infile );
		
		  lseek( fileno( infile ), 0L, L_SET );
		
		  while ( ( c = getc( infile ) ) != EOF ) putchar( c );
		}


Eric Marshall
Software Productivity Consortium
SPC Building
2214 Rock Hill Road
Herndon, VA 22070
(703) 742-7153

UUCP: ...!uunet!software!marshall
ARPANET: marshall%software.org@relay.cs.net

cpcahil@virtech.uucp (Conor P. Cahill) (07/06/90)

In article <1416@software.software.org> marshall@software.org (Eric Marshall) writes:
>
>	I was trying to use lseek to rewind to the beginning
>of input (a file), but I ran into difficulties.  When I run
>the program below, it outputs the file missing the first 3 characters,
>as if the lseek didn't do anything, then it outputs the entire
>file.  Could someone please explain why this occurs.  I eventually
>found the rewind(3S) call, and it works fine.  I am running
>on SunOS 4.1.

You cannot mix FILE POINTER calls with file descriptor calls (or in other
words, stdio calls with system calls).  

if you use getc, fgets, gets, scanf, etc you must use fseek to seek in a file.
if you use read you must use lseek.


-- 
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.,
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170 

lm@snafu.Sun.COM (Larry McVoy) (07/06/90)

In article <1416@software.software.org> marshall@software.org (Eric Marshall) writes:
>
>	I was trying to use lseek to rewind to the beginning
>of input (a file), but I ran into difficulties.  When I run
>the program below, it outputs the file missing the first 3 characters,
>as if the lseek didn't do anything, then it outputs the entire
>file.  Could someone please explain why this occurs.  I eventually
>found the rewind(3S) call, and it works fine.  I am running
>on SunOS 4.1.

You are using stdio routines which buffer.  You bypassed those routines
when you issued the lseek() call; rewind is built on top of lseek and
looks something like:

rewind(f)
	FILE *f;
{
	lseek(f->_fd, 0, 0);
	f->_chars_in_buf = 0;
}

This is a common problem; many test suites make the same mistake.
---
Larry McVoy, Sun Microsystems     (415) 336-7627       ...!sun!lm or lm@sun.com

gwyn@smoke.BRL.MIL (Doug Gwyn) (07/06/90)

In article <1416@software.software.org> marshall@software.org (Eric Marshall) writes:
>	I was trying to use lseek to rewind to the beginning
>of input (a file), but I ran into difficulties.

Don't mix direct system calls such as lseek() with stdio operations such
as fopen() and getc().  Use fseek() instead.