[PATCH 1/3] Change _offset type from int to _off_t
Sebastian Huber
sebastian.huber@embedded-brains.de
Mon Nov 26 16:44:00 GMT 2012
On 11/23/2012 02:56 PM, Corinna Vinschen wrote:
> On Nov 23 14:26, Sebastian Huber wrote:
>> >On 11/23/2012 02:15 PM, Corinna Vinschen wrote:
>>> > >On Nov 23 13:24, Sebastian Huber wrote:
>>>> > >>On 11/23/2012 11:21 AM, Corinna Vinschen wrote:
>>>>> > >>>It breaks binary compatibility. Full stop. And this is a problem.
>>>> > >>
>>>> > >>Yes, this is a problem, but not for RTEMS.
>>>> > >>
>>>>> > >>>
>>>>> > >>>If we do that, we must make really sure that this isn't a problem.
>>>> > >>
>>>> > >>We can add a new type, which is int by default and for example _off_t on RTEMS.
>>> > >
>>> > >But this new type doesn't match your fseeko/ftello implementation
>>> > >anymore.
>> >
>> >Yes, this is bad.
> Note that I didn't say that the change from int to _off_t is wrong per
> se. It just has to be considered very carefully.
>
> We get no problems at all for targets where sizeof(long) == sizeof(int).
> But we're in trouble as soon as that's not the case anymore.
>
> This affects 16 bit targets with typically sizeof(int) == 2 and
> sizeof(long) == 4 as well as all LP64 targets.
>
> But here's another problem: For these targets with sizeof(int) <
> sizeof(long), the structure __sFILE was always(!) wrong, because the
> offset member was never able to cover the whole _off_t offset range.
>
> So, on second thought, it might be*necessary* to change offset from
> int to _off_t, because that's a required bug fix.
>
> But then, how do we handle backward compatibility here? I really
> don't know.
>
> Any suggestions?
Lets introduce
#if defined(__rtems__) || X
typedef _off_t __sFile_off_t;
#else
typedef int __sFile_off_t;
#endif
somewhere.
I assume _off_t is equal to _fpos_t.
How do my change to use ftello() and fseeko() work with
sizeof(__sFile_off_t) <= sizeof(long) or
sizeof(__sFile_off_t) <= sizeof(_off_t).
First ftello():
_off_t
_DEFUN(_ftello_r, (ptr, fp),
struct _reent * ptr _AND
register FILE * fp)
{
_fpos_t pos;
[...]
if (fp->_flags & __SOFF)
pos = fp->_offset;
[...]
return pos;
}
So this is not a problem.
Now fseeko():
int
_DEFUN(_fseeko_r, (ptr, fp, offset, whence),
struct _reent *ptr _AND
register FILE *fp _AND
_off_t offset _AND
int whence)
{
_fpos_t _EXFNPTR(seekfn, (struct _reent *, _PTR, _fpos_t, int));
_fpos_t target;
_fpos_t curoff = 0;
[...]
switch (whence)
{
case SEEK_CUR:
/*
* In order to seek relative to the current stream offset,
* we have to first find the current stream offset a la
* ftell (see ftell for details).
*/
_fflush_r (ptr, fp); /* may adjust seek offset on append stream */
if (fp->_flags & __SOFF)
curoff = fp->_offset;
[...]
if (!havepos)
{
if (fp->_flags & __SOFF)
curoff = fp->_offset;
[...]
}
So this is not a problem.
The problem is here (newlib/libc/stdio/fflush.c):
int
_DEFUN(__sflush_r, (ptr, fp),
struct _reent *ptr _AND
register FILE * fp)
{
[...]
#ifdef __LARGE64_FILES
_fpos64_t curoff;
#else
_fpos_t curoff;
#endif
[...]
if ((fp->_flags & __SOFF) && (curoff != -1 || ptr->_errno == 0))
fp->_offset = curoff;
[...]
}
And here (newlib/libc/stdio/stdio.c):
_READ_WRITE_RETURN_TYPE
_DEFUN(__sread, (ptr, cookie, buf, n),
struct _reent *ptr _AND
void *cookie _AND
char *buf _AND
int n)
{
register FILE *fp = (FILE *) cookie;
register int ret;
[...]
if (ret >= 0)
fp->_offset += ret;
[...]
return ret;
}
I think we have a bug here. The
"register int ret;" should be
"register _READ_WRITE_RETURN_TYPE ret;".
_fpos_t
_DEFUN(__sseek, (ptr, cookie, offset, whence),
struct _reent *ptr _AND
void *cookie _AND
_fpos_t offset _AND
int whence)
{
register FILE *fp = (FILE *) cookie;
register _off_t ret;
[...]
fp->_offset = ret;
}
return ret;
}
>
>>>>> > >>>In theory you're not supposed to change struct __sFILE, rather you're
>>>>> > >>>supposed to use struct __sFILE64 and the functions defined in the
>>>>> > >>>libc/stdio64 subdir. This discussion seems to have gone lost.
>>>> > >>
>>>> > >>Ok, and how can I do this. Is this a configure option? I don't
>>>> > >>want to use fseeko64() directly.
>>> > >
>>> > >Why not? Cygwin is doing the same. The application calls fseeko,
>>> > >but internally Cygwin calls fseeko64 since the link lib redirects
>>> > >the call. fseeko64 does not exist on the application level.
>> >
>> >Ok, the problem is that I am not a Newlib configuration guru. How
>> >do I get this behaviour for RTEMS. Is this a magic configure option
>> >or do I have to set some pre-processor defines somewhere?
> I don't know how to do that for RTEMS. In Cygwin we have an import
> library which defines a symbol fseeko which is nothing but an assembler
> jmp to fseeko64.
Since there seem to be no ready to use solution I prefer to fix fseeko() and
ftello().
--
Sebastian Huber, embedded brains GmbH
Address : Obere Lagerstr. 30, D-82178 Puchheim, Germany
Phone : +49 89 18 90 80 79-6
Fax : +49 89 18 90 80 79-9
E-Mail : sebastian.huber@embedded-brains.de
PGP : Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
More information about the Newlib
mailing list