/trunk/kernel/generic/include/errno.h |
---|
55,6 → 55,7 |
#define ETIMEOUT -12 /* Timeout expired */ |
#define EINVAL -13 /* Invalid value */ |
#define EBUSY -14 /* Resource is busy */ |
#define EOVERFLOW -15 /* The result does not fit its size. */ |
#endif |
/trunk/uspace/lib/libc/include/unistd.h |
---|
41,8 → 41,14 |
#define NULL 0 |
#define getpagesize() (PAGE_SIZE) |
#define SEEK_SET 0 |
#define SEEK_CUR 1 |
#define SEEK_END 2 |
extern ssize_t write(int fd, const void * buf, size_t count); |
extern ssize_t read(int fd, void * buf, size_t count); |
extern off_t lseek(int, off_t, int); |
extern void _exit(int status); |
extern void *sbrk(ssize_t incr); |
extern int usleep(unsigned long usec); |
/trunk/uspace/lib/libc/generic/vfs.c |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2007 Jakub Jermar |
* Copyright (c) 2008 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
184,5 → 184,35 |
futex_up(&vfs_phone_futex); |
return (ssize_t) IPC_GET_ARG1(answer); |
} |
off_t lseek(int fildes, off_t offset, int whence) |
{ |
int res; |
ipcarg_t rc; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
return res; |
} |
} |
off_t newoffs; |
rc = async_req_3_1(vfs_phone, VFS_SEEK, fildes, offset, whence, |
&newoffs); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
if (rc != EOK) |
return (off_t) -1; |
return newoffs; |
} |
/** @} |
*/ |
/trunk/uspace/srv/vfs/vfs.c |
---|
99,10 → 99,12 |
case VFS_WRITE: |
vfs_write(callid, &call); |
break; |
case VFS_SEEK: |
vfs_seek(callid, &call); |
break; |
case VFS_UNMOUNT: |
case VFS_CREATE: |
case VFS_CLOSE: |
case VFS_SEEK: |
case VFS_UNLINK: |
case VFS_RENAME: |
default: |
/trunk/uspace/srv/vfs/vfs.h |
---|
135,6 → 135,7 |
VFS_TRIPLET; /**< Identity of the node. */ |
unsigned refcnt; /**< Usage counter. */ |
link_t nh_link; /**< Node hash-table link. */ |
size_t size; /**< Cached size of the file. */ |
/** |
* Holding this rwlock prevents modifications of the node's contents. |
210,6 → 211,7 |
extern void vfs_open(ipc_callid_t, ipc_call_t *); |
extern void vfs_read(ipc_callid_t, ipc_call_t *); |
extern void vfs_write(ipc_callid_t, ipc_call_t *); |
extern void vfs_seek(ipc_callid_t, ipc_call_t *); |
#endif |
/trunk/uspace/srv/vfs/vfs_rdwr.c |
---|
40,6 → 40,7 |
#include <async.h> |
#include <errno.h> |
#include <rwlock.h> |
#include <unistd.h> |
static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read) |
{ |
155,6 → 156,60 |
vfs_rdwr(rid, request, false); |
} |
void vfs_seek(ipc_callid_t rid, ipc_call_t *request) |
{ |
int fd = (int) IPC_GET_ARG1(*request); |
off_t off = (off_t) IPC_GET_ARG2(*request); |
int whence = (int) IPC_GET_ARG3(*request); |
/* |
* Lookup the file structure corresponding to the file descriptor. |
*/ |
vfs_file_t *file = vfs_file_get(fd); |
if (!file) { |
ipc_answer_0(rid, ENOENT); |
return; |
} |
off_t newpos; |
futex_down(&file->lock); |
if (whence == SEEK_SET) { |
file->pos = off; |
futex_up(&file->lock); |
ipc_answer_1(rid, EOK, off); |
return; |
} |
if (whence == SEEK_CUR) { |
if (file->pos + off < file->pos) { |
futex_up(&file->lock); |
ipc_answer_0(rid, EOVERFLOW); |
return; |
} |
file->pos += off; |
newpos = file->pos; |
futex_up(&file->lock); |
ipc_answer_1(rid, EOK, newpos); |
return; |
} |
if (whence == SEEK_END) { |
rwlock_reader_lock(&file->node->contents_rwlock); |
size_t size = file->node->size; |
rwlock_reader_unlock(&file->node->contents_rwlock); |
if (size + off < size) { |
futex_up(&file->lock); |
ipc_answer_0(rid, EOVERFLOW); |
return; |
} |
newpos = size + off; |
futex_up(&file->lock); |
ipc_answer_1(rid, EOK, newpos); |
return; |
} |
futex_up(&file->lock); |
ipc_answer_0(rid, EINVAL); |
} |
/** |
* @} |
*/ |