"R5" fs_shell: Remove (mostly.)
Two files remain: "argv.c" and "argv.h", as these are still used by some other, non-FS-related tests. This was one of the last significant chunks of "no commercial use" code in the tree, as it originally came from the "Filesystem Construction Kit," the sample code distributed with "Practical Filesystem Design with the Be FS", and contained a sigifincant amount of BeOS kernel filesystem code in it (the original README, not preserved here, noted that "the cache code is the real Release 4 BeOS disk cache code".) It has long been replaced by Ingo's from-scratch, MIT-licensed fs_shell that lives in src/tools/fs_shell. Perhaps a note should be made somewhere of this code's prior existence, but I don't think we will have much use for it again, so confined to the dustbin of Git history it shall be.
This commit is contained in:
parent
38c59f2971
commit
0f36120d8d
@ -4,7 +4,6 @@ HaikuSubInclude bfs ;
|
||||
HaikuSubInclude btrfs ;
|
||||
HaikuSubInclude cdda ;
|
||||
HaikuSubInclude consistency_check ;
|
||||
HaikuSubInclude fs_shell ;
|
||||
HaikuSubInclude fragmenter ;
|
||||
HaikuSubInclude iso9660 ;
|
||||
HaikuSubInclude random_file_actions ;
|
||||
|
@ -1,19 +0,0 @@
|
||||
# Same as SetupIncludes, but doesn't include the posix headers.
|
||||
rule SetupFSShellIncludes
|
||||
{
|
||||
# XXX add "opengl" later
|
||||
local os_includes = add-ons add-ons/file_system add-ons/graphics add-ons/input_server
|
||||
add-ons/screen_saver add-ons/tracker app device drivers game interface kernel media mail
|
||||
midi midi2 net storage support translation ;
|
||||
|
||||
# Overwrite any exiting content when changing HDRS. This rule may be invoked multiple times.
|
||||
|
||||
# Use headers directory, to allow to do things like include <posix/string.h>
|
||||
SYSHDRS = [ FDirName $(OBOS_TOP) headers ] ;
|
||||
|
||||
# Use public OS header directories
|
||||
SYSHDRS += [ PublicHeaders $(os_includes) ] ;
|
||||
|
||||
# Use the root of the private headers -- not so nice, but simplifies things.
|
||||
SYSHDRS += [ PrivateHeaders $(DOT) ] ;
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
SubDir HAIKU_TOP src tests add-ons kernel file_systems fs_shell ;
|
||||
|
||||
include [ FDirName $(HAIKU_TOP) src tests add-ons kernel file_systems fs_shell
|
||||
FSShellRules ] ;
|
||||
|
||||
# We compile the fs_shell in a mixed environment: We use the platform POSIX
|
||||
# and STL headers (to have a proper interface to use), and we use all other
|
||||
# BeOS specific headers. Ideally we would get rid of the latter, but we still
|
||||
# have dependencies to them.
|
||||
|
||||
# platform specific sources
|
||||
local fsShellCommandSources ;
|
||||
local externalCommandsSources ;
|
||||
local attributeSupportSources ;
|
||||
local byteOrderSupportSources ;
|
||||
if $(HOST_PLATFORM_BEOS_COMPATIBLE) {
|
||||
fsShellCommandSources = fs_shell_command_beos.cpp ;
|
||||
externalCommandsSources = external_commands_beos.cpp ;
|
||||
} else {
|
||||
fsShellCommandSources = fs_shell_command_unix.cpp ;
|
||||
externalCommandsSources = external_commands_unix.cpp ;
|
||||
attributeSupportSources = fs_attr.cpp ;
|
||||
byteOrderSupportSources = byteorder.cpp ;
|
||||
}
|
||||
|
||||
SetupFSShellIncludes ;
|
||||
|
||||
if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
|
||||
SubDirHdrs [ FDirName $(HAIKU_TOP) src build libroot ] ;
|
||||
}
|
||||
|
||||
UsePrivateHeaders shared ;
|
||||
|
||||
rule BuildLibFSShell
|
||||
{
|
||||
# some defines actually only relevant for fs_attr.cpp
|
||||
local defines =
|
||||
HAIKU_BUILD_ATTRIBUTES_DIR="\\\"$(HAIKU_BUILD_ATTRIBUTES_DIR)\\\""
|
||||
BUILDING_FS_SHELL=1
|
||||
;
|
||||
|
||||
ObjectDefines $(2) : $(defines) ;
|
||||
|
||||
BuildPlatformStaticLibrary $(1) : $(2) : false ;
|
||||
}
|
||||
|
||||
{
|
||||
local defines = [ FDefines USER _GNU_SOURCE ] ;
|
||||
SubDirCcFlags $(defines) ;
|
||||
SubDirC++Flags $(defines) -fno-exceptions -fno-rtti ;
|
||||
}
|
||||
|
||||
BuildLibFSShell libfs_shell.a
|
||||
:
|
||||
fsh.cpp rootfs.c initfs.c kernel.c cache.c $(externalCommandsSources) sl.c
|
||||
stub.c tracker.cpp sysdep.c hexdump.c argv.c errors.cpp xcp.cpp
|
||||
path_util.cpp stat_util.cpp
|
||||
$(attributeSupportSources)
|
||||
$(byteOrderSupportSources)
|
||||
;
|
||||
|
||||
SEARCH on [ FGristFiles fs_attr.cpp byteorder.cpp ]
|
||||
= [ FDirName $(HAIKU_TOP) src build libroot ] ;
|
||||
|
||||
# fs_shell_command
|
||||
|
||||
BuildPlatformMain fs_shell_command
|
||||
: fs_shell_command.cpp $(fsShellCommandSources) ;
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef FS_SHELL_ADDITIONAL_COMMANDS_H
|
||||
#define FS_SHELL_ADDITIONAL_COMMANDS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct cmd_entry {
|
||||
char *name;
|
||||
int (*func)(int argc, char **argv);
|
||||
char *help;
|
||||
} cmd_entry;
|
||||
|
||||
extern cmd_entry additional_commands[];
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FS_SHELL_ADDITIONAL_COMMANDS_H
|
File diff suppressed because it is too large
Load Diff
@ -1,99 +0,0 @@
|
||||
#ifndef _CACHE_H_
|
||||
#define _CACHE_H_
|
||||
|
||||
typedef struct hash_ent {
|
||||
int dev;
|
||||
fs_off_t bnum;
|
||||
fs_off_t hash_val;
|
||||
void *data;
|
||||
struct hash_ent *next;
|
||||
} hash_ent;
|
||||
|
||||
|
||||
typedef struct hash_table {
|
||||
hash_ent **table;
|
||||
int max;
|
||||
int mask; /* == max - 1 */
|
||||
int num_elements;
|
||||
} hash_table;
|
||||
|
||||
|
||||
#define HT_DEFAULT_MAX 128
|
||||
|
||||
|
||||
typedef struct cache_ent {
|
||||
int dev;
|
||||
fs_off_t block_num;
|
||||
int bsize;
|
||||
volatile int flags;
|
||||
|
||||
void *data;
|
||||
void *clone; /* copy of data by set_block_info() */
|
||||
int lock;
|
||||
|
||||
void (*func)(fs_off_t bnum, size_t num_blocks, void *arg);
|
||||
fs_off_t logged_bnum;
|
||||
void *arg;
|
||||
|
||||
struct cache_ent *next, /* points toward mru end of list */
|
||||
*prev; /* points toward lru end of list */
|
||||
|
||||
} cache_ent;
|
||||
|
||||
#define CE_NORMAL 0x0000 /* a nice clean pristine page */
|
||||
#define CE_DIRTY 0x0002 /* needs to be written to disk */
|
||||
#define CE_BUSY 0x0004 /* this block has i/o happening, don't touch it */
|
||||
|
||||
|
||||
typedef struct cache_ent_list {
|
||||
cache_ent *lru; /* tail of the list */
|
||||
cache_ent *mru; /* head of the list */
|
||||
} cache_ent_list;
|
||||
|
||||
|
||||
typedef struct block_cache {
|
||||
struct lock lock;
|
||||
int flags;
|
||||
int cur_blocks;
|
||||
int max_blocks;
|
||||
hash_table ht;
|
||||
|
||||
cache_ent_list normal, /* list of "normal" blocks (clean & dirty) */
|
||||
locked; /* list of clean and locked blocks */
|
||||
} block_cache;
|
||||
|
||||
#define ALLOW_WRITES 1
|
||||
#define NO_WRITES 0
|
||||
|
||||
extern int init_block_cache(int max_blocks, int flags);
|
||||
extern void shutdown_block_cache(void);
|
||||
|
||||
extern void force_cache_flush(int dev, int prefer_log_blocks);
|
||||
extern int flush_blocks(int dev, fs_off_t bnum, int nblocks);
|
||||
extern int flush_device(int dev, int warn_locked);
|
||||
|
||||
extern int init_cache_for_device(int fd, fs_off_t max_blocks);
|
||||
extern int remove_cached_device_blocks(int dev, int allow_write);
|
||||
|
||||
extern void *get_block(int dev, fs_off_t bnum, int bsize);
|
||||
extern void *get_empty_block(int dev, fs_off_t bnum, int bsize);
|
||||
extern int release_block(int dev, fs_off_t bnum);
|
||||
extern int mark_blocks_dirty(int dev, fs_off_t bnum, int nblocks);
|
||||
|
||||
|
||||
extern int cached_read(int dev, fs_off_t bnum, void *data,
|
||||
fs_off_t num_blocks, int bsize);
|
||||
extern int cached_write(int dev, fs_off_t bnum, const void *data,
|
||||
fs_off_t num_blocks, int bsize);
|
||||
extern int cached_write_locked(int dev, fs_off_t bnum, const void *data,
|
||||
fs_off_t num_blocks, int bsize);
|
||||
extern int set_blocks_info(int dev, fs_off_t *blocks, int nblocks,
|
||||
void (*func)(fs_off_t bnum, size_t nblocks, void *arg),
|
||||
void *arg);
|
||||
|
||||
extern size_t read_phys_blocks (int fd, fs_off_t bnum, void *data,
|
||||
uint num_blocks, int bsize);
|
||||
extern size_t write_phys_blocks(int fd, fs_off_t bnum, void *data,
|
||||
uint num_blocks, int bsize);
|
||||
|
||||
#endif /* _CACHE_H_ */
|
@ -1,293 +0,0 @@
|
||||
/*
|
||||
This file contains some kit-wide typedefs and structs that basically
|
||||
emulate most of a normal posix-y type system. The purpose of hiding
|
||||
everything behind these typedefs is to avoid inconsistencies between
|
||||
various systems (such as the difference in size between off_t on BeOS
|
||||
and some versions of Unix). To further avoid complications I've also
|
||||
hidden the stat and dirent structs since those vary even more widely.
|
||||
|
||||
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
|
||||
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
|
||||
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
|
||||
|
||||
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
|
||||
|
||||
Dominic Giampaolo
|
||||
dbg@be.com
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _COMPAT_H
|
||||
#define _COMPAT_H
|
||||
|
||||
#define _FS_INTERFACE_H
|
||||
// don't include that file
|
||||
|
||||
#if (!defined(__BEOS__) && !defined(__HAIKU__))
|
||||
# define dprintf build_platform_dprintf
|
||||
# include <stdio.h>
|
||||
# undef dprintf
|
||||
|
||||
typedef struct dirent dirent_t;
|
||||
typedef struct iovec iovec;
|
||||
|
||||
#endif // __BEOS__
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef _ERRORS_H
|
||||
# define _ERRORS_H
|
||||
// don't include <Errors.h>, we use the platform <errno.h>
|
||||
#endif
|
||||
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
|
||||
#if (defined(__BEOS__) || defined(__HAIKU__))
|
||||
# include <OS.h> /* for typedefs and prototypes */
|
||||
# include <image.h> /* for a few typedefs */
|
||||
# include <Drivers.h> /* for various ioctl structs, etc */
|
||||
# include <iovec.h> /* because we're boneheads sometimes */
|
||||
#elif HAIKU_HOST_PLATFORM_FREEBSD
|
||||
/* BSD Compilant stat.h */
|
||||
# define __BSD_VISIBLE 1
|
||||
#undef __XSI_VISIBLE
|
||||
# define __XSI_VISIBLE 1
|
||||
/* for mknod */
|
||||
# define __POSIX_VISIBLE 200112
|
||||
/* for S_ISLNK, S_ISSOCK and lstat */
|
||||
# include <sys/stat.h>
|
||||
# include <sys/uio.h>
|
||||
# include <image.h> /* for a few typedefs */
|
||||
# include <Drivers.h> /* for various ioctl structs, etc */
|
||||
typedef unsigned long ulong;
|
||||
#else
|
||||
# include <sys/uio.h>
|
||||
# include <image.h> /* for a few typedefs */
|
||||
# include <Drivers.h> /* for various ioctl structs, etc */
|
||||
#endif
|
||||
|
||||
#include <fs_attr.h>
|
||||
|
||||
#include "errors.h"
|
||||
|
||||
|
||||
/*
|
||||
By default (for portability reasons) the size of off_t's and ino_t's
|
||||
is 32-bit. You can change the file system to be 64-bit if you want
|
||||
by defining OFF_T_SIZE to be 8.
|
||||
|
||||
NOTE: if you change the size of OFF_T_SIZE to be 8 you will have to
|
||||
go through the code and change any calls to printf() to use the
|
||||
appropriate format for 64-bit integers on your OS. I have seen
|
||||
4 different formats now: %Ld (BeOS and Linux), %qd (FreeBSD),
|
||||
%lld (Irix) and %I64d (NT).
|
||||
*/
|
||||
#define OFF_T_SIZE 8
|
||||
|
||||
#if OFF_T_SIZE == 4
|
||||
typedef long fs_off_t;
|
||||
typedef long my_ino_t;
|
||||
#elif OFF_T_SIZE == 8
|
||||
typedef long long fs_off_t;
|
||||
typedef long long my_ino_t;
|
||||
#else
|
||||
#error OFF_T_SIZE must be either 4 or 8.
|
||||
#endif
|
||||
|
||||
typedef int my_dev_t;
|
||||
typedef int my_mode_t;
|
||||
typedef int my_uid_t;
|
||||
typedef int my_gid_t;
|
||||
|
||||
/* This is the maximum length of a file name. Adjust it as you see fit */
|
||||
#define FILE_NAME_LENGTH 256
|
||||
|
||||
/* This is maximum name size for naming a volume or semaphore/lock */
|
||||
#define IDENT_NAME_LENGTH 32
|
||||
|
||||
|
||||
typedef struct my_dirent {
|
||||
my_dev_t d_dev;
|
||||
my_dev_t d_pdev;
|
||||
my_ino_t d_ino;
|
||||
my_ino_t d_pino;
|
||||
unsigned short d_reclen;
|
||||
char d_name[1];
|
||||
} my_dirent_t;
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
struct my_dirent ent;
|
||||
} MY_DIR;
|
||||
|
||||
|
||||
/*
|
||||
This is a pretty regular stat structure but it's our "internal"
|
||||
version since if we depended on the host version we'd be exposed
|
||||
to all sorts of nasty things (different sized ino_t's, etc).
|
||||
We also can't use the normal naming style of "st_" for each field
|
||||
name because on some systems fields like st_atime are really just
|
||||
define's that expand to all sorts of weird stuff.
|
||||
*/
|
||||
struct my_stat {
|
||||
my_dev_t dev; /* "device" that this file resides on */
|
||||
my_ino_t ino; /* this file's inode #, unique per device */
|
||||
my_mode_t mode; /* mode bits (rwx for user, group, etc) */
|
||||
int nlink; /* number of hard links to this file */
|
||||
my_uid_t uid; /* user id of the owner of this file */
|
||||
my_gid_t gid; /* group id of the owner of this file */
|
||||
fs_off_t size; /* size in bytes of this file */
|
||||
dev_t rdev; /* device type (not used) */
|
||||
size_t blksize; /* preferred block size for i/o */
|
||||
time_t atime; /* last access time */
|
||||
time_t mtime; /* last modification time */
|
||||
time_t ctime; /* last change time, not creation time */
|
||||
time_t crtime; /* creation time; not posix but useful */
|
||||
};
|
||||
|
||||
|
||||
#define MY_S_ATTR_DIR 01000000000 /* attribute directory */
|
||||
#define MY_S_ATTR 02000000000 /* attribute */
|
||||
#define MY_S_INDEX_DIR 04000000000 /* index (or index directory) */
|
||||
#define MY_S_STR_INDEX 00100000000 /* string index */
|
||||
#define MY_S_INT_INDEX 00200000000 /* int32 index */
|
||||
#define MY_S_UINT_INDEX 00400000000 /* uint32 index */
|
||||
#define MY_S_LONG_LONG_INDEX 00010000000 /* int64 index */
|
||||
#define MY_S_ULONG_LONG_INDEX 00020000000 /* uint64 index */
|
||||
#define MY_S_FLOAT_INDEX 00040000000 /* float index */
|
||||
#define MY_S_DOUBLE_INDEX 00001000000 /* double index */
|
||||
#define MY_S_ALLOW_DUPS 00002000000 /* allow duplicate entries (currently unused) */
|
||||
|
||||
#define MY_S_LINK_SELF_HEALING 00001000000 /* link will be updated if you move its target */
|
||||
#define MY_S_LINK_AUTO_DELETE 00002000000 /* link will be deleted if you delete its target */
|
||||
|
||||
#define MY_S_IFMT 00000170000 /* type of file */
|
||||
#define MY_S_IFLNK 00000120000 /* symbolic link */
|
||||
#define MY_S_IFREG 00000100000 /* regular */
|
||||
#define MY_S_IFBLK 00000060000 /* block special */
|
||||
#define MY_S_IFDIR 00000040000 /* directory */
|
||||
#define MY_S_IFCHR 00000020000 /* character special */
|
||||
#define MY_S_IFIFO 00000010000 /* fifo */
|
||||
|
||||
#define MY_S_ISREG(m) (((m) & MY_S_IFMT) == MY_S_IFREG)
|
||||
#define MY_S_ISLNK(m) (((m) & MY_S_IFMT) == MY_S_IFLNK)
|
||||
#define MY_S_ISBLK(m) (((m) & MY_S_IFMT) == MY_S_IFBLK)
|
||||
#define MY_S_ISDIR(m) (((m) & MY_S_IFMT) == MY_S_IFDIR)
|
||||
#define MY_S_ISCHR(m) (((m) & MY_S_IFMT) == MY_S_IFCHR)
|
||||
#define MY_S_ISFIFO(m) (((m) & MY_S_IFMT) == MY_S_IFIFO)
|
||||
|
||||
#define MY_S_IUMSK 07777 /* user settable bits */
|
||||
|
||||
#define MY_S_ISUID 04000 /* set user id on execution */
|
||||
#define MY_S_ISGID 02000 /* set group id on execution */
|
||||
|
||||
#define MY_S_ISVTX 01000 /* save swapped text even after use */
|
||||
|
||||
#define MY_S_IRWXU 00700 /* read, write, execute: owner */
|
||||
#define MY_S_IRUSR 00400 /* read permission: owner */
|
||||
#define MY_S_IWUSR 00200 /* write permission: owner */
|
||||
#define MY_S_IXUSR 00100 /* execute permission: owner */
|
||||
#define MY_S_IRWXG 00070 /* read, write, execute: group */
|
||||
#define MY_S_IRGRP 00040 /* read permission: group */
|
||||
#define MY_S_IWGRP 00020 /* write permission: group */
|
||||
#define MY_S_IXGRP 00010 /* execute permission: group */
|
||||
#define MY_S_IRWXO 00007 /* read, write, execute: other */
|
||||
#define MY_S_IROTH 00004 /* read permission: other */
|
||||
#define MY_S_IWOTH 00002 /* write permission: other */
|
||||
#define MY_S_IXOTH 00001 /* execute permission: other */
|
||||
|
||||
#define MY_O_RDONLY 0 /* read only */
|
||||
#define MY_O_WRONLY 1 /* write only */
|
||||
#define MY_O_RDWR 2 /* read and write */
|
||||
#define MY_O_RWMASK 3 /* Mask to get open mode */
|
||||
|
||||
#define MY_O_CLOEXEC 0x0040 /* close fd on exec */
|
||||
#define MY_O_NONBLOCK 0x0080 /* non blocking io */
|
||||
#define MY_O_EXCL 0x0100 /* exclusive creat */
|
||||
#define MY_O_CREAT 0x0200 /* create and open file */
|
||||
#define MY_O_TRUNC 0x0400 /* open with truncation */
|
||||
#define MY_O_APPEND 0x0800 /* to end of file */
|
||||
#define MY_O_NOCTTY 0x1000 /* currently unsupported */
|
||||
#define MY_O_NOTRAVERSE 0x2000 /* do not traverse leaf link */
|
||||
#define MY_O_ACCMODE 0x0003 /* currently unsupported */
|
||||
#define MY_O_TEXT 0x4000 /* CR-LF translation */
|
||||
#define MY_O_BINARY 0x8000 /* no translation */
|
||||
|
||||
#define MY_SEEK_SET 0
|
||||
#define MY_SEEK_CUR 1
|
||||
#define MY_SEEK_END 2
|
||||
|
||||
// O_NOTRAVERSE is called O_NOFOLLOW under Linux
|
||||
#ifndef O_NOTRAVERSE
|
||||
#ifdef O_NOFOLLOW
|
||||
#define O_NOTRAVERSE O_NOFOLLOW
|
||||
#else
|
||||
#define O_NOTRAVERSE 0
|
||||
#endif
|
||||
#endif
|
||||
#ifndef S_IUMSK
|
||||
#define S_IUMSK (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
|
||||
#endif
|
||||
|
||||
|
||||
#if (defined(__BEOS__) || defined(__HAIKU__))
|
||||
|
||||
typedef attr_info my_attr_info;
|
||||
|
||||
#else // ! __BEOS__
|
||||
|
||||
typedef struct my_attr_info
|
||||
{
|
||||
uint32 type;
|
||||
fs_off_t size;
|
||||
} my_attr_info;
|
||||
|
||||
#endif // ! __BEOS__
|
||||
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#if (!defined(__BEOS__) && !defined(__HAIKU__))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
ssize_t read_pos(int fd, fs_off_t _pos, void *data, size_t nbytes);
|
||||
ssize_t write_pos(int fd, fs_off_t _pos, const void *data, size_t nbytes);
|
||||
ssize_t readv_pos(int fd, fs_off_t _pos, const struct iovec *iov, int count);
|
||||
ssize_t writev_pos(int fd, fs_off_t _pos, const struct iovec *iov, int count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ! __BEOS__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void panic(const char *msg, ...);
|
||||
int device_is_read_only(const char *device);
|
||||
int get_device_block_size(int fd);
|
||||
fs_off_t get_num_device_blocks(int fd);
|
||||
int device_is_removeable(int fd);
|
||||
int lock_removeable_device(int fd, bool on_or_off);
|
||||
void hexdump(void *address, int size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _COMPAT_H */
|
@ -1,175 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "errors.h"
|
||||
|
||||
const char *
|
||||
fs_strerror(int error)
|
||||
{
|
||||
return strerror(to_platform_error(error));
|
||||
}
|
||||
|
||||
|
||||
#if (defined(__BEOS__) || defined(__HAIKU__))
|
||||
|
||||
int
|
||||
from_platform_error(int error)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
to_platform_error(int error)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
struct error_entry {
|
||||
int fs_error;
|
||||
int platform_error;
|
||||
};
|
||||
|
||||
static error_entry sErrors[] = {
|
||||
{ FS_OK, 0 },
|
||||
|
||||
// POSIX errors
|
||||
{ FS_E2BIG, E2BIG },
|
||||
{ FS_ECHILD, ECHILD },
|
||||
{ FS_EDEADLK, EDEADLK },
|
||||
{ FS_EFBIG, EFBIG },
|
||||
{ FS_EMLINK, EMLINK },
|
||||
{ FS_ENFILE, ENFILE },
|
||||
{ FS_ENODEV, ENODEV },
|
||||
{ FS_ENOLCK, ENOLCK },
|
||||
{ FS_ENOSYS, ENOSYS },
|
||||
{ FS_ENOTTY, ENOTTY },
|
||||
{ FS_ENXIO, ENXIO },
|
||||
{ FS_ESPIPE, ESPIPE },
|
||||
{ FS_ESRCH, ESRCH },
|
||||
#ifdef EFPOS
|
||||
{ FS_EFPOS, EFPOS },
|
||||
#endif
|
||||
#ifdef ESIGPARM
|
||||
{ FS_ESIGPARM, ESIGPARM },
|
||||
#endif
|
||||
{ FS_EDOM, EDOM },
|
||||
{ FS_ERANGE, ERANGE },
|
||||
{ FS_EPROTOTYPE, EPROTOTYPE },
|
||||
{ FS_EPROTONOSUPPORT, EPROTONOSUPPORT },
|
||||
{ FS_EPFNOSUPPORT, EPFNOSUPPORT },
|
||||
{ FS_EAFNOSUPPORT, EAFNOSUPPORT },
|
||||
{ FS_EADDRINUSE, EADDRINUSE },
|
||||
{ FS_EADDRNOTAVAIL, EADDRNOTAVAIL },
|
||||
{ FS_ENETDOWN, ENETDOWN },
|
||||
{ FS_ENETUNREACH, ENETUNREACH },
|
||||
{ FS_ENETRESET, ENETRESET },
|
||||
{ FS_ECONNABORTED, ECONNABORTED },
|
||||
{ FS_ECONNRESET, ECONNRESET },
|
||||
{ FS_EISCONN, EISCONN },
|
||||
{ FS_ENOTCONN, ENOTCONN },
|
||||
{ FS_ESHUTDOWN, ESHUTDOWN },
|
||||
{ FS_ECONNREFUSED, ECONNREFUSED },
|
||||
{ FS_EHOSTUNREACH, EHOSTUNREACH },
|
||||
{ FS_ENOPROTOOPT, ENOPROTOOPT },
|
||||
{ FS_ENOBUFS, ENOBUFS },
|
||||
{ FS_EINPROGRESS, EINPROGRESS },
|
||||
{ FS_EALREADY, EALREADY },
|
||||
{ FS_EILSEQ, EILSEQ },
|
||||
{ FS_ENOMSG, ENOMSG },
|
||||
{ FS_ESTALE, ESTALE },
|
||||
{ FS_EOVERFLOW, EOVERFLOW },
|
||||
{ FS_EMSGSIZE, EMSGSIZE },
|
||||
{ FS_EOPNOTSUPP, EOPNOTSUPP },
|
||||
{ FS_ENOTSOCK, ENOTSOCK },
|
||||
{ FS_EHOSTDOWN, EHOSTDOWN },
|
||||
{ FS_EBADMSG, EBADMSG },
|
||||
{ FS_ECANCELED, ECANCELED },
|
||||
{ FS_EDESTADDRREQ, EDESTADDRREQ },
|
||||
{ FS_EDQUOT, EDQUOT },
|
||||
{ FS_EIDRM, EIDRM },
|
||||
{ FS_EMULTIHOP, EMULTIHOP },
|
||||
#ifdef ENODATA
|
||||
{ FS_ENODATA, ENODATA },
|
||||
#endif
|
||||
{ FS_ENOLINK, ENOLINK },
|
||||
#ifdef ENOSR
|
||||
{ FS_ENOSR, ENOSR },
|
||||
#endif
|
||||
#ifdef ENOSTR
|
||||
{ FS_ENOSTR, ENOSTR },
|
||||
#endif
|
||||
{ FS_ENOTSUP, ENOTSUP },
|
||||
{ FS_EPROTO, EPROTO },
|
||||
#ifdef ETIME
|
||||
{ FS_ETIME, ETIME },
|
||||
#endif
|
||||
{ FS_ETXTBSY, ETXTBSY },
|
||||
|
||||
{ FS_ENOMEM, ENOMEM },
|
||||
{ FS_EACCES, EACCES },
|
||||
{ FS_EINTR, EINTR },
|
||||
{ FS_EIO, EIO },
|
||||
{ FS_EBUSY, EBUSY },
|
||||
{ FS_EFAULT, EFAULT },
|
||||
{ FS_ETIMEDOUT, ETIMEDOUT },
|
||||
{ FS_EAGAIN, EAGAIN },
|
||||
{ FS_EWOULDBLOCK, EWOULDBLOCK },
|
||||
{ FS_EBADF, EBADF },
|
||||
{ FS_EEXIST, EEXIST },
|
||||
{ FS_EINVAL, EINVAL },
|
||||
{ FS_ENAMETOOLONG, ENAMETOOLONG },
|
||||
{ FS_ENOENT, ENOENT },
|
||||
{ FS_EPERM, EPERM },
|
||||
{ FS_ENOTDIR, ENOTDIR },
|
||||
{ FS_EISDIR, EISDIR },
|
||||
{ FS_ENOTEMPTY, ENOTEMPTY },
|
||||
{ FS_ENOSPC, ENOSPC },
|
||||
{ FS_EROFS, EROFS },
|
||||
{ FS_EMFILE, EMFILE },
|
||||
{ FS_EXDEV, EXDEV },
|
||||
{ FS_ELOOP, ELOOP },
|
||||
{ FS_ENOEXEC, ENOEXEC },
|
||||
{ FS_EPIPE, EPIPE },
|
||||
};
|
||||
const int sErrorCount = sizeof(sErrors) / sizeof(error_entry);
|
||||
|
||||
int
|
||||
from_platform_error(int error)
|
||||
{
|
||||
if (error == 0)
|
||||
return FS_OK;
|
||||
|
||||
for (int i = 0; i < sErrorCount; i++) {
|
||||
if (sErrors[i].platform_error == error)
|
||||
return sErrors[i].fs_error;
|
||||
}
|
||||
|
||||
return (error > 0 ? -error : error);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
to_platform_error(int error)
|
||||
{
|
||||
if (error == FS_OK)
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < sErrorCount; i++) {
|
||||
if (sErrors[i].fs_error == error)
|
||||
return sErrors[i].platform_error;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#endif // ! __BEOS__
|
@ -1,197 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef FS_SHELL_ERRORS_H
|
||||
#define FS_SHELL_ERRORS_H
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#define FS_GENERAL_ERROR_BASE LONG_MIN
|
||||
#define FS_OS_ERROR_BASE FS_GENERAL_ERROR_BASE + 0x1000
|
||||
#define FS_APP_ERROR_BASE FS_GENERAL_ERROR_BASE + 0x2000
|
||||
#define FS_INTERFACE_ERROR_BASE FS_GENERAL_ERROR_BASE + 0x3000
|
||||
#define FS_MEDIA_ERROR_BASE FS_GENERAL_ERROR_BASE + 0x4000 /* - 0x41ff */
|
||||
#define FS_TRANSLATION_ERROR_BASE FS_GENERAL_ERROR_BASE + 0x4800 /* - 0x48ff */
|
||||
#define FS_MIDI_ERROR_BASE FS_GENERAL_ERROR_BASE + 0x5000
|
||||
#define FS_STORAGE_ERROR_BASE FS_GENERAL_ERROR_BASE + 0x6000
|
||||
#define FS_POSIX_ERROR_BASE FS_GENERAL_ERROR_BASE + 0x7000
|
||||
#define FS_MAIL_ERROR_BASE FS_GENERAL_ERROR_BASE + 0x8000
|
||||
#define FS_PRINT_ERROR_BASE FS_GENERAL_ERROR_BASE + 0x9000
|
||||
#define FS_DEVICE_ERROR_BASE FS_GENERAL_ERROR_BASE + 0xa000
|
||||
|
||||
#define FS_ERRORS_END (FS_GENERAL_ERROR_BASE + 0xffff)
|
||||
|
||||
// General Errors
|
||||
enum {
|
||||
FS_NO_MEMORY = FS_GENERAL_ERROR_BASE,
|
||||
FS_IO_ERROR,
|
||||
FS_PERMISSION_DENIED,
|
||||
FS_BAD_INDEX,
|
||||
FS_BAD_TYPE,
|
||||
FS_BAD_VALUE,
|
||||
FS_MISMATCHED_VALUES,
|
||||
FS_NAME_NOT_FOUND,
|
||||
FS_NAME_IN_USE,
|
||||
FS_TIMED_OUT,
|
||||
FS_INTERRUPTED,
|
||||
FS_WOULD_BLOCK,
|
||||
FS_CANCELED,
|
||||
FS_NO_INIT,
|
||||
FS_BUSY,
|
||||
FS_NOT_ALLOWED,
|
||||
FS_BAD_DATA,
|
||||
|
||||
FS_ERROR = -1,
|
||||
FS_OK = 0,
|
||||
FS_NO_ERROR = 0
|
||||
};
|
||||
|
||||
|
||||
// Kernel Kit Errors
|
||||
enum {
|
||||
FS_BAD_SEM_ID = FS_OS_ERROR_BASE,
|
||||
FS_NO_MORE_SEMS,
|
||||
|
||||
FS_BAD_THREAD_ID = FS_OS_ERROR_BASE + 0x100,
|
||||
FS_NO_MORE_THREADS,
|
||||
FS_BAD_THREAD_STATE,
|
||||
FS_BAD_TEAM_ID,
|
||||
FS_NO_MORE_TEAMS,
|
||||
|
||||
FS_BAD_PORT_ID = FS_OS_ERROR_BASE + 0x200,
|
||||
FS_NO_MORE_PORTS,
|
||||
|
||||
FS_BAD_IMAGE_ID = FS_OS_ERROR_BASE + 0x300,
|
||||
FS_BAD_ADDRESS,
|
||||
FS_NOT_AN_EXECUTABLE,
|
||||
FS_MISSING_LIBRARY,
|
||||
FS_MISSING_SYMBOL,
|
||||
|
||||
FS_DEBUGGER_ALREADY_INSTALLED = FS_OS_ERROR_BASE + 0x400
|
||||
};
|
||||
|
||||
|
||||
// Storage Kit/File System Errors
|
||||
enum {
|
||||
FS_FILE_ERROR = FS_STORAGE_ERROR_BASE,
|
||||
FS_FILE_NOT_FOUND,
|
||||
FS_FILE_EXISTS,
|
||||
FS_ENTRY_NOT_FOUND,
|
||||
FS_NAME_TOO_LONG,
|
||||
FS_NOT_A_DIRECTORY,
|
||||
FS_DIRECTORY_NOT_EMPTY,
|
||||
FS_DEVICE_FULL,
|
||||
FS_READ_ONLY_DEVICE,
|
||||
FS_IS_A_DIRECTORY,
|
||||
FS_NO_MORE_FDS,
|
||||
FS_CROSS_DEVICE_LINK,
|
||||
FS_LINK_LIMIT,
|
||||
FS_BUSTED_PIPE,
|
||||
FS_UNSUPPORTED,
|
||||
FS_PARTITION_TOO_SMALL
|
||||
};
|
||||
|
||||
|
||||
// POSIX errors
|
||||
#define FS_E2BIG (FS_POSIX_ERROR_BASE + 1)
|
||||
#define FS_ECHILD (FS_POSIX_ERROR_BASE + 2)
|
||||
#define FS_EDEADLK (FS_POSIX_ERROR_BASE + 3)
|
||||
#define FS_EFBIG (FS_POSIX_ERROR_BASE + 4)
|
||||
#define FS_EMLINK (FS_POSIX_ERROR_BASE + 5)
|
||||
#define FS_ENFILE (FS_POSIX_ERROR_BASE + 6)
|
||||
#define FS_ENODEV (FS_POSIX_ERROR_BASE + 7)
|
||||
#define FS_ENOLCK (FS_POSIX_ERROR_BASE + 8)
|
||||
#define FS_ENOSYS (FS_POSIX_ERROR_BASE + 9)
|
||||
#define FS_ENOTTY (FS_POSIX_ERROR_BASE + 10)
|
||||
#define FS_ENXIO (FS_POSIX_ERROR_BASE + 11)
|
||||
#define FS_ESPIPE (FS_POSIX_ERROR_BASE + 12)
|
||||
#define FS_ESRCH (FS_POSIX_ERROR_BASE + 13)
|
||||
#define FS_EFPOS (FS_POSIX_ERROR_BASE + 14)
|
||||
#define FS_ESIGPARM (FS_POSIX_ERROR_BASE + 15)
|
||||
#define FS_EDOM (FS_POSIX_ERROR_BASE + 16)
|
||||
#define FS_ERANGE (FS_POSIX_ERROR_BASE + 17)
|
||||
#define FS_EPROTOTYPE (FS_POSIX_ERROR_BASE + 18)
|
||||
#define FS_EPROTONOSUPPORT (FS_POSIX_ERROR_BASE + 19)
|
||||
#define FS_EPFNOSUPPORT (FS_POSIX_ERROR_BASE + 20)
|
||||
#define FS_EAFNOSUPPORT (FS_POSIX_ERROR_BASE + 21)
|
||||
#define FS_EADDRINUSE (FS_POSIX_ERROR_BASE + 22)
|
||||
#define FS_EADDRNOTAVAIL (FS_POSIX_ERROR_BASE + 23)
|
||||
#define FS_ENETDOWN (FS_POSIX_ERROR_BASE + 24)
|
||||
#define FS_ENETUNREACH (FS_POSIX_ERROR_BASE + 25)
|
||||
#define FS_ENETRESET (FS_POSIX_ERROR_BASE + 26)
|
||||
#define FS_ECONNABORTED (FS_POSIX_ERROR_BASE + 27)
|
||||
#define FS_ECONNRESET (FS_POSIX_ERROR_BASE + 28)
|
||||
#define FS_EISCONN (FS_POSIX_ERROR_BASE + 29)
|
||||
#define FS_ENOTCONN (FS_POSIX_ERROR_BASE + 30)
|
||||
#define FS_ESHUTDOWN (FS_POSIX_ERROR_BASE + 31)
|
||||
#define FS_ECONNREFUSED (FS_POSIX_ERROR_BASE + 32)
|
||||
#define FS_EHOSTUNREACH (FS_POSIX_ERROR_BASE + 33)
|
||||
#define FS_ENOPROTOOPT (FS_POSIX_ERROR_BASE + 34)
|
||||
#define FS_ENOBUFS (FS_POSIX_ERROR_BASE + 35)
|
||||
#define FS_EINPROGRESS (FS_POSIX_ERROR_BASE + 36)
|
||||
#define FS_EALREADY (FS_POSIX_ERROR_BASE + 37)
|
||||
#define FS_EILSEQ (FS_POSIX_ERROR_BASE + 38)
|
||||
#define FS_ENOMSG (FS_POSIX_ERROR_BASE + 39)
|
||||
#define FS_ESTALE (FS_POSIX_ERROR_BASE + 40)
|
||||
#define FS_EOVERFLOW (FS_POSIX_ERROR_BASE + 41)
|
||||
#define FS_EMSGSIZE (FS_POSIX_ERROR_BASE + 42)
|
||||
#define FS_EOPNOTSUPP (FS_POSIX_ERROR_BASE + 43)
|
||||
#define FS_ENOTSOCK (FS_POSIX_ERROR_BASE + 44)
|
||||
#define FS_EHOSTDOWN (FS_POSIX_ERROR_BASE + 45)
|
||||
#define FS_EBADMSG (FS_POSIX_ERROR_BASE + 46)
|
||||
#define FS_ECANCELED (FS_POSIX_ERROR_BASE + 47)
|
||||
#define FS_EDESTADDRREQ (FS_POSIX_ERROR_BASE + 48)
|
||||
#define FS_EDQUOT (FS_POSIX_ERROR_BASE + 49)
|
||||
#define FS_EIDRM (FS_POSIX_ERROR_BASE + 50)
|
||||
#define FS_EMULTIHOP (FS_POSIX_ERROR_BASE + 51)
|
||||
#define FS_ENODATA (FS_POSIX_ERROR_BASE + 52)
|
||||
#define FS_ENOLINK (FS_POSIX_ERROR_BASE + 53)
|
||||
#define FS_ENOSR (FS_POSIX_ERROR_BASE + 54)
|
||||
#define FS_ENOSTR (FS_POSIX_ERROR_BASE + 55)
|
||||
#define FS_ENOTSUP (FS_POSIX_ERROR_BASE + 56)
|
||||
#define FS_EPROTO (FS_POSIX_ERROR_BASE + 57)
|
||||
#define FS_ETIME (FS_POSIX_ERROR_BASE + 58)
|
||||
#define FS_ETXTBSY (FS_POSIX_ERROR_BASE + 59)
|
||||
|
||||
#define FS_ENOMEM FS_NO_MEMORY
|
||||
#define FS_EACCES FS_PERMISSION_DENIED
|
||||
#define FS_EINTR FS_INTERRUPTED
|
||||
#define FS_EIO FS_IO_ERROR
|
||||
#define FS_EBUSY FS_BUSY
|
||||
#define FS_EFAULT FS_BAD_ADDRESS
|
||||
#define FS_ETIMEDOUT FS_TIMED_OUT
|
||||
#define FS_EAGAIN FS_WOULD_BLOCK
|
||||
#define FS_EWOULDBLOCK FS_WOULD_BLOCK
|
||||
#define FS_EBADF FS_FILE_ERROR
|
||||
#define FS_EEXIST FS_FILE_EXISTS
|
||||
#define FS_EINVAL FS_BAD_VALUE
|
||||
#define FS_ENAMETOOLONG FS_NAME_TOO_LONG
|
||||
#define FS_ENOENT FS_ENTRY_NOT_FOUND
|
||||
#define FS_EPERM FS_NOT_ALLOWED
|
||||
#define FS_ENOTDIR FS_NOT_A_DIRECTORY
|
||||
#define FS_EISDIR FS_IS_A_DIRECTORY
|
||||
#define FS_ENOTEMPTY FS_DIRECTORY_NOT_EMPTY
|
||||
#define FS_ENOSPC FS_DEVICE_FULL
|
||||
#define FS_EROFS FS_READ_ONLY_DEVICE
|
||||
#define FS_EMFILE FS_NO_MORE_FDS
|
||||
#define FS_EXDEV FS_CROSS_DEVICE_LINK
|
||||
#define FS_ELOOP FS_LINK_LIMIT
|
||||
#define FS_ENOEXEC FS_NOT_AN_EXECUTABLE
|
||||
#define FS_EPIPE FS_BUSTED_PIPE
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int from_platform_error(int error);
|
||||
int to_platform_error(int error);
|
||||
|
||||
const char *fs_strerror(int error);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FS_SHELL_ERRORS_H
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef FS_SHELL_EXTERNAL_COMMANDS_H
|
||||
#define FS_SHELL_EXTERNAL_COMMANDS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char *get_external_command(const char *prompt, char *input, int len);
|
||||
void reply_to_external_command(int result);
|
||||
void external_command_cleanup();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FS_SHELL_EXTERNAL_COMMANDS_H
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include "external_commands.h"
|
||||
#include "fs_shell_command_beos.h"
|
||||
|
||||
static port_id sReplyPort = -1;
|
||||
|
||||
static port_id
|
||||
get_command_port()
|
||||
{
|
||||
static port_id port = -1;
|
||||
static bool initialized = false;
|
||||
|
||||
if (!initialized) {
|
||||
port = create_port(10, kFSShellCommandPort);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
get_external_command(const char *prompt, char *input, int len)
|
||||
{
|
||||
// get/create the port
|
||||
port_id port = get_command_port();
|
||||
if (port < 0) {
|
||||
fprintf(stderr, "Failed to create command port: %s\n", strerror(port));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
while (true) {
|
||||
// read a message
|
||||
external_command_message message;
|
||||
ssize_t bytesRead;
|
||||
do {
|
||||
int32 code;
|
||||
bytesRead = read_port(port, &code, &message, sizeof(message));
|
||||
} while (bytesRead == B_INTERRUPTED);
|
||||
|
||||
if (bytesRead < 0) {
|
||||
fprintf(stderr, "Reading from port failed: %s\n",
|
||||
strerror(bytesRead));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// get the len of the command
|
||||
int commandLen = (char*)&message + bytesRead - message.command;
|
||||
if (commandLen <= 1) {
|
||||
fprintf(stderr, "No command given.\n");
|
||||
continue;
|
||||
}
|
||||
if (commandLen > len) {
|
||||
fprintf(stderr, "Command too long. Ignored.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// copy the command
|
||||
memcpy(input, message.command, commandLen);
|
||||
input[len - 1] = '\0'; // always NULL-terminate
|
||||
sReplyPort = message.reply_port;
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
reply_to_external_command(int result)
|
||||
{
|
||||
if (sReplyPort >= 0) {
|
||||
// prepare the message
|
||||
external_command_reply reply;
|
||||
reply.error = result;
|
||||
|
||||
// send the reply
|
||||
status_t error;
|
||||
do {
|
||||
error = write_port(sReplyPort, 0, &reply, sizeof(reply));
|
||||
} while (error == B_INTERRUPTED);
|
||||
sReplyPort = -1;
|
||||
|
||||
if (error != B_OK) {
|
||||
fprintf(stderr, "Failed to send command result to reply port: %s\n",
|
||||
strerror(error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
external_command_cleanup()
|
||||
{
|
||||
// The port will be deleted automatically when the team exits.
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "external_commands.h"
|
||||
#include "fs_shell_command_unix.h"
|
||||
|
||||
static int sClientConnection = -1;
|
||||
|
||||
static int
|
||||
get_command_socket()
|
||||
{
|
||||
static int fd = -1;
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
// get the listener socket
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
// bind it to the port
|
||||
sockaddr_un addr;
|
||||
unlink(kFSShellCommandSocketAddress);
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy(addr.sun_path, kFSShellCommandSocketAddress);
|
||||
int addrLen = addr.sun_path + strlen(addr.sun_path) + 1 - (char*)&addr;
|
||||
if (bind(fd, (sockaddr*)&addr, addrLen) < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// start listening
|
||||
if (listen(fd, 1) < 0) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_client_connection()
|
||||
{
|
||||
if (sClientConnection >= 0)
|
||||
return sClientConnection;
|
||||
|
||||
// get the listener socket
|
||||
int commandFD = get_command_socket();
|
||||
if (commandFD < 0)
|
||||
return -1;
|
||||
|
||||
// accept a connection
|
||||
do {
|
||||
sockaddr_un addr;
|
||||
socklen_t addrLen = sizeof(addr);
|
||||
sClientConnection = accept(commandFD, (sockaddr*)&addr, &addrLen);
|
||||
} while (sClientConnection < 0 && errno == EINTR);
|
||||
|
||||
return sClientConnection;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
close_client_connection()
|
||||
{
|
||||
if (sClientConnection >= 0) {
|
||||
close(sClientConnection);
|
||||
sClientConnection = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
get_external_command(const char *prompt, char *input, int len)
|
||||
{
|
||||
do {
|
||||
// get a connection
|
||||
int connection = get_client_connection();
|
||||
if (connection < 0)
|
||||
return NULL;
|
||||
|
||||
// read until we have a full command
|
||||
external_command_message message;
|
||||
int toRead = sizeof(message);
|
||||
char *buffer = (char*)&message;
|
||||
while (toRead > 0) {
|
||||
int bytesRead = read(connection, buffer, toRead);
|
||||
if (bytesRead < 0) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
} else {
|
||||
fprintf(stderr, "Reading from connection failed: %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// connection closed?
|
||||
if (bytesRead == 0)
|
||||
break;
|
||||
|
||||
buffer += bytesRead;
|
||||
toRead -= bytesRead;
|
||||
}
|
||||
|
||||
// connection may be broken: discard it
|
||||
if (toRead > 0) {
|
||||
close_client_connection();
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the len of the command
|
||||
message.command[sizeof(message.command) - 1] = '\0';
|
||||
int commandLen = strlen(message.command) + 1;
|
||||
if (commandLen <= 1) {
|
||||
fprintf(stderr, "No command given.\n");
|
||||
continue;
|
||||
}
|
||||
if (commandLen > len) {
|
||||
fprintf(stderr, "Command too long. Ignored.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// copy the command
|
||||
memcpy(input, message.command, commandLen);
|
||||
input[len - 1] = '\0'; // always NULL-terminate
|
||||
return input;
|
||||
|
||||
} while (true);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
reply_to_external_command(int result)
|
||||
{
|
||||
if (sClientConnection < 0)
|
||||
return;
|
||||
|
||||
// prepare the reply
|
||||
external_command_reply reply;
|
||||
reply.error = result;
|
||||
|
||||
// send the reply
|
||||
int toWrite = sizeof(reply);
|
||||
char *replyBuffer = (char*)&reply;
|
||||
ssize_t bytesWritten;
|
||||
do {
|
||||
bytesWritten = write(sClientConnection, replyBuffer, toWrite);
|
||||
if (bytesWritten > 0) {
|
||||
replyBuffer += bytesWritten;
|
||||
toWrite -= bytesWritten;
|
||||
}
|
||||
} while (toWrite > 0 && !(bytesWritten < 0 && errno != EINTR));
|
||||
|
||||
// connection may be broken: discard it
|
||||
if (bytesWritten < 0)
|
||||
close_client_connection();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
external_command_cleanup()
|
||||
{
|
||||
unlink(kFSShellCommandSocketAddress);
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fs_shell_command.h"
|
||||
|
||||
static void
|
||||
add_char(char *&buffer, int &bufferSize, char c)
|
||||
{
|
||||
if (bufferSize <= 0) {
|
||||
fprintf(stderr, "Command line too long\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
*buffer = c;
|
||||
buffer++;
|
||||
bufferSize--;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
prepare_command_string(const char *const *argv, int argc, char *buffer,
|
||||
int bufferSize)
|
||||
{
|
||||
for (int argi = 0; argi < argc; argi++) {
|
||||
const char *arg = argv[argi];
|
||||
|
||||
if (argi > 0)
|
||||
add_char(buffer, bufferSize, ' ');
|
||||
|
||||
while (*arg) {
|
||||
if (strchr(" ", *arg))
|
||||
add_char(buffer, bufferSize, '\\');
|
||||
add_char(buffer, bufferSize, *arg);
|
||||
arg++;
|
||||
}
|
||||
}
|
||||
|
||||
add_char(buffer, bufferSize, '\0');
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, const char *const *argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "No command given.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// prepare the command string
|
||||
char command[20480];
|
||||
prepare_command_string(argv + 1, argc - 1, command, sizeof(command));
|
||||
|
||||
// send the command
|
||||
int result;
|
||||
int error = send_external_command(command, &result);
|
||||
if (error != 0)
|
||||
exit(1);
|
||||
|
||||
// evaluate result
|
||||
if (result != 0) {
|
||||
fprintf(stderr, "Command failed: %s\n", strerror(result));
|
||||
fprintf(stderr, "Command was:\n %s\n", command);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef FS_SHELL_COMMAND_H
|
||||
#define FS_SHELL_COMMAND_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int send_external_command(const char *command, int *result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FS_SHELL_COMMAND_H
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include "fs_shell_command.h"
|
||||
#include "fs_shell_command_beos.h"
|
||||
|
||||
int
|
||||
send_external_command(const char *command, int *result)
|
||||
{
|
||||
external_command_message message;
|
||||
strncpy(message.command, command, sizeof(message.command));
|
||||
|
||||
// find the command port
|
||||
port_id commandPort = find_port(kFSShellCommandPort);
|
||||
if (commandPort < 0) {
|
||||
fprintf(stderr, "Couldn't find fs_shell command port.\n");
|
||||
return commandPort;
|
||||
}
|
||||
|
||||
// create a reply port
|
||||
port_id replyPort = create_port(1, "fs shell reply port");
|
||||
if (replyPort < 0) {
|
||||
fprintf(stderr, "Failed to create a reply port: %s\n",
|
||||
strerror(replyPort));
|
||||
return replyPort;
|
||||
}
|
||||
message.reply_port = replyPort;
|
||||
|
||||
// send the command message
|
||||
status_t error;
|
||||
do {
|
||||
error = write_port(commandPort, 0, &message, sizeof(message));
|
||||
} while (error == B_INTERRUPTED);
|
||||
|
||||
if (error != B_OK) {
|
||||
fprintf(stderr, "Failed to send command: %s\n", strerror(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
// wait for the reply
|
||||
external_command_reply reply;
|
||||
ssize_t bytesRead;
|
||||
do {
|
||||
int32 code;
|
||||
bytesRead = read_port(replyPort, &code, &reply, sizeof(reply));
|
||||
} while (bytesRead == B_INTERRUPTED);
|
||||
|
||||
if (bytesRead < 0) {
|
||||
fprintf(stderr, "Failed to read reply from fs_shell: %s\n",
|
||||
strerror(bytesRead));
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
*result = reply.error;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef FS_SHELL_COMMAND_BEOS_H
|
||||
#define FS_SHELL_COMMAND_BEOS_H
|
||||
|
||||
static const char *kFSShellCommandPort = "fs shell command port";
|
||||
|
||||
struct external_command_message {
|
||||
port_id reply_port;
|
||||
char command[20480];
|
||||
};
|
||||
|
||||
struct external_command_reply {
|
||||
int error;
|
||||
};
|
||||
|
||||
#endif // FS_SHELL_COMMAND_BEOS_H
|
@ -1,86 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "fs_shell_command.h"
|
||||
#include "fs_shell_command_unix.h"
|
||||
|
||||
int
|
||||
send_external_command(const char *command, int *result)
|
||||
{
|
||||
external_command_message message;
|
||||
strncpy(message.command, command, sizeof(message.command));
|
||||
|
||||
// create a socket
|
||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
return errno;
|
||||
|
||||
// connect to the fs_shell
|
||||
sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy(addr.sun_path, kFSShellCommandSocketAddress);
|
||||
int addrLen = addr.sun_path + strlen(addr.sun_path) + 1 - (char*)&addr;
|
||||
if (connect(fd, (sockaddr*)&addr, addrLen) < 0) {
|
||||
close(fd);
|
||||
return errno;
|
||||
}
|
||||
|
||||
// send the command message
|
||||
int toWrite = sizeof(message);
|
||||
const char *messageBuffer = (char*)&message;
|
||||
ssize_t bytesWritten;
|
||||
do {
|
||||
bytesWritten = write(fd, messageBuffer, toWrite);
|
||||
if (bytesWritten > 0) {
|
||||
messageBuffer += bytesWritten;
|
||||
toWrite -= bytesWritten;
|
||||
}
|
||||
} while (toWrite > 0 && !(bytesWritten < 0 && errno != EINTR));
|
||||
|
||||
// close connection on error
|
||||
if (bytesWritten < 0) {
|
||||
fprintf(stderr, "Writing to fs_shell failed: %s\n", strerror(errno));
|
||||
close(fd);
|
||||
return errno;
|
||||
}
|
||||
|
||||
// read the reply
|
||||
external_command_reply reply;
|
||||
int toRead = sizeof(reply);
|
||||
char *replyBuffer = (char*)&reply;
|
||||
while (toRead > 0) {
|
||||
int bytesRead = read(fd, replyBuffer, toRead);
|
||||
if (bytesRead < 0) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
} else {
|
||||
fprintf(stderr, "Failed to read reply from fs_shell: %s\n",
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
if (bytesRead == 0) {
|
||||
fprintf(stderr, "Unexpected end of fs_shell reply. Was still "
|
||||
"expecting %d bytes\n", toRead);
|
||||
return EPIPE;
|
||||
}
|
||||
|
||||
replyBuffer += bytesRead;
|
||||
toRead -= bytesRead;
|
||||
}
|
||||
|
||||
*result = reply.error;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef FS_SHELL_COMMAND_UNIX_H
|
||||
#define FS_SHELL_COMMAND_UNIX_H
|
||||
|
||||
static const char *kFSShellCommandSocketAddress = "/tmp/fs_shell_commands";
|
||||
|
||||
struct external_command_message {
|
||||
char command[20480];
|
||||
};
|
||||
|
||||
struct external_command_reply {
|
||||
int error;
|
||||
};
|
||||
|
||||
#endif // FS_SHELL_COMMAND_UNIX_H
|
File diff suppressed because it is too large
Load Diff
@ -1,259 +0,0 @@
|
||||
/*
|
||||
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#ifndef _FSPROTO_H
|
||||
#define _FSPROTO_H
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <OS.h>
|
||||
#include <NodeMonitor.h>
|
||||
#include <fs_attr.h>
|
||||
#include <fs_info.h>
|
||||
#include <BeBuild.h>
|
||||
#include <Drivers.h>
|
||||
|
||||
typedef my_dev_t nspace_id;
|
||||
typedef my_ino_t vnode_id;
|
||||
|
||||
/*
|
||||
* PUBLIC PART OF THE FILE SYSTEM PROTOCOL
|
||||
*/
|
||||
|
||||
#define WSTAT_MODE 0x0001
|
||||
#define WSTAT_UID 0x0002
|
||||
#define WSTAT_GID 0x0004
|
||||
#define WSTAT_SIZE 0x0008
|
||||
#define WSTAT_ATIME 0x0010
|
||||
#define WSTAT_MTIME 0x0020
|
||||
#define WSTAT_CRTIME 0x0040
|
||||
|
||||
#define WFSSTAT_NAME 0x0001
|
||||
|
||||
#define SELECT_READ 1
|
||||
#define SELECT_WRITE 2
|
||||
#define SELECT_EXCEPTION 3
|
||||
|
||||
// missing ioctl() call added
|
||||
#define IOCTL_FILE_UNCACHED_IO 10000
|
||||
#define IOCTL_CREATE_TIME 10002
|
||||
#define IOCTL_MODIFIED_TIME 10003
|
||||
|
||||
|
||||
// B_CUR_FS_API_VERSION is 2 for R5, but 3 on Dano, because of the
|
||||
// added calls for power management - so it's set to 3 here because
|
||||
// that's a requirement to let Dano boot from our fs...
|
||||
#ifdef B_BEOS_VERSION_DANO
|
||||
# define B_CUR_FS_API_VERSION 3
|
||||
#else
|
||||
# define B_CUR_FS_API_VERSION 2
|
||||
#endif
|
||||
|
||||
struct index_info;
|
||||
|
||||
typedef int op_read_vnode(void *ns, vnode_id vnid, char r, void **node);
|
||||
typedef int op_write_vnode(void *ns, void *node, char r);
|
||||
typedef int op_remove_vnode(void *ns, void *node, char r);
|
||||
typedef int op_secure_vnode(void *ns, void *node);
|
||||
typedef int op_wake_vnode(void *ns, void *node);
|
||||
typedef int op_suspend_vnode(void *ns, void *node);
|
||||
|
||||
typedef int op_walk(void *ns, void *base, const char *file, char **newpath,
|
||||
vnode_id *vnid);
|
||||
|
||||
typedef int op_access(void *ns, void *node, int mode);
|
||||
|
||||
typedef int op_create(void *ns, void *dir, const char *name,
|
||||
int omode, int perms, vnode_id *vnid, void **cookie);
|
||||
typedef int op_mkdir(void *ns, void *dir, const char *name, int perms);
|
||||
typedef int op_symlink(void *ns, void *dir, const char *name,
|
||||
const char *path);
|
||||
typedef int op_link(void *ns, void *dir, const char *name, void *node);
|
||||
|
||||
typedef int op_rename(void *ns, void *olddir, const char *oldname,
|
||||
void *newdir, const char *newname);
|
||||
typedef int op_unlink(void *ns, void *dir, const char *name);
|
||||
typedef int op_rmdir(void *ns, void *dir, const char *name);
|
||||
|
||||
typedef int op_readlink(void *ns, void *node, char *buf, size_t *bufsize);
|
||||
|
||||
typedef int op_opendir(void *ns, void *node, void **cookie);
|
||||
typedef int op_closedir(void *ns, void *node, void *cookie);
|
||||
typedef int op_rewinddir(void *ns, void *node, void *cookie);
|
||||
typedef int op_readdir(void *ns, void *node, void *cookie, long *num,
|
||||
struct my_dirent *buf, size_t bufsize);
|
||||
|
||||
typedef int op_open(void *ns, void *node, int omode, void **cookie);
|
||||
typedef int op_close(void *ns, void *node, void *cookie);
|
||||
typedef int op_free_cookie(void *ns, void *node, void *cookie);
|
||||
typedef int op_read(void *ns, void *node, void *cookie, fs_off_t pos, void *buf,
|
||||
size_t *len);
|
||||
typedef int op_write(void *ns, void *node, void *cookie, fs_off_t pos,
|
||||
const void *buf, size_t *len);
|
||||
typedef int op_readv(void *ns, void *node, void *cookie, fs_off_t pos, const iovec *vec,
|
||||
size_t count, size_t *len);
|
||||
typedef int op_writev(void *ns, void *node, void *cookie, fs_off_t pos, const iovec *vec,
|
||||
size_t count, size_t *len);
|
||||
typedef int op_ioctl(void *ns, void *node, void *cookie, int cmd, void *buf,
|
||||
size_t len);
|
||||
typedef int op_setflags(void *ns, void *node, void *cookie, int flags);
|
||||
|
||||
typedef int op_rstat(void *ns, void *node, struct my_stat *);
|
||||
typedef int op_wstat(void *ns, void *node, struct my_stat *, long mask);
|
||||
typedef int op_fsync(void *ns, void *node);
|
||||
|
||||
typedef int op_select(void *ns, void *node, void *cookie, uint8 event,
|
||||
uint32 ref, selectsync *sync);
|
||||
typedef int op_deselect(void *ns, void *node, void *cookie, uint8 event,
|
||||
selectsync *sync);
|
||||
|
||||
typedef int op_initialize(const char *devname, void *parms, size_t len);
|
||||
typedef int op_mount(nspace_id nsid, const char *devname, ulong flags,
|
||||
void *parms, size_t len, void **data, vnode_id *vnid);
|
||||
typedef int op_unmount(void *ns);
|
||||
typedef int op_sync(void *ns);
|
||||
typedef int op_rfsstat(void *ns, struct fs_info *);
|
||||
typedef int op_wfsstat(void *ns, struct fs_info *, long mask);
|
||||
|
||||
|
||||
typedef int op_open_attrdir(void *ns, void *node, void **cookie);
|
||||
typedef int op_close_attrdir(void *ns, void *node, void *cookie);
|
||||
typedef int op_rewind_attrdir(void *ns, void *node, void *cookie);
|
||||
typedef int op_read_attrdir(void *ns, void *node, void *cookie, long *num,
|
||||
struct my_dirent *buf, size_t bufsize);
|
||||
typedef int op_remove_attr(void *ns, void *node, const char *name);
|
||||
typedef int op_rename_attr(void *ns, void *node, const char *oldname,
|
||||
const char *newname);
|
||||
typedef int op_stat_attr(void *ns, void *node, const char *name,
|
||||
my_attr_info *buf);
|
||||
|
||||
typedef int op_write_attr(void *ns, void *node, const char *name, int type,
|
||||
const void *buf, size_t *len, fs_off_t pos);
|
||||
typedef int op_read_attr(void *ns, void *node, const char *name, int type,
|
||||
void *buf, size_t *len, fs_off_t pos);
|
||||
|
||||
typedef int op_open_indexdir(void *ns, void **cookie);
|
||||
typedef int op_close_indexdir(void *ns, void *cookie);
|
||||
typedef int op_rewind_indexdir(void *ns, void *cookie);
|
||||
typedef int op_read_indexdir(void *ns, void *cookie, long *num,
|
||||
struct my_dirent *buf, size_t bufsize);
|
||||
typedef int op_create_index(void *ns, const char *name, int type, int flags);
|
||||
typedef int op_remove_index(void *ns, const char *name);
|
||||
typedef int op_rename_index(void *ns, const char *oldname,
|
||||
const char *newname);
|
||||
typedef int op_stat_index(void *ns, const char *name, struct index_info *buf);
|
||||
|
||||
typedef int op_open_query(void *ns, const char *query, ulong flags,
|
||||
port_id port, long token, void **cookie);
|
||||
typedef int op_close_query(void *ns, void *cookie);
|
||||
typedef int op_read_query(void *ns, void *cookie, long *num,
|
||||
struct my_dirent *buf, size_t bufsize);
|
||||
|
||||
typedef struct vnode_ops {
|
||||
op_read_vnode (*read_vnode);
|
||||
op_write_vnode (*write_vnode);
|
||||
op_remove_vnode (*remove_vnode);
|
||||
op_secure_vnode (*secure_vnode);
|
||||
op_walk (*walk);
|
||||
op_access (*access);
|
||||
op_create (*create);
|
||||
op_mkdir (*mkdir);
|
||||
op_symlink (*symlink);
|
||||
op_link (*link);
|
||||
op_rename (*rename);
|
||||
op_unlink (*unlink);
|
||||
op_rmdir (*rmdir);
|
||||
op_readlink (*readlink);
|
||||
op_opendir (*opendir);
|
||||
op_closedir (*closedir);
|
||||
op_free_cookie (*free_dircookie);
|
||||
op_rewinddir (*rewinddir);
|
||||
op_readdir (*readdir);
|
||||
op_open (*open);
|
||||
op_close (*close);
|
||||
op_free_cookie (*free_cookie);
|
||||
op_read (*read);
|
||||
op_write (*write);
|
||||
op_readv (*readv);
|
||||
op_writev (*writev);
|
||||
op_ioctl (*ioctl);
|
||||
op_setflags (*setflags);
|
||||
op_rstat (*rstat);
|
||||
op_wstat (*wstat);
|
||||
op_fsync (*fsync);
|
||||
op_initialize (*initialize);
|
||||
op_mount (*mount);
|
||||
op_unmount (*unmount);
|
||||
op_sync (*sync);
|
||||
op_rfsstat (*rfsstat);
|
||||
op_wfsstat (*wfsstat);
|
||||
op_select (*select);
|
||||
op_deselect (*deselect);
|
||||
op_open_indexdir (*open_indexdir);
|
||||
op_close_indexdir (*close_indexdir);
|
||||
op_free_cookie (*free_indexdircookie);
|
||||
op_rewind_indexdir (*rewind_indexdir);
|
||||
op_read_indexdir (*read_indexdir);
|
||||
op_create_index (*create_index);
|
||||
op_remove_index (*remove_index);
|
||||
op_rename_index (*rename_index);
|
||||
op_stat_index (*stat_index);
|
||||
op_open_attrdir (*open_attrdir);
|
||||
op_close_attrdir (*close_attrdir);
|
||||
op_free_cookie (*free_attrdircookie);
|
||||
op_rewind_attrdir (*rewind_attrdir);
|
||||
op_read_attrdir (*read_attrdir);
|
||||
op_write_attr (*write_attr);
|
||||
op_read_attr (*read_attr);
|
||||
op_remove_attr (*remove_attr);
|
||||
op_rename_attr (*rename_attr);
|
||||
op_stat_attr (*stat_attr);
|
||||
op_open_query (*open_query);
|
||||
op_close_query (*close_query);
|
||||
op_free_cookie (*free_querycookie);
|
||||
op_read_query (*read_query);
|
||||
// for Dano compatibility only
|
||||
op_wake_vnode (*wake_vnode);
|
||||
op_suspend_vnode (*suspend_vnode);
|
||||
} vnode_ops;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern _IMPEXP_KERNEL int new_path(const char *path, char **copy);
|
||||
extern _IMPEXP_KERNEL void free_path(char *p);
|
||||
|
||||
extern _IMPEXP_KERNEL status_t notify_listener(int op, nspace_id nsid,
|
||||
vnode_id vnida, vnode_id vnidb,
|
||||
vnode_id vnidc, const char *name);
|
||||
// extern _IMPEXP_KERNEL void notify_select_event(selectsync *sync, uint32 ref);
|
||||
extern _IMPEXP_KERNEL status_t send_notification(port_id port, long token,
|
||||
ulong what, long op, nspace_id nsida,
|
||||
nspace_id nsidb, vnode_id vnida,
|
||||
vnode_id vnidb, vnode_id vnidc,
|
||||
const char *name);
|
||||
extern _IMPEXP_KERNEL status_t get_vnode(nspace_id nsid, vnode_id vnid, void **data);
|
||||
extern _IMPEXP_KERNEL status_t put_vnode(nspace_id nsid, vnode_id vnid);
|
||||
extern _IMPEXP_KERNEL status_t new_vnode(nspace_id nsid, vnode_id vnid, void *data);
|
||||
extern _IMPEXP_KERNEL status_t remove_vnode(nspace_id nsid, vnode_id vnid);
|
||||
extern _IMPEXP_KERNEL status_t unremove_vnode(nspace_id nsid, vnode_id vnid);
|
||||
extern _IMPEXP_KERNEL status_t is_vnode_removed(nspace_id nsid, vnode_id vnid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
extern _EXPORT vnode_ops fs_entry;
|
||||
extern _EXPORT int32 api_version;
|
||||
|
||||
#endif
|
@ -1,125 +0,0 @@
|
||||
/*
|
||||
This file contains a simple hex dump routine.
|
||||
|
||||
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
|
||||
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
|
||||
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
|
||||
|
||||
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
|
||||
|
||||
Dominic Giampaolo
|
||||
dbg@be.com
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
/*
|
||||
* This routine is a simple memory dumper. It's nice and simple, and works
|
||||
* well.
|
||||
*
|
||||
* The bad things about it are that it assumes roughly an 80 column output
|
||||
* device and that output is fixed at BYTES_PER_LINE/2 columns (separated
|
||||
* every two bytes).
|
||||
*
|
||||
* Obviously the bad things are fixable, but I don't need the extra
|
||||
* flexibility at the moment, so I don't feel like doing it.
|
||||
*
|
||||
* Dominic Giampaolo
|
||||
* (dbg@be.com)
|
||||
*/
|
||||
|
||||
#define BYTES_PER_LINE 16 /* a reasonable power of two */
|
||||
|
||||
|
||||
void hexdump(void *address, int size)
|
||||
{
|
||||
int i;
|
||||
int offset, num_spaces;
|
||||
unsigned char *mem, *tmp;
|
||||
|
||||
|
||||
offset = 0;
|
||||
mem = (unsigned char *)address;
|
||||
|
||||
/*
|
||||
* Each line contains BYTES_PER_LINE bytes of data (presently 16). I
|
||||
* chose 16 because it is a nice power of two and makes reading the
|
||||
* hex offset column much easier. I used to use a value of 18 to fit
|
||||
* more info on the screen, and 20 is also doable but much too crowded.
|
||||
* Ideally it should be an argument or settable parameter...
|
||||
*
|
||||
* The data is formatted into BYTES_PER_LINE/2 (8) columns of 2 bytes
|
||||
* each (printed in hex).
|
||||
*
|
||||
* The offset is formatted as a 4 byte hex number (i.e. 8 characters).
|
||||
*/
|
||||
while(offset < size)
|
||||
{
|
||||
printf("%.8x: ", offset);
|
||||
|
||||
for(i=0,tmp=mem; i < BYTES_PER_LINE && (offset+i) < size; i++,tmp++)
|
||||
{
|
||||
printf("%.2x", *tmp);
|
||||
if (((i+1) % 4) == 0)
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
/*
|
||||
* This formula for the number of spaces to print is as follows:
|
||||
* 10 is the number of characters printed at the beginning of
|
||||
* the line (8 hex digits, the colon and a space).
|
||||
* i*2 is the number of characters of data we dumped in hex.
|
||||
* i/2 is the number of blanks we printed between columns.
|
||||
* i is the number of bytes we will print in ascii.
|
||||
*
|
||||
* Then we subtract all that from 74 (the width of the output
|
||||
* device) to decide how many spaces we need to push the ascii
|
||||
* column as far to the right as possible.
|
||||
*
|
||||
* The number 58 is the column where we start we start printing
|
||||
* the ascii dump. We subtract how many characters we've already
|
||||
* printed and that gets us to where we need to be to start the
|
||||
* ascii portion of the dump.
|
||||
*
|
||||
*/
|
||||
num_spaces = 58 - (12 + i*2 + i/4);
|
||||
for(i=0; i < num_spaces; i++)
|
||||
printf(" ");
|
||||
|
||||
for(i=0,tmp=mem; i < BYTES_PER_LINE && (offset+i) < size; i++, tmp++)
|
||||
if (isprint(*tmp))
|
||||
printf("%c", *tmp);
|
||||
else
|
||||
printf(".");
|
||||
|
||||
printf("\n");
|
||||
|
||||
offset += BYTES_PER_LINE;
|
||||
mem = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
|
||||
char buff[] = "!blah, blah blah blah blah asldfj lkasjdf lka lkjasdflasdlj"
|
||||
"asdj lasdfj lasdjf lasdjf lkasjdfl kjasdlf jasldfj lasdfj l"
|
||||
"asdjflkasjdflk;ja sdfljasdfjk asjkfl;kasjfl;asjdfl;azzzzzzz";
|
||||
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i,j,k;
|
||||
FILE *fp;
|
||||
|
||||
hexdump(buff, 171);
|
||||
|
||||
printf("---------\n");
|
||||
|
||||
hexdump(main, 57);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
This file contains some glue code that initializes the block cache,
|
||||
the vnode layer, mounts the root file system (a simple container)
|
||||
and then mounts our file system at the mount point /myfs. You could
|
||||
modify this to mount other file systems or even multiple file systems
|
||||
if you wanted.
|
||||
|
||||
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
|
||||
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
|
||||
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
|
||||
|
||||
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
|
||||
|
||||
Dominic Giampaolo
|
||||
dbg@be.com
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "compat.h"
|
||||
#include "kprotos.h"
|
||||
#include "fsproto.h"
|
||||
|
||||
|
||||
extern vnode_ops fs_entry;
|
||||
|
||||
void *
|
||||
init_fs(char *disk_name)
|
||||
{
|
||||
int err;
|
||||
void *data = NULL;
|
||||
|
||||
init_block_cache(16348, 0);
|
||||
init_vnode_layer();
|
||||
|
||||
err = sys_mkdir(1, -1, "/myfs", 0);
|
||||
|
||||
if (install_file_system(&fs_entry, "myfs", 1, -1) == NULL) {
|
||||
printf("can't install my file system\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
data = sys_mount(1, "myfs", -1, "/myfs", disk_name, 0, NULL, 0);
|
||||
if (data == NULL) {
|
||||
printf("could not mount %s on /myfs\n", disk_name);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
err = sys_chdir(1, -1, "/myfs");
|
||||
if (err != 0) {
|
||||
printf("Failed to cd into /myfs.");
|
||||
sys_unmount(1, -1, "/myfs");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
status_t
|
||||
initialize_fs(const char *deviceName, void *params, int paramLength)
|
||||
{
|
||||
status_t error;
|
||||
|
||||
init_block_cache(16348, 0);
|
||||
init_vnode_layer();
|
||||
|
||||
if (install_file_system(&fs_entry, "myfs", 1, -1) == NULL) {
|
||||
fprintf(stderr, "can't install my file system\n");
|
||||
return FS_ERROR;
|
||||
}
|
||||
|
||||
error = initialize_file_system(deviceName, "myfs", params, paramLength);
|
||||
if (error < FS_OK) {
|
||||
fprintf(stderr, "Initializing the file system failed: %s\n",
|
||||
strerror(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
shutdown_block_cache();
|
||||
|
||||
return FS_OK;
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
void *init_fs(char *disk_name);
|
||||
status_t initialize_fs(const char *deviceName, void *params, int paramLength);
|
File diff suppressed because it is too large
Load Diff
@ -1,85 +0,0 @@
|
||||
#ifndef KPROTOS_H
|
||||
#define KPROTOS_H
|
||||
|
||||
#include "compat.h"
|
||||
#include "myfs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int sys_symlink(int kernel, const char *oldpath, int nfd,
|
||||
const char *newpath);
|
||||
ssize_t sys_readlink(int kernel, int fd, const char *path, char *buf,
|
||||
size_t bufsize);
|
||||
int sys_mkdir(int kernel, int fd, const char *path, int perms);
|
||||
int sys_open(int kernel, int fd, const char *path, int omode,
|
||||
int perms, int coe);
|
||||
int sys_open_entry_ref(int kernel, nspace_id device, vnode_id parent,
|
||||
const char *name, int openMode, int coe);
|
||||
int sys_close(int kernel, int fd);
|
||||
fs_off_t sys_lseek(int kernel, int fd, fs_off_t pos, int whence);
|
||||
ssize_t sys_read(int kernel, int fd, void *buf, size_t len);
|
||||
ssize_t sys_write(int kernel, int fd, const void *buf, size_t len);
|
||||
int sys_unlink(int kernel, int fd, const char *path);
|
||||
int sys_link(int kernel, int ofd, const char *oldpath, int nfd,
|
||||
const char *newpath);
|
||||
int sys_rmdir(int kernel, int fd, const char *path);
|
||||
int sys_rename(int glb, int fd, const char *oldpath,
|
||||
int nfd, const char *newpath);
|
||||
void *sys_mount(int kernel, const char *filesystem, int fd,
|
||||
const char *where, const char *device, ulong flags,
|
||||
void *parms, size_t len);
|
||||
int sys_unmount(int kernel, int fd, const char *where);
|
||||
int sys_write_fs_info(int kernel, dev_t device, struct fs_info *info, int mask);
|
||||
int sys_rstat(int kernel, int fd, const char *path, struct my_stat *st,
|
||||
int eatlink);
|
||||
int sys_wstat(int kernel, int fd, const char *path, struct my_stat *st,
|
||||
long mask, int eatlink);
|
||||
int sys_ioctl(int kernel, int fd, int cmd, void *arg, size_t sz);
|
||||
|
||||
int sys_opendir(int kernel, int fd, const char *path, int coe);
|
||||
int sys_readdir(int kernel, int fd, struct my_dirent *buf, size_t bufsize,
|
||||
long count);
|
||||
int sys_rewinddir(int kernel, int fd);
|
||||
int sys_closedir(int kernel, int fd);
|
||||
int sys_chdir(int kernel, int fd, const char *path);
|
||||
int sys_access(int kernel, int fd, const char *path, int mode);
|
||||
|
||||
int sys_sync(void);
|
||||
|
||||
int sys_open_attr_dir(int kernel, int fd, const char *path);
|
||||
ssize_t sys_read_attr(int kernel, int fd, const char *name, int type,
|
||||
void *buffer, size_t len, off_t pos);
|
||||
ssize_t sys_write_attr(int kernel, int fd, const char *name, int type,
|
||||
const void *buffer, size_t len, off_t pos);
|
||||
ssize_t sys_remove_attr(int kernel, int fd, const char *name);
|
||||
int sys_stat_attr(int kernel, int fd, const char *path, const char *name,
|
||||
my_attr_info *info);
|
||||
|
||||
int sys_mkindex(int kernel, dev_t device, const char *index, int type, int flags);
|
||||
|
||||
int sys_open_query(int kernel, int fd, const char *path, const char *query, ulong flags, port_id port, ulong token, void **cookie);
|
||||
int sys_close_query(int kernel, int fd, const char *path, void *cookie);
|
||||
int sys_read_query(int kernel, int fd, const char *path, void *cookie, struct my_dirent *dent,size_t bufferSize,long num);
|
||||
|
||||
struct nspace;
|
||||
struct fsystem;
|
||||
void kill_device_vnodes(dev_t id);
|
||||
struct nspace *allocate_nspace(void);
|
||||
void remove_nspace(struct nspace *);
|
||||
status_t add_nspace(struct nspace *, struct fsystem *, const char *fileSystem, dev_t, ino_t);
|
||||
// for initialize() hack use only :)
|
||||
|
||||
int init_vnode_layer(void);
|
||||
void *install_file_system(vnode_ops *ops, const char *name,
|
||||
int fixed, image_id aid);
|
||||
|
||||
status_t initialize_file_system(const char *device, const char *fs,
|
||||
void *params, int paramLength);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KPROTOS_H */
|
@ -1,37 +0,0 @@
|
||||
#ifndef _LOCK_H
|
||||
#define _LOCK_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
//# define lock fsh_lock
|
||||
#endif
|
||||
|
||||
typedef struct lock lock;
|
||||
typedef struct mlock mlock;
|
||||
|
||||
struct lock {
|
||||
sem_id s;
|
||||
long c;
|
||||
};
|
||||
|
||||
struct mlock {
|
||||
sem_id s;
|
||||
};
|
||||
|
||||
extern int new_lock(lock *l, const char *name);
|
||||
extern int free_lock(lock *l);
|
||||
|
||||
#define LOCK(l) if (atomic_add(&l.c, -1) <= 0) acquire_sem(l.s);
|
||||
#define UNLOCK(l) if (atomic_add(&l.c, 1) < 0) release_sem(l.s);
|
||||
|
||||
extern int new_mlock(mlock *l, long c, const char *name);
|
||||
extern int free_mlock(mlock *l);
|
||||
|
||||
#define LOCKM(l,cnt) acquire_sem_etc(l.s, cnt, 0, 0.0)
|
||||
#define UNLOCKM(l,cnt) release_sem_etc(l.s, cnt, 0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LOCK_H */
|
@ -1,65 +0,0 @@
|
||||
TARGETS = fsh tstfs
|
||||
|
||||
all : $(TARGETS)
|
||||
|
||||
zip:
|
||||
zip -y obfs-fskit-`date +%Y-%m-%d`.zip *.[ch]* makefile
|
||||
|
||||
#
|
||||
# change the -O7 to -O3 if your compiler doesn't grok -O7
|
||||
#
|
||||
DEFINES = -DUSER=1 -DDEBUG=1
|
||||
CFLAGS = -D_NO_INLINE_ASM -O0 -g -fno-exceptions -fno-rtti -I. -fcheck-memory-usage
|
||||
LDFLAGS = #-p
|
||||
|
||||
SUPPORT_OBJS = rootfs.o initfs.o kernel.o cache.o sl.o stub.o
|
||||
MISC_OBJS = sysdep.o hexdump.o argv.o
|
||||
|
||||
FS_OBJS = Volume.o BPlusTree.o Inode.o Index.o Query.o Journal.o \
|
||||
BlockAllocator.o kernel_interface.o Utility.o Debug.o BufferPool.o cpp.o
|
||||
|
||||
|
||||
fsh : fsh.o $(FS_OBJS) $(SUPPORT_OBJS) $(MISC_OBJS)
|
||||
cc $(LDFLAGS) -o $@ fsh.o $(FS_OBJS) $(SUPPORT_OBJS) $(MISC_OBJS)
|
||||
|
||||
tstfs : tstfs.o $(FS_OBJS) $(SUPPORT_OBJS) $(MISC_OBJS)
|
||||
cc $(LDFLAGS) -o $@ tstfs.o $(FS_OBJS) $(SUPPORT_OBJS) $(MISC_OBJS)
|
||||
|
||||
makefs : makefs.o $(FS_OBJS) $(SUPPORT_OBJS) $(MISC_OBJS)
|
||||
cc $(LDFLAGS) -o $@ makefs.o $(FS_OBJS) $(SUPPORT_OBJS) $(MISC_OBJS)
|
||||
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(DEFINES) $(CFLAGS) -o $@ $<
|
||||
|
||||
.cpp.o:
|
||||
$(CC) -c $(DEFINES) $(CFLAGS) -o $@ $<
|
||||
|
||||
|
||||
#makefs.o : makefs.c bfs.h
|
||||
fsh.o : fsh.c bfs.h
|
||||
tstfs.o : tstfs.c bfs.h
|
||||
|
||||
|
||||
# mount.o : mount.c myfs.h
|
||||
# journal.o : journal.c myfs.h
|
||||
# bitmap.o : bitmap.c myfs.h
|
||||
# inode.o : inode.c myfs.h
|
||||
# dstream.o : dstream.c myfs.h
|
||||
# dir.o : dir.c myfs.h
|
||||
# file.o : file.c myfs.h
|
||||
# bitvector.o : bitvector.c bitvector.h
|
||||
# util.o : util.c myfs.h
|
||||
#
|
||||
bfs.h : compat.h cache.h lock.h fsproto.h
|
||||
|
||||
sysdep.o : sysdep.c compat.h
|
||||
kernel.o : kernel.c compat.h fsproto.h kprotos.h
|
||||
rootfs.o : compat.h fsproto.h
|
||||
initfs.o : initfs.c compat.h fsproto.h
|
||||
sl.o : sl.c skiplist.h
|
||||
cache.o : cache.c cache.h compat.h
|
||||
stub.o : stub.c compat.h
|
||||
|
||||
clean:
|
||||
rm -f *.o $(TARGETS)
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
This file contains the code that will call the initialization routine
|
||||
for a file system (which in turn will initialize the file system). It
|
||||
also has to do a few other housekeeping chores to make sure that the
|
||||
file system is unmounted properly and all that.
|
||||
|
||||
|
||||
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
|
||||
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
|
||||
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
|
||||
|
||||
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
|
||||
|
||||
Dominic Giampaolo
|
||||
dbg@be.com
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "myfs.h"
|
||||
#include "kprotos.h"
|
||||
|
||||
|
||||
static int
|
||||
get_value(char *str)
|
||||
{
|
||||
char buff[128];
|
||||
|
||||
printf("%s: ", str); fflush(stdout);
|
||||
fgets(buff, sizeof(buff), stdin);
|
||||
|
||||
return strtol(buff, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int block_size = 1024, i;
|
||||
char *disk_name = "big_file";
|
||||
char *volume_name = "untitled";
|
||||
myfs_info *myfs;
|
||||
|
||||
for (i=1; i < argc; i++) {
|
||||
if (isdigit(argv[i][0])) {
|
||||
block_size = strtoul(argv[i], NULL, 0);
|
||||
} else if (disk_name == NULL) {
|
||||
disk_name = argv[i];
|
||||
} else {
|
||||
volume_name = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (disk_name == NULL) {
|
||||
fprintf(stderr, "makefs error: you must specify a file name that\n");
|
||||
fprintf(stderr, " will contain the file systemn");
|
||||
exit(5);
|
||||
}
|
||||
|
||||
init_block_cache(256, 0);
|
||||
|
||||
myfs = myfs_create_fs(disk_name, volume_name, block_size, NULL);
|
||||
if (myfs != NULL)
|
||||
printf("MYFS w/%d byte blocks successfully created on %s as %s\n",
|
||||
block_size, disk_name, volume_name);
|
||||
else {
|
||||
printf("!HOLA! FAILED to create a MYFS file system on %s\n", disk_name);
|
||||
exit(5);
|
||||
}
|
||||
|
||||
myfs_unmount(myfs);
|
||||
|
||||
shutdown_block_cache();
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,416 +0,0 @@
|
||||
/*
|
||||
This file contains the code that will create a file system, mount
|
||||
a file system and unmount a file system.
|
||||
|
||||
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
|
||||
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
|
||||
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
|
||||
|
||||
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
|
||||
|
||||
Dominic Giampaolo
|
||||
dbg@be.com
|
||||
*/
|
||||
#include "myfs.h"
|
||||
|
||||
|
||||
#ifndef min_c
|
||||
#define min_c(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#endif /* min_c */
|
||||
|
||||
|
||||
|
||||
myfs_info *
|
||||
myfs_create_fs(char *device, char *name, int block_size, char *opts)
|
||||
{
|
||||
int dev_block_size, bshift, warned = 0;
|
||||
char *ptr;
|
||||
fs_off_t num_dev_blocks;
|
||||
myfs_info *myfs;
|
||||
|
||||
if ((block_size % sizeof(myfs_inode)) != 0) {
|
||||
printf("ERROR: inode size %d is not an even divisor of the block "
|
||||
"size %d\n", sizeof(myfs_inode), block_size);
|
||||
printf(" check myfs.h for more details and info.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (name == NULL)
|
||||
name = "untitled";
|
||||
|
||||
for(ptr=name; *ptr; ptr++) {
|
||||
if (*ptr == '/') {
|
||||
if (warned == 0) {
|
||||
fprintf(stderr, "Volume name: %s contains the '/' character. "
|
||||
"They are being converted to '-' for safety.\n", name);
|
||||
warned = 1;
|
||||
}
|
||||
*ptr = '-';
|
||||
}
|
||||
}
|
||||
|
||||
if (block_size < 512) {
|
||||
printf("minimum block size is 512 bytes\n");
|
||||
block_size = 512;
|
||||
}
|
||||
|
||||
for(bshift=0; bshift < sizeof(int)*8; bshift++)
|
||||
if ((1 << bshift) == block_size)
|
||||
break;
|
||||
|
||||
if (bshift >= sizeof(int)*8) {
|
||||
printf("block_size %d is not a power of two!\n", block_size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
myfs = (myfs_info *)calloc(1, sizeof(myfs_info));
|
||||
if (myfs == NULL) {
|
||||
printf("can't allocate mem for myfs_info struct\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
myfs->fd = -1;
|
||||
|
||||
myfs->nsid = (nspace_id)myfs; /* we can only do this when creating */
|
||||
|
||||
myfs->dsb.magic1 = SUPER_BLOCK_MAGIC1;
|
||||
myfs->dsb.magic2 = SUPER_BLOCK_MAGIC2;
|
||||
myfs->dsb.magic3 = SUPER_BLOCK_MAGIC3;
|
||||
myfs->dsb.fs_byte_order = MYFS_BIG_ENDIAN; /* checked when mounting */
|
||||
|
||||
myfs->sem = create_sem(MAX_READERS, "myfs_sem");
|
||||
if (myfs->sem < 0) {
|
||||
printf("can't create semaphore!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
myfs->fd = open(device, O_RDWR);
|
||||
if (myfs->fd < 0) {
|
||||
printf("can't open device %s\n", device);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dev_block_size = get_device_block_size(myfs->fd);
|
||||
num_dev_blocks = get_num_device_blocks(myfs->fd);
|
||||
if (block_size < dev_block_size) {
|
||||
printf("warning: fs block size too small, set to device block size %d\n",
|
||||
dev_block_size);
|
||||
block_size = dev_block_size;
|
||||
}
|
||||
|
||||
if ((block_size % dev_block_size) != 0) {
|
||||
printf("error: block size %d is not an even multiple of ",
|
||||
block_size);
|
||||
printf("device block size %d\n", dev_block_size);
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
myfs->dsb.block_size = block_size;
|
||||
myfs->dsb.block_shift = bshift;
|
||||
myfs->dev_block_conversion = block_size / dev_block_size;
|
||||
myfs->dev_block_size = dev_block_size;
|
||||
myfs->dsb.num_blocks = num_dev_blocks / myfs->dev_block_conversion;
|
||||
|
||||
init_cache_for_device(myfs->fd, num_dev_blocks / myfs->dev_block_conversion);
|
||||
|
||||
|
||||
if (init_tmp_blocks(myfs) != 0) {
|
||||
printf("init_tmp_blocks failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (myfs_create_storage_map(myfs) != 0) {
|
||||
printf("create storage map failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (myfs_create_inodes(myfs) != 0) {
|
||||
printf("create inodes failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (myfs_create_journal(myfs) != 0) {
|
||||
printf("create journal failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (myfs_create_root_dir(myfs) != 0) {
|
||||
printf("create root dir failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
strncpy(myfs->dsb.name, name,
|
||||
min_c(sizeof(myfs->dsb.name) - 1, strlen(name)));
|
||||
|
||||
/* now it's finally safe to write this */
|
||||
if (write_super_block(myfs) != 0) {
|
||||
printf("creating superblock failed\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return myfs;
|
||||
|
||||
|
||||
cleanup:
|
||||
if (myfs) {
|
||||
/* making the file system failed so make sure block zero is bogus */
|
||||
if (myfs->fd >= 0) {
|
||||
static char block[4096];
|
||||
|
||||
memset(block, 0xff, sizeof(block));
|
||||
write_blocks(myfs, 0, block, 1);
|
||||
}
|
||||
|
||||
myfs_shutdown_storage_map(myfs);
|
||||
myfs_shutdown_inodes(myfs);
|
||||
myfs_shutdown_journal(myfs);
|
||||
shutdown_tmp_blocks(myfs);
|
||||
|
||||
close(myfs->fd);
|
||||
|
||||
delete_sem(myfs->sem);
|
||||
|
||||
free(myfs);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
super_block_is_sane(myfs_info *myfs)
|
||||
{
|
||||
fs_off_t num_dev_blocks;
|
||||
int block_size;
|
||||
|
||||
if (myfs->dsb.magic1 != SUPER_BLOCK_MAGIC1 ||
|
||||
myfs->dsb.magic2 != SUPER_BLOCK_MAGIC2 ||
|
||||
myfs->dsb.magic3 != SUPER_BLOCK_MAGIC3) {
|
||||
|
||||
printf("warning: superblock magic numbers are wrong:\n");
|
||||
printf("0x%x (0x%x) 0x%x (0x%x) 0x%x (0x%x)\n",
|
||||
myfs->dsb.magic1, SUPER_BLOCK_MAGIC1,
|
||||
myfs->dsb.magic2, SUPER_BLOCK_MAGIC2,
|
||||
myfs->dsb.magic3, SUPER_BLOCK_MAGIC3);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
if ((myfs->dsb.block_size % myfs->dev_block_size) != 0) {
|
||||
printf("warning: fs block size %d not a multiple of ",
|
||||
myfs->dsb.block_size);
|
||||
printf(" device block size %d\n", myfs->dev_block_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
block_size = get_device_block_size(myfs->fd);
|
||||
if (block_size == 0) {
|
||||
printf("warning: could not fetch block size\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* make sure that the partition is as big as the superblock
|
||||
says it is */
|
||||
num_dev_blocks = get_num_device_blocks(myfs->fd);
|
||||
if (myfs->dsb.num_blocks * myfs->dsb.block_size >
|
||||
num_dev_blocks * block_size) {
|
||||
printf("warning: fs blocks %lx larger than device blocks %lx\n",
|
||||
myfs->dsb.num_blocks * (myfs->dsb.block_size/block_size),
|
||||
num_dev_blocks);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (myfs->dsb.block_size != (1 << myfs->dsb.block_shift)) {
|
||||
int i;
|
||||
|
||||
printf("warning: block_shift %d does not match block size %d\n",
|
||||
myfs->dsb.block_shift, myfs->dsb.block_size);
|
||||
|
||||
if (myfs->dsb.block_shift > 8 && myfs->dsb.block_shift < 16) {
|
||||
printf("setting block_size to %d\n", (1 << myfs->dsb.block_shift));
|
||||
myfs->dsb.block_size = (1 << myfs->dsb.block_shift);
|
||||
} else {
|
||||
for(i=0; i < sizeof(int) * 8; i++)
|
||||
if ((1 << i) == myfs->dsb.block_size)
|
||||
break;
|
||||
|
||||
if (i >= sizeof(int) * 8 || i > 16) {
|
||||
printf("neither block_size nor block_shift make sense!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
myfs->dsb.block_shift = i;
|
||||
printf("setting block_shift to %d\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
myfs_mount(nspace_id nsid, const char *device, ulong flags,
|
||||
void *parms, size_t len, void **data, vnode_id *vnid)
|
||||
{
|
||||
int ret = 0, oflags = O_RDWR;
|
||||
char buff[128];
|
||||
myfs_info *myfs;
|
||||
|
||||
myfs = (myfs_info *)calloc(1, sizeof(myfs_info));
|
||||
if (myfs == NULL) {
|
||||
printf("no memory for myfs structure!\n");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
myfs->nsid = nsid;
|
||||
*data = (void *)myfs;
|
||||
|
||||
|
||||
sprintf(buff, "myfs:%s", device);
|
||||
myfs->sem = create_sem(MAX_READERS, buff);
|
||||
if (myfs->sem < 0) {
|
||||
printf("could not create myfs sem!\n");
|
||||
ret = ENOMEM;
|
||||
goto error0;
|
||||
}
|
||||
|
||||
myfs->fd = open(device, oflags);
|
||||
if (myfs->fd < 0) {
|
||||
printf("could not open %s to try and mount a myfs\n", device);
|
||||
ret = ENODEV;
|
||||
goto error1;
|
||||
}
|
||||
|
||||
if (read_super_block(myfs) != 0) {
|
||||
printf("could not read superblock on device %s\n", device);
|
||||
ret = EBADF;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
if (super_block_is_sane(myfs) == 0) {
|
||||
printf("bad superblock\n");
|
||||
ret = EBADF;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
if ((myfs->dsb.block_size % sizeof(myfs_inode)) != 0) {
|
||||
printf("ERROR: inode size %d is not an even divisor of the block "
|
||||
"size %d\n", sizeof(myfs_inode), myfs->dsb.block_size);
|
||||
printf(" check myfs.h for more details and info.\n");
|
||||
ret = EINVAL;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
if (init_cache_for_device(myfs->fd, myfs->dsb.num_blocks) != 0) {
|
||||
printf("could not initialize cache access for fd %d\n", myfs->fd);
|
||||
ret = EBADF;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
if (init_tmp_blocks(myfs) != 0) {
|
||||
printf("could not init tmp blocks\n");
|
||||
ret = ENOMEM;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
if (myfs_init_journal(myfs) != 0) {
|
||||
printf("could not initialize the journal\n");
|
||||
ret = EBADF;
|
||||
goto error3;
|
||||
}
|
||||
|
||||
if (myfs_init_inodes(myfs) != 0) {
|
||||
printf("could not initialize inodes\n");
|
||||
ret = ENOMEM;
|
||||
goto error5;
|
||||
}
|
||||
|
||||
if (myfs_init_storage_map(myfs) != 0) {
|
||||
printf("could not initialize the storage map\n");
|
||||
ret = EBADF;
|
||||
goto error6;
|
||||
}
|
||||
|
||||
*vnid = myfs->dsb.root_inum;
|
||||
if (myfs_read_vnode(myfs, *vnid, 0, (void **)&myfs->root_dir) != 0) {
|
||||
printf("could not read root dir inode\n");
|
||||
ret = EBADF;
|
||||
goto error7;
|
||||
}
|
||||
|
||||
if (new_vnode(myfs->nsid, *vnid, (void *)myfs->root_dir) != 0) {
|
||||
printf("could not initialize a vnode for the root directory!\n");
|
||||
ret = ENOMEM;
|
||||
goto error7;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
error7:
|
||||
myfs_shutdown_storage_map(myfs);
|
||||
error6:
|
||||
myfs_shutdown_inodes(myfs);
|
||||
error5:
|
||||
myfs_shutdown_journal(myfs);
|
||||
error3:
|
||||
shutdown_tmp_blocks(myfs);
|
||||
error2:
|
||||
remove_cached_device_blocks(myfs->fd, NO_WRITES);
|
||||
close(myfs->fd);
|
||||
error1:
|
||||
delete_sem(myfs->sem);
|
||||
error0:
|
||||
memset(myfs, 0xff, sizeof(*myfs)); /* yeah, I'm paranoid */
|
||||
free(myfs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
note that the order in which things are done here is *very*
|
||||
important. don't mess with it unless you know what you're doing
|
||||
*/
|
||||
int
|
||||
myfs_unmount(void *ns)
|
||||
{
|
||||
myfs_info *myfs = (myfs_info *)ns;
|
||||
|
||||
if (myfs == NULL)
|
||||
return EINVAL;
|
||||
|
||||
sync_journal(myfs);
|
||||
|
||||
myfs_shutdown_storage_map(myfs);
|
||||
myfs_shutdown_inodes(myfs);
|
||||
|
||||
/*
|
||||
have to do this after the above steps because the above steps
|
||||
might actually have to do transactions
|
||||
*/
|
||||
sync_journal(myfs);
|
||||
|
||||
remove_cached_device_blocks(myfs->fd, ALLOW_WRITES);
|
||||
myfs_shutdown_journal(myfs);
|
||||
|
||||
write_super_block(myfs);
|
||||
|
||||
shutdown_tmp_blocks(myfs);
|
||||
|
||||
close(myfs->fd);
|
||||
|
||||
if (myfs->sem > 0)
|
||||
delete_sem(myfs->sem);
|
||||
|
||||
memset(myfs, 0xff, sizeof(*myfs)); /* trash it just to be sure */
|
||||
free(myfs);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
myfs_info *myfs_create_fs(char *device, char *volname,
|
||||
int block_size, char *opts);
|
||||
int myfs_mount(nspace_id nsid, const char *device, ulong flags,
|
||||
void *parms, size_t len, void **data, vnode_id *vnid);
|
||||
int myfs_unmount(void *ns);
|
@ -1,24 +0,0 @@
|
||||
#ifndef MYFS_H
|
||||
#define MYFS_H
|
||||
|
||||
|
||||
#include "fsproto.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#include "compat.h"
|
||||
|
||||
#include "lock.h"
|
||||
#include "cache.h"
|
||||
|
||||
#include "initfs.h"
|
||||
|
||||
typedef void myfs_info;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MYFS_H */
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "path_util.h"
|
||||
|
||||
status_t
|
||||
get_last_path_component(const char *path, char *buffer, int bufferLen)
|
||||
{
|
||||
int len = strlen(path);
|
||||
if (len == 0)
|
||||
return FS_EINVAL;
|
||||
|
||||
// eat trailing '/'
|
||||
while (len > 0 && path[len - 1] == '/')
|
||||
len--;
|
||||
|
||||
if (len == 0) {
|
||||
// path is `/'
|
||||
len = 1;
|
||||
} else {
|
||||
// find previous '/'
|
||||
int pos = len - 1;
|
||||
while (pos > 0 && path[pos] != '/')
|
||||
pos--;
|
||||
if (path[pos] == '/')
|
||||
pos++;
|
||||
|
||||
path += pos;
|
||||
len -= pos;
|
||||
}
|
||||
|
||||
if (len >= bufferLen)
|
||||
return FS_NAME_TOO_LONG;
|
||||
|
||||
memcpy(buffer, path, len);
|
||||
buffer[len] = '\0';
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
char *
|
||||
make_path(const char *dir, const char *entry)
|
||||
{
|
||||
// get the len
|
||||
int dirLen = strlen(dir);
|
||||
int entryLen = strlen(entry);
|
||||
bool insertSeparator = (dir[dirLen - 1] != '/');
|
||||
int pathLen = dirLen + entryLen + (insertSeparator ? 1 : 0) + 1;
|
||||
|
||||
// allocate the path
|
||||
char *path = (char*)malloc(pathLen);
|
||||
if (!path)
|
||||
return NULL;
|
||||
|
||||
// compose the path
|
||||
strcpy(path, dir);
|
||||
if (insertSeparator)
|
||||
strcat(path + dirLen, "/");
|
||||
strcat(path + dirLen, entry);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef FS_SHELL_PATH_UTIL_H
|
||||
#define FS_SHELL_PATH_UTIL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
status_t get_last_path_component(const char *path, char *buffer, int bufferLen);
|
||||
char *make_path(const char *dir, const char *entry);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // FS_SHELL_PATH_UTIL_H
|
File diff suppressed because it is too large
Load Diff
@ -1,83 +0,0 @@
|
||||
/*
|
||||
This header file contains the definitions for use with the generic
|
||||
SkipList package.
|
||||
|
||||
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
|
||||
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
|
||||
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
|
||||
|
||||
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
|
||||
|
||||
Dominic Giampaolo
|
||||
dbg@be.com
|
||||
*/
|
||||
|
||||
#ifndef SKIPLIST_H
|
||||
#define SKIPLIST_H
|
||||
|
||||
|
||||
/* RAND_MAX should be defined if you are using an ANSI compiler system,
|
||||
* but alas it isn't always. You should define it to be the correct
|
||||
* value for whatever your library rand() function returns.
|
||||
*
|
||||
* Under unix (mach, bsd, etc), that's 2^31 - 1. On my Amiga at home
|
||||
* it's 2^15 - 1. It would be wise to verify what your compiler uses
|
||||
* for RAND_MAX (the maximum value returned from rand()) because otherwise
|
||||
* the code will _not_ work.
|
||||
*/
|
||||
#ifndef RAND_MAX
|
||||
#define RAND_MAX (0x7fffffff)
|
||||
#endif
|
||||
|
||||
|
||||
#define ALLOW_DUPLICATES 1 /* allow or disallow duplicates in a list */
|
||||
#define NO_DUPLICATES 0
|
||||
#define DUPLICATE_ITEM -1 /* ret val from InsertSL if dups not allowed */
|
||||
|
||||
|
||||
/* typedef's */
|
||||
typedef struct SLNodeStruct *SLNode;
|
||||
|
||||
struct SLNodeStruct
|
||||
{
|
||||
void *key;
|
||||
SLNode forward[1]; /* variable sized array of forward pointers */
|
||||
};
|
||||
|
||||
typedef struct _SkipList
|
||||
{
|
||||
struct SLNodeStruct *header; /* pointer to header */
|
||||
|
||||
int (*compare)();
|
||||
void (*freeitem)();
|
||||
|
||||
int flags;
|
||||
int level; /* max index+1 of the forward array */
|
||||
|
||||
int count; /* number of elements in the list */
|
||||
} *SkipList;
|
||||
|
||||
|
||||
|
||||
/* protos */
|
||||
SkipList NewSL(int (*compare)(), void (*freeitem)(), int flags);
|
||||
void FreeSL(SkipList l);
|
||||
int InsertSL(SkipList l, void *key);
|
||||
int DeleteSL(SkipList l, void *key);
|
||||
void *SearchSL(SkipList l, void *key);
|
||||
void DoForSL(SkipList l, int (*function)(), void *arg);
|
||||
void DoForRangeSL(SkipList l, void *key, int (*compare)(),
|
||||
int (*func)(), void *arg);
|
||||
|
||||
int NumInSL(SkipList l);
|
||||
|
||||
|
||||
/* These defines are to be used as return values from the function
|
||||
* you pass to DoForSL(). They can be or'ed together to do multiple
|
||||
* things (like delete a node and then quit going through the list).
|
||||
*/
|
||||
#define SL_CONTINUE 0x00
|
||||
#define SL_DELETE 0x01
|
||||
#define SL_QUIT 0x02
|
||||
|
||||
#endif /* SKIPLIST_H */
|
@ -1,401 +0,0 @@
|
||||
/* This file contains a heavily hacked and generalized version of the
|
||||
Example skiplist code distributed on mimsy.cs.umd.edu.
|
||||
|
||||
Here is a short excerpt from the original comment :
|
||||
|
||||
Example of Skip List source code for C :
|
||||
|
||||
Skip Lists are a probabilistic alternative to balanced trees,
|
||||
as described in the June 1990 issue of CACM and were invented by
|
||||
William Pugh in 1987.
|
||||
|
||||
These are my additions :
|
||||
|
||||
This file contains my (Dominic Giampaolo's) heavily hacked version
|
||||
of skip lists. These work on any arbitrary data by using callback
|
||||
functions which you supply (at list creation time) to do the data
|
||||
comparisons. You could instantly use this package to implement a
|
||||
symbol table for a compiler which would be blazingly fast and
|
||||
require zippo effort on your part.
|
||||
|
||||
I've changed the function names (not to protect the innocent, but
|
||||
to make them easier to read :) and changed the data structures a bit.
|
||||
I've ansi'fied the code, added prototypes, and changed all those ugly
|
||||
do/while's to for loops. I also removed the dependance on those silly
|
||||
NIL items at the end of the list (it just checks for regular NULL
|
||||
pointers instead). Additionally, the code is more easily reentrant now,
|
||||
and doesn't depend on any global variables. The code is quite a bit
|
||||
different looking than it originally was, but the underlying algorithims
|
||||
(of course) remain unchanged.
|
||||
|
||||
|
||||
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
|
||||
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
|
||||
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
|
||||
|
||||
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
|
||||
|
||||
Dominic Giampaolo
|
||||
dbg@be.com
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "skiplist.h"
|
||||
|
||||
/* define's */
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define MaxNumberOfLevels 16
|
||||
#define MaxLevel (MaxNumberOfLevels-1)
|
||||
#define NewNodeOfLevel(x) (SLNode)malloc(sizeof(struct SLNodeStruct)+(x)*sizeof(SLNode *))
|
||||
|
||||
|
||||
/* private proto */
|
||||
static int RandomLevelSL(SkipList l);
|
||||
|
||||
|
||||
/* functions */
|
||||
SkipList NewSL(int (*compare)(), void (*freeitem)(), int flags)
|
||||
{
|
||||
SkipList l;
|
||||
int i;
|
||||
|
||||
if (compare == NULL) /* need at least a compare function... */
|
||||
return NULL;
|
||||
|
||||
l = (SkipList)malloc(sizeof(struct _SkipList));
|
||||
if (l == NULL)
|
||||
return NULL;
|
||||
|
||||
l->level = 1;
|
||||
l->header = NewNodeOfLevel(MaxNumberOfLevels);
|
||||
if (l->header == NULL)
|
||||
{ free(l); return NULL; }
|
||||
|
||||
for(i=0; i < MaxNumberOfLevels; i++)
|
||||
l->header->forward[i] = NULL;
|
||||
l->header->key = NULL; /* just to be sure */
|
||||
|
||||
/* XXXdbg -- don't want this! srand(time(NULL) | 0x01); */ /* seed with an odd number */
|
||||
|
||||
l->compare = compare;
|
||||
l->freeitem = freeitem;
|
||||
l->flags = flags;
|
||||
|
||||
l->count = 0;
|
||||
|
||||
return(l);
|
||||
}
|
||||
|
||||
|
||||
void FreeSL(SkipList l)
|
||||
{
|
||||
register SLNode p,q;
|
||||
void (*freeitem)() = l->freeitem;
|
||||
|
||||
if (l == NULL)
|
||||
return;
|
||||
|
||||
if (l->header == NULL)
|
||||
{
|
||||
free(l);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
p = l->header; /* free header node first, because it doesn't */
|
||||
q = p->forward[0]; /* have a real key to it */
|
||||
free(p);
|
||||
p = q;
|
||||
|
||||
while (p != NULL)
|
||||
{
|
||||
q = p->forward[0];
|
||||
if (freeitem)
|
||||
(*freeitem)(p->key);
|
||||
free(p);
|
||||
p = q;
|
||||
}
|
||||
|
||||
free(l);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This RandomLevelSL function generates a very good representation of
|
||||
* p=.25 (or p=.5, etc). The number of nodes of each level works out
|
||||
* to be very very close to what they should be. I didn't check it
|
||||
* statistically, but on large data sets, I imagine it's +/- 5% of what
|
||||
* it should be. This P value is good for lists of up to 64K elements.
|
||||
*
|
||||
* For more info about the P value, see the papers by Mr. Pugh (available
|
||||
* in postscript from mimsy.umd.edu).
|
||||
*/
|
||||
#define P_50 (RAND_MAX / 2) /* p value of .50 */
|
||||
#define P_25 (RAND_MAX / 4) /* p value of .25 */
|
||||
#define P_125 (RAND_MAX / 8) /* p value of .125 */
|
||||
|
||||
static int RandomLevelSL(SkipList l)
|
||||
{
|
||||
register int level = 0;
|
||||
|
||||
while(rand() < P_25)
|
||||
{
|
||||
level++;
|
||||
}
|
||||
|
||||
return (level > MaxLevel ? MaxLevel : level);
|
||||
}
|
||||
|
||||
|
||||
int InsertSL(SkipList l, void *key)
|
||||
{
|
||||
register int i,k;
|
||||
SLNode update[MaxNumberOfLevels];
|
||||
register SLNode p,q = 0;
|
||||
int (*compare)() = l->compare;
|
||||
|
||||
p = l->header;
|
||||
|
||||
for(k = l->level-1; k >= 0; k--)
|
||||
{
|
||||
while((q = p->forward[k]) && (*compare)(q->key, key) < 0)
|
||||
p = q;
|
||||
|
||||
update[k] = p;
|
||||
}
|
||||
|
||||
if ((l->flags & ALLOW_DUPLICATES) == FALSE) /* if no duplicates allowed */
|
||||
if (q && (*compare)(q->key, key) == 0) /* item is a duplicate */
|
||||
{
|
||||
return DUPLICATE_ITEM;
|
||||
}
|
||||
|
||||
|
||||
k = RandomLevelSL(l);
|
||||
if (k >= l->level)
|
||||
{
|
||||
k = l->level;
|
||||
l->level++;
|
||||
update[k] = l->header;
|
||||
}
|
||||
|
||||
q = NewNodeOfLevel(k); /* was k+1 */
|
||||
|
||||
if (q == NULL)
|
||||
return FALSE;
|
||||
|
||||
l->count++; /* update the number of nodes in the list */
|
||||
|
||||
q->key = key;
|
||||
for(i=0; i < k; i++)
|
||||
q->forward[i] = NULL;
|
||||
|
||||
for(; k >= 0; k--)
|
||||
{
|
||||
p = update[k];
|
||||
q->forward[k] = p->forward[k];
|
||||
p->forward[k] = q;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int DeleteSL(SkipList l, void *key)
|
||||
{
|
||||
register int k,m;
|
||||
SLNode update[MaxNumberOfLevels];
|
||||
register SLNode p,q;
|
||||
int (*compare)() = l->compare;
|
||||
void (*freeitem)() = l->freeitem;
|
||||
|
||||
p = l->header;
|
||||
|
||||
for(k=l->level-1; k >= 0; k--)
|
||||
{
|
||||
while((q = p->forward[k]) && (*compare)(q->key, key) < 0)
|
||||
p = q;
|
||||
|
||||
update[k] = p;
|
||||
}
|
||||
q = p->forward[0];
|
||||
|
||||
if (q && (*compare)(q->key, key) == 0)
|
||||
{
|
||||
m = l->level;
|
||||
for(k=0; k < m; k++)
|
||||
{
|
||||
p = update[k];
|
||||
if (p == NULL || p->forward[k] != q)
|
||||
break;
|
||||
p->forward[k] = q->forward[k];
|
||||
}
|
||||
|
||||
l->count--;
|
||||
|
||||
if (freeitem)
|
||||
(*freeitem)(q->key);
|
||||
|
||||
free(q);
|
||||
|
||||
m = l->level - 1;
|
||||
while(l->header->forward[m] == NULL && m > 0)
|
||||
m--;
|
||||
|
||||
l->level = m + 1;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void *SearchSL(SkipList l, void *key)
|
||||
{
|
||||
register int k;
|
||||
register SLNode p,q = 0;
|
||||
int (*compare)() = l->compare;
|
||||
|
||||
p = l->header;
|
||||
|
||||
for(k=l->level-1; k >= 0; k--)
|
||||
{
|
||||
while((q = p->forward[k]) && (*compare)(q->key, key) < 0)
|
||||
p = q;
|
||||
}
|
||||
|
||||
if (q == NULL || (*compare)(q->key, key) != 0)
|
||||
return NULL;
|
||||
|
||||
return q->key;
|
||||
}
|
||||
|
||||
|
||||
void DoForSL(SkipList l, int (*function)(), void *arg)
|
||||
{
|
||||
register SLNode p, q, fix;
|
||||
register int k, ret;
|
||||
SLNode save[MaxNumberOfLevels], who[MaxNumberOfLevels];
|
||||
void (*freeitem)() = l->freeitem;
|
||||
|
||||
|
||||
if (l == NULL || l->header == NULL || function == NULL)
|
||||
return;
|
||||
|
||||
p = l->header; /* skip header node because it isn't a real node */
|
||||
|
||||
/* Save the initial header info
|
||||
*/
|
||||
for(k=0; k < l->level; k++)
|
||||
{
|
||||
save[k] = p->forward[k];
|
||||
who[k] = p;
|
||||
}
|
||||
|
||||
p = p->forward[0]; /* skip to the first data node */
|
||||
|
||||
while (p != NULL)
|
||||
{
|
||||
q = p->forward[0];
|
||||
ret = (*function)(p->key, arg);
|
||||
|
||||
if (ret & SL_DELETE)
|
||||
{
|
||||
k = 0;
|
||||
while(save[k] == p)
|
||||
{
|
||||
fix = who[k];
|
||||
fix->forward[k] = p->forward[k];
|
||||
save[k] = p->forward[k];
|
||||
k++;
|
||||
}
|
||||
|
||||
l->count--; /* decrement the count of items */
|
||||
|
||||
if (freeitem)
|
||||
(*freeitem)(p->key, arg);
|
||||
free(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
k = 0;
|
||||
while(save[k] == p)
|
||||
{
|
||||
save[k] = p->forward[k];
|
||||
who[k] = p;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret & SL_QUIT)
|
||||
break;
|
||||
|
||||
p = q; /* advance to the next one */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DoForRangeSL(SkipList l, void *key, int (*compare)(), int (*func)(),
|
||||
void *arg)
|
||||
{
|
||||
register int k;
|
||||
SLNode update[MaxNumberOfLevels];
|
||||
register SLNode p,q;
|
||||
void (*freeitem)() = l->freeitem;
|
||||
int ret;
|
||||
|
||||
p = l->header;
|
||||
|
||||
for(k=l->level-1; k >= 0; k--)
|
||||
{
|
||||
while((q = p->forward[k]) && (*compare)(q->key, key) < 0)
|
||||
p = q;
|
||||
|
||||
update[k] = p;
|
||||
}
|
||||
p = p->forward[0];
|
||||
|
||||
if (p == NULL || (*compare)(p->key, key) != 0) /* then nothing matched */
|
||||
return;
|
||||
|
||||
do
|
||||
{
|
||||
q = p->forward[0]; /* save next pointer */
|
||||
ret = (*func)(p->key, arg);
|
||||
|
||||
if (ret & SL_DELETE)
|
||||
{
|
||||
for(k=0; k < l->level && update[k] && update[k]->forward[k] == p; k++)
|
||||
update[k]->forward[k] = p->forward[k];
|
||||
|
||||
l->count--; /* decrement the count of items */
|
||||
|
||||
if (freeitem)
|
||||
(*freeitem)(p->key, arg);
|
||||
free(p);
|
||||
}
|
||||
|
||||
if (ret & SL_QUIT)
|
||||
break;
|
||||
|
||||
p = q; /* advance to the next one */
|
||||
}
|
||||
while(p != NULL && (*compare)(p->key, key) == 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int NumInSL(SkipList l)
|
||||
{
|
||||
return l->count;
|
||||
}
|
||||
|
@ -1,286 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "stat_util.h"
|
||||
|
||||
#if (defined(__BEOS__) || defined(__HAIKU__))
|
||||
|
||||
void
|
||||
from_platform_stat(const struct stat *st, struct my_stat *myst)
|
||||
{
|
||||
myst->dev = st->st_dev;
|
||||
myst->ino = st->st_ino;
|
||||
myst->nlink = st->st_nlink;
|
||||
myst->uid = st->st_uid;
|
||||
myst->gid = st->st_gid;
|
||||
myst->size = st->st_size;
|
||||
myst->blksize = st->st_blksize;
|
||||
myst->atime = st->st_atime;
|
||||
myst->mtime = st->st_mtime;
|
||||
myst->ctime = st->st_ctime;
|
||||
myst->crtime = st->st_ctime;
|
||||
myst->mode = st->st_mode;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
to_platform_stat(const struct my_stat *myst, struct stat *st)
|
||||
{
|
||||
st->st_dev = myst->dev;
|
||||
st->st_ino = myst->ino;
|
||||
st->st_nlink = myst->nlink;
|
||||
st->st_uid = myst->uid;
|
||||
st->st_gid = myst->gid;
|
||||
st->st_size = myst->size;
|
||||
st->st_blksize = myst->blksize;
|
||||
st->st_atime = myst->atime;
|
||||
st->st_mtime = myst->mtime;
|
||||
st->st_ctime = myst->ctime;
|
||||
st->st_crtime = myst->crtime;
|
||||
st->st_mode = myst->mode;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
to_platform_open_mode(int myMode)
|
||||
{
|
||||
return myMode;
|
||||
}
|
||||
|
||||
|
||||
#else // !__BEOS__
|
||||
|
||||
#ifndef S_ATTR_DIR
|
||||
#define S_ATTR_DIR 0
|
||||
#endif
|
||||
#ifndef S_ATTR
|
||||
#define S_ATTR 0
|
||||
#endif
|
||||
#ifndef S_INDEX_DIR
|
||||
#define S_INDEX_DIR 0
|
||||
#endif
|
||||
#ifndef S_INT_INDEX
|
||||
#define S_INT_INDEX 0
|
||||
#endif
|
||||
#ifndef S_UINT_INDEX
|
||||
#define S_UINT_INDEX 0
|
||||
#endif
|
||||
#ifndef S_LONG_LONG_INDEX
|
||||
#define S_LONG_LONG_INDEX 0
|
||||
#endif
|
||||
#ifndef S_ULONG_LONG_INDEX
|
||||
#define S_ULONG_LONG_INDEX 0
|
||||
#endif
|
||||
#ifndef S_FLOAT_INDEX
|
||||
#define S_FLOAT_INDEX 0
|
||||
#endif
|
||||
#ifndef S_DOUBLE_INDEX
|
||||
#define S_DOUBLE_INDEX 0
|
||||
#endif
|
||||
#ifndef S_ALLOW_DUPS
|
||||
#define S_ALLOW_DUPS 0
|
||||
#endif
|
||||
#ifndef S_LINK_SELF_HEALING
|
||||
#define S_LINK_SELF_HEALING 0
|
||||
#endif
|
||||
#ifndef S_LINK_AUTO_DELETE
|
||||
#define S_LINK_AUTO_DELETE 0
|
||||
#endif
|
||||
|
||||
|
||||
my_mode_t
|
||||
from_platform_mode(mode_t mode)
|
||||
{
|
||||
#define SET_ST_MODE_BIT(flag, myFlag) \
|
||||
if (mode & flag) \
|
||||
myMode |= myFlag;
|
||||
|
||||
my_mode_t myMode = 0;
|
||||
|
||||
SET_ST_MODE_BIT(MY_S_ATTR_DIR, S_ATTR_DIR);
|
||||
SET_ST_MODE_BIT(MY_S_ATTR, S_ATTR);
|
||||
SET_ST_MODE_BIT(MY_S_INDEX_DIR, S_INDEX_DIR);
|
||||
SET_ST_MODE_BIT(MY_S_INT_INDEX, S_INT_INDEX);
|
||||
SET_ST_MODE_BIT(MY_S_UINT_INDEX, S_UINT_INDEX);
|
||||
SET_ST_MODE_BIT(MY_S_LONG_LONG_INDEX, S_LONG_LONG_INDEX);
|
||||
SET_ST_MODE_BIT(MY_S_ULONG_LONG_INDEX, S_ULONG_LONG_INDEX);
|
||||
SET_ST_MODE_BIT(MY_S_FLOAT_INDEX, S_FLOAT_INDEX);
|
||||
SET_ST_MODE_BIT(MY_S_DOUBLE_INDEX, S_DOUBLE_INDEX);
|
||||
SET_ST_MODE_BIT(MY_S_ALLOW_DUPS, S_ALLOW_DUPS);
|
||||
SET_ST_MODE_BIT(MY_S_LINK_SELF_HEALING, S_LINK_SELF_HEALING);
|
||||
SET_ST_MODE_BIT(MY_S_LINK_AUTO_DELETE, S_LINK_AUTO_DELETE);
|
||||
|
||||
switch (mode & S_IFMT) {
|
||||
case S_IFLNK:
|
||||
myMode |= MY_S_IFLNK;
|
||||
break;
|
||||
case S_IFREG:
|
||||
myMode |= MY_S_IFREG;
|
||||
break;
|
||||
case S_IFBLK:
|
||||
myMode |= MY_S_IFBLK;
|
||||
break;
|
||||
case S_IFDIR:
|
||||
myMode |= MY_S_IFDIR;
|
||||
break;
|
||||
case S_IFIFO:
|
||||
myMode |= MY_S_IFIFO;
|
||||
break;
|
||||
}
|
||||
|
||||
SET_ST_MODE_BIT(MY_S_ISUID, S_ISUID);
|
||||
SET_ST_MODE_BIT(MY_S_ISGID, S_ISGID);
|
||||
SET_ST_MODE_BIT(MY_S_ISVTX, S_ISVTX);
|
||||
SET_ST_MODE_BIT(MY_S_IRUSR, S_IRUSR);
|
||||
SET_ST_MODE_BIT(MY_S_IWUSR, S_IWUSR);
|
||||
SET_ST_MODE_BIT(MY_S_IXUSR, S_IXUSR);
|
||||
SET_ST_MODE_BIT(MY_S_IRGRP, S_IRGRP);
|
||||
SET_ST_MODE_BIT(MY_S_IWGRP, S_IWGRP);
|
||||
SET_ST_MODE_BIT(MY_S_IXGRP, S_IXGRP);
|
||||
SET_ST_MODE_BIT(MY_S_IROTH, S_IROTH);
|
||||
SET_ST_MODE_BIT(MY_S_IWOTH, S_IWOTH);
|
||||
SET_ST_MODE_BIT(MY_S_IXOTH, S_IXOTH);
|
||||
|
||||
#undef SET_ST_MODE_BIT
|
||||
|
||||
return myMode;
|
||||
}
|
||||
|
||||
|
||||
mode_t
|
||||
to_platform_mode(my_mode_t myMode)
|
||||
{
|
||||
#define SET_ST_MODE_BIT(flag, myFlag) \
|
||||
if (myMode & myFlag) \
|
||||
mode |= flag;
|
||||
|
||||
mode_t mode = 0;
|
||||
|
||||
SET_ST_MODE_BIT(MY_S_ATTR_DIR, S_ATTR_DIR);
|
||||
SET_ST_MODE_BIT(MY_S_ATTR, S_ATTR);
|
||||
SET_ST_MODE_BIT(MY_S_INDEX_DIR, S_INDEX_DIR);
|
||||
SET_ST_MODE_BIT(MY_S_INT_INDEX, S_INT_INDEX);
|
||||
SET_ST_MODE_BIT(MY_S_UINT_INDEX, S_UINT_INDEX);
|
||||
SET_ST_MODE_BIT(MY_S_LONG_LONG_INDEX, S_LONG_LONG_INDEX);
|
||||
SET_ST_MODE_BIT(MY_S_ULONG_LONG_INDEX, S_ULONG_LONG_INDEX);
|
||||
SET_ST_MODE_BIT(MY_S_FLOAT_INDEX, S_FLOAT_INDEX);
|
||||
SET_ST_MODE_BIT(MY_S_DOUBLE_INDEX, S_DOUBLE_INDEX);
|
||||
SET_ST_MODE_BIT(MY_S_ALLOW_DUPS, S_ALLOW_DUPS);
|
||||
SET_ST_MODE_BIT(MY_S_LINK_SELF_HEALING, S_LINK_SELF_HEALING);
|
||||
SET_ST_MODE_BIT(MY_S_LINK_AUTO_DELETE, S_LINK_AUTO_DELETE);
|
||||
|
||||
switch (myMode & MY_S_IFMT) {
|
||||
case MY_S_IFLNK:
|
||||
mode |= S_IFLNK;
|
||||
break;
|
||||
case MY_S_IFREG:
|
||||
mode |= S_IFREG;
|
||||
break;
|
||||
case MY_S_IFBLK:
|
||||
mode |= S_IFBLK;
|
||||
break;
|
||||
case MY_S_IFDIR:
|
||||
mode |= S_IFDIR;
|
||||
break;
|
||||
case MY_S_IFIFO:
|
||||
mode |= S_IFIFO;
|
||||
break;
|
||||
}
|
||||
|
||||
SET_ST_MODE_BIT(MY_S_ISUID, S_ISUID);
|
||||
SET_ST_MODE_BIT(MY_S_ISGID, S_ISGID);
|
||||
SET_ST_MODE_BIT(MY_S_ISVTX, S_ISVTX);
|
||||
SET_ST_MODE_BIT(MY_S_IRUSR, S_IRUSR);
|
||||
SET_ST_MODE_BIT(MY_S_IWUSR, S_IWUSR);
|
||||
SET_ST_MODE_BIT(MY_S_IXUSR, S_IXUSR);
|
||||
SET_ST_MODE_BIT(MY_S_IRGRP, S_IRGRP);
|
||||
SET_ST_MODE_BIT(MY_S_IWGRP, S_IWGRP);
|
||||
SET_ST_MODE_BIT(MY_S_IXGRP, S_IXGRP);
|
||||
SET_ST_MODE_BIT(MY_S_IROTH, S_IROTH);
|
||||
SET_ST_MODE_BIT(MY_S_IWOTH, S_IWOTH);
|
||||
SET_ST_MODE_BIT(MY_S_IXOTH, S_IXOTH);
|
||||
|
||||
#undef SET_ST_MODE_BIT
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
from_platform_stat(const struct stat *st, struct my_stat *myst)
|
||||
{
|
||||
myst->dev = st->st_dev;
|
||||
myst->ino = st->st_ino;
|
||||
myst->mode = from_platform_mode(st->st_mode);
|
||||
myst->nlink = st->st_nlink;
|
||||
myst->uid = st->st_uid;
|
||||
myst->gid = st->st_gid;
|
||||
myst->size = st->st_size;
|
||||
myst->blksize = st->st_blksize;
|
||||
myst->atime = st->st_atime;
|
||||
myst->mtime = st->st_mtime;
|
||||
myst->ctime = st->st_ctime;
|
||||
myst->crtime = st->st_ctime;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
to_platform_stat(const struct my_stat *myst, struct stat *st)
|
||||
{
|
||||
st->st_dev = myst->dev;
|
||||
st->st_ino = myst->ino;
|
||||
st->st_mode = to_platform_mode(myst->mode);
|
||||
st->st_nlink = myst->nlink;
|
||||
st->st_uid = myst->uid;
|
||||
st->st_gid = myst->gid;
|
||||
st->st_size = myst->size;
|
||||
st->st_blksize = myst->blksize;
|
||||
st->st_atime = myst->atime;
|
||||
st->st_mtime = myst->mtime;
|
||||
st->st_ctime = myst->ctime;
|
||||
// st->st_crtime = myst->crtime;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
to_platform_open_mode(int myMode)
|
||||
{
|
||||
#define SET_OPEN_MODE_FLAG(flag, myFlag) \
|
||||
if (myMode & myFlag) \
|
||||
mode |= flag;
|
||||
|
||||
int mode = 0;
|
||||
|
||||
// the r/w mode
|
||||
switch (myMode & MY_O_RWMASK) {
|
||||
case MY_O_RDONLY:
|
||||
mode |= O_RDONLY;
|
||||
break;
|
||||
case MY_O_WRONLY:
|
||||
mode |= O_WRONLY;
|
||||
break;
|
||||
case MY_O_RDWR:
|
||||
mode |= O_RDWR;
|
||||
break;
|
||||
}
|
||||
|
||||
// the flags
|
||||
//SET_OPEN_MODE_FLAG(O_CLOEXEC, MY_O_CLOEXEC)
|
||||
SET_OPEN_MODE_FLAG(O_NONBLOCK, MY_O_NONBLOCK)
|
||||
SET_OPEN_MODE_FLAG(O_EXCL, MY_O_EXCL)
|
||||
SET_OPEN_MODE_FLAG(O_CREAT, MY_O_CREAT)
|
||||
SET_OPEN_MODE_FLAG(O_TRUNC, MY_O_TRUNC)
|
||||
SET_OPEN_MODE_FLAG(O_APPEND, MY_O_APPEND)
|
||||
SET_OPEN_MODE_FLAG(O_NOCTTY, MY_O_NOCTTY)
|
||||
SET_OPEN_MODE_FLAG(O_NOTRAVERSE, MY_O_NOTRAVERSE)
|
||||
//SET_OPEN_MODE_FLAG(O_TEXT, MY_O_TEXT)
|
||||
//SET_OPEN_MODE_FLAG(O_BINARY, MY_O_BINARY)
|
||||
|
||||
#undef SET_OPEN_MODE_FLAG
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
#endif // !__BEOS__
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef FS_SHELL_STAT_UTIL_H
|
||||
#define FS_SHELL_STAT_UTIL_H
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
my_mode_t from_platform_mode(mode_t mode);
|
||||
mode_t to_platform_mode(my_mode_t mode);
|
||||
|
||||
void from_platform_stat(const struct stat *st, struct my_stat *myst);
|
||||
void to_platform_stat(const struct my_stat *myst, struct stat *st);
|
||||
|
||||
extern int to_platform_open_mode(int myMode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // FS_SHELL_STAT_UTIL_H
|
@ -1,215 +0,0 @@
|
||||
/*
|
||||
This file contains some stub routines to cover up the differences
|
||||
between the BeOS and the rest of the world.
|
||||
|
||||
|
||||
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
|
||||
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
|
||||
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
|
||||
|
||||
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
|
||||
|
||||
Dominic Giampaolo
|
||||
dbg@be.com
|
||||
*/
|
||||
#include "compat.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fs_attr.h>
|
||||
#include <KernelExport.h>
|
||||
#include <OS.h>
|
||||
|
||||
#include "myfs.h"
|
||||
|
||||
|
||||
#if (!defined(__BEOS__) && !defined(__HAIKU__))
|
||||
|
||||
static void
|
||||
myfs_die(const char *format,...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
vfprintf(stderr, format, list);
|
||||
va_end(list);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
//void
|
||||
//unload_kernel_addon(aid)
|
||||
//{
|
||||
//}
|
||||
|
||||
sem_id
|
||||
create_sem(long count, const char *name)
|
||||
{
|
||||
int *ptr;
|
||||
ptr = (int *)malloc(sizeof(int) + strlen(name) + 1); /* a hack */
|
||||
*ptr = count;
|
||||
memcpy(ptr+1, name, strlen(name));
|
||||
|
||||
return (sem_id)ptr;
|
||||
}
|
||||
|
||||
|
||||
long
|
||||
delete_sem(sem_id semid)
|
||||
{
|
||||
int *ptr = (int *)semid;
|
||||
|
||||
free(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
acquire_sem(sem_id sem)
|
||||
{
|
||||
int *ptr = (int *)sem;
|
||||
|
||||
if (*ptr <= 0) {
|
||||
myfs_die("You lose sucka! acquire of sem with count == %d\n", *ptr);
|
||||
}
|
||||
|
||||
*ptr -= 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long
|
||||
acquire_sem_etc(sem_id sem, int32 count, uint32 j1, bigtime_t j2)
|
||||
{
|
||||
int *ptr = (int *)sem;
|
||||
|
||||
if (*ptr <= 0) {
|
||||
myfs_die("You lose sucka! acquire_sem_etc of sem with count == %d\n",
|
||||
*ptr);
|
||||
}
|
||||
|
||||
*ptr -= count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
release_sem(sem_id sem)
|
||||
{
|
||||
int *ptr = (int *)sem;
|
||||
|
||||
*ptr += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
release_sem_etc(sem_id sem, long count, uint32 j1)
|
||||
{
|
||||
int *ptr = (int *)sem;
|
||||
|
||||
*ptr += count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
long
|
||||
atomic_add(vint32 *ptr, long val)
|
||||
{
|
||||
int old = *ptr;
|
||||
|
||||
*ptr += val;
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
status_t
|
||||
snooze(bigtime_t f)
|
||||
{
|
||||
sleep(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
void
|
||||
debugger(const char *message)
|
||||
{
|
||||
myfs_die("debugger() call: `%s'\n", message);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
thread_id
|
||||
find_thread(const char *name)
|
||||
{
|
||||
if (!name)
|
||||
return 42;
|
||||
|
||||
return FS_EINVAL;
|
||||
}
|
||||
|
||||
|
||||
thread_id
|
||||
spawn_thread(thread_func func, const char *name, int32 priority, void *data)
|
||||
{
|
||||
fprintf(stderr, "spawn_thread() not supported on this platform.\n");
|
||||
return FS_EINVAL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
resume_thread(thread_id thread)
|
||||
{
|
||||
fprintf(stderr, "resume_thread() not supported on this platform.\n");
|
||||
return FS_EINVAL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
wait_for_thread(thread_id thread, status_t *returnValue)
|
||||
{
|
||||
fprintf(stderr, "wait_for_thread() not supported on this platform.\n");
|
||||
return FS_EINVAL;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
port_id
|
||||
create_port(int32 capacity, const char *name)
|
||||
{
|
||||
fprintf(stderr, "create_port() not supported on this platform.\n");
|
||||
return FS_EINVAL;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
read_port(port_id port, int32 *code, void *buffer, size_t bufferSize)
|
||||
{
|
||||
fprintf(stderr, "read_port() not supported on this platform.\n");
|
||||
return FS_EINVAL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
write_port(port_id port, int32 code, const void *buffer, size_t bufferSize)
|
||||
{
|
||||
fprintf(stderr, "write_port() not supported on this platform.\n");
|
||||
return FS_EINVAL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
delete_port(port_id port)
|
||||
{
|
||||
fprintf(stderr, "delete_port() not supported on this platform.\n");
|
||||
return FS_EINVAL;
|
||||
}
|
||||
|
||||
#endif /* ! __BEOS__ */
|
@ -1,546 +0,0 @@
|
||||
/*
|
||||
This file contains some routines that are #ifdef'ed based on what
|
||||
system you're on. Currently it supports the BeOS and Unix. It
|
||||
could be extended to support Windows NT but their posix support
|
||||
is such a joke that it would probably be a real pain in the arse.
|
||||
|
||||
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
|
||||
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
|
||||
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
|
||||
|
||||
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
|
||||
|
||||
Dominic Giampaolo
|
||||
dbg@be.com
|
||||
*/
|
||||
#include "compat.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "stat_util.h"
|
||||
|
||||
// Linux support
|
||||
#ifdef HAIKU_HOST_PLATFORM_LINUX
|
||||
# include <linux/hdreg.h>
|
||||
#endif // HAIKU_HOST_PLATFORM_LINUX
|
||||
|
||||
|
||||
// Let the FS think, we are the root user.
|
||||
uid_t
|
||||
geteuid()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
gid_t
|
||||
getegid()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
device_is_read_only(const char *device)
|
||||
{
|
||||
#ifdef unix
|
||||
return 0; /* XXXdbg should do an ioctl or something */
|
||||
#else
|
||||
int fd;
|
||||
device_geometry dg;
|
||||
|
||||
fd = open(device, O_RDONLY);
|
||||
if (ioctl(fd, B_GET_GEOMETRY, &dg) < 0)
|
||||
return 0;
|
||||
|
||||
close(fd);
|
||||
|
||||
return dg.read_only;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
get_device_block_size(int fd)
|
||||
{
|
||||
#ifdef unix
|
||||
return 512; /* XXXdbg should do an ioctl or something */
|
||||
#else
|
||||
struct stat st;
|
||||
device_geometry dg;
|
||||
|
||||
if (ioctl(fd, B_GET_GEOMETRY, &dg) < 0) {
|
||||
if (fstat(fd, &st) < 0 || S_ISDIR(st.st_mode))
|
||||
return 0;
|
||||
|
||||
return 512; /* just assume it's a plain old file or something */
|
||||
}
|
||||
|
||||
return dg.bytes_per_sector;
|
||||
#endif
|
||||
}
|
||||
|
||||
fs_off_t
|
||||
get_num_device_blocks(int fd)
|
||||
{
|
||||
#ifdef unix
|
||||
struct stat st;
|
||||
|
||||
fstat(fd, &st); /* XXXdbg should be an ioctl or something */
|
||||
|
||||
return st.st_size / get_device_block_size(fd);
|
||||
#else
|
||||
struct stat st;
|
||||
device_geometry dg;
|
||||
|
||||
if (ioctl(fd, B_GET_GEOMETRY, &dg) >= 0) {
|
||||
return (fs_off_t)dg.cylinder_count *
|
||||
(fs_off_t)dg.sectors_per_track *
|
||||
(fs_off_t)dg.head_count;
|
||||
}
|
||||
|
||||
/* if the ioctl fails, try just stat'ing in case it's a regular file */
|
||||
if (fstat(fd, &st) < 0)
|
||||
return 0;
|
||||
|
||||
return st.st_size / get_device_block_size(fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
device_is_removeable(int fd)
|
||||
{
|
||||
#ifdef unix
|
||||
return 0; /* XXXdbg should do an ioctl or something */
|
||||
#else
|
||||
device_geometry dg;
|
||||
|
||||
if (ioctl(fd, B_GET_GEOMETRY, &dg) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return dg.removable;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (defined(__BEOS__) || defined(__HAIKU__)) && !defined(USER)
|
||||
#include "scsi.h"
|
||||
#endif
|
||||
|
||||
int
|
||||
lock_removeable_device(int fd, bool on_or_off)
|
||||
{
|
||||
#if defined(unix) || defined(USER)
|
||||
return 0; /* XXXdbg should do an ioctl or something */
|
||||
#else
|
||||
return ioctl(fd, B_SCSI_PREVENT_ALLOW, &on_or_off);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#if (!defined(__BEOS__) && !defined(__HAIKU__))
|
||||
ssize_t
|
||||
read_pos(int fd, fs_off_t _pos, void *data, size_t nbytes)
|
||||
{
|
||||
off_t pos = (off_t)_pos;
|
||||
size_t ret;
|
||||
|
||||
if (lseek(fd, pos, SEEK_SET) < 0) {
|
||||
perror("read lseek");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = read(fd, data, nbytes);
|
||||
|
||||
if (ret != nbytes) {
|
||||
printf("read_pos: wanted %d, got %d\n", nbytes, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
write_pos(int fd, fs_off_t _pos, const void *data, size_t nbytes)
|
||||
{
|
||||
off_t pos = (off_t)_pos;
|
||||
size_t ret;
|
||||
|
||||
if (lseek(fd, pos, SEEK_SET) < 0) {
|
||||
perror("read lseek");
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = write(fd, data, nbytes);
|
||||
|
||||
if (ret != nbytes) {
|
||||
printf("write_pos: wanted %d, got %d\n", nbytes, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef sun /* bloody wankers */
|
||||
#include <sys/stream.h>
|
||||
#ifdef DEF_IOV_MAX
|
||||
#define MAX_IOV DEF_IOV_MAX
|
||||
#else
|
||||
#define MAX_IOV 16
|
||||
#endif
|
||||
#else /* the rest of the world... */
|
||||
#define MAX_IOV 8192 /* something way bigger than we'll ever use */
|
||||
#endif
|
||||
|
||||
ssize_t
|
||||
readv_pos(int fd, fs_off_t _pos, const struct iovec *iov, int count)
|
||||
{
|
||||
off_t pos = (off_t)_pos;
|
||||
size_t amt = 0;
|
||||
ssize_t ret;
|
||||
const struct iovec *tmpiov;
|
||||
int i, n;
|
||||
|
||||
if (lseek(fd, pos, SEEK_SET) < 0) {
|
||||
perror("read lseek");
|
||||
return FS_EINVAL;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
tmpiov = iov;
|
||||
while (i < count) {
|
||||
if (i + MAX_IOV < count)
|
||||
n = MAX_IOV;
|
||||
else
|
||||
n = (count - i);
|
||||
|
||||
ret = readv(fd, tmpiov, n);
|
||||
amt += ret;
|
||||
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
i += n;
|
||||
tmpiov += n;
|
||||
}
|
||||
|
||||
return amt;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
writev_pos(int fd, fs_off_t _pos, const struct iovec *iov, int count)
|
||||
{
|
||||
off_t pos = (off_t)_pos;
|
||||
size_t amt = 0;
|
||||
ssize_t ret;
|
||||
const struct iovec *tmpiov;
|
||||
int i, n;
|
||||
|
||||
if (lseek(fd, pos, SEEK_SET) < 0) {
|
||||
perror("read lseek");
|
||||
return FS_EINVAL;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
tmpiov = iov;
|
||||
while (i < count) {
|
||||
if (i + MAX_IOV < count)
|
||||
n = MAX_IOV;
|
||||
else
|
||||
n = (count - i);
|
||||
|
||||
ret = writev(fd, tmpiov, n);
|
||||
amt += ret;
|
||||
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
i += n;
|
||||
tmpiov += n;
|
||||
}
|
||||
|
||||
return amt;
|
||||
}
|
||||
|
||||
|
||||
int build_platform_open(const char *pathname, int oflags, my_mode_t mode);
|
||||
|
||||
int
|
||||
build_platform_open(const char *pathname, int oflags, my_mode_t mode)
|
||||
{
|
||||
int fd = open(pathname, to_platform_open_mode(oflags),
|
||||
to_platform_mode(mode));
|
||||
if (fd < 0) {
|
||||
errno = from_platform_error(errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
int build_platform_close(int fd);
|
||||
|
||||
int
|
||||
build_platform_close(int fd)
|
||||
{
|
||||
if (close(fd) < 0) {
|
||||
errno = from_platform_error(errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int build_platform_fstat(int fd, struct my_stat *myst);
|
||||
|
||||
int
|
||||
build_platform_fstat(int fd, struct my_stat *myst)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (!myst) {
|
||||
errno = FS_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fstat(fd, &st) < 0) {
|
||||
errno = from_platform_error(errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
from_platform_stat(&st, myst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ssize_t build_platform_read_pos(int fd, fs_off_t pos, void *buf, size_t count);
|
||||
|
||||
ssize_t
|
||||
build_platform_read_pos(int fd, fs_off_t pos, void *buf, size_t count)
|
||||
{
|
||||
ssize_t result = read_pos(fd, pos, buf, count);
|
||||
if (result < 0) {
|
||||
errno = from_platform_error(errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAIKU_HOST_PLATFORM_LINUX
|
||||
|
||||
static bool
|
||||
test_size(int fd, off_t size)
|
||||
{
|
||||
char buffer[1];
|
||||
|
||||
if (size == 0)
|
||||
return true;
|
||||
|
||||
if (lseek(fd, size - 1, SEEK_SET) < 0)
|
||||
return false;
|
||||
|
||||
return (read(fd, &buffer, 1) == 1);
|
||||
}
|
||||
|
||||
|
||||
static off_t
|
||||
get_partition_size(int fd, off_t maxSize)
|
||||
{
|
||||
// binary search
|
||||
off_t lower = 0;
|
||||
off_t upper = maxSize;
|
||||
while (lower < upper) {
|
||||
off_t mid = (lower + upper + 1) / 2;
|
||||
if (test_size(fd, mid))
|
||||
lower = mid;
|
||||
else
|
||||
upper = mid - 1;
|
||||
}
|
||||
|
||||
return lower;
|
||||
}
|
||||
|
||||
#endif // HAIKU_HOST_PLATFORM_LINUX
|
||||
|
||||
|
||||
extern int build_platform_ioctl(int fd, unsigned long op, ...);
|
||||
|
||||
int
|
||||
build_platform_ioctl(int fd, unsigned long op, ...)
|
||||
{
|
||||
status_t error = FS_BAD_VALUE;
|
||||
va_list list;
|
||||
|
||||
// count arguments
|
||||
|
||||
va_start(list, op);
|
||||
|
||||
switch (op) {
|
||||
case 7: // B_GET_GEOMETRY
|
||||
{
|
||||
#ifdef HAIKU_HOST_PLATFORM_LINUX
|
||||
{
|
||||
device_geometry *geometry = va_arg(list, device_geometry*);
|
||||
struct hd_geometry hdGeometry;
|
||||
// BLKGETSIZE and BLKGETSIZE64 don't seem to work for
|
||||
// partitions. So we get the device geometry (there only seems
|
||||
// to be HDIO_GETGEO, which is kind of obsolete, BTW), and
|
||||
// get the partition size via binary search.
|
||||
if (ioctl(fd, HDIO_GETGEO, &hdGeometry) == 0) {
|
||||
off_t bytesPerCylinder = (off_t)hdGeometry.heads
|
||||
* hdGeometry.sectors * 512;
|
||||
off_t deviceSize = bytesPerCylinder * hdGeometry.cylinders;
|
||||
off_t partitionSize = get_partition_size(fd, deviceSize);
|
||||
|
||||
geometry->head_count = hdGeometry.heads;
|
||||
geometry->cylinder_count = partitionSize / bytesPerCylinder;
|
||||
geometry->sectors_per_track = hdGeometry.sectors;
|
||||
|
||||
// TODO: Get the real values...
|
||||
geometry->bytes_per_sector = 512;
|
||||
geometry->device_type = B_DISK;
|
||||
geometry->removable = false;
|
||||
geometry->read_only = false;
|
||||
geometry->write_once = false;
|
||||
error = FS_OK;
|
||||
} else
|
||||
error = from_platform_error(errno);
|
||||
}
|
||||
#endif // HAIKU_HOST_PLATFORM_LINUX
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 20: // B_FLUSH_DRIVE_CACHE
|
||||
error = FS_OK;
|
||||
break;
|
||||
|
||||
case 10000: // IOCTL_FILE_UNCACHED_IO
|
||||
error = FS_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(list);
|
||||
|
||||
if (error != FS_OK) {
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* ! __BEOS__ */
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
void
|
||||
panic(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
while (TRUE)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "lock.h"
|
||||
|
||||
int
|
||||
new_lock(lock *l, const char *name)
|
||||
{
|
||||
l->c = 1;
|
||||
l->s = create_sem(0, (char *)name);
|
||||
if (l->s <= 0)
|
||||
return l->s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
free_lock(lock *l)
|
||||
{
|
||||
delete_sem(l->s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
new_mlock(mlock *l, long c, const char *name)
|
||||
{
|
||||
l->s = create_sem(c, (char *)name);
|
||||
if (l->s <= 0)
|
||||
return l->s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
free_mlock(mlock *l)
|
||||
{
|
||||
delete_sem(l->s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef unix
|
||||
#include <sys/time.h>
|
||||
|
||||
bigtime_t
|
||||
system_time(void)
|
||||
{
|
||||
bigtime_t t;
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
t = ((bigtime_t)tv.tv_sec * 1000000) + (bigtime_t)tv.tv_usec;
|
||||
return t;
|
||||
}
|
||||
|
||||
/*
|
||||
If you're compiler/system can't deal with the version of system_time()
|
||||
as defined above, use this one instead
|
||||
bigtime_t
|
||||
system_time(void)
|
||||
{
|
||||
return (bigtime_t)time(NULL);
|
||||
}
|
||||
*/
|
||||
|
||||
#endif /* unix */
|
||||
|
||||
#if (defined(__BEOS__) || defined(__HAIKU__))
|
||||
#include <KernelExport.h>
|
||||
|
||||
void
|
||||
dprintf(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,78 +0,0 @@
|
||||
#include "tracker.h"
|
||||
#include "kprotos.h"
|
||||
|
||||
//#include <map>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
port_id gTrackerPort;
|
||||
|
||||
|
||||
/*static void
|
||||
tracker_query_attributes(dev_t device, ino_t node, char *name)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
static void
|
||||
tracker_query_file(dev_t device, ino_t parent, char *name)
|
||||
{
|
||||
if (name == NULL || parent == 0)
|
||||
return;
|
||||
|
||||
int fd = sys_open_entry_ref(1, device, parent, name, O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
printf("tracker: could not open file: %s\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
struct my_stat stat;
|
||||
int status = sys_rstat(true, fd, NULL, &stat, 1);
|
||||
if (status < 0) {
|
||||
printf("tracker: could not stat file: %s\n", name);
|
||||
}
|
||||
|
||||
sys_close(true, fd);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
tracker_scan_files(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" int32
|
||||
tracker_loop(void *data)
|
||||
{
|
||||
// create global messaging port
|
||||
|
||||
gTrackerPort = create_port(128, "fsh tracker port");
|
||||
if (gTrackerPort < FS_OK)
|
||||
return gTrackerPort;
|
||||
|
||||
while (true) {
|
||||
update_message message;
|
||||
int32 code;
|
||||
status_t status = read_port(gTrackerPort, &code, &message, sizeof(message));
|
||||
if (status < FS_OK)
|
||||
continue;
|
||||
|
||||
if (code == FSH_KILL_TRACKER)
|
||||
break;
|
||||
|
||||
if (code == FSH_NOTIFY_LISTENER) {
|
||||
printf("tracker: notify listener received\n");
|
||||
if (message.op != B_ATTR_CHANGED && message.op != B_DEVICE_UNMOUNTED)
|
||||
tracker_query_file(message.device, message.parentNode, message.name);
|
||||
} else if (code == B_QUERY_UPDATE) {
|
||||
printf("tracker: query update received\n");
|
||||
tracker_query_file(message.device, message.parentNode, message.name);
|
||||
} else {
|
||||
printf("tracker: unknown code received: 0x%lx\n", code);
|
||||
}
|
||||
}
|
||||
|
||||
delete_port(gTrackerPort);
|
||||
return FS_OK;
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
#ifndef TRACKER_H
|
||||
#define TRACKER_H
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <OS.h>
|
||||
#include <AppDefs.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
#define FSH_KILL_TRACKER 'kill'
|
||||
#define FSH_NOTIFY_LISTENER 'notl'
|
||||
|
||||
typedef struct update_message {
|
||||
int32 op;
|
||||
dev_t device;
|
||||
dev_t toDevice;
|
||||
ino_t parentNode;
|
||||
ino_t targetNode;
|
||||
ino_t node;
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
} update_message;
|
||||
|
||||
|
||||
extern port_id gTrackerPort;
|
||||
|
||||
extern
|
||||
#ifdef __cplusplus
|
||||
"C"
|
||||
#endif
|
||||
int32 tracker_loop(void *data);
|
||||
|
||||
#endif /* TRACKER_H */
|
@ -1,257 +0,0 @@
|
||||
/*
|
||||
This file contains a simple test program that can be used as a sort
|
||||
of stress test for the file system. It's not exhaustive but it provides
|
||||
a decent first level sanity check on whether a file system will work.
|
||||
|
||||
Basically it just randomly creates and deletes files. The defines
|
||||
just after the includes control how many files and how many iterations.
|
||||
Be careful if you just bump up the numbers really high -- it will take
|
||||
a long time to run and if you only have a 16 megabyte file system
|
||||
it will probably run out of space.
|
||||
|
||||
|
||||
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
|
||||
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
|
||||
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
|
||||
|
||||
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
|
||||
|
||||
Dominic Giampaolo
|
||||
dbg@be.com
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "myfs.h"
|
||||
#include "kprotos.h"
|
||||
|
||||
#define MAX_LOOPS 1024
|
||||
#define MAX_FILES 512
|
||||
#define MAX_NAME 24
|
||||
|
||||
char buf[MAX_FILES][MAX_NAME];
|
||||
fs_off_t sizes[MAX_FILES];
|
||||
|
||||
|
||||
static void
|
||||
make_random_name(char *buf, int len)
|
||||
{
|
||||
int i, max = (rand() % (len - 7)) + 6;
|
||||
|
||||
for(i=0; i < max; i++) {
|
||||
buf[i] = 'a' + (rand() % 26);
|
||||
}
|
||||
|
||||
buf[i] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
SubTime(struct timeval *a, struct timeval *b, struct timeval *c)
|
||||
{
|
||||
if ((long)(a->tv_usec - b->tv_usec) < 0)
|
||||
{
|
||||
a->tv_sec--;
|
||||
a->tv_usec += 1000000;
|
||||
}
|
||||
|
||||
c->tv_sec = a->tv_sec - b->tv_sec;
|
||||
c->tv_usec = a->tv_usec - b->tv_usec;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
write_rand_data(int fd, int max_data)
|
||||
{
|
||||
int i, k, err;
|
||||
size_t j;
|
||||
static char buf[4096];
|
||||
ulong sum = 0;
|
||||
|
||||
for(i=0; max_data > 0; i++) {
|
||||
j = rand() % sizeof(buf);
|
||||
if ((int)(max_data - j) < 0)
|
||||
j = max_data;
|
||||
|
||||
memset(buf, rand() >> 8, j);
|
||||
|
||||
for(k=0; k < j; k++)
|
||||
sum += buf[k];
|
||||
|
||||
/* printf("write: %d\n", j); */
|
||||
err = sys_write(1, fd, buf, j);
|
||||
if (err != j) {
|
||||
errno = err;
|
||||
perror("write_rand_data");
|
||||
printf("err %d j %d\n", err, j);
|
||||
if (errno != ENOSPC)
|
||||
while(1)
|
||||
sleep(1);
|
||||
break;
|
||||
}
|
||||
|
||||
max_data -= j;
|
||||
}
|
||||
|
||||
#if INSANELY_SLOW_CHECKSUM
|
||||
pos = 0;
|
||||
err = sys_lseek(1, fd, SEEK_SET, &pos);
|
||||
for(i=0; i < max; i++) {
|
||||
j = sizeof(buf);
|
||||
sys_read(1, fd, buf, j);
|
||||
for(k=0; k < j; k++)
|
||||
nsum += buf[k];
|
||||
}
|
||||
|
||||
if (sum != nsum)
|
||||
printf("sum = 0x%x, nsum 0x%x\n", sum, nsum);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i, j, fd, seed, err, size, sum, name_size = 0;
|
||||
struct my_stat st;
|
||||
struct timeval start, end, result;
|
||||
char *disk_name = "big_file";
|
||||
myfs_info *myfs;
|
||||
|
||||
|
||||
if (argv[1] != NULL && !isdigit(argv[1][0]))
|
||||
disk_name = argv[1];
|
||||
else if (argv[1] && isdigit(argv[1][0]))
|
||||
seed = strtoul(argv[1], NULL, 0);
|
||||
else
|
||||
seed = getpid() * time(NULL) | 1;
|
||||
printf("random seed == 0x%x\n", seed);
|
||||
|
||||
srand(seed);
|
||||
|
||||
myfs = init_fs(disk_name);
|
||||
|
||||
|
||||
for(i=0; i < MAX_FILES; i++)
|
||||
buf[i][0] = '\0';
|
||||
|
||||
|
||||
printf("creating & deleting files...\n"); fflush(stdout);
|
||||
gettimeofday(&start, NULL);
|
||||
for(i=0,sum=0; i < MAX_LOOPS; i++) {
|
||||
j = rand() % MAX_FILES;
|
||||
|
||||
size = (rand() % 65536) + 1;
|
||||
|
||||
#if 1
|
||||
if ((i % 10) == 0) {
|
||||
printf("\r \r");
|
||||
printf("iteration: %7d", i);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (buf[j][0] == '\0') { /* then create a file */
|
||||
strcpy(&buf[j][0], "/myfs/");
|
||||
make_random_name(&buf[j][6], MAX_NAME-6);
|
||||
name_size += strlen(&buf[j][6]);
|
||||
|
||||
sum += sizes[j] = size;
|
||||
|
||||
/* printf("\rcreating: %s %d bytes", &buf[j][0], size); */
|
||||
|
||||
fd = sys_open(1, -1, &buf[j][0], O_CREAT|O_RDWR,
|
||||
MY_S_IFREG|MY_S_IRWXU, 0);
|
||||
|
||||
if (fd < 0) {
|
||||
printf("error creating: %s\n", &buf[j][0]);
|
||||
break;
|
||||
}
|
||||
|
||||
write_rand_data(fd, size);
|
||||
|
||||
sys_close(1, fd);
|
||||
} else { /* then delete the file */
|
||||
/* printf("\runlinking %s", &buf[j][0]); */
|
||||
name_size -= strlen(&buf[j][6]);
|
||||
|
||||
err = sys_unlink(1, -1, &buf[j][0]);
|
||||
if (err != 0) {
|
||||
printf("error removing: %s: %s\n", &buf[j][0], strerror(err));
|
||||
break;
|
||||
}
|
||||
|
||||
buf[j][0] = '\0';
|
||||
sum -= sizes[j];
|
||||
}
|
||||
|
||||
#if 0 /* doing this is really anal */
|
||||
for(k=0; k < MAX_FILES; k++) {
|
||||
if (buf[k][0] == '\0')
|
||||
continue;
|
||||
|
||||
fd = sys_open(1, -1, &buf[k][0], O_RDWR, 0, 0);
|
||||
if (fd < 0) {
|
||||
printf("file: %s is not present and should be!\n", &buf[k][0]);
|
||||
sys_unmount(1, -1, "/myfs");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
sys_close(1, fd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
gettimeofday(&end, NULL);
|
||||
SubTime(&end, &start, &result);
|
||||
|
||||
printf("\rcreated %d files in %2ld.%.6ld seconds (%d k data)\n", i,
|
||||
result.tv_sec, result.tv_usec, sum/1024);
|
||||
|
||||
printf("now verifying files....\n");
|
||||
for(i=0; i < MAX_FILES; i++) {
|
||||
if (buf[i][0] == '\0')
|
||||
continue;
|
||||
|
||||
printf(" \r");
|
||||
printf("opening: %s\r", &buf[i][0]);
|
||||
fflush(stdout);
|
||||
|
||||
fd = sys_open(1, -1, &buf[i][0], O_RDWR, 0, 0);
|
||||
if (fd != 0) {
|
||||
printf("file: %s is not present and should be!\n", &buf[i][0]);
|
||||
sys_unmount(1, -1, "/myfs");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
err = sys_rstat(1, -1, &buf[i][0], &st, 1);
|
||||
if (err != 0) {
|
||||
printf("stat failed for: %s\n", &buf[i][0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (st.st_size != sizes[i]) {
|
||||
printf("size mismatch on %s: %ld != %ld\n", &buf[i][0],
|
||||
st.st_size, sizes[i]);
|
||||
}
|
||||
|
||||
sys_close(1, fd);
|
||||
}
|
||||
printf("done verifying files \n");
|
||||
|
||||
if (sys_unmount(1, -1, "/myfs") != 0) {
|
||||
printf("could not UNmount /myfs\n");
|
||||
return 5;
|
||||
}
|
||||
|
||||
shutdown_block_cache();
|
||||
|
||||
/* check_mem(); */
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2005, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef FS_SHELL_XCP_H
|
||||
#define FS_SHELL_XCP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int do_xcp(int argc, char **argv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // FS_SHELL_XCP_H
|
Loading…
Reference in New Issue
Block a user