* Introduced ref-counting for the I/O contexts.
* The I/O context related vfs_*() functions have io_context* instead of void* parameters/return values, now. * vfs_new_io_context(): Lock the parent I/O context before getting its table size. Otherwise the table size could change until we do. * vfs_resize_fd_table(): Fixed use of MutexLocker. We created only a temporary object, not one with function scope. * Renamed load_image_etc() to load_image_internal() and added a parameter for specifying the parent team of the one to create. * Introduced a kernel private load_image_etc() with a few more arguments than load_image(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29375 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -14,8 +14,6 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
status_t team_init(struct kernel_args *args);
|
status_t team_init(struct kernel_args *args);
|
||||||
team_id team_create_team(const char *path, const char *name, char **args,
|
|
||||||
int argc, char **envp, int envc, int priority);
|
|
||||||
status_t wait_for_team(team_id id, status_t *returnCode);
|
status_t wait_for_team(team_id id, status_t *returnCode);
|
||||||
void team_remove_team(struct team *team);
|
void team_remove_team(struct team *team);
|
||||||
void team_delete_team(struct team *team);
|
void team_delete_team(struct team *team);
|
||||||
@@ -36,6 +34,9 @@ struct team *team_get_team_struct_locked(team_id id);
|
|||||||
int32 team_max_teams(void);
|
int32 team_max_teams(void);
|
||||||
int32 team_used_teams(void);
|
int32 team_used_teams(void);
|
||||||
|
|
||||||
|
thread_id load_image_etc(int32 argCount, const char* const* args,
|
||||||
|
const char* const* env, int32 priority, team_id parentID, uint32 flags);
|
||||||
|
|
||||||
void team_set_job_control_state(struct team* team, job_control_state newState,
|
void team_set_job_control_state(struct team* team, job_control_state newState,
|
||||||
int signal, bool threadsLocked);
|
int signal, bool threadsLocked);
|
||||||
void team_set_controlling_tty(int32 index);
|
void team_set_controlling_tty(int32 index);
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ typedef enum job_control_state {
|
|||||||
|
|
||||||
|
|
||||||
struct image; // defined in image.c
|
struct image; // defined in image.c
|
||||||
|
struct io_context;
|
||||||
struct realtime_sem_context; // defined in realtime_sem.cpp
|
struct realtime_sem_context; // defined in realtime_sem.cpp
|
||||||
struct select_info;
|
struct select_info;
|
||||||
struct user_thread; // defined in libroot/user_thread.h
|
struct user_thread; // defined in libroot/user_thread.h
|
||||||
@@ -172,7 +173,7 @@ struct team {
|
|||||||
int num_threads; // number of threads in this team
|
int num_threads; // number of threads in this team
|
||||||
int state; // current team state, see above
|
int state; // current team state, see above
|
||||||
int32 flags;
|
int32 flags;
|
||||||
void *io_context;
|
struct io_context *io_context;
|
||||||
struct realtime_sem_context *realtime_sem_context;
|
struct realtime_sem_context *realtime_sem_context;
|
||||||
struct xsi_sem_context *xsi_sem_context;
|
struct xsi_sem_context *xsi_sem_context;
|
||||||
sem_id death_sem; // semaphore to wait on for dying threads
|
sem_id death_sem; // semaphore to wait on for dying threads
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ extern "C" {
|
|||||||
|
|
||||||
void inherit_parent_user_and_group(struct team* team,
|
void inherit_parent_user_and_group(struct team* team,
|
||||||
struct team* parent);
|
struct team* parent);
|
||||||
|
void inherit_parent_user_and_group_locked(struct team* team,
|
||||||
|
struct team* parent);
|
||||||
status_t update_set_id_user_and_group(struct team* team, const char* file);
|
status_t update_set_id_user_and_group(struct team* team, const char* file);
|
||||||
|
|
||||||
// syscalls
|
// syscalls
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ typedef struct io_context {
|
|||||||
struct vnode *root;
|
struct vnode *root;
|
||||||
struct vnode *cwd;
|
struct vnode *cwd;
|
||||||
mutex io_mutex;
|
mutex io_mutex;
|
||||||
|
int32 ref_count;
|
||||||
uint32 table_size;
|
uint32 table_size;
|
||||||
uint32 num_used_fds;
|
uint32 num_used_fds;
|
||||||
struct file_descriptor **fds;
|
struct file_descriptor **fds;
|
||||||
@@ -69,9 +70,10 @@ extern "C" {
|
|||||||
status_t vfs_init(struct kernel_args *args);
|
status_t vfs_init(struct kernel_args *args);
|
||||||
status_t vfs_bootstrap_file_systems(void);
|
status_t vfs_bootstrap_file_systems(void);
|
||||||
void vfs_mount_boot_file_system(struct kernel_args *args);
|
void vfs_mount_boot_file_system(struct kernel_args *args);
|
||||||
void vfs_exec_io_context(void *context);
|
void vfs_exec_io_context(io_context *context);
|
||||||
void *vfs_new_io_context(void *parentContext);
|
io_context *vfs_new_io_context(io_context *parentContext);
|
||||||
status_t vfs_free_io_context(void *context);
|
void vfs_get_io_context(io_context *context);
|
||||||
|
void vfs_put_io_context(io_context *context);
|
||||||
|
|
||||||
struct rlimit;
|
struct rlimit;
|
||||||
int vfs_getrlimit(int resource, struct rlimit * rlp);
|
int vfs_getrlimit(int resource, struct rlimit * rlp);
|
||||||
|
|||||||
@@ -4595,9 +4595,8 @@ vfs_unlock_vnode_if_locked(struct file_descriptor* descriptor)
|
|||||||
have the O_CLOEXEC flag set.
|
have the O_CLOEXEC flag set.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
vfs_exec_io_context(void* _context)
|
vfs_exec_io_context(io_context* context)
|
||||||
{
|
{
|
||||||
struct io_context* context = (struct io_context*)_context;
|
|
||||||
uint32 i;
|
uint32 i;
|
||||||
|
|
||||||
for (i = 0; i < context->table_size; i++) {
|
for (i = 0; i < context->table_size; i++) {
|
||||||
@@ -4626,23 +4625,24 @@ vfs_exec_io_context(void* _context)
|
|||||||
/*! Sets up a new io_control structure, and inherits the properties
|
/*! Sets up a new io_control structure, and inherits the properties
|
||||||
of the parent io_control if it is given.
|
of the parent io_control if it is given.
|
||||||
*/
|
*/
|
||||||
void*
|
io_context*
|
||||||
vfs_new_io_context(void* _parentContext)
|
vfs_new_io_context(io_context* parentContext)
|
||||||
{
|
{
|
||||||
size_t tableSize;
|
size_t tableSize;
|
||||||
struct io_context* context;
|
struct io_context* context;
|
||||||
struct io_context* parentContext;
|
|
||||||
|
|
||||||
context = (io_context*)malloc(sizeof(struct io_context));
|
context = (io_context*)malloc(sizeof(struct io_context));
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memset(context, 0, sizeof(struct io_context));
|
memset(context, 0, sizeof(struct io_context));
|
||||||
|
context->ref_count = 1;
|
||||||
|
|
||||||
parentContext = (struct io_context*)_parentContext;
|
MutexLocker parentLocker;
|
||||||
if (parentContext)
|
if (parentContext) {
|
||||||
|
parentLocker.SetTo(parentContext->io_mutex, false);
|
||||||
tableSize = parentContext->table_size;
|
tableSize = parentContext->table_size;
|
||||||
else
|
} else
|
||||||
tableSize = DEFAULT_FD_TABLE_SIZE;
|
tableSize = DEFAULT_FD_TABLE_SIZE;
|
||||||
|
|
||||||
// allocate space for FDs and their close-on-exec flag
|
// allocate space for FDs and their close-on-exec flag
|
||||||
@@ -4669,8 +4669,6 @@ vfs_new_io_context(void* _parentContext)
|
|||||||
if (parentContext) {
|
if (parentContext) {
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
mutex_lock(&parentContext->io_mutex);
|
|
||||||
|
|
||||||
mutex_lock(&sIOContextRootLock);
|
mutex_lock(&sIOContextRootLock);
|
||||||
context->root = parentContext->root;
|
context->root = parentContext->root;
|
||||||
if (context->root)
|
if (context->root)
|
||||||
@@ -4695,7 +4693,7 @@ vfs_new_io_context(void* _parentContext)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&parentContext->io_mutex);
|
parentLocker.Unlock();
|
||||||
} else {
|
} else {
|
||||||
context->root = sRoot;
|
context->root = sRoot;
|
||||||
context->cwd = sRoot;
|
context->cwd = sRoot;
|
||||||
@@ -4716,10 +4714,9 @@ vfs_new_io_context(void* _parentContext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
static status_t
|
||||||
vfs_free_io_context(void* _ioContext)
|
vfs_free_io_context(io_context* context)
|
||||||
{
|
{
|
||||||
struct io_context* context = (struct io_context*)_ioContext;
|
|
||||||
uint32 i;
|
uint32 i;
|
||||||
|
|
||||||
if (context->root)
|
if (context->root)
|
||||||
@@ -4747,13 +4744,26 @@ vfs_free_io_context(void* _ioContext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void vfs_get_io_context(io_context *context)
|
||||||
|
{
|
||||||
|
atomic_add(&context->ref_count, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void vfs_put_io_context(io_context *context)
|
||||||
|
{
|
||||||
|
if (atomic_add(&context->ref_count, -1) == 1)
|
||||||
|
vfs_free_io_context(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
vfs_resize_fd_table(struct io_context* context, const int newSize)
|
vfs_resize_fd_table(struct io_context* context, const int newSize)
|
||||||
{
|
{
|
||||||
if (newSize <= 0 || newSize > MAX_FD_TABLE_SIZE)
|
if (newSize <= 0 || newSize > MAX_FD_TABLE_SIZE)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
MutexLocker(context->io_mutex);
|
MutexLocker _(context->io_mutex);
|
||||||
|
|
||||||
int oldSize = context->table_size;
|
int oldSize = context->table_size;
|
||||||
int oldCloseOnExitBitmapSize = (oldSize + 7) / 8;
|
int oldCloseOnExitBitmapSize = (oldSize + 7) / 8;
|
||||||
|
|||||||
+63
-31
@@ -1085,37 +1085,33 @@ team_create_thread_start(void *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! The BeOS kernel exports a function with this name, but most probably with
|
|
||||||
different parameters; we should not make it public.
|
|
||||||
*/
|
|
||||||
static thread_id
|
static thread_id
|
||||||
load_image_etc(char**& _flatArgs, size_t flatArgsSize, int32 argCount,
|
load_image_internal(char**& _flatArgs, size_t flatArgsSize, int32 argCount,
|
||||||
int32 envCount, int32 priority, uint32 flags, port_id errorPort,
|
int32 envCount, int32 priority, team_id parentID, uint32 flags,
|
||||||
uint32 errorToken)
|
port_id errorPort, uint32 errorToken)
|
||||||
{
|
{
|
||||||
char** flatArgs = _flatArgs;
|
char** flatArgs = _flatArgs;
|
||||||
struct team *team, *parent;
|
struct team *team;
|
||||||
const char *threadName;
|
const char *threadName;
|
||||||
thread_id thread;
|
thread_id thread;
|
||||||
status_t status;
|
status_t status;
|
||||||
cpu_status state;
|
cpu_status state;
|
||||||
struct team_arg *teamArgs;
|
struct team_arg *teamArgs;
|
||||||
struct team_loading_info loadingInfo;
|
struct team_loading_info loadingInfo;
|
||||||
|
io_context* parentIOContext = NULL;
|
||||||
|
|
||||||
if (flatArgs == NULL || argCount == 0)
|
if (flatArgs == NULL || argCount == 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
const char* path = flatArgs[0];
|
const char* path = flatArgs[0];
|
||||||
|
|
||||||
TRACE(("load_image_etc: name '%s', args = %p, argCount = %ld\n",
|
TRACE(("load_image_internal: name '%s', args = %p, argCount = %ld\n",
|
||||||
path, flatArgs, argCount));
|
path, flatArgs, argCount));
|
||||||
|
|
||||||
team = create_team_struct(path, false);
|
team = create_team_struct(path, false);
|
||||||
if (team == NULL)
|
if (team == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
parent = thread_get_current_thread()->team;
|
|
||||||
|
|
||||||
if (flags & B_WAIT_TILL_LOADED) {
|
if (flags & B_WAIT_TILL_LOADED) {
|
||||||
loadingInfo.thread = thread_get_current_thread();
|
loadingInfo.thread = thread_get_current_thread();
|
||||||
loadingInfo.result = B_ERROR;
|
loadingInfo.result = B_ERROR;
|
||||||
@@ -1123,21 +1119,38 @@ load_image_etc(char**& _flatArgs, size_t flatArgsSize, int32 argCount,
|
|||||||
team->loading_info = &loadingInfo;
|
team->loading_info = &loadingInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inherit the parent's user/group, but also check the executable's
|
InterruptsSpinLocker teamLocker(gTeamSpinlock);
|
||||||
// set-user/group-id permission
|
|
||||||
inherit_parent_user_and_group(team, parent);
|
|
||||||
update_set_id_user_and_group(team, path);
|
|
||||||
|
|
||||||
state = disable_interrupts();
|
// get the parent team
|
||||||
GRAB_TEAM_LOCK();
|
struct team* parent;
|
||||||
|
|
||||||
|
if (parentID == B_CURRENT_TEAM)
|
||||||
|
parent = thread_get_current_thread()->team;
|
||||||
|
else
|
||||||
|
parent = team_get_team_struct_locked(parentID);
|
||||||
|
|
||||||
|
if (parent == NULL) {
|
||||||
|
teamLocker.Unlock();
|
||||||
|
status = B_BAD_TEAM_ID;
|
||||||
|
goto err0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// inherit the parent's user/group
|
||||||
|
inherit_parent_user_and_group_locked(team, parent);
|
||||||
|
|
||||||
hash_insert(sTeamHash, team);
|
hash_insert(sTeamHash, team);
|
||||||
insert_team_into_parent(parent, team);
|
insert_team_into_parent(parent, team);
|
||||||
insert_team_into_group(parent->group, team);
|
insert_team_into_group(parent->group, team);
|
||||||
sUsedTeams++;
|
sUsedTeams++;
|
||||||
|
|
||||||
RELEASE_TEAM_LOCK();
|
// get a reference to the parent's I/O context -- we need it to create ours
|
||||||
restore_interrupts(state);
|
parentIOContext = parent->io_context;
|
||||||
|
vfs_get_io_context(parentIOContext);
|
||||||
|
|
||||||
|
teamLocker.Unlock();
|
||||||
|
|
||||||
|
// check the executable's set-user/group-id permission
|
||||||
|
update_set_id_user_and_group(team, path);
|
||||||
|
|
||||||
status = create_team_arg(&teamArgs, path, flatArgs, flatArgsSize, argCount,
|
status = create_team_arg(&teamArgs, path, flatArgs, flatArgsSize, argCount,
|
||||||
envCount, errorPort, errorToken);
|
envCount, errorPort, errorToken);
|
||||||
@@ -1149,12 +1162,16 @@ load_image_etc(char**& _flatArgs, size_t flatArgsSize, int32 argCount,
|
|||||||
// args are owned by the team_arg structure now
|
// args are owned by the team_arg structure now
|
||||||
|
|
||||||
// create a new io_context for this team
|
// create a new io_context for this team
|
||||||
team->io_context = vfs_new_io_context(parent->io_context);
|
team->io_context = vfs_new_io_context(parentIOContext);
|
||||||
if (!team->io_context) {
|
if (!team->io_context) {
|
||||||
status = B_NO_MEMORY;
|
status = B_NO_MEMORY;
|
||||||
goto err2;
|
goto err2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We don't need the parent's I/O context any longer.
|
||||||
|
vfs_put_io_context(parentIOContext);
|
||||||
|
parentIOContext = NULL;
|
||||||
|
|
||||||
// remove any fds that have the CLOEXEC flag set (emulating BeOS behaviour)
|
// remove any fds that have the CLOEXEC flag set (emulating BeOS behaviour)
|
||||||
vfs_exec_io_context(team->io_context);
|
vfs_exec_io_context(team->io_context);
|
||||||
|
|
||||||
@@ -1229,21 +1246,25 @@ err5:
|
|||||||
err4:
|
err4:
|
||||||
vm_put_address_space(team->address_space);
|
vm_put_address_space(team->address_space);
|
||||||
err3:
|
err3:
|
||||||
vfs_free_io_context(team->io_context);
|
vfs_put_io_context(team->io_context);
|
||||||
err2:
|
err2:
|
||||||
free_team_arg(teamArgs);
|
free_team_arg(teamArgs);
|
||||||
err1:
|
err1:
|
||||||
|
if (parentIOContext != NULL)
|
||||||
|
vfs_put_io_context(parentIOContext);
|
||||||
|
|
||||||
// remove the team structure from the team hash table and delete the team structure
|
// remove the team structure from the team hash table and delete the team structure
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_TEAM_LOCK();
|
GRAB_TEAM_LOCK();
|
||||||
|
|
||||||
remove_team_from_group(team);
|
remove_team_from_group(team);
|
||||||
remove_team_from_parent(parent, team);
|
remove_team_from_parent(team->parent, team);
|
||||||
hash_remove(sTeamHash, team);
|
hash_remove(sTeamHash, team);
|
||||||
|
|
||||||
RELEASE_TEAM_LOCK();
|
RELEASE_TEAM_LOCK();
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
|
err0:
|
||||||
delete_team_struct(team);
|
delete_team_struct(team);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -1431,7 +1452,8 @@ fork_team(void)
|
|||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
|
|
||||||
// create a new team
|
// create a new team
|
||||||
// ToDo: this is very similar to team_create_team() - maybe we can do something about it :)
|
// TODO: this is very similar to load_image_internal() - maybe we can do
|
||||||
|
// something about it :)
|
||||||
|
|
||||||
team = create_team_struct(parentTeam->name, false);
|
team = create_team_struct(parentTeam->name, false);
|
||||||
if (team == NULL)
|
if (team == NULL)
|
||||||
@@ -1562,7 +1584,7 @@ err4:
|
|||||||
err3:
|
err3:
|
||||||
delete_realtime_sem_context(team->realtime_sem_context);
|
delete_realtime_sem_context(team->realtime_sem_context);
|
||||||
err25:
|
err25:
|
||||||
vfs_free_io_context(team->io_context);
|
vfs_put_io_context(team->io_context);
|
||||||
err2:
|
err2:
|
||||||
free(forkArgs);
|
free(forkArgs);
|
||||||
err1:
|
err1:
|
||||||
@@ -2354,7 +2376,7 @@ team_delete_team(struct team *team)
|
|||||||
|
|
||||||
// free team resources
|
// free team resources
|
||||||
|
|
||||||
vfs_free_io_context(team->io_context);
|
vfs_put_io_context(team->io_context);
|
||||||
delete_realtime_sem_context(team->realtime_sem_context);
|
delete_realtime_sem_context(team->realtime_sem_context);
|
||||||
xsi_sem_undo(team);
|
xsi_sem_undo(team);
|
||||||
delete_owned_ports(teamID);
|
delete_owned_ports(teamID);
|
||||||
@@ -2638,6 +2660,15 @@ team_free_user_thread(struct thread* thread)
|
|||||||
|
|
||||||
thread_id
|
thread_id
|
||||||
load_image(int32 argCount, const char **args, const char **env)
|
load_image(int32 argCount, const char **args, const char **env)
|
||||||
|
{
|
||||||
|
return load_image_etc(argCount, args, env, B_NORMAL_PRIORITY,
|
||||||
|
B_CURRENT_TEAM, B_WAIT_TILL_LOADED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
thread_id
|
||||||
|
load_image_etc(int32 argCount, const char* const* args,
|
||||||
|
const char* const* env, int32 priority, team_id parentID, uint32 flags)
|
||||||
{
|
{
|
||||||
// we need to flatten the args and environment
|
// we need to flatten the args and environment
|
||||||
|
|
||||||
@@ -2685,11 +2716,11 @@ load_image(int32 argCount, const char **args, const char **env)
|
|||||||
|
|
||||||
*slot++ = NULL;
|
*slot++ = NULL;
|
||||||
|
|
||||||
thread_id thread = load_image_etc(flatArgs, size, argCount, envCount,
|
thread_id thread = load_image_internal(flatArgs, size, argCount, envCount,
|
||||||
B_NORMAL_PRIORITY, B_WAIT_TILL_LOADED, -1, 0);
|
B_NORMAL_PRIORITY, parentID, B_WAIT_TILL_LOADED, -1, 0);
|
||||||
|
|
||||||
free(flatArgs);
|
free(flatArgs);
|
||||||
// load_image_etc() unset our variable if it took over ownership
|
// load_image_internal() unset our variable if it took over ownership
|
||||||
|
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
@@ -3277,7 +3308,7 @@ _user_load_image(const char* const* userFlatArgs, size_t flatArgsSize,
|
|||||||
int32 argCount, int32 envCount, int32 priority, uint32 flags,
|
int32 argCount, int32 envCount, int32 priority, uint32 flags,
|
||||||
port_id errorPort, uint32 errorToken)
|
port_id errorPort, uint32 errorToken)
|
||||||
{
|
{
|
||||||
TRACE(("_user_load_image_etc: argc = %ld\n", argCount));
|
TRACE(("_user_load_image: argc = %ld\n", argCount));
|
||||||
|
|
||||||
if (argCount < 1)
|
if (argCount < 1)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
@@ -3289,11 +3320,12 @@ _user_load_image(const char* const* userFlatArgs, size_t flatArgsSize,
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
thread_id thread = load_image_etc(flatArgs, _ALIGN(flatArgsSize), argCount,
|
thread_id thread = load_image_internal(flatArgs, _ALIGN(flatArgsSize),
|
||||||
envCount, priority, flags, errorPort, errorToken);
|
argCount, envCount, priority, B_CURRENT_TEAM, flags, errorPort,
|
||||||
|
errorToken);
|
||||||
|
|
||||||
free(flatArgs);
|
free(flatArgs);
|
||||||
// load_image_etc() unset our variable if it took over ownership
|
// load_image_internal() unset our variable if it took over ownership
|
||||||
|
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,10 +243,8 @@ common_setgroups(int groupCount, const gid_t* groupList, bool kernel)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
inherit_parent_user_and_group(struct team* team, struct team* parent)
|
inherit_parent_user_and_group_locked(struct team* team, struct team* parent)
|
||||||
{
|
{
|
||||||
InterruptsSpinLocker _(gTeamSpinlock);
|
|
||||||
|
|
||||||
team->saved_set_uid = parent->saved_set_uid;
|
team->saved_set_uid = parent->saved_set_uid;
|
||||||
team->real_uid = parent->real_uid;
|
team->real_uid = parent->real_uid;
|
||||||
team->effective_uid = parent->effective_uid;
|
team->effective_uid = parent->effective_uid;
|
||||||
@@ -260,6 +258,14 @@ inherit_parent_user_and_group(struct team* team, struct team* parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
inherit_parent_user_and_group(struct team* team, struct team* parent)
|
||||||
|
{
|
||||||
|
InterruptsSpinLocker _(gTeamSpinlock);
|
||||||
|
inherit_parent_user_and_group_locked(team, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
update_set_id_user_and_group(struct team* team, const char* file)
|
update_set_id_user_and_group(struct team* team, const char* file)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user