source: rtems/cpukit/libfs/src/defaults/default_lseek_file.c @ 30d4124

4.115
Last change on this file since 30d4124 was 30d4124, checked in by Sebastian Huber <sebastian.huber@…>, on 05/07/12 at 14:30:37

Filesystem: PR1398: Fix lseek() mechanic

According to POSIX the lseek() function shall not, by itself, extend the
size of a file.

Remove the size field of rtems_libio_t. A file has only one size but
may have multiple open file descriptors. Thus a file size field in the
file descriptor may lead to inconsistencies.

New default handlers rtems_filesystem_default_lseek_file() and
rtems_filesystem_default_lseek_directory().

  • Property mode set to 100644
File size: 1.4 KB
RevLine 
[30d4124]1/*
2 * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Obere Lagerstr. 30
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.com/license/LICENSE.
13 */
14
15#if HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <rtems/libio_.h>
20
21off_t rtems_filesystem_default_lseek_file(
22  rtems_libio_t *iop,
23  off_t offset,
24  int whence
25)
26{
27  off_t rv = 0;
28  off_t reference_offset;
29  off_t new_offset;
30  struct stat st;
31
32  switch ( whence ) {
33    case SEEK_SET:
34      reference_offset = 0;
35      break;
36    case SEEK_CUR:
37      reference_offset = iop->offset;
38      break;
39    case SEEK_END:
40      st.st_size = 0;
41      rv = (*iop->pathinfo.handlers->fstat_h)( &iop->pathinfo, &st );
42      reference_offset = st.st_size;
43      break;
44    default:
45      errno = EINVAL;
46      rv = -1;
47      break;
48  }
49  new_offset = reference_offset + offset;
50
51  if ( rv == 0 ) {
52    if (
53      (offset >= 0 && new_offset >= reference_offset)
54        || (offset < 0 && new_offset < reference_offset)
55    ) {
56      if ( new_offset >= 0 ) {
57        iop->offset = new_offset;
58        rv = new_offset;
59      } else {
60        errno = EINVAL;
61        rv = -1;
62      }
63    } else {
64      errno = EOVERFLOW;
65      rv = -1;
66    }
67  }
68
69  return rv;
70}
Note: See TracBrowser for help on using the repository browser.