parent
280fc59edf
commit
dcfcbce856
|
@ -77,6 +77,7 @@ namespace Libc {
|
||||||
virtual void freeaddrinfo(struct ::addrinfo *res);
|
virtual void freeaddrinfo(struct ::addrinfo *res);
|
||||||
virtual int fstat(File_descriptor *, struct stat *buf);
|
virtual int fstat(File_descriptor *, struct stat *buf);
|
||||||
virtual int fsync(File_descriptor *);
|
virtual int fsync(File_descriptor *);
|
||||||
|
virtual int ftruncate(File_descriptor *, ::off_t length);
|
||||||
virtual int getaddrinfo(const char *node, const char *service,
|
virtual int getaddrinfo(const char *node, const char *service,
|
||||||
const struct ::addrinfo *hints,
|
const struct ::addrinfo *hints,
|
||||||
struct ::addrinfo **res);
|
struct ::addrinfo **res);
|
||||||
|
|
|
@ -50,7 +50,6 @@ DUMMY(-1, _fpathconf)
|
||||||
DUMMY(-1, fpathconf)
|
DUMMY(-1, fpathconf)
|
||||||
DUMMY(-1, freebsd7___semctl)
|
DUMMY(-1, freebsd7___semctl)
|
||||||
DUMMY(-1, fstatat)
|
DUMMY(-1, fstatat)
|
||||||
DUMMY(-1, ftruncate)
|
|
||||||
DUMMY(-1, getcontext)
|
DUMMY(-1, getcontext)
|
||||||
DUMMY( 0, __getcwd)
|
DUMMY( 0, __getcwd)
|
||||||
DUMMY( 0, getdtablesize)
|
DUMMY( 0, getdtablesize)
|
||||||
|
|
|
@ -219,6 +219,10 @@ extern "C" int fsync(int libc_fd) {
|
||||||
FD_FUNC_WRAPPER(fsync, libc_fd); }
|
FD_FUNC_WRAPPER(fsync, libc_fd); }
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" int ftruncate(int libc_fd, ::off_t length) {
|
||||||
|
FD_FUNC_WRAPPER(ftruncate, libc_fd, length); }
|
||||||
|
|
||||||
|
|
||||||
extern "C" int getaddrinfo(const char *node, const char *service,
|
extern "C" int getaddrinfo(const char *node, const char *service,
|
||||||
const struct addrinfo *hints,
|
const struct addrinfo *hints,
|
||||||
struct addrinfo **res)
|
struct addrinfo **res)
|
||||||
|
|
|
@ -154,6 +154,7 @@ DUMMY(int, -1, fchdir, (File_descriptor *));
|
||||||
DUMMY(int, -1, fcntl, (File_descriptor *, int cmd, long arg));
|
DUMMY(int, -1, fcntl, (File_descriptor *, int cmd, long arg));
|
||||||
DUMMY(int, -1, fstat, (File_descriptor *, struct stat *));
|
DUMMY(int, -1, fstat, (File_descriptor *, struct stat *));
|
||||||
DUMMY(int, -1, fsync, (File_descriptor *));
|
DUMMY(int, -1, fsync, (File_descriptor *));
|
||||||
|
DUMMY(int, -1, ftruncate, (File_descriptor *, ::off_t));
|
||||||
DUMMY(ssize_t, -1, getdirentries, (File_descriptor *, char *, ::size_t, ::off_t *));
|
DUMMY(ssize_t, -1, getdirentries, (File_descriptor *, char *, ::size_t, ::off_t *));
|
||||||
DUMMY(int, -1, getpeername, (File_descriptor *, struct sockaddr *, socklen_t *));
|
DUMMY(int, -1, getpeername, (File_descriptor *, struct sockaddr *, socklen_t *));
|
||||||
DUMMY(int, -1, getsockname, (File_descriptor *, struct sockaddr *, socklen_t *));
|
DUMMY(int, -1, getsockname, (File_descriptor *, struct sockaddr *, socklen_t *));
|
||||||
|
|
|
@ -312,6 +312,33 @@ class Plugin : public Libc::Plugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ftruncate(Libc::File_descriptor *fd, ::off_t length)
|
||||||
|
{
|
||||||
|
using namespace Ffat;
|
||||||
|
|
||||||
|
/* 'f_truncate()' truncates to the current seek pointer */
|
||||||
|
|
||||||
|
if (lseek(fd, length, SEEK_SET) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FRESULT res = f_truncate(_get_ffat_file(fd));
|
||||||
|
|
||||||
|
switch(res) {
|
||||||
|
case FR_OK:
|
||||||
|
return 0;
|
||||||
|
case FR_DISK_ERR:
|
||||||
|
case FR_INT_ERR:
|
||||||
|
case FR_NOT_READY:
|
||||||
|
case FR_INVALID_OBJECT:
|
||||||
|
errno = EIO;
|
||||||
|
return -1;
|
||||||
|
default:
|
||||||
|
/* not supposed to occur according to the libffat documentation */
|
||||||
|
PERR("f_truncate() returned an unexpected error code");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t getdirentries(Libc::File_descriptor *fd, char *buf,
|
ssize_t getdirentries(Libc::File_descriptor *fd, char *buf,
|
||||||
::size_t nbytes, ::off_t *basep)
|
::size_t nbytes, ::off_t *basep)
|
||||||
{
|
{
|
||||||
|
|
|
@ -356,6 +356,25 @@ class Plugin : public Libc::Plugin
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ftruncate(Libc::File_descriptor *fd, ::off_t length)
|
||||||
|
{
|
||||||
|
File_system::Node_handle node_handle = context(fd)->node_handle();
|
||||||
|
File_system::File_handle &file_handle =
|
||||||
|
static_cast<File_system::File_handle&>(node_handle);
|
||||||
|
|
||||||
|
try {
|
||||||
|
file_system()->truncate(file_handle, length);
|
||||||
|
} catch (File_system::Invalid_handle) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
} catch (File_system::Permission_denied) {
|
||||||
|
errno = EPERM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* *basep does not get initialized by the libc and is therefore
|
* *basep does not get initialized by the libc and is therefore
|
||||||
* useless for determining a specific directory index. This
|
* useless for determining a specific directory index. This
|
||||||
|
|
|
@ -31,6 +31,13 @@ namespace Ffat { extern "C" {
|
||||||
#include <ffat/ff.h>
|
#include <ffat/ff.h>
|
||||||
} }
|
} }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This macro is defined in later versions of the FatFs lib, but not in the
|
||||||
|
* one currently used for Genode.
|
||||||
|
*/
|
||||||
|
#define f_tell(fp) ((fp)->fptr)
|
||||||
|
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
|
@ -767,14 +774,44 @@ namespace File_system {
|
||||||
|
|
||||||
using namespace Ffat;
|
using namespace Ffat;
|
||||||
|
|
||||||
FRESULT res = f_truncate(file->ffat_fil());
|
/* 'f_truncate()' truncates to the current seek pointer */
|
||||||
|
|
||||||
|
FRESULT res = f_lseek(file->ffat_fil(), size);
|
||||||
|
|
||||||
|
switch(res) {
|
||||||
|
case FR_OK:
|
||||||
|
/* according to the FatFs documentation this can happen */
|
||||||
|
if (f_tell(file->ffat_fil()) != size) {
|
||||||
|
PERR("f_lseek() could not seek to offset %llu", size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FR_DISK_ERR:
|
||||||
|
PERR("f_lseek() failed with error code FR_DISK_ERR");
|
||||||
|
return;
|
||||||
|
case FR_INT_ERR:
|
||||||
|
PERR("f_lseek() failed with error code FR_INT_ERR");
|
||||||
|
return;
|
||||||
|
case FR_NOT_READY:
|
||||||
|
PERR("f_lseek() failed with error code FR_NOT_READY");
|
||||||
|
return;
|
||||||
|
case FR_INVALID_OBJECT:
|
||||||
|
PERR("f_lseek() failed with error code FR_INVALID_OBJECT");
|
||||||
|
throw Invalid_handle();
|
||||||
|
default:
|
||||||
|
/* not supposed to occur according to the libffat documentation */
|
||||||
|
PERR("f_lseek() returned an unexpected error code");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = f_truncate(file->ffat_fil());
|
||||||
|
|
||||||
switch(res) {
|
switch(res) {
|
||||||
case FR_OK:
|
case FR_OK:
|
||||||
return;
|
return;
|
||||||
case FR_INVALID_OBJECT:
|
case FR_INVALID_OBJECT:
|
||||||
PERR("f_truncate() failed with error code FR_INVALID_OBJECT");
|
PERR("f_truncate() failed with error code FR_INVALID_OBJECT");
|
||||||
return;
|
throw Invalid_handle();
|
||||||
case FR_DISK_ERR:
|
case FR_DISK_ERR:
|
||||||
PERR("f_truncate() failed with error code FR_DISK_ERR");
|
PERR("f_truncate() failed with error code FR_DISK_ERR");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -47,6 +47,7 @@ int main(int argc, char *argv[])
|
||||||
char const *file_name = "test.tst";
|
char const *file_name = "test.tst";
|
||||||
char const *file_name2 = "test2.tst";
|
char const *file_name2 = "test2.tst";
|
||||||
char const *file_name3 = "test3.tst";
|
char const *file_name3 = "test3.tst";
|
||||||
|
char const *file_name4 = "test4.tst";
|
||||||
char const *pattern = "a single line of text";
|
char const *pattern = "a single line of text";
|
||||||
|
|
||||||
size_t pattern_size = strlen(pattern) + 1;
|
size_t pattern_size = strlen(pattern) + 1;
|
||||||
|
@ -165,6 +166,20 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* test 'ftruncate()' */
|
||||||
|
CALL_AND_CHECK(fd, open(file_name4, O_CREAT | O_WRONLY), fd >= 0, "file_name=%s", file_name4);
|
||||||
|
CALL_AND_CHECK(ret, ftruncate(fd, 100), ret == 0, ""); /* increase size */
|
||||||
|
CALL_AND_CHECK(ret, close(fd), ret == 0, "");
|
||||||
|
CALL_AND_CHECK(ret, stat(file_name4, &stat_buf),
|
||||||
|
(ret == 0) && (stat_buf.st_size == 100),
|
||||||
|
"file_name=%s", file_name4);
|
||||||
|
CALL_AND_CHECK(fd, open(file_name4, O_WRONLY), fd >= 0, "file_name=%s", file_name4);
|
||||||
|
CALL_AND_CHECK(ret, ftruncate(fd, 10), ret == 0, ""); /* decrease size */
|
||||||
|
CALL_AND_CHECK(ret, close(fd), ret == 0, "");
|
||||||
|
CALL_AND_CHECK(ret, stat(file_name4, &stat_buf),
|
||||||
|
(ret == 0) && (stat_buf.st_size == 10),
|
||||||
|
"file_name=%s", file_name4);
|
||||||
|
|
||||||
if (i < (iterations - 1))
|
if (i < (iterations - 1))
|
||||||
sleep(2);
|
sleep(2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,14 @@ namespace File_system {
|
||||||
}
|
}
|
||||||
|
|
||||||
file_size_t length() const { return _length; }
|
file_size_t length() const { return _length; }
|
||||||
|
|
||||||
|
void truncate(file_size_t size)
|
||||||
|
{
|
||||||
|
if (size < _chunk.used_size())
|
||||||
|
_chunk.truncate(size);
|
||||||
|
else
|
||||||
|
_length = size;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -373,7 +373,15 @@ namespace File_system {
|
||||||
destroy(env()->heap(), node);
|
destroy(env()->heap(), node);
|
||||||
}
|
}
|
||||||
|
|
||||||
void truncate(File_handle, file_size_t size) { }
|
void truncate(File_handle file_handle, file_size_t size)
|
||||||
|
{
|
||||||
|
if (!_writable)
|
||||||
|
throw Permission_denied();
|
||||||
|
|
||||||
|
File *file = _handle_registry.lookup_and_lock(file_handle);
|
||||||
|
Node_lock_guard file_guard(*file);
|
||||||
|
file->truncate(size);
|
||||||
|
}
|
||||||
|
|
||||||
void move(Dir_handle from_dir_handle, Name const &from_name,
|
void move(Dir_handle from_dir_handle, Name const &from_name,
|
||||||
Dir_handle to_dir_handle, Name const &to_name)
|
Dir_handle to_dir_handle, Name const &to_name)
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace Noux {
|
||||||
SYSCALL_STAT,
|
SYSCALL_STAT,
|
||||||
SYSCALL_LSTAT,
|
SYSCALL_LSTAT,
|
||||||
SYSCALL_FSTAT,
|
SYSCALL_FSTAT,
|
||||||
|
SYSCALL_FTRUNCATE,
|
||||||
SYSCALL_FCNTL,
|
SYSCALL_FCNTL,
|
||||||
SYSCALL_OPEN,
|
SYSCALL_OPEN,
|
||||||
SYSCALL_CLOSE,
|
SYSCALL_CLOSE,
|
||||||
|
@ -83,6 +84,7 @@ namespace Noux {
|
||||||
NOUX_DECL_SYSCALL_NAME(STAT)
|
NOUX_DECL_SYSCALL_NAME(STAT)
|
||||||
NOUX_DECL_SYSCALL_NAME(LSTAT)
|
NOUX_DECL_SYSCALL_NAME(LSTAT)
|
||||||
NOUX_DECL_SYSCALL_NAME(FSTAT)
|
NOUX_DECL_SYSCALL_NAME(FSTAT)
|
||||||
|
NOUX_DECL_SYSCALL_NAME(FTRUNCATE)
|
||||||
NOUX_DECL_SYSCALL_NAME(FCNTL)
|
NOUX_DECL_SYSCALL_NAME(FCNTL)
|
||||||
NOUX_DECL_SYSCALL_NAME(OPEN)
|
NOUX_DECL_SYSCALL_NAME(OPEN)
|
||||||
NOUX_DECL_SYSCALL_NAME(CLOSE)
|
NOUX_DECL_SYSCALL_NAME(CLOSE)
|
||||||
|
|
|
@ -275,6 +275,7 @@ namespace Noux {
|
||||||
enum Stat_error { STAT_ERR_NO_ENTRY = NUM_GENERAL_ERRORS };
|
enum Stat_error { STAT_ERR_NO_ENTRY = NUM_GENERAL_ERRORS };
|
||||||
enum Fchdir_error { FCHDIR_ERR_NOT_DIR = NUM_GENERAL_ERRORS };
|
enum Fchdir_error { FCHDIR_ERR_NOT_DIR = NUM_GENERAL_ERRORS };
|
||||||
enum Fcntl_error { FCNTL_ERR_CMD_INVALID = NUM_GENERAL_ERRORS };
|
enum Fcntl_error { FCNTL_ERR_CMD_INVALID = NUM_GENERAL_ERRORS };
|
||||||
|
enum Ftruncate_error { FTRUNCATE_ERR_NO_PERM = NUM_GENERAL_ERRORS };
|
||||||
enum Open_error { OPEN_ERR_UNACCESSIBLE, OPEN_ERR_NO_PERM,
|
enum Open_error { OPEN_ERR_UNACCESSIBLE, OPEN_ERR_NO_PERM,
|
||||||
OPEN_ERR_EXISTS };
|
OPEN_ERR_EXISTS };
|
||||||
enum Execve_error { EXECVE_NONEXISTENT = NUM_GENERAL_ERRORS };
|
enum Execve_error { EXECVE_NONEXISTENT = NUM_GENERAL_ERRORS };
|
||||||
|
@ -290,6 +291,7 @@ namespace Noux {
|
||||||
Stat_error stat;
|
Stat_error stat;
|
||||||
Fchdir_error fchdir;
|
Fchdir_error fchdir;
|
||||||
Fcntl_error fcntl;
|
Fcntl_error fcntl;
|
||||||
|
Ftruncate_error ftruncate;
|
||||||
Open_error open;
|
Open_error open;
|
||||||
Execve_error execve;
|
Execve_error execve;
|
||||||
Unlink_error unlink;
|
Unlink_error unlink;
|
||||||
|
@ -308,6 +310,8 @@ namespace Noux {
|
||||||
|
|
||||||
SYSIO_DECL(fstat, { int fd; }, { Stat st; });
|
SYSIO_DECL(fstat, { int fd; }, { Stat st; });
|
||||||
|
|
||||||
|
SYSIO_DECL(ftruncate, { int fd; off_t length; }, { });
|
||||||
|
|
||||||
SYSIO_DECL(fcntl, { int fd; long long_arg; Fcntl_cmd cmd; },
|
SYSIO_DECL(fcntl, { int fd; long long_arg; Fcntl_cmd cmd; },
|
||||||
{ int result; });
|
{ int result; });
|
||||||
|
|
||||||
|
|
|
@ -552,6 +552,7 @@ namespace {
|
||||||
int fstat(Libc::File_descriptor *, struct stat *);
|
int fstat(Libc::File_descriptor *, struct stat *);
|
||||||
int fsync(Libc::File_descriptor *);
|
int fsync(Libc::File_descriptor *);
|
||||||
int fstatfs(Libc::File_descriptor *, struct statfs *);
|
int fstatfs(Libc::File_descriptor *, struct statfs *);
|
||||||
|
int ftruncate(Libc::File_descriptor *, ::off_t);
|
||||||
int fcntl(Libc::File_descriptor *, int, long);
|
int fcntl(Libc::File_descriptor *, int, long);
|
||||||
ssize_t getdirentries(Libc::File_descriptor *, char *, ::size_t, ::off_t *);
|
ssize_t getdirentries(Libc::File_descriptor *, char *, ::size_t, ::off_t *);
|
||||||
::off_t lseek(Libc::File_descriptor *, ::off_t offset, int whence);
|
::off_t lseek(Libc::File_descriptor *, ::off_t offset, int whence);
|
||||||
|
@ -855,6 +856,21 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Plugin::ftruncate(Libc::File_descriptor *fd, ::off_t length)
|
||||||
|
{
|
||||||
|
sysio()->ftruncate_in.fd = noux_fd(fd->context);
|
||||||
|
sysio()->ftruncate_in.length = length;
|
||||||
|
if (!noux()->syscall(Noux::Session::SYSCALL_FTRUNCATE)) {
|
||||||
|
switch (sysio()->error.ftruncate) {
|
||||||
|
case Noux::Sysio::FTRUNCATE_ERR_NO_PERM: errno = EPERM; break;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int Plugin::fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
int Plugin::fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
||||||
{
|
{
|
||||||
/* copy arguments to sysio */
|
/* copy arguments to sysio */
|
||||||
|
|
|
@ -518,6 +518,7 @@ namespace Noux {
|
||||||
|
|
||||||
bool write(Sysio *sysio, Vfs_handle *handle) { return false; }
|
bool write(Sysio *sysio, Vfs_handle *handle) { return false; }
|
||||||
bool read(Sysio *sysio, Vfs_handle *vfs_handle) { return false; }
|
bool read(Sysio *sysio, Vfs_handle *vfs_handle) { return false; }
|
||||||
|
bool ftruncate(Sysio *sysio, Vfs_handle *vfs_handle) { return false; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace Noux {
|
||||||
{
|
{
|
||||||
virtual bool write(Sysio *sysio, Vfs_handle *vfs_handle) = 0;
|
virtual bool write(Sysio *sysio, Vfs_handle *vfs_handle) = 0;
|
||||||
virtual bool read(Sysio *sysio, Vfs_handle *vfs_handle) = 0;
|
virtual bool read(Sysio *sysio, Vfs_handle *vfs_handle) = 0;
|
||||||
|
virtual bool ftruncate(Sysio *sysio, Vfs_handle *vfs_handle) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -516,6 +516,27 @@ namespace Noux {
|
||||||
source.release_packet(packet);
|
source.release_packet(packet);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ftruncate(Sysio *sysio, Vfs_handle *vfs_handle)
|
||||||
|
{
|
||||||
|
Fs_vfs_handle const *handle = static_cast<Fs_vfs_handle *>(vfs_handle);
|
||||||
|
|
||||||
|
Sysio::Ftruncate_error error;
|
||||||
|
|
||||||
|
try {
|
||||||
|
_fs.truncate(handle->file_handle(), sysio->ftruncate_in.length);
|
||||||
|
return true;
|
||||||
|
} catch (::File_system::Invalid_handle) {
|
||||||
|
/* should not happen */
|
||||||
|
error = Sysio::FTRUNCATE_ERR_NO_PERM;
|
||||||
|
} catch (::File_system::Permission_denied) {
|
||||||
|
error = Sysio::FTRUNCATE_ERR_NO_PERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
sysio->error.ftruncate = error;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ namespace Noux {
|
||||||
virtual bool write(Sysio *sysio, size_t &count) { return false; }
|
virtual bool write(Sysio *sysio, size_t &count) { return false; }
|
||||||
virtual bool read(Sysio *sysio) { return false; }
|
virtual bool read(Sysio *sysio) { return false; }
|
||||||
virtual bool fstat(Sysio *sysio) { return false; }
|
virtual bool fstat(Sysio *sysio) { return false; }
|
||||||
|
virtual bool ftruncate(Sysio *sysio) { return false; }
|
||||||
virtual bool fcntl(Sysio *sysio) { return false; }
|
virtual bool fcntl(Sysio *sysio) { return false; }
|
||||||
virtual bool fchdir(Sysio *sysio, Pwd *pwd) { return false; }
|
virtual bool fchdir(Sysio *sysio, Pwd *pwd) { return false; }
|
||||||
virtual bool dirent(Sysio *sysio) { return false; }
|
virtual bool dirent(Sysio *sysio) { return false; }
|
||||||
|
|
|
@ -121,6 +121,16 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SYSCALL_FTRUNCATE:
|
||||||
|
{
|
||||||
|
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->ftruncate_in.fd);
|
||||||
|
|
||||||
|
while (!io->check_unblock(true, false, false))
|
||||||
|
_block_for_io_channel(io);
|
||||||
|
|
||||||
|
return io->ftruncate(_sysio);
|
||||||
|
}
|
||||||
|
|
||||||
case SYSCALL_STAT:
|
case SYSCALL_STAT:
|
||||||
case SYSCALL_LSTAT: /* XXX implement difference between 'lstat' and 'stat' */
|
case SYSCALL_LSTAT: /* XXX implement difference between 'lstat' and 'stat' */
|
||||||
|
|
||||||
|
|
|
@ -468,6 +468,12 @@ namespace Noux {
|
||||||
sysio->read_out.count = count;
|
sysio->read_out.count = count;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ftruncate(Sysio *sysio, Vfs_handle *handle)
|
||||||
|
{
|
||||||
|
PDBG("called\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -204,6 +204,8 @@ namespace Noux {
|
||||||
sysio->read_out.count = _terminal.read(sysio->read_out.chunk, sysio->read_in.count);
|
sysio->read_out.count = _terminal.read(sysio->read_out.chunk, sysio->read_in.count);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ftruncate(Sysio *sysio, Vfs_handle *vfs_handle) { return false; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ namespace Noux {
|
||||||
|
|
||||||
bool write(Sysio *sysio, Vfs_handle *handle) { return _msg("write"); }
|
bool write(Sysio *sysio, Vfs_handle *handle) { return _msg("write"); }
|
||||||
bool read(Sysio *sysio, Vfs_handle *handle) { return _msg("read"); }
|
bool read(Sysio *sysio, Vfs_handle *handle) { return _msg("read"); }
|
||||||
|
bool ftruncate(Sysio *sysio, Vfs_handle *handle) { return _msg("ftruncate"); }
|
||||||
};
|
};
|
||||||
static Pseudo_file_io_service fs;
|
static Pseudo_file_io_service fs;
|
||||||
return &fs;
|
return &fs;
|
||||||
|
|
|
@ -65,6 +65,11 @@ namespace Noux {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ftruncate(Sysio *sysio)
|
||||||
|
{
|
||||||
|
return _fh->fs()->ftruncate(sysio, _fh);
|
||||||
|
}
|
||||||
|
|
||||||
bool fcntl(Sysio *sysio)
|
bool fcntl(Sysio *sysio)
|
||||||
{
|
{
|
||||||
switch (sysio->fcntl_in.cmd) {
|
switch (sysio->fcntl_in.cmd) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user