Changeset ed903174 in mainline for uspace/lib/libc


Ignore:
Timestamp:
2010-02-10T23:51:23Z (15 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e70edd1
Parents:
b32c604f
Message:

implement support for 64bit file offsets

  • the libc API is a small deviation from standard, but we have no reason to keep a strict backward compatibility with ancient code so far
    • the basic signed 64bit offset type is called off64_t
      • lseek() and fseek() take off64_t arguments (since the argument represents a relative offset)
      • ftell() returns off64_t values (since it is a wrapper of lseek())
      • vfs_seek() implementation supports negative offsets when SEEK_CUR and SEEK_END is used
    • aoff64_t is used for internal unsigned representation of sizes (in bytes, blocks, etc.) and absolute offsets
      • mmap() and ftruncate() take aoff64_t arguments (since the full range of the absolute file offset should be used here)
      • struct stat stores the file size as aoff64_t
    • in both cases the explicit range of the types shown in the names is helpful for proper filesystem and IPC interaction
    • note: size_t should be used only for representing in-memory sizes and offsets, not device and file-related information, and vice versa
      • the code base still needs a thorough revision with respect to this rule
    • PRIdOFF64 and PRIuOFF64 can be used for printing the offsets
  • VFS_OUT_LOOKUP returns the 64bit file size in two IPC arguments
    • since all 5 IPC arguments have already been taken, the fs_handle is returned as the return value (fs_handle has only 16 bits, thus the return value can be used for both indicating errors as negative values and returning positive handles)
  • VFS_OUT_READ and VFS_OUT_WRITE use aoff64_t absolute offsets split into two IPC arguments

replace bn_t with aoff64_t as a generic 64bit bytes/block counter type

note: filesystem drivers need to be revised with respect to make sure that all out-of-range checks are correct (especially w.r.t. file and block offsets)

Location:
uspace/lib/libc
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/generic/io/io.c

    rb32c604f red903174  
    541541}
    542542
    543 int fseek(FILE *stream, long offset, int origin)
    544 {
    545         off_t rc = lseek(stream->fd, offset, origin);
    546         if (rc == (off_t) (-1)) {
    547                 /* errno has been set by lseek. */
     543int fseek(FILE *stream, off64_t offset, int whence)
     544{
     545        off64_t rc = lseek(stream->fd, offset, whence);
     546        if (rc == (off64_t) (-1)) {
     547                /* errno has been set by lseek64. */
    548548                return -1;
    549549        }
     
    554554}
    555555
    556 int ftell(FILE *stream)
    557 {
    558         off_t rc = lseek(stream->fd, 0, SEEK_CUR);
    559         if (rc == (off_t) (-1)) {
    560                 /* errno has been set by lseek. */
    561                 return -1;
    562         }
    563 
    564         return rc;
     556off64_t ftell(FILE *stream)
     557{
     558        return lseek(stream->fd, 0, SEEK_CUR);
    565559}
    566560
  • uspace/lib/libc/generic/mman.c

    rb32c604f red903174  
    3939
    4040void *mmap(void *start, size_t length, int prot, int flags, int fd,
    41     off_t offset)
     41    aoff64_t offset)
    4242{
    4343        if (!start)
  • uspace/lib/libc/generic/vfs/vfs.c

    rb32c604f red903174  
    3535#include <vfs/vfs.h>
    3636#include <vfs/canonify.h>
     37#include <macros.h>
    3738#include <stdlib.h>
    3839#include <unistd.h>
     
    434435}
    435436
    436 off_t lseek(int fildes, off_t offset, int whence)
    437 {
    438         ipcarg_t rc;
    439 
    440         futex_down(&vfs_phone_futex);
    441         async_serialize_start();
    442         vfs_connect();
    443        
    444         ipcarg_t newoffs;
    445         rc = async_req_3_1(vfs_phone, VFS_IN_SEEK, fildes, offset, whence,
    446             &newoffs);
    447 
    448         async_serialize_end();
    449         futex_up(&vfs_phone_futex);
    450 
     437off64_t lseek(int fildes, off64_t offset, int whence)
     438{
     439        futex_down(&vfs_phone_futex);
     440        async_serialize_start();
     441        vfs_connect();
     442       
     443        ipcarg_t newoff_lo;
     444        ipcarg_t newoff_hi;
     445        ipcarg_t rc = async_req_4_2(vfs_phone, VFS_IN_SEEK, fildes,
     446            LOWER32(offset), UPPER32(offset), whence,
     447            &newoff_lo, &newoff_hi);
     448       
     449        async_serialize_end();
     450        futex_up(&vfs_phone_futex);
     451       
    451452        if (rc != EOK)
    452                 return (off_t) -1;
    453        
    454         return (off_t) newoffs;
    455 }
    456 
    457 int ftruncate(int fildes, off_t length)
    458 {
    459         ipcarg_t rc;
    460        
    461         futex_down(&vfs_phone_futex);
    462         async_serialize_start();
    463         vfs_connect();
    464        
    465         rc = async_req_2_0(vfs_phone, VFS_IN_TRUNCATE, fildes, length);
    466         async_serialize_end();
    467         futex_up(&vfs_phone_futex);
     453                return (off64_t) -1;
     454       
     455        return (off64_t) MERGE_LOUP32(newoff_lo, newoff_hi);
     456}
     457
     458int ftruncate(int fildes, aoff64_t length)
     459{
     460        ipcarg_t rc;
     461       
     462        futex_down(&vfs_phone_futex);
     463        async_serialize_start();
     464        vfs_connect();
     465       
     466        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
     467            LOWER32(length), UPPER32(length));
     468        async_serialize_end();
     469        futex_up(&vfs_phone_futex);
     470       
    468471        return (int) rc;
    469472}
     
    479482       
    480483        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    481         rc = async_data_read_start(vfs_phone, (void *)stat, sizeof(struct stat));
     484        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    482485        if (rc != EOK) {
    483486                ipcarg_t rc_orig;
     
    553556        if (!abs) {
    554557                free(dirp);
    555                 return ENOMEM;
     558                return NULL;
    556559        }
    557560       
  • uspace/lib/libc/include/limits.h

    rb32c604f red903174  
    4646
    4747#ifdef __CHAR_UNSIGNED__
    48 # define CHAR_MIN UCHAR_MIN
    49 # define CHAR_MAX UCHAR_MAX
     48        #define CHAR_MIN UCHAR_MIN
     49        #define CHAR_MAX UCHAR_MAX
    5050#else
    51 # define CHAR_MIN SCHAR_MIN
    52 # define CHAR_MAX SCHAR_MAX
     51        #define CHAR_MIN SCHAR_MIN
     52        #define CHAR_MAX SCHAR_MAX
    5353#endif
    5454
     
    5959#define USHRT_MAX MAX_UINT16
    6060
     61/* int */
    6162#define INT_MIN MIN_INT32
    6263#define INT_MAX MAX_INT32
     
    6465#define UINT_MAX MAX_UINT32
    6566
     67/* long long int */
    6668#define LLONG_MIN MIN_INT64
    6769#define LLONG_MAX MAX_INT64
     
    6971#define ULLONG_MAX MAX_UINT64
    7072
     73/* off64_t */
     74#define OFF64_MIN MIN_INT64
     75#define OFF64_MAX MAX_INT64
     76
     77/* aoff64_t */
     78#define AOFF64_MIN MIN_UINT64
     79#define AOFF64_MAX MAX_UINT64
     80
    7181#endif
    7282
  • uspace/lib/libc/include/stdio.h

    rb32c604f red903174  
    4646#define BUFSIZ  4096
    4747
    48 #define DEBUG(fmt, ...) \
     48#define DEBUG(fmt, ...)se\
    4949        { \
    5050                char _buf[256]; \
     
    5656#ifndef SEEK_SET
    5757        #define SEEK_SET  0
     58#endif
     59
     60#ifndef SEEK_CUR
    5861        #define SEEK_CUR  1
     62#endif
     63
     64#ifndef SEEK_END
    5965        #define SEEK_END  2
    6066#endif
     
    135141extern size_t fwrite(const void *, size_t, size_t, FILE *);
    136142
    137 extern int fseek(FILE *, long, int);
     143extern int fseek(FILE *, off64_t, int);
    138144extern void rewind(FILE *);
    139 extern int ftell(FILE *);
     145extern off64_t ftell(FILE *);
    140146extern int feof(FILE *);
    141147
  • uspace/lib/libc/include/sys/mman.h

    rb32c604f red903174  
    4141#define MAP_FAILED  ((void *) -1)
    4242
    43 #define MAP_SHARED       (1 << 0)
    44 #define MAP_PRIVATE      (1 << 1)
    45 #define MAP_FIXED        (1 << 2)
    46 #define MAP_ANONYMOUS    (1 << 3)
     43#define MAP_SHARED     (1 << 0)
     44#define MAP_PRIVATE    (1 << 1)
     45#define MAP_FIXED      (1 << 2)
     46#define MAP_ANONYMOUS  (1 << 3)
    4747
    4848#define PROTO_READ   AS_AREA_READ
     
    5050#define PROTO_EXEC   AS_AREA_EXEC
    5151
    52 extern void *mmap(void  *start, size_t length, int prot, int flags, int fd,
    53     off_t offset);
     52extern void *mmap(void *start, size_t length, int prot, int flags, int fd,
     53    aoff64_t offset);
    5454extern int munmap(void *start, size_t length);
    5555
  • uspace/lib/libc/include/sys/stat.h

    rb32c604f red903174  
    3131 */
    3232/** @file
    33  */ 
     33 */
    3434
    3535#ifndef LIBC_SYS_STAT_H_
     
    4848        bool is_file;
    4949        bool is_directory;
    50         off_t size;
     50        aoff64_t size;
    5151        dev_handle_t device;
    5252};
  • uspace/lib/libc/include/sys/typefmt.h

    rb32c604f red903174  
    3939#include <inttypes.h>
    4040
    41 /* off_t */
    42 #define PRIdOFF "ld"
    43 #define PRIuOFF "lu"
    44 #define PRIxOFF "lx"
    45 #define PRIXOFF "lX"
    46 
    47 /* bn_t */
    48 #define PRIdBN PRId64
    49 #define PRIuBN PRIu64
    50 #define PRIxBN PRIx64
    51 #define PRIXBN PRIX64
     41/* off64_t */
     42#define PRIdOFF64 PRId64
     43#define PRIuOFF64 PRIu64
     44#define PRIxOFF64 PRIx64
     45#define PRIXOFF64 PRIX64
    5246
    5347/* (s)size_t */
  • uspace/lib/libc/include/sys/types.h

    rb32c604f red903174  
    3838#include <libarch/types.h>
    3939
    40 typedef long off_t;
    41 typedef int mode_t;
    42 typedef uint64_t bn_t;  /**< Block number type. */
     40typedef unsigned int mode_t;
    4341
     42/** Relative offset */
     43typedef int64_t off64_t;
     44
     45/** Absolute offset */
     46typedef uint64_t aoff64_t;
     47
     48/** Unicode code point */
    4449typedef int32_t wchar_t;
    4550
  • uspace/lib/libc/include/unistd.h

    rb32c604f red903174  
    4747#ifndef SEEK_SET
    4848        #define SEEK_SET  0
     49#endif
     50
     51#ifndef SEEK_CUR
    4952        #define SEEK_CUR  1
     53#endif
     54
     55#ifndef SEEK_END
    5056        #define SEEK_END  2
    5157#endif
     
    5864extern ssize_t read(int, void *, size_t);
    5965
    60 extern off_t lseek(int, off_t, int);
    61 extern int ftruncate(int, off_t);
     66extern off64_t lseek(int, off64_t, int);
     67extern int ftruncate(int, aoff64_t);
    6268
    6369extern int close(int);
     
    6975extern int chdir(const char *);
    7076
    71 extern void _exit(int status) __attribute__ ((noreturn));
    72 extern int usleep(useconds_t uses);
    73 extern unsigned int sleep(unsigned int se);
     77extern void _exit(int) __attribute__((noreturn));
     78extern int usleep(useconds_t);
     79extern unsigned int sleep(unsigned int);
    7480
    7581#endif
Note: See TracChangeset for help on using the changeset viewer.