Merge branch 'master' into package-management
Additional changes: * Add src/system/kernel/lib/zlib, which builds a kernel version of zlib, needed by packagefs. * BuildFeatures: Add a build feature "gcc2" to allow for easier checks. * Referenceable.cpp: Include <OS.h> instead of <debugger.h>. The latter is not needed and prevents building for the build platform. * zlib/zutil.h: Fix gcc 2 build. We really should use the external package instead. Conflicts: .gitignore build/jam/BuildSetup build/jam/FileRules build/jam/FloppyBootImage build/jam/HaikuImage build/jam/ImageRules build/jam/KernelRules build/jam/NetBootArchive build/jam/OptionalBuildFeatures build/jam/OptionalLibPackages build/jam/OptionalPackageDependencies build/jam/OptionalPackages build/scripts/build_haiku_image configure data/bin/installoptionalpackage data/system/boot/Bootscript headers/os/app/Message.h headers/os/package/PackageInfo.h headers/os/package/PackageInfoAttributes.h headers/os/package/PackageInfoSet.h headers/os/package/PackageRoster.h headers/os/package/PackageVersion.h headers/os/package/hpkg/PackageInfoAttributeValue.h headers/os/storage/FindDirectory.h headers/os/storage/Node.h headers/os/support/StringList.h headers/private/system/directories.h src/add-ons/kernel/drivers/audio/ac97/es1370/Jamfile src/add-ons/kernel/file_systems/packagefs/AttributeIndex.cpp src/add-ons/kernel/file_systems/packagefs/Jamfile src/add-ons/kernel/file_systems/packagefs/Package.cpp src/add-ons/kernel/file_systems/packagefs/Package.h src/add-ons/kernel/file_systems/packagefs/PackageDomain.cpp src/add-ons/kernel/file_systems/packagefs/PackageDomain.h src/add-ons/kernel/file_systems/packagefs/PackageFSRoot.cpp src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.cpp src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.h src/add-ons/kernel/file_systems/packagefs/PackageLinkSymlink.cpp src/add-ons/kernel/file_systems/packagefs/PackageLinkSymlink.h src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.cpp src/add-ons/kernel/file_systems/packagefs/PackageNode.h src/add-ons/kernel/file_systems/packagefs/ResolvableFamily.cpp src/add-ons/kernel/file_systems/packagefs/Version.cpp src/add-ons/kernel/file_systems/packagefs/Version.h src/add-ons/kernel/file_systems/packagefs/Volume.cpp src/add-ons/kernel/file_systems/packagefs/Volume.h src/add-ons/kernel/file_systems/packagefs/kernel_interface.cpp src/add-ons/kernel/file_systems/userlandfs/shared/driver_settings.c src/apps/deskbar/BarApp.cpp src/apps/deskbar/BarMenuBar.cpp src/apps/deskbar/BarMenuBar.h src/apps/deskbar/BarView.cpp src/apps/deskbar/BarView.h src/apps/deskbar/BarWindow.cpp src/apps/deskbar/BarWindow.h src/apps/deskbar/DeskbarMenu.cpp src/apps/deskbar/DeskbarMenu.h src/apps/deskbar/DeskbarUtils.cpp src/apps/deskbar/DeskbarUtils.h src/apps/deskbar/ExpandoMenuBar.cpp src/apps/deskbar/ExpandoMenuBar.h src/apps/deskbar/TeamMenu.cpp src/apps/processcontroller/ProcessController.cpp src/apps/remotedesktop/RemoteDesktop.cpp src/bin/bash/config-top.h src/bin/finddir.c src/bin/package/Jamfile src/bin/package/command_add.cpp src/bin/package/command_create.cpp src/bin/package/command_list.cpp src/bin/package_repo/command_list.cpp src/bin/pkgman/command_refresh.cpp src/build/libbe/support/Jamfile src/build/libpackage/Jamfile src/build/libroot/Jamfile src/build/libroot/fs.cpp src/build/libroot/remapped_functions.h src/kits/locale/MutableLocaleRoster.cpp src/kits/opengl/GLRendererRoster.cpp src/kits/package/PackageInfo.cpp src/kits/package/PackageInfoSet.cpp src/kits/package/PackageRoster.cpp src/kits/package/PackageVersion.cpp src/kits/package/RepositoryCache.cpp src/kits/package/hpkg/PackageWriterImpl.cpp src/kits/package/hpkg/ReaderImplBase.cpp src/kits/package/hpkg/WriterImplBase.cpp src/kits/print/PrintTransport.cpp src/kits/print/Printer.cpp src/kits/screensaver/ScreenSaverRunner.cpp src/kits/support/StringList.cpp src/kits/tracker/ContainerWindow.cpp src/kits/tracker/DeskWindow.cpp src/kits/tracker/PoseView.cpp src/libs/print/libprint/Transport.cpp src/preferences/printers/AddPrinterDialog.cpp src/preferences/screensaver/ScreenSaverWindow.cpp src/servers/debug/DebugServer.cpp src/servers/input/AddOnManager.cpp src/servers/media_addon/MediaAddonServer.cpp src/system/boot/Jamfile src/system/boot/loader/Jamfile src/system/boot/loader/loader.cpp src/system/boot/loader/vfs.cpp src/system/kernel/fs/vfs.cpp src/system/kernel/fs/vfs_boot.cpp src/system/libroot/os/find_directory.cpp src/system/runtime_loader/runtime_loader.cpp src/tools/package/Jamfile
This commit is contained in:
@@ -86,8 +86,6 @@ if $(HOST_PLATFORM_BEOS_COMPATIBLE) {
|
||||
|
||||
BuildPlatformMain <build>mkindex : mkindex.cpp : $(HOST_LIBBE) ;
|
||||
|
||||
# We want rm_attrs to be self-contained, so we link against the static libroot.
|
||||
HOST_LIBROOT on <build>rm_attrs_tmp = $(HOST_STATIC_LIBROOT) ;
|
||||
BuildPlatformMain <build>rm_attrs_tmp : rm_attrs.cpp
|
||||
: $(HOST_LIBSUPC++) $(HOST_LIBSTDC++) ;
|
||||
MakeLocateDebug <build>rm_attrs ;
|
||||
@@ -146,4 +144,3 @@ SubInclude HAIKU_TOP src tools unzip ;
|
||||
SubInclude HAIKU_TOP src tools vmdkimage ;
|
||||
SubInclude HAIKU_TOP src tools unflatten ;
|
||||
SubInclude HAIKU_TOP src tools zip ;
|
||||
|
||||
|
||||
@@ -33,9 +33,16 @@ if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
|
||||
fsShellCommandLibs = $(HOST_NETWORK_LIBS) ;
|
||||
}
|
||||
|
||||
UsePrivateHeaders storage ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers build ] : true ;
|
||||
|
||||
if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers build os ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers build os support ] : true ;
|
||||
}
|
||||
|
||||
UsePrivateHeaders shared storage ;
|
||||
UsePrivateHeaders fs_shell ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src tools fs_shell ] ;
|
||||
|
||||
local bfsSource =
|
||||
bfs_disk_system.cpp
|
||||
@@ -47,7 +54,6 @@ local bfsSource =
|
||||
Inode.cpp
|
||||
Journal.cpp
|
||||
Query.cpp
|
||||
Utility.cpp
|
||||
Volume.cpp
|
||||
|
||||
kernel_interface.cpp
|
||||
@@ -57,6 +63,8 @@ BuildPlatformMergeObject <build>bfs.o : $(bfsSource) ;
|
||||
|
||||
BuildPlatformMain <build>bfs_shell
|
||||
:
|
||||
additional_commands.cpp
|
||||
command_checkfs.cpp
|
||||
:
|
||||
<build>bfs.o
|
||||
<build>fs_shell.a $(libHaikuCompat) $(HOST_LIBSUPC++) $(HOST_LIBSTDC++)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2012, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "fssh.h"
|
||||
|
||||
#include "command_checkfs.h"
|
||||
|
||||
|
||||
namespace FSShell {
|
||||
|
||||
|
||||
void
|
||||
register_additional_commands()
|
||||
{
|
||||
CommandManager::Default()->AddCommand(command_checkfs, "checkfs",
|
||||
"check file system");
|
||||
}
|
||||
|
||||
|
||||
} // namespace FSShell
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2008-2012, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "fssh_stdio.h"
|
||||
#include "syscalls.h"
|
||||
|
||||
#include "bfs.h"
|
||||
#include "bfs_control.h"
|
||||
|
||||
|
||||
namespace FSShell {
|
||||
|
||||
|
||||
fssh_status_t
|
||||
command_checkfs(int argc, const char* const* argv)
|
||||
{
|
||||
if (argc == 2 && !strcmp(argv[1], "--help")) {
|
||||
fssh_dprintf("Usage: %s [-c]\n"
|
||||
" -c Check only; don't perform any changes\n", argv[0]);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
bool checkOnly = false;
|
||||
if (argc == 2 && !strcmp(argv[1], "-c"))
|
||||
checkOnly = true;
|
||||
|
||||
int rootDir = _kern_open_dir(-1, "/myfs");
|
||||
if (rootDir < 0)
|
||||
return rootDir;
|
||||
|
||||
struct check_control result;
|
||||
memset(&result, 0, sizeof(result));
|
||||
result.magic = BFS_IOCTL_CHECK_MAGIC;
|
||||
result.flags = 0;
|
||||
if (!checkOnly) {
|
||||
result.flags |= BFS_FIX_BITMAP_ERRORS | BFS_REMOVE_WRONG_TYPES
|
||||
| BFS_REMOVE_INVALID | BFS_FIX_NAME_MISMATCHES | BFS_FIX_BPLUSTREES;
|
||||
}
|
||||
|
||||
// start checking
|
||||
fssh_status_t status = _kern_ioctl(rootDir, BFS_IOCTL_START_CHECKING,
|
||||
&result, sizeof(result));
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
uint64 attributeDirectories = 0, attributes = 0;
|
||||
uint64 files = 0, directories = 0, indices = 0;
|
||||
uint64 counter = 0;
|
||||
uint32 previousPass = result.pass;
|
||||
|
||||
// check all files and report errors
|
||||
while (_kern_ioctl(rootDir, BFS_IOCTL_CHECK_NEXT_NODE, &result,
|
||||
sizeof(result)) == B_OK) {
|
||||
if (++counter % 50 == 0)
|
||||
fssh_dprintf("%9Ld nodes processed\x1b[1A\n", counter);
|
||||
|
||||
if (result.pass == BFS_CHECK_PASS_BITMAP) {
|
||||
if (result.errors) {
|
||||
fssh_dprintf("%s (inode = %lld)", result.name, result.inode);
|
||||
if ((result.errors & BFS_MISSING_BLOCKS) != 0)
|
||||
fssh_dprintf(", some blocks weren't allocated");
|
||||
if ((result.errors & BFS_BLOCKS_ALREADY_SET) != 0)
|
||||
fssh_dprintf(", has blocks already set");
|
||||
if ((result.errors & BFS_INVALID_BLOCK_RUN) != 0)
|
||||
fssh_dprintf(", has invalid block run(s)");
|
||||
if ((result.errors & BFS_COULD_NOT_OPEN) != 0)
|
||||
fssh_dprintf(", could not be opened");
|
||||
if ((result.errors & BFS_WRONG_TYPE) != 0)
|
||||
fssh_dprintf(", has wrong type");
|
||||
if ((result.errors & BFS_NAMES_DONT_MATCH) != 0)
|
||||
fssh_dprintf(", names don't match");
|
||||
if ((result.errors & BFS_INVALID_BPLUSTREE) != 0)
|
||||
fssh_dprintf(", invalid b+tree");
|
||||
fssh_dprintf("\n");
|
||||
}
|
||||
|
||||
if ((result.mode & (S_INDEX_DIR | 0777)) == S_INDEX_DIR)
|
||||
indices++;
|
||||
else if (result.mode & S_ATTR_DIR)
|
||||
attributeDirectories++;
|
||||
else if (result.mode & S_ATTR)
|
||||
attributes++;
|
||||
else if (S_ISDIR(result.mode))
|
||||
directories++;
|
||||
else
|
||||
files++;
|
||||
} else if (result.pass == BFS_CHECK_PASS_INDEX) {
|
||||
if (previousPass != result.pass) {
|
||||
fssh_dprintf("Recreating broken index b+trees...\n");
|
||||
previousPass = result.pass;
|
||||
counter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stop checking
|
||||
if (_kern_ioctl(rootDir, BFS_IOCTL_STOP_CHECKING, &result, sizeof(result))
|
||||
!= B_OK) {
|
||||
_kern_close(rootDir);
|
||||
return errno;
|
||||
}
|
||||
|
||||
_kern_close(rootDir);
|
||||
|
||||
fssh_dprintf(" %" B_PRIu64 " nodes checked,\n\t%" B_PRIu64 " blocks "
|
||||
"not allocated,\n\t%" B_PRIu64 " blocks already set,\n\t%" B_PRIu64
|
||||
" blocks could be freed\n\n", counter, result.stats.missing,
|
||||
result.stats.already_set, result.stats.freed);
|
||||
fssh_dprintf("\tfiles\t\t%" B_PRIu64 "\n\tdirectories\t%" B_PRIu64 "\n"
|
||||
"\tattributes\t%" B_PRIu64 "\n\tattr. dirs\t%" B_PRIu64 "\n"
|
||||
"\tindices\t\t%" B_PRIu64 "\n", files, directories, attributes,
|
||||
attributeDirectories, indices);
|
||||
|
||||
fssh_dprintf("\n\tdirect block runs\t\t%" B_PRIu64 " (%lld)\n",
|
||||
result.stats.direct_block_runs,
|
||||
result.stats.blocks_in_direct * result.stats.block_size);
|
||||
fssh_dprintf("\tindirect block runs\t\t%" B_PRIu64 " (in %" B_PRIu64
|
||||
" array blocks, %lld)\n", result.stats.indirect_block_runs,
|
||||
result.stats.indirect_array_blocks,
|
||||
result.stats.blocks_in_indirect * result.stats.block_size);
|
||||
fssh_dprintf("\tdouble indirect block runs\t%" B_PRIu64 " (in %" B_PRIu64
|
||||
" array blocks, %lld)\n", result.stats.double_indirect_block_runs,
|
||||
result.stats.double_indirect_array_blocks,
|
||||
result.stats.blocks_in_double_indirect * result.stats.block_size);
|
||||
|
||||
if (result.status == B_ENTRY_NOT_FOUND)
|
||||
result.status = B_OK;
|
||||
|
||||
return result.status;
|
||||
}
|
||||
|
||||
|
||||
} // namespace FSShell
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef CHECKFS_H
|
||||
#define CHECKFS_H
|
||||
|
||||
|
||||
#include "fssh_types.h"
|
||||
|
||||
|
||||
namespace FSShell {
|
||||
|
||||
|
||||
fssh_status_t command_checkfs(int argc, const char* const* argv);
|
||||
|
||||
|
||||
} // namespace FSShell
|
||||
|
||||
|
||||
#endif // CHECKFS_H
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2012 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Alexander von Gluck, [email protected]
|
||||
*/
|
||||
|
||||
/*
|
||||
* Pass a standard CPUID in hex, and get out a CPUID for OS.h
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define EXT_FAMILY_MASK 0xF00000
|
||||
#define EXT_MODEL_MASK 0x0F0000
|
||||
#define FAMILY_MASK 0x000F00
|
||||
#define MODEL_MASK 0x0000F0
|
||||
#define STEPPING_MASK 0x00000F
|
||||
|
||||
|
||||
// Converts a hexadecimal string to integer
|
||||
static int
|
||||
xtoi(const char* xs, unsigned int* result)
|
||||
{
|
||||
size_t szlen = strlen(xs);
|
||||
int i;
|
||||
int xv;
|
||||
int fact;
|
||||
|
||||
if (szlen > 0) {
|
||||
// Converting more than 32bit hexadecimal value?
|
||||
if (szlen > 8)
|
||||
return 2;
|
||||
|
||||
// Begin conversion here
|
||||
*result = 0;
|
||||
fact = 1;
|
||||
|
||||
// Run until no more character to convert
|
||||
for (i = szlen - 1; i>=0; i--) {
|
||||
if (isxdigit(*(xs + i))) {
|
||||
if (*(xs + i) >= 97)
|
||||
xv = (*(xs + i) - 97) + 10;
|
||||
else if (*(xs + i) >= 65)
|
||||
xv = (*(xs + i) - 65) + 10;
|
||||
else
|
||||
xv = *(xs + i) - 48;
|
||||
|
||||
*result += (xv * fact);
|
||||
fact *= 16;
|
||||
} else {
|
||||
// Conversion was abnormally terminated
|
||||
// by non hexadecimal digit, hence
|
||||
// returning only the converted with
|
||||
// an error value 4 (illegal hex character)
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing to convert
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 3) {
|
||||
printf("Provide the cpuid in hex, and you will get how we id it\n");
|
||||
printf("usage: cpuidhaiku <AMD|INTEL> <cpuid_hex>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int cpuid = 0;
|
||||
xtoi(argv[2], &cpuid);
|
||||
|
||||
printf("cpuid: 0x%X\n", cpuid);
|
||||
|
||||
unsigned int extFam = (cpuid & EXT_FAMILY_MASK) >> 20;
|
||||
unsigned int extMod = (cpuid & EXT_MODEL_MASK) >> 16;
|
||||
unsigned int family = (cpuid & FAMILY_MASK) >> 8;
|
||||
unsigned int model = (cpuid & MODEL_MASK) >> 4;
|
||||
unsigned int stepping = (cpuid & STEPPING_MASK);
|
||||
|
||||
unsigned int cpuidHaiku;
|
||||
if (strncmp(argv[1], "AMD", 3) == 0) {
|
||||
if (family == 0xF) {
|
||||
cpuidHaiku = (extFam << 20) + (extMod << 16)
|
||||
+ (family << 4) + model;
|
||||
} else
|
||||
cpuidHaiku = (family << 4) + model;
|
||||
cpuidHaiku += 0x1100; // AMD vendor id
|
||||
} else if (strncmp(argv[1], "INTEL", 5) == 0) {
|
||||
cpuidHaiku = (extFam << 20) + (extMod << 16)
|
||||
+ (family << 4) + model;
|
||||
cpuidHaiku += 0x1000; // Intel vendor id
|
||||
} else {
|
||||
printf("Vendor should be AMD or INTEL\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Haiku CPUID: 0x%lx\n", cpuidHaiku);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -4,9 +4,7 @@ UseHeaders [ FDirName $(HAIKU_TOP) headers build ] : true ;
|
||||
|
||||
if ! $(HOST_PLATFORM_BEOS_COMPATIBLE) {
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers build os ] : true ;
|
||||
#UseHeaders [ FDirName $(HAIKU_TOP) headers build os app ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers build os kernel ] : true ;
|
||||
#UseHeaders [ FDirName $(HAIKU_TOP) headers build os interface ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers build os storage ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers build os support ] : true ;
|
||||
}
|
||||
@@ -80,11 +78,15 @@ BuildPlatformStaticLibrary <build>fs_shell.a :
|
||||
$(externalCommandsSources)
|
||||
|
||||
fssh.cpp
|
||||
fssh_additional_commands.cpp
|
||||
|
||||
: <build>fs_shell_kernel.o
|
||||
;
|
||||
|
||||
SEARCH on [ FGristFiles rootfs.cpp ]
|
||||
= [ FDirName $(HAIKU_TOP) src system kernel fs ] ;
|
||||
SEARCH on [ FGristFiles file_map.cpp ]
|
||||
= [ FDirName $(HAIKU_TOP) src system kernel cache ] ;
|
||||
|
||||
BuildPlatformMain <build>fs_shell_command
|
||||
: fs_shell_command.cpp $(fsShellCommandSources)
|
||||
|
||||
@@ -173,7 +173,7 @@ static fssh_mutex sNotificationsLock;
|
||||
// #pragma mark - notifications/listener
|
||||
|
||||
|
||||
/*! Checks wether or not this is an event that closes a transaction. */
|
||||
/*! Checks whether or not this is an event that closes a transaction. */
|
||||
static inline bool
|
||||
is_closing_event(int32_t event)
|
||||
{
|
||||
@@ -709,7 +709,7 @@ put_cached_block(block_cache* cache, fssh_off_t blockNumber)
|
||||
/*! Retrieves the block \a blockNumber from the hash table, if it's already
|
||||
there, or reads it from the disk.
|
||||
|
||||
\param _allocated tells you wether or not a new block has been allocated
|
||||
\param _allocated tells you whether or not a new block has been allocated
|
||||
to satisfy your request.
|
||||
\param readBlock if \c false, the block will not be read in case it was
|
||||
not already in the cache. The block you retrieve may contain random
|
||||
@@ -927,7 +927,7 @@ write_cached_block(block_cache* cache, cached_block* block,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (block->transaction == NULL && block->ref_count == 0) {
|
||||
if (block->transaction == NULL && block->ref_count == 0 && !block->unused) {
|
||||
// the block is no longer used
|
||||
block->unused = true;
|
||||
cache->unused_blocks.Add(block);
|
||||
|
||||
@@ -64,7 +64,7 @@ struct file_cache_ref {
|
||||
fssh_mutex lock;
|
||||
fssh_mount_id mountID;
|
||||
fssh_vnode_id nodeID;
|
||||
void* node;
|
||||
struct vnode* node;
|
||||
fssh_off_t virtual_size;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,511 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2008, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "fssh_fs_cache.h"
|
||||
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fssh_kernel_export.h"
|
||||
#include "vfs.h"
|
||||
|
||||
|
||||
//#define TRACE_FILE_MAP
|
||||
#ifdef TRACE_FILE_MAP
|
||||
# define TRACE(x) fssh_dprintf x
|
||||
#else
|
||||
# define TRACE(x) ;
|
||||
#endif
|
||||
|
||||
#define CACHED_FILE_EXTENTS 2
|
||||
// must be smaller than MAX_FILE_IO_VECS
|
||||
// ToDo: find out how much of these are typically used
|
||||
|
||||
using namespace FSShell;
|
||||
|
||||
namespace FSShell {
|
||||
|
||||
struct file_extent {
|
||||
fssh_off_t offset;
|
||||
fssh_file_io_vec disk;
|
||||
};
|
||||
|
||||
struct file_extent_array {
|
||||
file_extent* array;
|
||||
fssh_size_t max_count;
|
||||
};
|
||||
|
||||
class FileMap {
|
||||
public:
|
||||
FileMap(void* vnode, fssh_off_t size);
|
||||
~FileMap();
|
||||
|
||||
void Invalidate(fssh_off_t offset, fssh_off_t size);
|
||||
void SetSize(fssh_off_t size);
|
||||
|
||||
fssh_status_t Translate(fssh_off_t offset, fssh_size_t size,
|
||||
fssh_file_io_vec* vecs, fssh_size_t* _count,
|
||||
fssh_size_t align);
|
||||
|
||||
file_extent* ExtentAt(uint32_t index);
|
||||
|
||||
fssh_size_t Count() const { return fCount; }
|
||||
void* Vnode() const { return fVnode; }
|
||||
fssh_off_t Size() const { return fSize; }
|
||||
|
||||
fssh_status_t SetMode(uint32_t mode);
|
||||
|
||||
private:
|
||||
file_extent* _FindExtent(fssh_off_t offset, uint32_t* _index);
|
||||
fssh_status_t _MakeSpace(fssh_size_t count);
|
||||
fssh_status_t _Add(fssh_file_io_vec* vecs, fssh_size_t vecCount,
|
||||
fssh_off_t& lastOffset);
|
||||
fssh_status_t _Cache(fssh_off_t offset, fssh_off_t size);
|
||||
void _InvalidateAfter(fssh_off_t offset);
|
||||
void _Free();
|
||||
|
||||
union {
|
||||
file_extent fDirect[CACHED_FILE_EXTENTS];
|
||||
file_extent_array fIndirect;
|
||||
};
|
||||
fssh_mutex fLock;
|
||||
fssh_size_t fCount;
|
||||
void* fVnode;
|
||||
fssh_off_t fSize;
|
||||
bool fCacheAll;
|
||||
};
|
||||
|
||||
|
||||
FileMap::FileMap(void* vnode, fssh_off_t size)
|
||||
:
|
||||
fCount(0),
|
||||
fVnode(vnode),
|
||||
fSize(size),
|
||||
fCacheAll(false)
|
||||
{
|
||||
fssh_mutex_init(&fLock, "file map");
|
||||
}
|
||||
|
||||
|
||||
FileMap::~FileMap()
|
||||
{
|
||||
_Free();
|
||||
fssh_mutex_destroy(&fLock);
|
||||
}
|
||||
|
||||
|
||||
file_extent*
|
||||
FileMap::ExtentAt(uint32_t index)
|
||||
{
|
||||
if (index >= fCount)
|
||||
return NULL;
|
||||
|
||||
if (fCount > CACHED_FILE_EXTENTS)
|
||||
return &fIndirect.array[index];
|
||||
|
||||
return &fDirect[index];
|
||||
}
|
||||
|
||||
|
||||
file_extent*
|
||||
FileMap::_FindExtent(fssh_off_t offset, uint32_t *_index)
|
||||
{
|
||||
int32_t left = 0;
|
||||
int32_t right = fCount - 1;
|
||||
|
||||
while (left <= right) {
|
||||
int32_t index = (left + right) / 2;
|
||||
file_extent* extent = ExtentAt(index);
|
||||
|
||||
if (extent->offset > offset) {
|
||||
// search in left part
|
||||
right = index - 1;
|
||||
} else if (extent->offset + extent->disk.length <= offset) {
|
||||
// search in right part
|
||||
left = index + 1;
|
||||
} else {
|
||||
// found extent
|
||||
if (_index)
|
||||
*_index = index;
|
||||
|
||||
return extent;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
fssh_status_t
|
||||
FileMap::_MakeSpace(fssh_size_t count)
|
||||
{
|
||||
if (count <= CACHED_FILE_EXTENTS) {
|
||||
// just use the reserved area in the file_cache_ref structure
|
||||
if (fCount > CACHED_FILE_EXTENTS) {
|
||||
// the new size is smaller than the minimal array size
|
||||
file_extent *array = fIndirect.array;
|
||||
memcpy(fDirect, array, sizeof(file_extent) * count);
|
||||
free(array);
|
||||
}
|
||||
} else {
|
||||
// resize array if needed
|
||||
file_extent* oldArray = NULL;
|
||||
fssh_size_t maxCount = CACHED_FILE_EXTENTS;
|
||||
if (fCount > CACHED_FILE_EXTENTS) {
|
||||
oldArray = fIndirect.array;
|
||||
maxCount = fIndirect.max_count;
|
||||
}
|
||||
|
||||
if (count > maxCount) {
|
||||
// allocate new array
|
||||
while (maxCount < count) {
|
||||
if (maxCount < 32768)
|
||||
maxCount <<= 1;
|
||||
else
|
||||
maxCount += 32768;
|
||||
}
|
||||
|
||||
file_extent* newArray = (file_extent *)realloc(oldArray,
|
||||
maxCount * sizeof(file_extent));
|
||||
if (newArray == NULL)
|
||||
return FSSH_B_NO_MEMORY;
|
||||
|
||||
if (fCount > 0 && fCount <= CACHED_FILE_EXTENTS)
|
||||
memcpy(newArray, fDirect, sizeof(file_extent) * fCount);
|
||||
|
||||
fIndirect.array = newArray;
|
||||
fIndirect.max_count = maxCount;
|
||||
}
|
||||
}
|
||||
|
||||
fCount = count;
|
||||
return FSSH_B_OK;
|
||||
}
|
||||
|
||||
|
||||
fssh_status_t
|
||||
FileMap::_Add(fssh_file_io_vec* vecs, fssh_size_t vecCount,
|
||||
fssh_off_t& lastOffset)
|
||||
{
|
||||
TRACE(("FileMap@%p::Add(vecCount = %ld)\n", this, vecCount));
|
||||
|
||||
uint32_t start = fCount;
|
||||
fssh_off_t offset = 0;
|
||||
|
||||
fssh_status_t status = _MakeSpace(fCount + vecCount);
|
||||
if (status != FSSH_B_OK)
|
||||
return status;
|
||||
|
||||
file_extent* lastExtent = NULL;
|
||||
if (start != 0) {
|
||||
lastExtent = ExtentAt(start - 1);
|
||||
offset = lastExtent->offset + lastExtent->disk.length;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < vecCount; i++) {
|
||||
if (lastExtent != NULL) {
|
||||
if (lastExtent->disk.offset + lastExtent->disk.length
|
||||
== vecs[i].offset) {
|
||||
lastExtent->disk.length += vecs[i].length;
|
||||
offset += vecs[i].length;
|
||||
start--;
|
||||
_MakeSpace(fCount - 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
file_extent* extent = ExtentAt(start + i);
|
||||
extent->offset = offset;
|
||||
extent->disk = vecs[i];
|
||||
|
||||
offset += extent->disk.length;
|
||||
lastExtent = extent;
|
||||
}
|
||||
|
||||
#ifdef TRACE_FILE_MAP
|
||||
for (uint32 i = 0; i < fCount; i++) {
|
||||
file_extent* extent = ExtentAt(i);
|
||||
dprintf("[%ld] extent offset %Ld, disk offset %Ld, length %Ld\n",
|
||||
i, extent->offset, extent->disk.offset, extent->disk.length);
|
||||
}
|
||||
#endif
|
||||
|
||||
lastOffset = offset;
|
||||
return FSSH_B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileMap::_InvalidateAfter(fssh_off_t offset)
|
||||
{
|
||||
uint32_t index;
|
||||
file_extent* extent = _FindExtent(offset, &index);
|
||||
if (extent != NULL) {
|
||||
_MakeSpace(index + 1);
|
||||
|
||||
if (extent->offset + extent->disk.length > offset) {
|
||||
extent->disk.length = offset - extent->offset;
|
||||
if (extent->disk.length == 0)
|
||||
_MakeSpace(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Invalidates or removes the specified part of the file map.
|
||||
*/
|
||||
void
|
||||
FileMap::Invalidate(fssh_off_t offset, fssh_off_t size)
|
||||
{
|
||||
MutexLocker _(fLock);
|
||||
|
||||
// TODO: honour size, we currently always remove everything after "offset"
|
||||
if (offset == 0) {
|
||||
_Free();
|
||||
return;
|
||||
}
|
||||
|
||||
_InvalidateAfter(offset);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileMap::SetSize(fssh_off_t size)
|
||||
{
|
||||
MutexLocker _(fLock);
|
||||
|
||||
if (size < fSize)
|
||||
_InvalidateAfter(size);
|
||||
|
||||
fSize = size;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FileMap::_Free()
|
||||
{
|
||||
if (fCount > CACHED_FILE_EXTENTS)
|
||||
free(fIndirect.array);
|
||||
|
||||
fCount = 0;
|
||||
}
|
||||
|
||||
|
||||
fssh_status_t
|
||||
FileMap::_Cache(fssh_off_t offset, fssh_off_t size)
|
||||
{
|
||||
file_extent* lastExtent = NULL;
|
||||
if (fCount > 0)
|
||||
lastExtent = ExtentAt(fCount - 1);
|
||||
|
||||
fssh_off_t mapEnd = 0;
|
||||
if (lastExtent != NULL)
|
||||
mapEnd = lastExtent->offset + lastExtent->disk.length;
|
||||
|
||||
fssh_off_t end = offset + size;
|
||||
|
||||
if (fCacheAll && mapEnd < end)
|
||||
return FSSH_B_ERROR;
|
||||
|
||||
fssh_status_t status = FSSH_B_OK;
|
||||
fssh_file_io_vec vecs[8];
|
||||
const fssh_size_t kMaxVecs = 8;
|
||||
|
||||
while (status == FSSH_B_OK && mapEnd < end) {
|
||||
// We don't have the requested extents yet, retrieve them
|
||||
fssh_size_t vecCount = kMaxVecs;
|
||||
status = vfs_get_file_map(Vnode(), mapEnd, FSSH_SIZE_MAX, vecs,
|
||||
&vecCount);
|
||||
if (status == FSSH_B_OK || status == FSSH_B_BUFFER_OVERFLOW)
|
||||
status = _Add(vecs, vecCount, mapEnd);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
fssh_status_t
|
||||
FileMap::SetMode(uint32_t mode)
|
||||
{
|
||||
if (mode != FSSH_FILE_MAP_CACHE_ALL
|
||||
&& mode != FSSH_FILE_MAP_CACHE_ON_DEMAND)
|
||||
return FSSH_B_BAD_VALUE;
|
||||
|
||||
MutexLocker _(fLock);
|
||||
|
||||
if ((mode == FSSH_FILE_MAP_CACHE_ALL && fCacheAll)
|
||||
|| (mode == FSSH_FILE_MAP_CACHE_ON_DEMAND && !fCacheAll))
|
||||
return FSSH_B_OK;
|
||||
|
||||
if (mode == FSSH_FILE_MAP_CACHE_ALL) {
|
||||
fssh_status_t status = _Cache(0, fSize);
|
||||
if (status != FSSH_B_OK)
|
||||
return status;
|
||||
|
||||
fCacheAll = true;
|
||||
} else
|
||||
fCacheAll = false;
|
||||
|
||||
return FSSH_B_OK;
|
||||
}
|
||||
|
||||
|
||||
fssh_status_t
|
||||
FileMap::Translate(fssh_off_t offset, fssh_size_t size, fssh_file_io_vec* vecs,
|
||||
fssh_size_t* _count, fssh_size_t align)
|
||||
{
|
||||
MutexLocker _(fLock);
|
||||
|
||||
fssh_size_t maxVecs = *_count;
|
||||
fssh_size_t padLastVec = 0;
|
||||
|
||||
if ((uint64_t)offset >= (uint64_t)Size()) {
|
||||
*_count = 0;
|
||||
return FSSH_B_OK;
|
||||
}
|
||||
if ((uint64_t)offset + size > (uint64_t)fSize) {
|
||||
if (align > 1) {
|
||||
fssh_off_t alignedSize = (fSize + align - 1) & ~(fssh_off_t)(align - 1);
|
||||
if ((uint64_t)offset + size >= (uint64_t)alignedSize)
|
||||
padLastVec = alignedSize - fSize;
|
||||
}
|
||||
size = fSize - offset;
|
||||
}
|
||||
|
||||
// First, we need to make sure that we have already cached all file
|
||||
// extents needed for this request.
|
||||
|
||||
fssh_status_t status = _Cache(offset, size);
|
||||
if (status != FSSH_B_OK)
|
||||
return status;
|
||||
|
||||
// We now have cached the map of this file as far as we need it, now
|
||||
// we need to translate it for the requested access.
|
||||
|
||||
uint32_t index;
|
||||
file_extent* fileExtent = _FindExtent(offset, &index);
|
||||
|
||||
offset -= fileExtent->offset;
|
||||
vecs[0].offset = fileExtent->disk.offset + offset;
|
||||
vecs[0].length = fileExtent->disk.length - offset;
|
||||
|
||||
if ((uint64_t)vecs[0].length >= (uint64_t)size) {
|
||||
vecs[0].length = size + padLastVec;
|
||||
*_count = 1;
|
||||
return FSSH_B_OK;
|
||||
}
|
||||
|
||||
// copy the rest of the vecs
|
||||
|
||||
size -= vecs[0].length;
|
||||
uint32_t vecIndex = 1;
|
||||
|
||||
while (true) {
|
||||
fileExtent++;
|
||||
|
||||
vecs[vecIndex++] = fileExtent->disk;
|
||||
|
||||
if ((uint64_t)size <= (uint64_t)fileExtent->disk.length) {
|
||||
vecs[vecIndex - 1].length = size + padLastVec;
|
||||
break;
|
||||
}
|
||||
|
||||
if (vecIndex >= maxVecs) {
|
||||
*_count = vecIndex;
|
||||
return FSSH_B_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
size -= fileExtent->disk.length;
|
||||
}
|
||||
|
||||
*_count = vecIndex;
|
||||
return FSSH_B_OK;
|
||||
}
|
||||
|
||||
|
||||
} // namespace FSShell
|
||||
|
||||
|
||||
// #pragma mark - public FS API
|
||||
|
||||
|
||||
extern "C" void*
|
||||
fssh_file_map_create(fssh_mount_id mountID, fssh_vnode_id vnodeID,
|
||||
fssh_off_t size)
|
||||
{
|
||||
TRACE(("file_map_create(mountID = %ld, vnodeID = %Ld, size = %Ld)\n",
|
||||
mountID, vnodeID, size));
|
||||
|
||||
// Get the vnode for the object
|
||||
// (note, this does not grab a reference to the node)
|
||||
void* vnode;
|
||||
if (vfs_lookup_vnode(mountID, vnodeID, &vnode) != FSSH_B_OK)
|
||||
return NULL;
|
||||
|
||||
return new(std::nothrow) FileMap(vnode, size);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
fssh_file_map_delete(void* _map)
|
||||
{
|
||||
FileMap* map = (FileMap*)_map;
|
||||
if (map == NULL)
|
||||
return;
|
||||
|
||||
TRACE(("file_map_delete(map = %p)\n", map));
|
||||
delete map;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
fssh_file_map_set_size(void* _map, fssh_off_t size)
|
||||
{
|
||||
FileMap* map = (FileMap*)_map;
|
||||
if (map == NULL)
|
||||
return;
|
||||
|
||||
map->SetSize(size);
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
fssh_file_map_invalidate(void* _map, fssh_off_t offset, fssh_off_t size)
|
||||
{
|
||||
FileMap* map = (FileMap*)_map;
|
||||
if (map == NULL)
|
||||
return;
|
||||
|
||||
map->Invalidate(offset, size);
|
||||
}
|
||||
|
||||
|
||||
extern "C" fssh_status_t
|
||||
fssh_file_map_set_mode(void* _map, uint32_t mode)
|
||||
{
|
||||
FileMap* map = (FileMap*)_map;
|
||||
if (map == NULL)
|
||||
return FSSH_B_BAD_VALUE;
|
||||
|
||||
return map->SetMode(mode);
|
||||
}
|
||||
|
||||
|
||||
extern "C" fssh_status_t
|
||||
fssh_file_map_translate(void* _map, fssh_off_t offset, fssh_size_t size,
|
||||
fssh_file_io_vec* vecs, fssh_size_t* _count, fssh_size_t align)
|
||||
{
|
||||
TRACE(("file_map_translate(map %p, offset %Ld, size %ld)\n",
|
||||
_map, offset, size));
|
||||
|
||||
FileMap* map = (FileMap*)_map;
|
||||
if (map == NULL)
|
||||
return FSSH_B_BAD_VALUE;
|
||||
|
||||
return map->Translate(offset, size, vecs, _count, align);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "compatibility.h"
|
||||
|
||||
#include "fssh.h"
|
||||
@@ -1194,6 +1195,9 @@ command_ioctl(int argc, const char* const* argv)
|
||||
return rootDir;
|
||||
|
||||
fssh_status_t status = _kern_ioctl(rootDir, atoi(argv[1]), NULL, 0);
|
||||
|
||||
_kern_close(rootDir);
|
||||
|
||||
if (status != FSSH_B_OK) {
|
||||
fprintf(stderr, "Error: ioctl failed: %s\n", fssh_strerror(status));
|
||||
return status;
|
||||
@@ -1471,6 +1475,7 @@ standard_session(const char* device, const char* fsName, bool interactive)
|
||||
|
||||
// register commands
|
||||
register_commands();
|
||||
register_additional_commands();
|
||||
|
||||
// process commands
|
||||
input_loop(interactive);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef _FSSH_FSSH_H
|
||||
#define _FSSH_FSSH_H
|
||||
|
||||
|
||||
#include "compatibility.h"
|
||||
|
||||
#include <map>
|
||||
@@ -71,6 +72,9 @@ private:
|
||||
};
|
||||
|
||||
|
||||
extern void register_additional_commands(void);
|
||||
|
||||
|
||||
} // namespace FSShell
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "fssh.h"
|
||||
|
||||
|
||||
namespace FSShell {
|
||||
|
||||
|
||||
void
|
||||
register_additional_commands()
|
||||
{
|
||||
// To be implemented by file system specific shell implementations.
|
||||
}
|
||||
|
||||
|
||||
} // namespace FSShell
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Copyright 2002-2012, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
@@ -102,6 +102,17 @@ fssh_recursive_lock_unlock(fssh_recursive_lock *lock)
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
fssh_recursive_lock_transfer_lock(fssh_recursive_lock *lock,
|
||||
fssh_thread_id thread)
|
||||
{
|
||||
if (lock->recursion != 1)
|
||||
fssh_panic("invalid recursion level for lock transfer!");
|
||||
|
||||
lock->holder = thread;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
|
||||
@@ -72,4 +72,4 @@ fssh_notify_query_attr_changed(fssh_port_id port, int32_t token,
|
||||
fssh_vnode_id node)
|
||||
{
|
||||
return FSSH_B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
+18
-25
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fd.h"
|
||||
#include "fssh_atomic.h"
|
||||
@@ -440,31 +441,21 @@ find_mount(fssh_mount_id id)
|
||||
static fssh_status_t
|
||||
get_mount(fssh_mount_id id, struct fs_mount **_mount)
|
||||
{
|
||||
struct fs_mount *mount;
|
||||
fssh_status_t status;
|
||||
|
||||
fssh_mutex_lock(&sMountMutex);
|
||||
|
||||
mount = find_mount(id);
|
||||
if (mount) {
|
||||
// ToDo: the volume is locked (against removal) by locking
|
||||
// its root node - investigate if that's a good idea
|
||||
if (mount->root_vnode)
|
||||
inc_vnode_ref_count(mount->root_vnode);
|
||||
else {
|
||||
// might have been called during a mount operation in which
|
||||
// case the root node may still be NULL
|
||||
mount = NULL;
|
||||
}
|
||||
} else
|
||||
status = FSSH_B_BAD_VALUE;
|
||||
|
||||
fssh_mutex_unlock(&sMountMutex);
|
||||
MutexLocker locker(&sMountMutex);
|
||||
|
||||
struct fs_mount *mount = find_mount(id);
|
||||
if (mount == NULL)
|
||||
return FSSH_B_BUSY;
|
||||
return FSSH_B_BAD_VALUE;
|
||||
|
||||
if (mount->root_vnode == NULL) {
|
||||
// might have been called during a mount operation in which
|
||||
// case the root node may still be NULL
|
||||
return FSSH_B_BUSY;
|
||||
}
|
||||
|
||||
inc_vnode_ref_count(mount->root_vnode);
|
||||
*_mount = mount;
|
||||
|
||||
return FSSH_B_OK;
|
||||
}
|
||||
|
||||
@@ -2393,7 +2384,8 @@ vfs_fs_vnode_to_node_ref(void *_vnode, fssh_mount_id *_mountID,
|
||||
*/
|
||||
|
||||
fssh_status_t
|
||||
vfs_lookup_vnode(fssh_mount_id mountID, fssh_vnode_id vnodeID, void **_vnode)
|
||||
vfs_lookup_vnode(fssh_mount_id mountID, fssh_vnode_id vnodeID,
|
||||
struct vnode **_vnode)
|
||||
{
|
||||
fssh_mutex_lock(&sVnodeMutex);
|
||||
struct vnode *vnode = lookup_vnode(mountID, vnodeID);
|
||||
@@ -2408,10 +2400,11 @@ vfs_lookup_vnode(fssh_mount_id mountID, fssh_vnode_id vnodeID, void **_vnode)
|
||||
|
||||
|
||||
fssh_status_t
|
||||
vfs_get_fs_node_from_path(fssh_fs_volume *volume, const char *path, bool kernel, void **_node)
|
||||
vfs_get_fs_node_from_path(fssh_fs_volume *volume, const char *path,
|
||||
bool kernel, void **_node)
|
||||
{
|
||||
TRACE(("vfs_get_fs_node_from_path(mountID = %ld, path = \"%s\", kernel %d)\n",
|
||||
mountID, path, kernel));
|
||||
TRACE(("vfs_get_fs_node_from_path(volume = %p (%ld), path = \"%s\", "
|
||||
"kernel %d)\n", volume, volume->id, path, kernel));
|
||||
|
||||
KPath pathBuffer(FSSH_B_PATH_NAME_LENGTH + 1);
|
||||
if (pathBuffer.InitCheck() != FSSH_B_OK)
|
||||
|
||||
@@ -45,6 +45,8 @@ struct fd_info {
|
||||
fssh_ino_t node;
|
||||
};
|
||||
|
||||
struct vnode;
|
||||
|
||||
/* macro to allocate a iovec array on the stack */
|
||||
#define IOVECS(name, size) \
|
||||
uint8_t _##name[sizeof(fssh_iovecs) + (size)*sizeof(fssh_iovec)]; \
|
||||
@@ -69,7 +71,7 @@ void vfs_vnode_to_node_ref(void *_vnode, fssh_mount_id *_mountID,
|
||||
fssh_vnode_id *_vnodeID);
|
||||
|
||||
fssh_status_t vfs_lookup_vnode(fssh_mount_id mountID, fssh_vnode_id vnodeID,
|
||||
void **_vnode);
|
||||
struct vnode **_vnode);
|
||||
void vfs_put_vnode(void *vnode);
|
||||
void vfs_acquire_vnode(void *vnode);
|
||||
fssh_status_t vfs_get_cookie_from_fd(int fd, void **_cookie);
|
||||
|
||||
@@ -201,11 +201,11 @@ read_png(const char* filename, int& width, int& height, png_bytep*& rowPtrs,
|
||||
png_set_bgr(pngPtr);
|
||||
|
||||
png_read_info(pngPtr, infoPtr);
|
||||
width = infoPtr->width;
|
||||
height = infoPtr->height;
|
||||
if (infoPtr->bit_depth != 8)
|
||||
width = (int)png_get_image_width(pngPtr, infoPtr);
|
||||
height = (int)png_get_image_height(pngPtr, infoPtr);
|
||||
if (png_get_bit_depth(pngPtr, infoPtr) != 8)
|
||||
error("[read_png] File %s has wrong bit depth\n", filename);
|
||||
if ((int)infoPtr->rowbytes < width * 3) {
|
||||
if ((int)png_get_rowbytes(pngPtr, infoPtr) < width * 3) {
|
||||
error("[read_png] File %s has wrong color type (RGB required)\n",
|
||||
filename);
|
||||
}
|
||||
@@ -221,7 +221,7 @@ read_png(const char* filename, int& width, int& height, png_bytep*& rowPtrs,
|
||||
|
||||
rowPtrs = (png_bytep*)malloc(sizeof(png_bytep) * height);
|
||||
for (int y = 0; y < height; y++)
|
||||
rowPtrs[y] = (png_byte*)malloc(infoPtr->rowbytes);
|
||||
rowPtrs[y] = (png_byte*)malloc(png_get_rowbytes(pngPtr, infoPtr));
|
||||
|
||||
png_read_image(pngPtr, rowPtrs);
|
||||
}
|
||||
@@ -252,7 +252,7 @@ write_24bit_image(const char* baseName, int width, int height, png_bytep* rowPtr
|
||||
static void
|
||||
write_8bit_image(const char* baseName, int width, int height, unsigned char** rowPtrs)
|
||||
{
|
||||
int buffer[128];
|
||||
//int buffer[128];
|
||||
// buffer[0] stores count, buffer[1..127] holds the actual values
|
||||
|
||||
fprintf(sOutput, "static uint8 %s8BitCompressedImage[] = {\n\t",
|
||||
|
||||
@@ -42,7 +42,7 @@ rule PreprocessSyscalls
|
||||
local headers = [ on $(1) return $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
|
||||
local sysHeaders =
|
||||
$(TARGET_PRIVATE_SYSTEM_HEADERS)
|
||||
[ ArchHeaders $(TARGET_ARCH) ]
|
||||
[ ArchHeaders $(TARGET_KERNEL_ARCH) ]
|
||||
[ on $(1) return $(SUBDIRSYSHDRS) $(SYSHDRS) ]
|
||||
$(HAIKU_HDRS) ;
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#define SYSCALL_RETURN_TYPE_ALIGNMENT_TYPE long
|
||||
#define SYSCALL_PARAMETER_ALIGNMENT_TYPE long
|
||||
@@ -115,31 +115,37 @@ DownloadAllLanguageTarballs()
|
||||
|
||||
DownloadLanguageTarball()
|
||||
{
|
||||
LANGUAGE=$1
|
||||
# The package for zh_hans catalogs is actually called zh-hans
|
||||
if [ "$LANGUAGE" = "zh_hans" ] ; then
|
||||
LANGUAGE="zh-hans"
|
||||
fi
|
||||
|
||||
cd "$tempDirectory"
|
||||
echo "Downloading language: $1"
|
||||
echo "Downloading language: $LANGUAGE"
|
||||
|
||||
if [ -e "$1.tgz" ] ; then
|
||||
rm "$1.tgz"
|
||||
if [ -e "$LANGUAGE.tgz" ] ; then
|
||||
rm "$LANGUAGE.tgz"
|
||||
fi
|
||||
|
||||
attempt=0
|
||||
local tarballURL="http://hta.polytect.org/catalogs/tarball"
|
||||
|
||||
while [ $(wget -nv -U hta_committer -O "$1.tgz" "$tarballURL/$1" ; echo $?) -ne 0 ]; do
|
||||
while [ $(wget -nv -U hta_committer -O "$LANGUAGE.tgz" "$tarballURL/$LANGUAGE" ; echo $?) -ne 0 ]; do
|
||||
if [ $attempt -eq 5 ]; then
|
||||
break
|
||||
fi
|
||||
(( attempt++ ))
|
||||
echo "Download attempt #$attempt failed. Retrying ..."
|
||||
if [ -e "$1" ]; then
|
||||
rm "$1"
|
||||
if [ -e "$LANGUAGE" ]; then
|
||||
rm "$LANGUAGE"
|
||||
fi
|
||||
done
|
||||
if [ $attempt -ge 5 ]; then
|
||||
if [ -e "$1" ]; then
|
||||
rm "$1"
|
||||
if [ -e "$LANGUAGE" ]; then
|
||||
rm "$LANGUAGE"
|
||||
fi
|
||||
echo "WARNING: Max download retries exceeded for language $1."
|
||||
echo "WARNING: Max download retries exceeded for language $LANGUAGE."
|
||||
fi
|
||||
|
||||
cd "$subversionRootDirectory"
|
||||
|
||||
+25
-173
@@ -1,61 +1,52 @@
|
||||
/*
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
** Copyright 2003-2004. All rights reserved.
|
||||
** Copyright 2003-2004,2012. All rights reserved.
|
||||
**
|
||||
** Authors: Axel Dörfler, axeld@pinc-software.de
|
||||
** Oliver Tappe, zooey@hirschkaefer.de
|
||||
*/
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#include <Application.h>
|
||||
#include <Catalog.h>
|
||||
#include <Locale.h>
|
||||
#include <LocaleRoster.h>
|
||||
#include <Node.h>
|
||||
#include <Roster.h>
|
||||
#include <CatalogData.h>
|
||||
|
||||
|
||||
BCatalog* be_catalog = NULL;
|
||||
// catalog used by translation macros
|
||||
BCatalog* be_app_catalog = NULL;
|
||||
// app-catalog (useful for accessing app's catalog from inside an add-on,
|
||||
// since in an add-on, be_catalog will hold the add-on's catalog.
|
||||
// Provides an implementation of BCatalog for the build host, in effect only
|
||||
// supporting setting and getting of catalog entries.
|
||||
|
||||
|
||||
//#pragma mark - BCatalog
|
||||
BCatalog::BCatalog()
|
||||
:
|
||||
fCatalog(NULL)
|
||||
fCatalogData(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BCatalog::BCatalog(const entry_ref& catalogOwner, const char *language,
|
||||
uint32 fingerprint)
|
||||
:
|
||||
fCatalogData(NULL)
|
||||
{
|
||||
// Unsupported - the build tools can't (and don't need to) load anything
|
||||
// this way.
|
||||
}
|
||||
|
||||
|
||||
BCatalog::~BCatalog()
|
||||
{
|
||||
if (be_catalog == this)
|
||||
be_app_catalog = be_catalog = NULL;
|
||||
//be_locale_roster->UnloadCatalog(fCatalog);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
BCatalog::GetString(const char *string, const char *context, const char *comment)
|
||||
{
|
||||
if (fCatalogData == 0)
|
||||
return string;
|
||||
|
||||
const char *translated;
|
||||
for (BCatalogAddOn* cat = fCatalog; cat != NULL; cat = cat->fNext) {
|
||||
for (BCatalogData* cat = fCatalogData; cat != NULL; cat = cat->fNext) {
|
||||
translated = cat->GetString(string, context, comment);
|
||||
if (translated)
|
||||
return translated;
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
@@ -63,12 +54,16 @@ BCatalog::GetString(const char *string, const char *context, const char *comment
|
||||
const char *
|
||||
BCatalog::GetString(uint32 id)
|
||||
{
|
||||
if (fCatalogData == 0)
|
||||
return "";
|
||||
|
||||
const char *translated;
|
||||
for (BCatalogAddOn* cat = fCatalog; cat != NULL; cat = cat->fNext) {
|
||||
for (BCatalogData* cat = fCatalogData; cat != NULL; cat = cat->fNext) {
|
||||
translated = cat->GetString(id);
|
||||
if (translated)
|
||||
return translated;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -76,15 +71,17 @@ BCatalog::GetString(uint32 id)
|
||||
status_t
|
||||
BCatalog::GetData(const char *name, BMessage *msg)
|
||||
{
|
||||
if (!fCatalog)
|
||||
if (fCatalogData == 0)
|
||||
return B_NO_INIT;
|
||||
|
||||
status_t res;
|
||||
for (BCatalogAddOn* cat = fCatalog; cat != NULL; cat = cat->fNext) {
|
||||
for (BCatalogData* cat = fCatalogData; cat != NULL; cat = cat->fNext) {
|
||||
res = cat->GetData(name, msg);
|
||||
if (res != B_NAME_NOT_FOUND && res != EOPNOTSUPP)
|
||||
return res;
|
||||
// return B_OK if found, or specific error-code
|
||||
}
|
||||
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
@@ -92,161 +89,16 @@ BCatalog::GetData(const char *name, BMessage *msg)
|
||||
status_t
|
||||
BCatalog::GetData(uint32 id, BMessage *msg)
|
||||
{
|
||||
if (!fCatalog)
|
||||
if (fCatalogData == 0)
|
||||
return B_NO_INIT;
|
||||
|
||||
status_t res;
|
||||
for (BCatalogAddOn* cat = fCatalog; cat != NULL; cat = cat->fNext) {
|
||||
for (BCatalogData* cat = fCatalogData; cat != NULL; cat = cat->fNext) {
|
||||
res = cat->GetData(id, msg);
|
||||
if (res != B_NAME_NOT_FOUND && res != EOPNOTSUPP)
|
||||
return res;
|
||||
// return B_OK if found, or specific error-code
|
||||
}
|
||||
|
||||
return B_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
//#pragma mark - BCatalogAddOn
|
||||
BCatalogAddOn::BCatalogAddOn(const char *signature, const char *language,
|
||||
uint32 fingerprint)
|
||||
:
|
||||
fInitCheck(B_NO_INIT),
|
||||
fSignature(signature),
|
||||
fLanguageName(language),
|
||||
fFingerprint(fingerprint),
|
||||
fNext(NULL)
|
||||
{
|
||||
fLanguageName.ToLower();
|
||||
// canonicalize language-name to lowercase
|
||||
}
|
||||
|
||||
|
||||
BCatalogAddOn::~BCatalogAddOn()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BCatalogAddOn::UpdateFingerprint()
|
||||
{
|
||||
fFingerprint = 0;
|
||||
// base implementation always yields the same fingerprint,
|
||||
// which means that no version-mismatch detection is possible.
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::InitCheck() const
|
||||
{
|
||||
return fInitCheck;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BCatalogAddOn::CanHaveData() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::GetData(const char *name, BMessage *msg)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::GetData(uint32 id, BMessage *msg)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::SetString(const char *string, const char *translated,
|
||||
const char *context, const char *comment)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::SetString(int32 id, const char *translated)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BCatalogAddOn::CanWriteData() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::SetData(const char *name, BMessage *msg)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::SetData(uint32 id, BMessage *msg)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::ReadFromFile(const char *path)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::ReadFromAttribute(const entry_ref &appOrAddOnRef)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::ReadFromResource(const entry_ref &appOrAddOnRef)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::WriteToFile(const char *path)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::WriteToAttribute(const entry_ref &appOrAddOnRef)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogAddOn::WriteToResource(const entry_ref &appOrAddOnRef)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
void BCatalogAddOn::MakeEmpty()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BCatalogAddOn::CountItems() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
** Copyright 2003-2004,2012. All rights reserved.
|
||||
**
|
||||
** Authors: Axel Dörfler, axeld@pinc-software.de
|
||||
** Oliver Tappe, zooey@hirschkaefer.de
|
||||
*/
|
||||
|
||||
#include <CatalogData.h>
|
||||
|
||||
|
||||
// Provides an empty implementation of BCatalogData for the build host.
|
||||
|
||||
|
||||
BCatalogData::BCatalogData(const char *signature, const char *language,
|
||||
uint32 fingerprint)
|
||||
:
|
||||
fInitCheck(B_NO_INIT),
|
||||
fSignature(signature),
|
||||
fLanguageName(language),
|
||||
fFingerprint(fingerprint),
|
||||
fNext(NULL)
|
||||
{
|
||||
fLanguageName.ToLower();
|
||||
// canonicalize language-name to lowercase
|
||||
}
|
||||
|
||||
|
||||
BCatalogData::~BCatalogData()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BCatalogData::UpdateFingerprint()
|
||||
{
|
||||
fFingerprint = 0;
|
||||
// base implementation always yields the same fingerprint,
|
||||
// which means that no version-mismatch detection is possible.
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::InitCheck() const
|
||||
{
|
||||
return fInitCheck;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BCatalogData::CanHaveData() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::GetData(const char *name, BMessage *msg)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::GetData(uint32 id, BMessage *msg)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::SetString(const char *string, const char *translated,
|
||||
const char *context, const char *comment)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::SetString(int32 id, const char *translated)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BCatalogData::CanWriteData() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::SetData(const char *name, BMessage *msg)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::SetData(uint32 id, BMessage *msg)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::ReadFromFile(const char *path)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::ReadFromAttribute(const entry_ref &appOrAddOnRef)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::ReadFromResource(const entry_ref &appOrAddOnRef)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::WriteToFile(const char *path)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::WriteToAttribute(const entry_ref &appOrAddOnRef)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCatalogData::WriteToResource(const entry_ref &appOrAddOnRef)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
||||
void BCatalogData::MakeEmpty()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
BCatalogData::CountItems() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
using BPrivate::DefaultCatalog;
|
||||
using std::auto_ptr;
|
||||
|
||||
|
||||
@@ -40,6 +41,9 @@ using std::auto_ptr;
|
||||
*/
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
|
||||
// several attributes/resource-IDs used within the Locale Kit:
|
||||
|
||||
const char *kCatLangAttr = "BEOS:LOCALE_LANGUAGE";
|
||||
@@ -64,7 +68,7 @@ static int16 kCatArchiveVersion = 1;
|
||||
DefaultCatalog::DefaultCatalog(const entry_ref &catalogOwner,
|
||||
const char *language, uint32 fingerprint)
|
||||
:
|
||||
BHashMapCatalog("", language, fingerprint)
|
||||
HashMapCatalog("", language, fingerprint)
|
||||
{
|
||||
fInitCheck = B_NOT_SUPPORTED;
|
||||
fprintf(stderr,
|
||||
@@ -80,7 +84,7 @@ DefaultCatalog::DefaultCatalog(const entry_ref &catalogOwner,
|
||||
*/
|
||||
DefaultCatalog::DefaultCatalog(entry_ref *appOrAddOnRef)
|
||||
:
|
||||
BHashMapCatalog("", "", 0)
|
||||
HashMapCatalog("", "", 0)
|
||||
{
|
||||
fInitCheck = ReadFromResource(*appOrAddOnRef);
|
||||
// fprintf(stderr,
|
||||
@@ -96,7 +100,7 @@ DefaultCatalog::DefaultCatalog(entry_ref *appOrAddOnRef)
|
||||
DefaultCatalog::DefaultCatalog(const char *path, const char *signature,
|
||||
const char *language)
|
||||
:
|
||||
BHashMapCatalog(signature, language, 0),
|
||||
HashMapCatalog(signature, language, 0),
|
||||
fPath(path)
|
||||
{
|
||||
fInitCheck = B_OK;
|
||||
@@ -397,7 +401,7 @@ DefaultCatalog::Unflatten(BDataIO *dataIO)
|
||||
}
|
||||
|
||||
|
||||
BCatalogAddOn *
|
||||
BCatalogData *
|
||||
DefaultCatalog::Instantiate(const entry_ref &catalogOwner, const char *language,
|
||||
uint32 fingerprint)
|
||||
{
|
||||
@@ -411,7 +415,7 @@ DefaultCatalog::Instantiate(const entry_ref &catalogOwner, const char *language,
|
||||
}
|
||||
|
||||
|
||||
BCatalogAddOn *
|
||||
BCatalogData *
|
||||
DefaultCatalog::Create(const char *signature, const char *language)
|
||||
{
|
||||
DefaultCatalog *catalog
|
||||
@@ -426,3 +430,6 @@ DefaultCatalog::Create(const char *signature, const char *language)
|
||||
|
||||
const uint8 DefaultCatalog::kDefaultCatalogAddOnPriority = 1;
|
||||
// give highest priority to our embedded catalog-add-on
|
||||
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
@@ -35,6 +35,7 @@ BuildPlatformMain <build>collectcatkeys :
|
||||
PlainTextCatalog.cpp
|
||||
HashMapCatalog.cpp
|
||||
Catalog.cpp
|
||||
CatalogData.cpp
|
||||
RegExp.cpp
|
||||
: $(HOST_LIBBE) $(HOST_LIBSUPC++) $(HOST_LIBSTDC++) ;
|
||||
|
||||
@@ -44,4 +45,5 @@ BuildPlatformMain <build>linkcatkeys :
|
||||
HashMapCatalog.cpp
|
||||
DefaultCatalog.cpp
|
||||
Catalog.cpp
|
||||
CatalogData.cpp
|
||||
: $(HOST_LIBBE) $(HOST_LIBSUPC++) $(HOST_LIBSTDC++) ;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <Catalog.h>
|
||||
|
||||
|
||||
using BPrivate::PlainTextCatalog;
|
||||
using std::auto_ptr;
|
||||
using std::min;
|
||||
using std::max;
|
||||
@@ -44,6 +45,9 @@ using std::pair;
|
||||
*/
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
|
||||
const char *PlainTextCatalog::kCatMimeType
|
||||
= "locale/x-vnd.Be.locale-catalog.plaintext";
|
||||
|
||||
@@ -73,7 +77,7 @@ escapeQuotedChars(BString& stringToEscape)
|
||||
PlainTextCatalog::PlainTextCatalog(const char *signature, const char *language,
|
||||
uint32 fingerprint)
|
||||
:
|
||||
BHashMapCatalog(signature, language, fingerprint)
|
||||
HashMapCatalog(signature, language, fingerprint)
|
||||
{
|
||||
// Look for the catalog in the directory we are going to use
|
||||
// This constructor is not used so lets disable that...
|
||||
@@ -93,7 +97,7 @@ PlainTextCatalog::PlainTextCatalog(const char *signature, const char *language,
|
||||
PlainTextCatalog::PlainTextCatalog(const char *path, const char *signature,
|
||||
const char *language)
|
||||
:
|
||||
BHashMapCatalog(signature, language, 0),
|
||||
HashMapCatalog(signature, language, 0),
|
||||
fPath(path)
|
||||
{
|
||||
fInitCheck = B_OK;
|
||||
@@ -325,7 +329,7 @@ PlainTextCatalog::UpdateAttributes(const char* path)
|
||||
}
|
||||
|
||||
|
||||
BCatalogAddOn *
|
||||
BCatalogData *
|
||||
PlainTextCatalog::Instantiate(const char *signature, const char *language,
|
||||
uint32 fingerprint)
|
||||
{
|
||||
@@ -339,7 +343,10 @@ PlainTextCatalog::Instantiate(const char *signature, const char *language,
|
||||
}
|
||||
|
||||
|
||||
extern "C" BCatalogAddOn *
|
||||
} // namespace BPrivate
|
||||
|
||||
|
||||
extern "C" BCatalogData *
|
||||
instantiate_catalog(const char *signature, const char *language,
|
||||
uint32 fingerprint)
|
||||
{
|
||||
@@ -353,9 +360,8 @@ instantiate_catalog(const char *signature, const char *language,
|
||||
}
|
||||
|
||||
|
||||
extern "C"
|
||||
BCatalogAddOn *create_catalog(const char *signature,
|
||||
const char *language)
|
||||
extern "C" BCatalogData *
|
||||
create_catalog(const char *signature, const char *language)
|
||||
{
|
||||
PlainTextCatalog *catalog
|
||||
= new(std::nothrow) PlainTextCatalog("emptycat", signature, language);
|
||||
|
||||
@@ -21,6 +21,9 @@
|
||||
#include <String.h>
|
||||
|
||||
|
||||
using BPrivate::PlainTextCatalog;
|
||||
|
||||
|
||||
bool showKeys = false;
|
||||
bool showSummary = false;
|
||||
bool showWarnings = false;
|
||||
|
||||
@@ -16,8 +16,13 @@
|
||||
#include <HashMapCatalog.h>
|
||||
#include <PlainTextCatalog.h>
|
||||
|
||||
using BPrivate::CatKey;
|
||||
using BPrivate::DefaultCatalog;
|
||||
using BPrivate::HashMapCatalog;
|
||||
using BPrivate::PlainTextCatalog;
|
||||
using std::vector;
|
||||
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
@@ -108,7 +113,7 @@ main(int argc, char **argv)
|
||||
|
||||
// now walk over all entries in input-catalog and add them to
|
||||
// target catalog, unless they already exist there.
|
||||
BHashMapCatalog::CatWalker walker(&inputCatalog);
|
||||
HashMapCatalog::CatWalker walker(&inputCatalog);
|
||||
while (!walker.AtEnd()) {
|
||||
const CatKey &key(walker.GetKey());
|
||||
|
||||
|
||||
@@ -9,4 +9,4 @@ SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src bin makebootable platform
|
||||
#AddFileDataResource <build>makebootable : RAWT:666:BootCode : stage1.bin ;
|
||||
|
||||
#BuildPlatformMain <build>makebootable : makebootable.cpp : $(HOST_LIBBE) ;
|
||||
BuildPlatformMain <build>makebootable : makebootable.cpp ;
|
||||
BuildPlatformMain <build>makebootable : makebootable.cpp : $(HOST_LIBSTDC++) ;
|
||||
|
||||
@@ -89,7 +89,7 @@ remove_dir_contents(Path& path, bool force, bool removeAttributes)
|
||||
{
|
||||
// open the dir
|
||||
DIR* dir = opendir(path.GetPath());
|
||||
if (dir < 0) {
|
||||
if (dir == NULL) {
|
||||
fprintf(stderr, "Error: Failed to open dir \"%s\": %s\n",
|
||||
path.GetPath(), strerror(errno));
|
||||
return;
|
||||
|
||||
+266
-159
@@ -39,6 +39,13 @@ typedef uint16_t Elf32_Half;
|
||||
typedef uint32_t Elf32_Off;
|
||||
typedef int32_t Elf32_Sword;
|
||||
typedef uint32_t Elf32_Word;
|
||||
typedef uint64_t Elf64_Addr;
|
||||
typedef uint64_t Elf64_Off;
|
||||
typedef uint16_t Elf64_Half;
|
||||
typedef uint32_t Elf64_Word;
|
||||
typedef int32_t Elf64_Sword;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
typedef int64_t Elf64_Sxword;
|
||||
|
||||
// e_ident indices
|
||||
#define EI_MAG0 0
|
||||
@@ -69,6 +76,23 @@ typedef struct {
|
||||
Elf32_Half e_shstrndx;
|
||||
} Elf32_Ehdr;
|
||||
|
||||
typedef struct {
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf64_Half e_type;
|
||||
Elf64_Half e_machine;
|
||||
Elf64_Word e_version;
|
||||
Elf64_Addr e_entry;
|
||||
Elf64_Off e_phoff;
|
||||
Elf64_Off e_shoff;
|
||||
Elf64_Word e_flags;
|
||||
Elf64_Half e_ehsize;
|
||||
Elf64_Half e_phentsize;
|
||||
Elf64_Half e_phnum;
|
||||
Elf64_Half e_shentsize;
|
||||
Elf64_Half e_shnum;
|
||||
Elf64_Half e_shstrndx;
|
||||
} Elf64_Ehdr;
|
||||
|
||||
// e_ident EI_CLASS and EI_DATA values
|
||||
#define ELFCLASSNONE 0
|
||||
#define ELFCLASS32 1
|
||||
@@ -89,6 +113,17 @@ typedef struct {
|
||||
Elf32_Word p_align;
|
||||
} Elf32_Phdr;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Word p_type;
|
||||
Elf64_Word p_flags;
|
||||
Elf64_Off p_offset;
|
||||
Elf64_Addr p_vaddr;
|
||||
Elf64_Addr p_paddr;
|
||||
Elf64_Xword p_filesz;
|
||||
Elf64_Xword p_memsz;
|
||||
Elf64_Xword p_align;
|
||||
} Elf64_Phdr;
|
||||
|
||||
// p_type
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
@@ -114,6 +149,19 @@ typedef struct {
|
||||
Elf32_Word sh_entsize;
|
||||
} Elf32_Shdr;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Word sh_name;
|
||||
Elf64_Word sh_type;
|
||||
Elf64_Xword sh_flags;
|
||||
Elf64_Addr sh_addr;
|
||||
Elf64_Off sh_offset;
|
||||
Elf64_Xword sh_size;
|
||||
Elf64_Word sh_link;
|
||||
Elf64_Word sh_info;
|
||||
Elf64_Xword sh_addralign;
|
||||
Elf64_Xword sh_entsize;
|
||||
} Elf64_Shdr;
|
||||
|
||||
// sh_type values
|
||||
#define SHT_NULL 0
|
||||
#define SHT_PROGBITS 1
|
||||
@@ -135,7 +183,6 @@ typedef struct {
|
||||
// special section indexes
|
||||
#define SHN_UNDEF 0
|
||||
|
||||
static const uint32_t kMaxELFHeaderSize = sizeof(Elf32_Ehdr) + 32;
|
||||
static const char kELFFileMagic[4] = { 0x7f, 'E', 'L', 'F' };
|
||||
|
||||
|
||||
@@ -168,8 +215,7 @@ print_usage(bool error)
|
||||
}
|
||||
|
||||
// print_usage_and_exit
|
||||
static
|
||||
void
|
||||
static void
|
||||
print_usage_and_exit(bool error)
|
||||
{
|
||||
print_usage(error);
|
||||
@@ -262,8 +308,8 @@ private:
|
||||
|
||||
struct SectionInfo {
|
||||
uint32_t type;
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
off_t offset;
|
||||
size_t size;
|
||||
const char* name;
|
||||
};
|
||||
|
||||
@@ -307,82 +353,17 @@ public:
|
||||
if (fFileSize < 0)
|
||||
throw Exception("Failed to get the file size.");
|
||||
|
||||
// read ELF header
|
||||
Elf32_Ehdr fileHeader;
|
||||
Read(0, &fileHeader, sizeof(Elf32_Ehdr), "Failed to read ELF header.");
|
||||
// Read identification information
|
||||
unsigned char ident[EI_NIDENT];
|
||||
Read(0, ident, sizeof(ident), "Failed to read ELF identification.");
|
||||
if (memcmp(ident, kELFFileMagic, sizeof(kELFFileMagic)) != 0)
|
||||
throw Exception("Not a valid ELF file.");
|
||||
fELFClass = ident[EI_CLASS];
|
||||
|
||||
// check data encoding (endianess)
|
||||
switch (fileHeader.e_ident[EI_DATA]) {
|
||||
case ELFDATA2LSB:
|
||||
fHostEndianess = (htonl(1) != 1);
|
||||
break;
|
||||
case ELFDATA2MSB:
|
||||
fHostEndianess = (htonl(1) == 1);
|
||||
break;
|
||||
default:
|
||||
case ELFDATANONE:
|
||||
throw Exception(EIO, "Unsupported ELF data encoding.");
|
||||
break;
|
||||
}
|
||||
|
||||
// get the header values
|
||||
fELFHeaderSize = GetUInt16(fileHeader.e_ehsize);
|
||||
fSectionHeaderTableOffset = GetUInt32(fileHeader.e_shoff);
|
||||
fSectionHeaderSize = GetUInt16(fileHeader.e_shentsize);
|
||||
fSectionHeaderCount = GetUInt16(fileHeader.e_shnum);
|
||||
bool hasSectionHeaderTable = (fSectionHeaderTableOffset != 0);
|
||||
|
||||
// check the sanity of the header values
|
||||
// ELF header size
|
||||
if (fELFHeaderSize < sizeof(Elf32_Ehdr) || fELFHeaderSize > kMaxELFHeaderSize) {
|
||||
throw Exception(EIO,
|
||||
"Invalid ELF header: invalid ELF header size: %lu.",
|
||||
fELFHeaderSize);
|
||||
}
|
||||
|
||||
// section header table offset and entry count/size
|
||||
uint32_t sectionHeaderTableSize = 0;
|
||||
if (hasSectionHeaderTable) {
|
||||
if (fSectionHeaderTableOffset < fELFHeaderSize
|
||||
|| fSectionHeaderTableOffset > fFileSize) {
|
||||
throw Exception(EIO, "Invalid ELF header: invalid section "
|
||||
"header table offset: %lu.",
|
||||
fSectionHeaderTableOffset);
|
||||
}
|
||||
sectionHeaderTableSize = fSectionHeaderSize * fSectionHeaderCount;
|
||||
if (fSectionHeaderSize < sizeof(Elf32_Shdr)
|
||||
|| fSectionHeaderTableOffset + sectionHeaderTableSize
|
||||
> fFileSize) {
|
||||
throw Exception(EIO, "Invalid ELF header: section header "
|
||||
"table exceeds file: %lu.",
|
||||
fSectionHeaderTableOffset
|
||||
+ sectionHeaderTableSize);
|
||||
}
|
||||
|
||||
|
||||
// load section header string section
|
||||
uint16_t sectionHeaderStringSectionIndex
|
||||
= GetUInt16(fileHeader.e_shstrndx);
|
||||
if (sectionHeaderStringSectionIndex != SHN_UNDEF) {
|
||||
if (sectionHeaderStringSectionIndex >= fSectionHeaderCount) {
|
||||
throw Exception(EIO, "Invalid ELF header: invalid section "
|
||||
"header string section index: %lu.",
|
||||
sectionHeaderStringSectionIndex);
|
||||
}
|
||||
|
||||
// get the section info
|
||||
SectionInfo info;
|
||||
if (_ReadSectionHeader(sectionHeaderStringSectionIndex,
|
||||
info)) {
|
||||
fSectionHeaderStrings = new char[info.size + 1];
|
||||
Read(info.offset, fSectionHeaderStrings, info.size,
|
||||
"Failed to read section header string section.");
|
||||
fSectionHeaderStringsLength = info.size;
|
||||
// null-terminate to be on the safe side
|
||||
fSectionHeaderStrings[info.size] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fELFClass == ELFCLASS64)
|
||||
_ParseELFHeader<Elf64_Ehdr, Elf64_Shdr>();
|
||||
else
|
||||
_ParseELFHeader<Elf32_Ehdr, Elf32_Shdr>();
|
||||
}
|
||||
|
||||
bool FindSectionByName(const char* name, SectionInfo& foundInfo)
|
||||
@@ -392,9 +373,16 @@ public:
|
||||
return false;
|
||||
|
||||
// iterate through the section headers
|
||||
for (int32_t i = 0; i < (int32_t)fSectionHeaderCount; i++) {
|
||||
for (size_t i = 0; i < fSectionHeaderCount; i++) {
|
||||
SectionInfo info;
|
||||
if (_ReadSectionHeader(i, info)) {
|
||||
|
||||
bool result;
|
||||
if (fELFClass == ELFCLASS64)
|
||||
result = _ReadSectionHeader<Elf64_Shdr>(i, info);
|
||||
else
|
||||
result = _ReadSectionHeader<Elf32_Shdr>(i, info);
|
||||
|
||||
if (result) {
|
||||
//printf("section %3d: offset: %7d, size: %7d, name: %s\n", i, info.offset, info.size, info.name);
|
||||
if (strcmp(info.name, name) == 0) {
|
||||
foundInfo = info;
|
||||
@@ -457,81 +445,15 @@ public:
|
||||
return lseek(fFD, currentPos, SEEK_SET);
|
||||
}
|
||||
|
||||
// GetInt16
|
||||
int16_t GetInt16(int16_t value)
|
||||
{
|
||||
return (fHostEndianess ? value : _SwapUInt16(value));
|
||||
}
|
||||
|
||||
// GetUInt16
|
||||
uint16_t GetUInt16(uint16_t value)
|
||||
{
|
||||
return (fHostEndianess ? value : _SwapUInt16(value));
|
||||
}
|
||||
|
||||
// GetInt32
|
||||
int32_t GetInt32(int32_t value)
|
||||
{
|
||||
return (fHostEndianess ? value : _SwapUInt32(value));
|
||||
}
|
||||
|
||||
// GetUInt32
|
||||
uint32_t GetUInt32(uint32_t value)
|
||||
{
|
||||
return (fHostEndianess ? value : _SwapUInt32(value));
|
||||
}
|
||||
template<typename Type>
|
||||
Type GetValue(Type& value);
|
||||
|
||||
private:
|
||||
bool _ReadSectionHeader(int index, SectionInfo& info)
|
||||
{
|
||||
uint32_t shOffset = fSectionHeaderTableOffset
|
||||
+ index * fSectionHeaderSize;
|
||||
Elf32_Shdr sectionHeader;
|
||||
Read(shOffset, §ionHeader, sizeof(Elf32_Shdr),
|
||||
"Failed to read ELF section header.");
|
||||
template<typename EhdrType, typename ShdrType>
|
||||
void _ParseELFHeader();
|
||||
|
||||
// get the header values
|
||||
uint32_t type = GetUInt32(sectionHeader.sh_type);
|
||||
uint32_t offset = GetUInt32(sectionHeader.sh_offset);
|
||||
uint32_t size = GetUInt32(sectionHeader.sh_size);
|
||||
uint32_t nameIndex = GetUInt32(sectionHeader.sh_name);
|
||||
|
||||
// check the values
|
||||
// SHT_NULL marks the header unused,
|
||||
if (type == SHT_NULL)
|
||||
return false;
|
||||
|
||||
// SHT_NOBITS sections take no space in the file
|
||||
if (type != SHT_NOBITS) {
|
||||
if (offset < fELFHeaderSize || offset > fFileSize) {
|
||||
throw Exception(EIO, "Invalid ELF section header: "
|
||||
"invalid section offset: %lu.", offset);
|
||||
}
|
||||
uint32_t sectionEnd = offset + size;
|
||||
if (sectionEnd > fFileSize) {
|
||||
throw Exception(EIO, "Invalid ELF section header: "
|
||||
"section exceeds file: %lu.", sectionEnd);
|
||||
}
|
||||
}
|
||||
|
||||
// get name, if we have a string section
|
||||
if (fSectionHeaderStrings) {
|
||||
if (nameIndex >= (uint32_t)fSectionHeaderStringsLength) {
|
||||
throw Exception(EIO, "Invalid ELF section header: "
|
||||
"invalid name index: %lu.", nameIndex);
|
||||
}
|
||||
info.name = fSectionHeaderStrings + nameIndex;
|
||||
} else {
|
||||
info.name = "";
|
||||
}
|
||||
|
||||
info.type = type;
|
||||
info.offset = offset;
|
||||
info.size = size;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
template<typename ShdrType>
|
||||
bool _ReadSectionHeader(int index, SectionInfo& info);
|
||||
|
||||
// _SwapUInt16
|
||||
static inline uint16_t _SwapUInt16(uint16_t value)
|
||||
@@ -546,19 +468,204 @@ private:
|
||||
| _SwapUInt16(uint16_t(value >> 16));
|
||||
}
|
||||
|
||||
// _SwapUInt64
|
||||
static inline uint64_t _SwapUInt64(uint64_t value)
|
||||
{
|
||||
return ((uint64_t)_SwapUInt32(value & 0xffffffff) << 32)
|
||||
| _SwapUInt32(uint32_t(value >> 32));
|
||||
}
|
||||
|
||||
private:
|
||||
int fFD;
|
||||
uint8_t fELFClass;
|
||||
bool fHostEndianess;
|
||||
off_t fFileSize;
|
||||
uint32_t fELFHeaderSize;
|
||||
uint32_t fSectionHeaderTableOffset;
|
||||
uint32_t fSectionHeaderSize;
|
||||
uint32_t fSectionHeaderCount;
|
||||
size_t fELFHeaderSize;
|
||||
off_t fSectionHeaderTableOffset;
|
||||
size_t fSectionHeaderSize;
|
||||
size_t fSectionHeaderCount;
|
||||
char* fSectionHeaderStrings;
|
||||
int fSectionHeaderStringsLength;
|
||||
uint32_t fSectionHeaderStringsLength;
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
int16_t ELFObject::GetValue(int16_t& value)
|
||||
{
|
||||
return (fHostEndianess ? value : _SwapUInt16(value));
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
uint16_t ELFObject::GetValue(uint16_t& value)
|
||||
{
|
||||
return (fHostEndianess ? value : _SwapUInt16(value));
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
int32_t ELFObject::GetValue(int32_t& value)
|
||||
{
|
||||
return (fHostEndianess ? value : _SwapUInt32(value));
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
uint32_t ELFObject::GetValue(uint32_t& value)
|
||||
{
|
||||
return (fHostEndianess ? value : _SwapUInt32(value));
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
int64_t ELFObject::GetValue(int64_t& value)
|
||||
{
|
||||
return (fHostEndianess ? value : _SwapUInt64(value));
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
uint64_t ELFObject::GetValue(uint64_t& value)
|
||||
{
|
||||
return (fHostEndianess ? value : _SwapUInt64(value));
|
||||
}
|
||||
|
||||
|
||||
template<typename EhdrType, typename ShdrType>
|
||||
void ELFObject::_ParseELFHeader()
|
||||
{
|
||||
// read ELF header
|
||||
EhdrType fileHeader;
|
||||
Read(0, &fileHeader, sizeof(EhdrType), "Failed to read ELF header.");
|
||||
|
||||
// check data encoding (endianess)
|
||||
switch (fileHeader.e_ident[EI_DATA]) {
|
||||
case ELFDATA2LSB:
|
||||
fHostEndianess = (htonl(1) != 1);
|
||||
break;
|
||||
case ELFDATA2MSB:
|
||||
fHostEndianess = (htonl(1) == 1);
|
||||
break;
|
||||
default:
|
||||
case ELFDATANONE:
|
||||
throw Exception(EIO, "Unsupported ELF data encoding.");
|
||||
break;
|
||||
}
|
||||
|
||||
// get the header values
|
||||
fELFHeaderSize = GetValue(fileHeader.e_ehsize);
|
||||
fSectionHeaderTableOffset = GetValue(fileHeader.e_shoff);
|
||||
fSectionHeaderSize = GetValue(fileHeader.e_shentsize);
|
||||
fSectionHeaderCount = GetValue(fileHeader.e_shnum);
|
||||
bool hasSectionHeaderTable = (fSectionHeaderTableOffset != 0);
|
||||
|
||||
// check the sanity of the header values
|
||||
// ELF header size
|
||||
if (fELFHeaderSize < sizeof(EhdrType)) {
|
||||
throw Exception(EIO,
|
||||
"Invalid ELF header: invalid ELF header size: %lu.",
|
||||
fELFHeaderSize);
|
||||
}
|
||||
|
||||
// section header table offset and entry count/size
|
||||
if (hasSectionHeaderTable) {
|
||||
if (fSectionHeaderTableOffset < (off_t)fELFHeaderSize
|
||||
|| fSectionHeaderTableOffset > fFileSize) {
|
||||
throw Exception(EIO, "Invalid ELF header: invalid section "
|
||||
"header table offset: %llu.",
|
||||
fSectionHeaderTableOffset);
|
||||
}
|
||||
size_t sectionHeaderTableSize
|
||||
= fSectionHeaderSize * fSectionHeaderCount;
|
||||
if (fSectionHeaderSize < (off_t)sizeof(ShdrType)
|
||||
|| fSectionHeaderTableOffset + (off_t)sectionHeaderTableSize
|
||||
> fFileSize) {
|
||||
throw Exception(EIO, "Invalid ELF header: section header "
|
||||
"table exceeds file: %llu.",
|
||||
fSectionHeaderTableOffset
|
||||
+ sectionHeaderTableSize);
|
||||
}
|
||||
|
||||
|
||||
// load section header string section
|
||||
uint16_t sectionHeaderStringSectionIndex
|
||||
= GetValue(fileHeader.e_shstrndx);
|
||||
if (sectionHeaderStringSectionIndex != SHN_UNDEF) {
|
||||
if (sectionHeaderStringSectionIndex >= fSectionHeaderCount) {
|
||||
throw Exception(EIO, "Invalid ELF header: invalid section "
|
||||
"header string section index: %u.",
|
||||
sectionHeaderStringSectionIndex);
|
||||
}
|
||||
|
||||
// get the section info
|
||||
SectionInfo info;
|
||||
if (_ReadSectionHeader<ShdrType>(sectionHeaderStringSectionIndex,
|
||||
info)) {
|
||||
fSectionHeaderStrings = new char[info.size + 1];
|
||||
Read(info.offset, fSectionHeaderStrings, info.size,
|
||||
"Failed to read section header string section.");
|
||||
fSectionHeaderStringsLength = info.size;
|
||||
// null-terminate to be on the safe side
|
||||
fSectionHeaderStrings[info.size] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename ShdrType>
|
||||
bool ELFObject::_ReadSectionHeader(int index, SectionInfo& info)
|
||||
{
|
||||
off_t shOffset = fSectionHeaderTableOffset
|
||||
+ index * fSectionHeaderSize;
|
||||
ShdrType sectionHeader;
|
||||
Read(shOffset, §ionHeader, sizeof(ShdrType),
|
||||
"Failed to read ELF section header.");
|
||||
|
||||
// get the header values
|
||||
uint32_t type = GetValue(sectionHeader.sh_type);
|
||||
off_t offset = GetValue(sectionHeader.sh_offset);
|
||||
size_t size = GetValue(sectionHeader.sh_size);
|
||||
uint32_t nameIndex = GetValue(sectionHeader.sh_name);
|
||||
|
||||
// check the values
|
||||
// SHT_NULL marks the header unused,
|
||||
if (type == SHT_NULL)
|
||||
return false;
|
||||
|
||||
// SHT_NOBITS sections take no space in the file
|
||||
if (type != SHT_NOBITS) {
|
||||
if (offset < (off_t)fELFHeaderSize || offset > fFileSize) {
|
||||
throw Exception(EIO, "Invalid ELF section header: "
|
||||
"invalid section offset: %llu.", offset);
|
||||
}
|
||||
off_t sectionEnd = offset + size;
|
||||
if (sectionEnd > fFileSize) {
|
||||
throw Exception(EIO, "Invalid ELF section header: "
|
||||
"section exceeds file: %llu.", sectionEnd);
|
||||
}
|
||||
}
|
||||
|
||||
// get name, if we have a string section
|
||||
if (fSectionHeaderStrings) {
|
||||
if (nameIndex >= (uint32_t)fSectionHeaderStringsLength) {
|
||||
throw Exception(EIO, "Invalid ELF section header: "
|
||||
"invalid name index: %lu.", nameIndex);
|
||||
}
|
||||
info.name = fSectionHeaderStrings + nameIndex;
|
||||
} else {
|
||||
info.name = "";
|
||||
}
|
||||
|
||||
info.type = type;
|
||||
info.offset = offset;
|
||||
info.size = size;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// main
|
||||
int
|
||||
main(int argc, const char* const* argv)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
Example usage for Haiku project:
|
||||
|
||||
stubgen -s -g -a *.h
|
||||
@@ -44,8 +44,8 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#undef B_TRANSLATE_CONTEXT
|
||||
#define B_TRANSLATE_CONTEXT "ActiveTranslatorsWindow"
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "ActiveTranslatorsWindow"
|
||||
|
||||
|
||||
ActiveTranslatorsWindow::ActiveTranslatorsWindow(BRect rect, const char *name,
|
||||
|
||||
@@ -61,8 +61,8 @@
|
||||
#define BORDER_HEIGHT 16
|
||||
#define PEN_SIZE 1.0f
|
||||
|
||||
#undef B_TRANSLATE_CONTEXT
|
||||
#define B_TRANSLATE_CONTEXT "ImageView"
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "ImageView"
|
||||
|
||||
|
||||
ImageView::ImageView(BRect rect, const char *name)
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
#include <ScrollView.h>
|
||||
#include <Alert.h>
|
||||
|
||||
#undef B_TRANSLATE_CONTEXT
|
||||
#define B_TRANSLATE_CONTEXT "ImageWindow"
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "ImageWindow"
|
||||
|
||||
|
||||
ImageWindow::ImageWindow(BRect rect, const char *name)
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
#include <String.h>
|
||||
#include <Window.h>
|
||||
|
||||
#undef B_TRANSLATE_CONTEXT
|
||||
#define B_TRANSLATE_CONTEXT "InspectorApp"
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "InspectorApp"
|
||||
|
||||
|
||||
InspectorApp::InspectorApp()
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
SubDir HAIKU_TOP src tools translation pnginfo ;
|
||||
|
||||
UseLibraryHeaders zlib ;
|
||||
UseLibraryHeaders png ;
|
||||
UseHeaders $(HAIKU_LIBPNG_HEADERS) : true ;
|
||||
|
||||
BinCommand pnginfo : pnginfo.cpp : be libpng.a libz.a $(TARGET_LIBSUPC++) ;
|
||||
Includes [ FGristFiles pnginfo.cpp ]
|
||||
: $(HAIKU_LIBPNG_HEADERS_DEPENDENCY) ;
|
||||
|
||||
BinCommand pnginfo : pnginfo.cpp : be $(HAIKU_LIBPNG_LIB) libz.a
|
||||
$(TARGET_LIBSUPC++) ;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user