The Pedigree Project  0.1
glue-fseek.c
1 /*
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley. The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 /*
19 FUNCTION
20 <<fseek>>, <<fseeko>>---set file position
21 
22 INDEX
23  fseek
24 INDEX
25  fseeko
26 INDEX
27  _fseek_r
28 INDEX
29  _fseeko_r
30 
31 ANSI_SYNOPSIS
32  #include <stdio.h>
33  int fseek(FILE *<[fp]>, long <[offset]>, int <[whence]>)
34  int fseeko(FILE *<[fp]>, off_t <[offset]>, int <[whence]>)
35  int _fseek_r(struct _reent *<[ptr]>, FILE *<[fp]>,
36  long <[offset]>, int <[whence]>)
37  int _fseeko_r(struct _reent *<[ptr]>, FILE *<[fp]>,
38  off_t <[offset]>, int <[whence]>)
39 
40 TRAD_SYNOPSIS
41  #include <stdio.h>
42  int fseek(<[fp]>, <[offset]>, <[whence]>)
43  FILE *<[fp]>;
44  long <[offset]>;
45  int <[whence]>;
46 
47  int fseeko(<[fp]>, <[offset]>, <[whence]>)
48  FILE *<[fp]>;
49  off_t <[offset]>;
50  int <[whence]>;
51 
52  int _fseek_r(<[ptr]>, <[fp]>, <[offset]>, <[whence]>)
53  struct _reent *<[ptr]>;
54  FILE *<[fp]>;
55  long <[offset]>;
56  int <[whence]>;
57 
58  int _fseeko_r(<[ptr]>, <[fp]>, <[offset]>, <[whence]>)
59  struct _reent *<[ptr]>;
60  FILE *<[fp]>;
61  off_t <[offset]>;
62  int <[whence]>;
63 
64 DESCRIPTION
65 Objects of type <<FILE>> can have a ``position'' that records how much
66 of the file your program has already read. Many of the <<stdio>> functions
67 depend on this position, and many change it as a side effect.
68 
69 You can use <<fseek>>/<<fseeko>> to set the position for the file identified by
70 <[fp]>. The value of <[offset]> determines the new position, in one
71 of three ways selected by the value of <[whence]> (defined as macros
72 in `<<stdio.h>>'):
73 
74 <<SEEK_SET>>---<[offset]> is the absolute file position (an offset
75 from the beginning of the file) desired. <[offset]> must be positive.
76 
77 <<SEEK_CUR>>---<[offset]> is relative to the current file position.
78 <[offset]> can meaningfully be either positive or negative.
79 
80 <<SEEK_END>>---<[offset]> is relative to the current end of file.
81 <[offset]> can meaningfully be either positive (to increase the size
82 of the file) or negative.
83 
84 See <<ftell>>/<<ftello>> to determine the current file position.
85 
86 RETURNS
87 <<fseek>>/<<fseeko>> return <<0>> when successful. On failure, the
88 result is <<EOF>>. The reason for failure is indicated in <<errno>>:
89 either <<ESPIPE>> (the stream identified by <[fp]> doesn't support
90 repositioning) or <<EINVAL>> (invalid file position).
91 
92 PORTABILITY
93 ANSI C requires <<fseek>>.
94 
95 <<fseeko>> is defined by the Single Unix specification.
96 
97 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
98 <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
99 */
100 
104 #define _COMPILING_NEWLIB
105 
106 #include "newlib.h"
107 
108 #include <stdio.h>
109 
110 #include "local.h"
111 #include <_ansi.h>
112 #include <errno.h>
113 #include <fcntl.h>
114 #include <reent.h>
115 #include <stdlib.h>
116 #include <string.h>
117 #include <sys/stat.h>
118 #include <time.h>
119 
120 #define POS_ERR (-(_fpos_t) 1)
121 
122 /*
123  * Seek the given file to the given offset.
124  * `Whence' must be one of the three SEEK_* macros.
125  */
126 
127 typedef _fpos_t _EXFUN((*seek_fnptr), (struct _reent *, _PTR, _fpos_t, int) );
128 
129 int _fseek_r(struct _reent *ptr, register FILE *fp, long offset, int whence)
130 {
131  _fpos_t _EXFUN((*seekfn), (struct _reent *, _PTR, _fpos_t, int) );
132  _fpos_t target;
133  _fpos_t curoff = 0;
134  size_t n;
135 #ifdef __USE_INTERNAL_STAT64
136  struct stat64 st;
137 #else
138  struct stat st;
139 #endif
140  int havepos;
141 
142  /* Make sure stdio is set up. */
143 
144  CHECK_INIT(ptr, fp);
145 
146  _flockfile(fp);
147 
148  /* If we've been doing some writing, and we're in append mode
149  then we don't really know where the filepos is. */
150 
151  if (fp->_flags & __SAPP && fp->_flags & __SWR)
152  {
153  /* So flush the buffer and seek to the end. */
154  _fflush_r(ptr, fp);
155  }
156 
157  /* Have to be able to seek. */
158 
159  if ((seekfn = (seek_fnptr) fp->_seek) == NULL)
160  {
161  ptr->_errno = ESPIPE; /* ??? */
162  _funlockfile(fp);
163  return EOF;
164  }
165 
166  if (_fflush_r(ptr, fp) ||
167  seekfn(ptr, fp->_cookie, offset, whence) == POS_ERR)
168  {
169  _funlockfile(fp);
170  return EOF;
171  }
172  /* success: clear EOF indicator and discard ungetc() data */
173  if (HASUB(fp))
174  FREEUB(ptr, fp);
175  fp->_p = fp->_bf._base;
176  fp->_r = 0;
177  /* fp->_w = 0; */ /* unnecessary (I think...) */
178  fp->_flags &= ~__SEOF;
179  /* Reset no-optimization flag after successful seek. The
180  no-optimization flag may be set in the case of a read
181  stream that is flushed which by POSIX/SUSv3 standards,
182  means that a corresponding seek must not optimize. The
183  optimization is then allowed if no subsequent flush
184  is performed. */
185  fp->_flags &= ~__SNPT;
186  // memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
187  _funlockfile(fp);
188  return 0;
189 }
190 
191 #ifndef _REENT_ONLY
192 
193 int fseek(register FILE *fp, long offset, int whence)
194 {
195  return _fseek_r(_REENT, fp, offset, whence);
196 }
197 
198 #endif /* !_REENT_ONLY */