From 0807998b5d8a99e73f3ec1401b471bc1b5a51cac Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Thu, 28 May 2009 21:19:13 +0000 Subject: [PATCH] * 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 --- .../layers/write_overlay/write_overlay.cpp | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp b/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp index cf328ae5bd..4c5298dba5 100644 --- a/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp +++ b/src/add-ons/kernel/file_systems/layers/write_overlay/write_overlay.cpp @@ -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); }