mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-19 03:06:39 +00:00
parent
4a3d852b65
commit
be171d86bb
@ -813,8 +813,15 @@ extern "C" int unlink(const char *path)
|
||||
}
|
||||
|
||||
|
||||
extern "C" ssize_t _write(int libc_fd, const void *buf, ::size_t count) {
|
||||
FD_FUNC_WRAPPER(write, libc_fd, buf, count); }
|
||||
extern "C" ssize_t _write(int libc_fd, const void *buf, ::size_t count)
|
||||
{
|
||||
int flags = fcntl(libc_fd, F_GETFL);
|
||||
|
||||
if ((flags != -1) && (flags & O_APPEND))
|
||||
lseek(libc_fd, 0, SEEK_END);
|
||||
|
||||
FD_FUNC_WRAPPER(write, libc_fd, buf, count);
|
||||
}
|
||||
|
||||
|
||||
extern "C" ssize_t write(int libc_fd, const void *buf, ::size_t count) {
|
||||
|
@ -51,10 +51,13 @@ class Plugin_context : public Libc::Plugin_context
|
||||
private:
|
||||
|
||||
char *_filename; /* needed for fstat() */
|
||||
int _fd_flags;
|
||||
int _status_flags;
|
||||
|
||||
public:
|
||||
|
||||
Plugin_context(const char *filename)
|
||||
: _fd_flags(0), _status_flags(0)
|
||||
{
|
||||
if (verbose)
|
||||
PDBG("new context at %p", this);
|
||||
@ -68,6 +71,18 @@ class Plugin_context : public Libc::Plugin_context
|
||||
}
|
||||
|
||||
const char *filename() { return _filename; }
|
||||
|
||||
/**
|
||||
* Set/get file descriptor flags
|
||||
*/
|
||||
void fd_flags(int flags) { _fd_flags = flags; }
|
||||
int fd_flags() { return _fd_flags; }
|
||||
|
||||
/**
|
||||
* Set/get file status status flags
|
||||
*/
|
||||
void status_flags(int flags) { _status_flags = flags; }
|
||||
int status_flags() { return _status_flags; }
|
||||
};
|
||||
|
||||
|
||||
@ -242,12 +257,14 @@ class Plugin : public Libc::Plugin
|
||||
}
|
||||
}
|
||||
|
||||
int fcntl(Libc::File_descriptor *, int cmd, long arg)
|
||||
int fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
||||
{
|
||||
/* libc's opendir() fails if fcntl() returns -1, so we return 0 here */
|
||||
if (verbose)
|
||||
PDBG("fcntl() called - not yet implemented");
|
||||
return 0;
|
||||
switch (cmd) {
|
||||
case F_GETFD: return context(fd)->fd_flags();
|
||||
case F_SETFD: context(fd)->fd_flags(arg); return 0;
|
||||
case F_GETFL: return context(fd)->status_flags();
|
||||
default: PERR("fcntl(): command %d not supported", cmd); return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int fstat(Libc::File_descriptor *fd, struct stat *buf)
|
||||
@ -478,6 +495,7 @@ class Plugin : public Libc::Plugin
|
||||
case FR_OK: {
|
||||
Plugin_context *context = new (Genode::env()->heap())
|
||||
File_plugin_context(pathname, ffat_file);
|
||||
context->status_flags(flags);
|
||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->alloc(this, context);
|
||||
if ((flags & O_TRUNC) && (ftruncate(fd, 0) == -1))
|
||||
return 0;
|
||||
@ -497,6 +515,7 @@ class Plugin : public Libc::Plugin
|
||||
case FR_OK: {
|
||||
Plugin_context *context = new (Genode::env()->heap())
|
||||
Directory_plugin_context(pathname, ffat_dir);
|
||||
context->status_flags(flags);
|
||||
Libc::File_descriptor *f =
|
||||
Libc::file_descriptor_allocator()->alloc(this, context);
|
||||
if (verbose)
|
||||
|
@ -76,6 +76,9 @@ class Plugin_context : public Libc::Plugin_context,
|
||||
|
||||
File_system::Node_handle _node_handle;
|
||||
|
||||
int _fd_flags;
|
||||
int _status_flags;
|
||||
|
||||
/**
|
||||
* Current file position if manually seeked, or ~0 for append mode
|
||||
*/
|
||||
@ -86,16 +89,31 @@ class Plugin_context : public Libc::Plugin_context,
|
||||
bool in_flight;
|
||||
|
||||
Plugin_context(File_system::File_handle handle)
|
||||
: _type(TYPE_FILE), _node_handle(handle), _seek_offset(~0), in_flight(false) { }
|
||||
: _type(TYPE_FILE), _node_handle(handle), _fd_flags(0),
|
||||
_status_flags(0), _seek_offset(~0), in_flight(false) { }
|
||||
|
||||
Plugin_context(File_system::Dir_handle handle)
|
||||
: _type(TYPE_DIR), _node_handle(handle), _seek_offset(0), in_flight(false) { }
|
||||
: _type(TYPE_DIR), _node_handle(handle), _fd_flags(0),
|
||||
_status_flags(0), _seek_offset(0), in_flight(false) { }
|
||||
|
||||
Plugin_context(File_system::Symlink_handle handle)
|
||||
: _type(TYPE_SYMLINK), _node_handle(handle), _seek_offset(~0), in_flight(false) { }
|
||||
: _type(TYPE_SYMLINK), _node_handle(handle), _fd_flags(0),
|
||||
_status_flags(0), _seek_offset(~0), in_flight(false) { }
|
||||
|
||||
File_system::Node_handle node_handle() const { return _node_handle; }
|
||||
|
||||
/**
|
||||
* Set/get file descriptor flags
|
||||
*/
|
||||
void fd_flags(int flags) { _fd_flags = flags; }
|
||||
int fd_flags() { return _fd_flags; }
|
||||
|
||||
/**
|
||||
* Set/get file status status flags
|
||||
*/
|
||||
void status_flags(int flags) { _status_flags = flags; }
|
||||
int status_flags() { return _status_flags; }
|
||||
|
||||
/**
|
||||
* Return true of handle is append mode
|
||||
*/
|
||||
@ -284,12 +302,14 @@ class Plugin : public Libc::Plugin
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fcntl(Libc::File_descriptor *, int cmd, long arg)
|
||||
int fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
||||
{
|
||||
/* libc's opendir() fails if fcntl() returns -1, so we return 0 here */
|
||||
if (verbose)
|
||||
PDBG("fcntl() called - not yet implemented");
|
||||
return 0;
|
||||
switch (cmd) {
|
||||
case F_GETFD: return context(fd)->fd_flags();
|
||||
case F_SETFD: context(fd)->fd_flags(arg); return 0;
|
||||
case F_GETFL: return context(fd)->status_flags();
|
||||
default: PERR("fcntl(): command %d not supported", cmd); return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int fstat(Libc::File_descriptor *fd, struct stat *buf)
|
||||
@ -506,6 +526,8 @@ class Plugin : public Libc::Plugin
|
||||
Plugin_context *context = new (Genode::env()->heap())
|
||||
Plugin_context(handle);
|
||||
|
||||
context->status_flags(flags);
|
||||
|
||||
Libc::File_descriptor *fd = Libc::file_descriptor_allocator()->alloc(this, context);
|
||||
if ((flags & O_TRUNC) && (ftruncate(fd, 0) == -1))
|
||||
return 0;
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
/* libc includes */
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
/* interface to 'log_console' */
|
||||
@ -51,6 +52,14 @@ namespace {
|
||||
_stderr(Libc::file_descriptor_allocator()->alloc(this, &_context, 2))
|
||||
{ }
|
||||
|
||||
int fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case F_GETFL: return O_WRONLY;
|
||||
default: PERR("fcntl(): command %d not supported", cmd); return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We provide fstat here because printf inqueries _fstat about stdout
|
||||
*/
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
/* libc includes */
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
@ -99,12 +100,25 @@ namespace {
|
||||
* notifications about data available for reading are delivered to
|
||||
* the 'Read_sigh' thread, which cares about unblocking 'select()'.
|
||||
*/
|
||||
struct Plugin_context : Libc::Plugin_context, Terminal::Connection
|
||||
class Plugin_context : public Libc::Plugin_context, public Terminal::Connection
|
||||
{
|
||||
Plugin_context()
|
||||
{
|
||||
read_avail_sigh(read_sigh());
|
||||
}
|
||||
private:
|
||||
|
||||
int _status_flags;
|
||||
|
||||
public:
|
||||
|
||||
Plugin_context()
|
||||
: _status_flags(0)
|
||||
{
|
||||
read_avail_sigh(read_sigh());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set/get file status status flags
|
||||
*/
|
||||
void status_flags(int flags) { _status_flags = flags; }
|
||||
int status_flags() { return _status_flags; }
|
||||
};
|
||||
|
||||
|
||||
@ -145,6 +159,7 @@ namespace {
|
||||
Libc::File_descriptor *open(const char *pathname, int flags)
|
||||
{
|
||||
Plugin_context *context = new (Genode::env()->heap()) Plugin_context;
|
||||
context->status_flags(flags);
|
||||
return Libc::file_descriptor_allocator()->alloc(this, context);
|
||||
}
|
||||
|
||||
@ -275,10 +290,13 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppress dummy message of the default plugin function
|
||||
*/
|
||||
int fcntl(Libc::File_descriptor *, int cmd, long arg) { return -1; }
|
||||
int fcntl(Libc::File_descriptor *fd, int cmd, long arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
case F_GETFL: return context(fd)->status_flags();
|
||||
default: PERR("fcntl(): command %d not supported", cmd); return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int ioctl(Libc::File_descriptor *, int request, char *argp)
|
||||
{
|
||||
|
@ -1074,12 +1074,14 @@ namespace {
|
||||
break;
|
||||
|
||||
case F_GETFL:
|
||||
PINF("fcntl: F_GETFL for libc_fd=%d", fd->libc_fd);
|
||||
if (verbose)
|
||||
PINF("fcntl: F_GETFL for libc_fd=%d", fd->libc_fd);
|
||||
sysio()->fcntl_in.cmd = Noux::Sysio::FCNTL_CMD_GET_FILE_STATUS_FLAGS;
|
||||
break;
|
||||
|
||||
case F_SETFL:
|
||||
PINF("fcntl: F_SETFL for libc_fd=%d", fd->libc_fd);
|
||||
if (verbose)
|
||||
PINF("fcntl: F_SETFL for libc_fd=%d", fd->libc_fd);
|
||||
sysio()->fcntl_in.cmd = Noux::Sysio::FCNTL_CMD_SET_FILE_STATUS_FLAGS;
|
||||
sysio()->fcntl_in.long_arg = arg;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user