* Implement O_APPEND.

* Also make set_flags available for setting it. O_NONBLOCK is ignored as in BFS.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30903 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2009-05-28 21:19:13 +00:00
parent 591bc3f2d9
commit 0807998b5d
1 changed files with 29 additions and 14 deletions

View File

@ -117,6 +117,7 @@ public:
size_t *length);
status_t Write(void *cookie, off_t position,
const void *buffer, size_t *length);
status_t SetFlags(void *cookie, int flags);
status_t CreateDir(const char *name, int perms);
status_t RemoveDir(const char *name);
@ -358,21 +359,23 @@ OverlayInode::Open(int openMode, void **_cookie)
if (!fHasStat)
ReadStat(NULL);
open_cookie *cookie = (open_cookie *)malloc(sizeof(open_cookie));
if (cookie == NULL)
return B_NO_MEMORY;
cookie->open_mode = openMode;
*_cookie = cookie;
if (fIsVirtual) {
if (openMode & O_TRUNC)
fStat.st_size = 0;
*_cookie = NULL;
return B_OK;
}
if (fSuperVnode.ops->open == NULL)
return B_UNSUPPORTED;
open_cookie *cookie = (open_cookie *)malloc(sizeof(open_cookie));
if (cookie == NULL)
return B_NO_MEMORY;
if (fOriginalNodeLength < 0) {
struct stat stat;
status_t result = fSuperVnode.ops->read_stat(SuperVolume(),
@ -383,9 +386,6 @@ OverlayInode::Open(int openMode, void **_cookie)
fOriginalNodeLength = stat.st_size;
}
cookie->open_mode = openMode;
*_cookie = cookie;
if (openMode & O_TRUNC)
fStat.st_size = 0;
@ -416,12 +416,13 @@ OverlayInode::Close(void *_cookie)
status_t
OverlayInode::FreeCookie(void *_cookie)
{
if (fIsVirtual)
return B_OK;
status_t result = B_OK;
open_cookie *cookie = (open_cookie *)_cookie;
status_t result = fSuperVnode.ops->free_cookie(SuperVolume(),
&fSuperVnode, cookie->super_cookie);
if (!fIsVirtual) {
result = fSuperVnode.ops->free_cookie(SuperVolume(),
&fSuperVnode, cookie->super_cookie);
}
free(cookie);
return result;
}
@ -476,6 +477,10 @@ status_t
OverlayInode::Write(void *_cookie, off_t position, const void *buffer,
size_t *length)
{
open_cookie *cookie = (open_cookie *)_cookie;
if (cookie->open_mode & O_APPEND)
position = fStat.st_size;
// find insertion point
write_buffer **link = &fWriteBuffers;
write_buffer *other = fWriteBuffers;
@ -563,6 +568,16 @@ OverlayInode::Write(void *_cookie, off_t position, const void *buffer,
}
status_t
OverlayInode::SetFlags(void *_cookie, int flags)
{
// we can only handle O_APPEND, O_NONBLOCK is ignored.
open_cookie *cookie = (open_cookie *)_cookie;
cookie->open_mode = (cookie->open_mode & ~O_APPEND) | (flags & ~O_APPEND);
return B_OK;
}
status_t
OverlayInode::CreateDir(const char *name, int perms)
{
@ -1063,7 +1078,7 @@ static status_t
overlay_set_flags(fs_volume *volume, fs_vnode *vnode, void *cookie,
int flags)
{
OVERLAY_CALL(set_flags, cookie, flags)
return ((OverlayInode *)vnode->private_node)->SetFlags(cookie, flags);
}