Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_FS_1_19910112
-
c/lib5/stdio/new/fseek.c
There are 10 other files named fseek.c in the archive. Click here to see a list.
/*
* FSEEK - set position in file
*
* Copyright (c) 1986 by Ian Macky, SRI International
*/
#include "stdio.h"
#include "sys/file.h"
int fseek(f, offset, whence)
FILE *f;
long offset;
int whence;
{
long new_offset;
int by; /* how much to expand string by */
if ((f->siocheck != _SIOF_OPEN))
return -1; /* validate FILE block */
/* Convert flags from STDIO SEEK_ to system L_ */
#if ((SEEK_SET!=L_SET) || (SEEK_CUR!=L_INCR) || (SEEK_END!=L_XTND))
switch (whence) {
case SEEK_SET: whence = L_SET; break;
case SEEK_CUR: whence = L_INCR; break;
case SEEK_END: whence = L_XTND; break;
default: return -1; /* Bad whence value */
}
#endif
fflush(f); /* first flush any buffered data */
if (whence == L_INCR) { /* this stuff is getting grosser */
offset += ftell(f); /* and grosser as time goes on! */
whence = L_SET; /* how can this be made better? */
}
if (f->sioflgs & _SIOF_STR) switch (whence) {
case L_XTND:
new_offset = f->siolbuf + offset;
if (offset > 0) {
by = f->siosinc * ((offset / f->siosinc) + 1);
if (!_expand(f, by)) return -1;
}
offset = new_offset; /* fall into L_SET now */
case L_SET:
if (offset < 0 || offset >= f->siolbuf) return -1;
f->siocp = f->siopbuf + offset - 1;
f->siocnt = f->siolbuf - offset;
f->siofdoff = offset; break;
return 0; /* success */
default:
return -1;
}
if ((offset = lseek(f->siofd, offset, whence)) != -1) {
f->sioflgs &= ~(_SIOF_PBC | _SIOF_EOF);
if (f->sioflgs & _SIOF_UPDATE) /* enter quiescent state */
f->sioflgs &= ~(_SIOF_READ | _SIOF_WRITE);
f->siofdoff = offset;
return 0;
} else return -1;
}