diff --git a/headers/private/kernel/team.h b/headers/private/kernel/team.h index c105b61262..47be3df72e 100644 --- a/headers/private/kernel/team.h +++ b/headers/private/kernel/team.h @@ -84,6 +84,8 @@ status_t _user_get_team_info(team_id id, team_info *info); status_t _user_get_next_team_info(int32 *cookie, team_info *info); status_t _user_get_team_usage_info(team_id team, int32 who, team_usage_info *info, size_t size); +status_t _user_get_extended_team_info(team_id teamID, uint32 flags, + void* buffer, size_t size, size_t* _sizeNeeded); #ifdef __cplusplus } diff --git a/headers/private/libroot/extended_system_info.h b/headers/private/libroot/extended_system_info.h new file mode 100644 index 0000000000..b6cd4c4a26 --- /dev/null +++ b/headers/private/libroot/extended_system_info.h @@ -0,0 +1,31 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef _LIBROOT_EXTENDED_SYSTEM_INFO_H +#define _LIBROOT_EXTENDED_SYSTEM_INFO_H + + +/* This is C++ only API. */ +#ifdef __cplusplus + + +#include <OS.h> + + +namespace BPrivate { + + +struct KMessage; + + +status_t get_extended_team_info(team_id teamID, uint32 flags, KMessage& info); + + +} // namespace BPrivate + + +#endif /* __cplusplus */ + + +#endif /* _LIBROOT_EXTENDED_SYSTEM_INFO_H */ diff --git a/headers/private/system/extended_system_info_defs.h b/headers/private/system/extended_system_info_defs.h new file mode 100644 index 0000000000..175b4cfd79 --- /dev/null +++ b/headers/private/system/extended_system_info_defs.h @@ -0,0 +1,20 @@ +/* + * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef _SYSTEM_EXTENDED_SYSTEM_INFO_DEFS_H +#define _SYSTEM_EXTENDED_SYSTEM_INFO_DEFS_H + + +enum { + B_TEAM_INFO_BASIC = 0x01, // basic general info + B_TEAM_INFO_THREADS = 0x02, // list of threads + B_TEAM_INFO_IMAGES = 0x04, // list of images + B_TEAM_INFO_AREAS = 0x08, // list of areas + B_TEAM_INFO_SEMAPHORES = 0x10, // list of semaphores + B_TEAM_INFO_PORTS = 0x20, // list of ports + B_TEAM_INFO_FILE_DESCRIPTORS = 0x40 // list of file descriptors +}; + + +#endif /* _SYSTEM_EXTENDED_SYSTEM_INFO_DEFS_H */ diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index 6cda990134..1217c0375f 100644 --- a/headers/private/system/syscalls.h +++ b/headers/private/system/syscalls.h @@ -171,6 +171,8 @@ extern status_t _kern_get_team_info(team_id id, team_info *info); extern status_t _kern_get_next_team_info(int32 *cookie, team_info *info); extern status_t _kern_get_team_usage_info(team_id team, int32 who, team_usage_info *info, size_t size); +extern status_t _kern_get_extended_team_info(team_id teamID, uint32 flags, + void* buffer, size_t size, size_t* _sizeNeeded); extern status_t _kern_block_thread(uint32 flags, bigtime_t timeout); extern status_t _kern_unblock_thread(thread_id thread, status_t status); diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 0cb75e9135..1384c0a507 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -23,6 +23,8 @@ #include <AutoDeleter.h> #include <FindDirectory.h> +#include <extended_system_info_defs.h> + #include <boot_device.h> #include <elf.h> #include <file_cache.h> @@ -3605,3 +3607,85 @@ _user_get_team_usage_info(team_id team, int32 who, team_usage_info* userInfo, return status; } + +status_t +_user_get_extended_team_info(team_id teamID, uint32 flags, void* buffer, + size_t size, size_t* _sizeNeeded) +{ + // check parameters + if ((buffer != NULL && !IS_USER_ADDRESS(buffer)) + || (buffer == NULL && size > 0) + || _sizeNeeded == NULL || !IS_USER_ADDRESS(_sizeNeeded)) { + return B_BAD_ADDRESS; + } + + KMessage info; + + if ((flags & B_TEAM_INFO_BASIC) != 0) { + // allocate memory for a copy of the team struct + struct team* teamClone = new(std::nothrow) team; + if (teamClone == NULL) + return B_NO_MEMORY; + ObjectDeleter<struct team> teamCloneDeleter(teamClone); + + io_context* ioContext; + { + // get the team structure + InterruptsSpinLocker _(gTeamSpinlock); + struct team* team = teamID == B_CURRENT_TEAM + ? thread_get_current_thread()->team + : team_get_team_struct_locked(teamID); + if (team == NULL) + return B_BAD_TEAM_ID; + + // copy it + memcpy(teamClone, team, sizeof(*team)); + + // also fetch a reference to the I/O context + ioContext = team->io_context; + vfs_get_io_context(ioContext); + } + CObjectDeleter<io_context> ioContextPutter(ioContext, + &vfs_put_io_context); + + // add the basic data to the info message + if (info.AddInt32("id", teamClone->id) != B_OK + || info.AddString("name", teamClone->name) != B_OK + || info.AddInt32("process group", teamClone->group_id) != B_OK + || info.AddInt32("session", teamClone->session_id) != B_OK + || info.AddInt32("uid", teamClone->real_uid) != B_OK + || info.AddInt32("gid", teamClone->real_gid) != B_OK + || info.AddInt32("euid", teamClone->effective_uid) != B_OK + || info.AddInt32("egid", teamClone->effective_gid) != B_OK) { + return B_NO_MEMORY; + } + + // get the current working directory from the I/O context + dev_t cwdDevice; + ino_t cwdDirectory; + { + MutexLocker ioContextLocker(ioContext->io_mutex); + vfs_vnode_to_node_ref(ioContext->cwd, &cwdDevice, &cwdDirectory); + } + + if (info.AddInt32("cwd device", cwdDevice) != B_OK + || info.AddInt64("cwd directory", cwdDirectory) != B_OK) { + return B_NO_MEMORY; + } + } + + // TODO: Support the other flags! + + // copy the needed size and, if it fits, the message back to userland + size_t sizeNeeded = info.ContentSize(); + if (user_memcpy(_sizeNeeded, &sizeNeeded, sizeof(sizeNeeded)) != B_OK) + return B_BAD_ADDRESS; + + if (sizeNeeded > size) + return B_BUFFER_OVERFLOW; + + if (user_memcpy(buffer, info.Buffer(), sizeNeeded) != B_OK) + return B_BAD_ADDRESS; + + return B_OK; +} diff --git a/src/system/libroot/os/Jamfile b/src/system/libroot/os/Jamfile index 217b7b9231..94613467b8 100644 --- a/src/system/libroot/os/Jamfile +++ b/src/system/libroot/os/Jamfile @@ -13,6 +13,7 @@ MergeObject os_main.o : debug.c driver_settings.cpp find_directory.cpp + extended_system_info.cpp fs_attr.cpp fs_index.c fs_info.c