35b40030a7
This is duplicated across multiple filesystems, and could probably be used in more still. Adjusted only BFS, EXT2, and NTFS in this commit, as they are the ones which make use of fs_ops_support.h already and thus need to be modified to avoid duplicate-definition errors. Also tweak next_dirent to support being built under fs_shell. (Possibly we should define ASSERT there, though?)
58 lines
1.3 KiB
C
58 lines
1.3 KiB
C
/*
|
|
* Copyright 2022, Haiku, Inc. All rights reserved.
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
#ifndef FS_OPS_SUPPORT_H
|
|
#define FS_OPS_SUPPORT_H
|
|
|
|
#ifndef FS_SHELL
|
|
# include <kernel.h>
|
|
# include <kernel/debug.h>
|
|
# include <dirent.h>
|
|
#else
|
|
# include "fssh_kernel_priv.h"
|
|
#endif
|
|
|
|
|
|
/*! Converts a given open mode (e.g. O_RDONLY) into access modes (e.g. R_OK).
|
|
*/
|
|
static inline int
|
|
open_mode_to_access(int openMode)
|
|
{
|
|
openMode &= O_RWMASK;
|
|
if (openMode == O_RDONLY)
|
|
return R_OK;
|
|
if (openMode == O_WRONLY)
|
|
return W_OK;
|
|
if (openMode == O_RDWR)
|
|
return R_OK | W_OK;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*! Computes and assigns `dirent->d_reclen`, adjusts `bufferRemaining` accordingly,
|
|
* and either advances to the next buffer, or returns NULL if no space remains.
|
|
*/
|
|
static inline struct dirent*
|
|
next_dirent(struct dirent* dirent, size_t nameLength, size_t& bufferRemaining)
|
|
{
|
|
const size_t reclen = offsetof(struct dirent, d_name) + nameLength + 1;
|
|
#ifdef ASSERT
|
|
ASSERT(reclen <= bufferRemaining);
|
|
#endif
|
|
dirent->d_reclen = reclen;
|
|
|
|
const size_t roundedReclen = ROUNDUP(reclen, alignof(struct dirent));
|
|
if (roundedReclen >= bufferRemaining) {
|
|
bufferRemaining -= reclen;
|
|
return NULL;
|
|
}
|
|
dirent->d_reclen = roundedReclen;
|
|
bufferRemaining -= roundedReclen;
|
|
|
|
return (struct dirent*)((uint8*)dirent + roundedReclen);
|
|
}
|
|
|
|
|
|
#endif // FS_OPS_SUPPORT_H
|