Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/lib/libc/stdio/fseek.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fseek

   1 /*-
   2  * Copyright (c) 1990, 1993
   3  *      The Regents of the University of California.  All rights reserved.
   4  *
   5  * This code is derived from software contributed to Berkeley by
   6  * Chris Torek.
   7  *
   8  * Redistribution and use in source and binary forms, with or without
   9  * modification, are permitted provided that the following conditions
  10  * are met:
  11  * 1. Redistributions of source code must retain the above copyright
  12  *    notice, this list of conditions and the following disclaimer.
  13  * 2. Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in the
  15  *    documentation and/or other materials provided with the distribution.
  16  * 3. Neither the name of the University nor the names of its contributors
  17  *    may be used to endorse or promote products derived from this software
  18  *    without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30  * SUCH DAMAGE.
  31  */
  32 
  33 #include <sys/types.h>
  34 #include <sys/stat.h>
  35 #include <fcntl.h>
  36 #include <stdio.h>
  37 #include <stdlib.h>
  38 #include <errno.h>
  39 #include "local.h"
  40 
  41 #define POS_ERR (-(fpos_t)1)
  42 
  43 /*
  44  * Seek the given file to the given offset.
  45  * `Whence' must be one of the three SEEK_* macros.
  46  */
  47 int
  48 fseek(fp, offset, whence)
  49         FILE *fp;
  50         long offset;
  51         int whence;
  52 {
  53         fpos_t curoff;
  54         int havepos;
  55 
  56         /* make sure stdio is set up */
  57         if (!__sdidinit)
  58                 __sinit();
  59 
  60         /*
  61          * Change any SEEK_CUR to SEEK_SET, and check `whence' argument.
  62          * After this, whence is either SEEK_SET or SEEK_END.
  63          */
  64         switch (whence) {
  65 
  66         case SEEK_CUR:
  67                 /*
  68                  * In order to seek relative to the current stream offset,
  69                  * we have to first find the current stream offset a la
  70                  * ftell (see ftell for details).
  71                  */
  72                 curoff = __sseek(fp, (fpos_t)0, SEEK_CUR);
  73                 if (curoff == POS_ERR)
  74                         return (EOF);
  75                 if (fp->_flags & __SRD) {
  76                         curoff -= fp->_r;
  77                         if (HASUB(fp))
  78                                 curoff -= fp->_ur;
  79                 } else if (fp->_flags & __SWR && fp->_p != NULL)
  80                         curoff += fp->_p - fp->_bf._base;
  81 
  82                 offset += curoff;
  83                 whence = SEEK_SET;
  84                 havepos = 1;
  85                 break;
  86 
  87         case SEEK_SET:
  88         case SEEK_END:
  89                 curoff = 0;             /* XXX just to keep gcc quiet */
  90                 havepos = 0;
  91                 break;
  92 
  93         default:
  94                 errno = EINVAL;
  95                 return (EOF);
  96         }
  97 
  98         if (fp->_bf._base == NULL)
  99                 __smakebuf(fp);
 100 
 101         if (__sflush(fp) ||
 102             __sseek(fp, (fpos_t)offset, whence) == POS_ERR) {
 103                 return (EOF);
 104         }
 105         /* success: clear EOF indicator and discard ungetc() data */
 106         if (HASUB(fp))
 107                 FREEUB(fp);
 108         fp->_p = fp->_bf._base;
 109         fp->_r = 0;
 110         /* fp->_w = 0; */       /* unnecessary (I think...) */
 111         fp->_flags &= ~__SEOF;
 112         return (0);
 113 }

/* [<][>][^][v][top][bottom][index][help] */