mirror of
https://github.com/apache/nuttx.git
synced 2026-06-01 07:45:16 +08:00
Fix more places where the user-mode allocator is used to allocate kernel thread resources -- before the user-mode allocator even exists
This commit is contained in:
+7
-3
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* fs/fs_fdopen.c
|
* fs/fs_fdopen.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2014 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -226,9 +226,13 @@ FAR struct file_struct *fs_fdopen(int fd, int oflags, FAR struct tcb_s *tcb)
|
|||||||
|
|
||||||
(void)sem_init(&stream->fs_sem, 0, 1);
|
(void)sem_init(&stream->fs_sem, 0, 1);
|
||||||
|
|
||||||
/* Allocate the IO buffer */
|
/* Allocate the IO buffer at the appropriate privilege level for
|
||||||
|
* the group.
|
||||||
|
*/
|
||||||
|
|
||||||
|
stream->fs_bufstart =
|
||||||
|
group_malloc(tcb->group, CONFIG_STDIO_BUFFER_SIZE);
|
||||||
|
|
||||||
stream->fs_bufstart = kumm_malloc(CONFIG_STDIO_BUFFER_SIZE);
|
|
||||||
if (!stream->fs_bufstart)
|
if (!stream->fs_bufstart)
|
||||||
{
|
{
|
||||||
err = ENOMEM;
|
err = ENOMEM;
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ struct addrenv_reserve_s
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define ARCH_DATA_RESERVE \
|
#define ARCH_DATA_RESERVE \
|
||||||
((FAR struct addrenv_reserve_s *)CONFIG_ARCH_TEXT_VBASE)
|
((FAR struct addrenv_reserve_s *)CONFIG_ARCH_DATA_VBASE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
+36
-1
@@ -81,7 +81,7 @@ extern "C"
|
|||||||
* from the kernel. In the flat build, the following are declared in
|
* from the kernel. In the flat build, the following are declared in
|
||||||
* stdlib.h and are directly callable. In the kernel-phase of the kernel
|
* stdlib.h and are directly callable. In the kernel-phase of the kernel
|
||||||
* build, the following are defined in userspace.h as macros that call
|
* build, the following are defined in userspace.h as macros that call
|
||||||
* into user-space via a header at the begining of the user-space blob.
|
* into user-space via a header at the beginning of the user-space blob.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define kumm_initialize(h,s) umm_initialize(h,s)
|
#define kumm_initialize(h,s) umm_initialize(h,s)
|
||||||
@@ -157,6 +157,41 @@ extern "C"
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \
|
||||||
|
defined(CONFIG_MM_KERNEL_HEAP)
|
||||||
|
/****************************************************************************
|
||||||
|
* Group memory management
|
||||||
|
*
|
||||||
|
* Manage memory allocations appropriately for the group type. If the
|
||||||
|
* memory is part of a privileged group, then it should be allocated so
|
||||||
|
* that it is only accessible by privileged code; Otherwise, it is a
|
||||||
|
* user mode group and must be allocated so that it accessible by
|
||||||
|
* unprivileged code.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
/* Functions defined in group/group_malloc.c ********************************/
|
||||||
|
|
||||||
|
FAR void *group_malloc(FAR struct task_group_s *group, size_t nbytes);
|
||||||
|
|
||||||
|
/* Functions defined in group/group_zalloc.c ********************************/
|
||||||
|
|
||||||
|
FAR void *group_zalloc(FAR struct task_group_s *group, size_t nbytes);
|
||||||
|
|
||||||
|
/* Functions defined in group/group_free.c **********************************/
|
||||||
|
|
||||||
|
void group_free(FAR struct task_group_s *group, FAR void *mem);
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* In the flat build, there is only one memory allocator and no distinction
|
||||||
|
* in privileges.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# define group_malloc(g,n) kumm_malloc(size)
|
||||||
|
# define group_zalloc(g,n) kumm_zalloc(size)
|
||||||
|
# define group_free(g,m) kumm_free(size)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Functions defined in sched/sched_kfree.c **********************************/
|
/* Functions defined in sched/sched_kfree.c **********************************/
|
||||||
|
|
||||||
/* Handles memory freed from an interrupt handler. In that context, kmm_free()
|
/* Handles memory freed from an interrupt handler. In that context, kmm_free()
|
||||||
|
|||||||
+1
-20
@@ -95,7 +95,7 @@ void weak_function task_initialize(void);
|
|||||||
/* Task group data structure management */
|
/* Task group data structure management */
|
||||||
|
|
||||||
#ifdef HAVE_TASK_GROUP
|
#ifdef HAVE_TASK_GROUP
|
||||||
int group_allocate(FAR struct task_tcb_s *tcb);
|
int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype);
|
||||||
int group_initialize(FAR struct task_tcb_s *tcb);
|
int group_initialize(FAR struct task_tcb_s *tcb);
|
||||||
#ifndef CONFIG_DISABLE_PTHREAD
|
#ifndef CONFIG_DISABLE_PTHREAD
|
||||||
int group_bind(FAR struct pthread_tcb_s *tcb);
|
int group_bind(FAR struct pthread_tcb_s *tcb);
|
||||||
@@ -114,25 +114,6 @@ int group_foreachchild(FAR struct task_group_s *group,
|
|||||||
int group_killchildren(FAR struct task_tcb_s *tcb);
|
int group_killchildren(FAR struct task_tcb_s *tcb);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Group memory management */
|
|
||||||
|
|
||||||
#if (defined(CONFIG_BUILD_PROTECTED) || defined(CONFIG_BUILD_KERNEL)) && \
|
|
||||||
defined(CONFIG_MM_KERNEL_HEAP)
|
|
||||||
/* Functions to pick the correct allocator based on group privileges */
|
|
||||||
|
|
||||||
FAR void *group_malloc(FAR struct task_group_s *group, size_t nbytes);
|
|
||||||
FAR void *group_zalloc(FAR struct task_group_s *group, size_t nbytes);
|
|
||||||
void group_free(FAR struct task_group_s *group, FAR void *mem);
|
|
||||||
|
|
||||||
#else
|
|
||||||
/* There is only one allocator */
|
|
||||||
|
|
||||||
# define group_malloc(g,n) kumm_malloc(size)
|
|
||||||
# define group_zalloc(g,n) kumm_zalloc(size)
|
|
||||||
# define group_free(g,m) kumm_free(size)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_ARCH_ADDRENV
|
#ifdef CONFIG_ARCH_ADDRENV
|
||||||
/* Group address environment management */
|
/* Group address environment management */
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,8 @@
|
|||||||
|
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
|
|
||||||
#include "group/group.h"
|
|
||||||
#include "environ/environ.h"
|
#include "environ/environ.h"
|
||||||
|
#include "group/group.h"
|
||||||
|
|
||||||
#ifdef HAVE_TASK_GROUP
|
#ifdef HAVE_TASK_GROUP
|
||||||
|
|
||||||
@@ -165,6 +165,7 @@ static void group_assigngid(FAR struct task_group_s *group)
|
|||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* tcb - The tcb in need of the task group.
|
* tcb - The tcb in need of the task group.
|
||||||
|
* ttype - Type of the thread that is the parent of the group
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* 0 (OK) on success; a negated errno value on failure.
|
* 0 (OK) on success; a negated errno value on failure.
|
||||||
@@ -175,7 +176,7 @@ static void group_assigngid(FAR struct task_group_s *group)
|
|||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
int group_allocate(FAR struct task_tcb_s *tcb)
|
int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype)
|
||||||
{
|
{
|
||||||
FAR struct task_group_s *group;
|
FAR struct task_group_s *group;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -196,7 +197,7 @@ int group_allocate(FAR struct task_tcb_s *tcb)
|
|||||||
* of the group must be created for privileged access.
|
* of the group must be created for privileged access.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((tcb->cmn.flags & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
|
if ((ttype & TCB_FLAG_TTYPE_MASK) == TCB_FLAG_TTYPE_KERNEL)
|
||||||
{
|
{
|
||||||
group->tg_flags |= GROUP_FLAG_PRIVILEGED;
|
group->tg_flags |= GROUP_FLAG_PRIVILEGED;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include <nuttx/sched.h>
|
#include <nuttx/sched.h>
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
|
|
||||||
@@ -82,6 +84,8 @@
|
|||||||
|
|
||||||
void group_free(FAR struct task_group_s *group, FAR void *mem)
|
void group_free(FAR struct task_group_s *group, FAR void *mem)
|
||||||
{
|
{
|
||||||
|
DEBUGASSERT(group && mem);
|
||||||
|
|
||||||
/* Check the group is privileged */
|
/* Check the group is privileged */
|
||||||
|
|
||||||
if ((group->tg_flags & GROUP_FLAG_PRIVILEGED) != 0)
|
if ((group->tg_flags & GROUP_FLAG_PRIVILEGED) != 0)
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include <nuttx/sched.h>
|
#include <nuttx/sched.h>
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
|
|
||||||
@@ -76,8 +78,8 @@
|
|||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Allocate memory appropriate for the group type. If the memory is
|
* Allocate memory appropriate for the group type. If the memory is
|
||||||
* part of a privileged, then it should be allocated so that it is
|
* part of a privileged group, then it should be allocated so that it
|
||||||
* only accessed by privileged code; Otherwise, it is a user mode
|
* is only accessible by privileged code; Otherwise, it is a user mode
|
||||||
* group and must be allocated so that it accessible by unprivileged
|
* group and must be allocated so that it accessible by unprivileged
|
||||||
* code.
|
* code.
|
||||||
*
|
*
|
||||||
@@ -85,6 +87,8 @@
|
|||||||
|
|
||||||
FAR void *group_malloc(FAR struct task_group_s *group, size_t nbytes)
|
FAR void *group_malloc(FAR struct task_group_s *group, size_t nbytes)
|
||||||
{
|
{
|
||||||
|
DEBUGASSERT(group);
|
||||||
|
|
||||||
/* Check the group type */
|
/* Check the group type */
|
||||||
|
|
||||||
if ((group->tg_flags & GROUP_FLAG_PRIVILEGED) != 0)
|
if ((group->tg_flags & GROUP_FLAG_PRIVILEGED) != 0)
|
||||||
|
|||||||
+11
-11
@@ -380,9 +380,9 @@ void os_start(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS)
|
||||||
/* Initialize tasking data structures */
|
/* Initialize tasking data structures */
|
||||||
|
|
||||||
#if defined(CONFIG_SCHED_HAVE_PARENT) && defined(CONFIG_SCHED_CHILD_STATUS)
|
|
||||||
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
||||||
if (task_initialize != NULL)
|
if (task_initialize != NULL)
|
||||||
#endif
|
#endif
|
||||||
@@ -427,9 +427,9 @@ void os_start(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
/* Initialize the signal facility (if in link) */
|
/* Initialize the signal facility (if in link) */
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
|
||||||
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
||||||
if (sig_initialize != NULL)
|
if (sig_initialize != NULL)
|
||||||
#endif
|
#endif
|
||||||
@@ -438,9 +438,9 @@ void os_start(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_MQUEUE
|
||||||
/* Initialize the named message queue facility (if in link) */
|
/* Initialize the named message queue facility (if in link) */
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_MQUEUE
|
|
||||||
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
||||||
if (mq_initialize != NULL)
|
if (mq_initialize != NULL)
|
||||||
#endif
|
#endif
|
||||||
@@ -449,9 +449,9 @@ void os_start(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_PTHREAD
|
||||||
/* Initialize the thread-specific data facility (if in link) */
|
/* Initialize the thread-specific data facility (if in link) */
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_PTHREAD
|
|
||||||
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
||||||
if (pthread_initialize != NULL)
|
if (pthread_initialize != NULL)
|
||||||
#endif
|
#endif
|
||||||
@@ -460,9 +460,9 @@ void os_start(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||||
/* Initialize the file system (needed to support device drivers) */
|
/* Initialize the file system (needed to support device drivers) */
|
||||||
|
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
|
||||||
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
|
||||||
if (fs_initialize != NULL)
|
if (fs_initialize != NULL)
|
||||||
#endif
|
#endif
|
||||||
@@ -471,9 +471,9 @@ void os_start(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET
|
||||||
/* Initialize the network system */
|
/* Initialize the network system */
|
||||||
|
|
||||||
#ifdef CONFIG_NET
|
|
||||||
net_initialize();
|
net_initialize();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -497,25 +497,25 @@ void os_start(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* IDLE Group Initialization **********************************************/
|
/* IDLE Group Initialization **********************************************/
|
||||||
/* Allocate the IDLE group and suppress child status. */
|
|
||||||
|
|
||||||
#ifdef HAVE_TASK_GROUP
|
#ifdef HAVE_TASK_GROUP
|
||||||
DEBUGVERIFY(group_allocate(&g_idletcb));
|
/* Allocate the IDLE group */
|
||||||
|
|
||||||
|
DEBUGVERIFY(group_allocate(&g_idletcb, g_idletcb.cmn.flags));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
|
||||||
/* Create stdout, stderr, stdin on the IDLE task. These will be
|
/* Create stdout, stderr, stdin on the IDLE task. These will be
|
||||||
* inherited by all of the threads created by the IDLE task.
|
* inherited by all of the threads created by the IDLE task.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if CONFIG_NFILE_DESCRIPTORS > 0 || CONFIG_NSOCKET_DESCRIPTORS > 0
|
|
||||||
DEBUGVERIFY(group_setupidlefiles(&g_idletcb));
|
DEBUGVERIFY(group_setupidlefiles(&g_idletcb));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_TASK_GROUP
|
||||||
/* Complete initialization of the IDLE group. Suppress retention
|
/* Complete initialization of the IDLE group. Suppress retention
|
||||||
* of child status in the IDLE group.
|
* of child status in the IDLE group.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_TASK_GROUP
|
|
||||||
DEBUGVERIFY(group_initialize(&g_idletcb));
|
DEBUGVERIFY(group_initialize(&g_idletcb));
|
||||||
g_idletcb.cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT;
|
g_idletcb.cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/task/task_create.c
|
* sched/task/task_create.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2010, 2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2010, 2013-2014 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
* Description:
|
* Description:
|
||||||
* This function creates and activates a new thread of the specified type
|
* This function creates and activates a new thread of the specified type
|
||||||
* with a specified priority and returns its system-assigned ID. It is the
|
* with a specified priority and returns its system-assigned ID. It is the
|
||||||
* internal, commn implementation of task_create() and kernel_thread().
|
* internal, common implementation of task_create() and kernel_thread().
|
||||||
* See comments with task_create() for further information.
|
* See comments with task_create() for further information.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
@@ -118,10 +118,12 @@ static int thread_create(FAR const char *name, uint8_t ttype, int priority,
|
|||||||
goto errout;
|
goto errout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a new task group */
|
/* Allocate a new task group with privileges appropriate for the parent
|
||||||
|
* thread type.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_TASK_GROUP
|
#ifdef HAVE_TASK_GROUP
|
||||||
ret = group_allocate(tcb);
|
ret = group_allocate(tcb, ttype);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
errcode = -ret;
|
errcode = -ret;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/task/task_init.c
|
* sched/task/task_init.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2013-2014 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -130,7 +130,7 @@ int task_init(FAR struct tcb_s *tcb, const char *name, int priority,
|
|||||||
/* Create a new task group */
|
/* Create a new task group */
|
||||||
|
|
||||||
#ifdef HAVE_TASK_GROUP
|
#ifdef HAVE_TASK_GROUP
|
||||||
ret = group_allocate(ttcb);
|
ret = group_allocate(ttcb, tcb->flags);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
errcode = -ret;
|
errcode = -ret;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/task/task_vfork
|
* sched/task/task_vfork
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2013-2014 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -144,10 +144,10 @@ FAR struct task_tcb_s *task_vforksetup(start_t retaddr)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a new task group */
|
/* Allocate a new task group with the same privileges as the parent */
|
||||||
|
|
||||||
#ifdef HAVE_TASK_GROUP
|
#ifdef HAVE_TASK_GROUP
|
||||||
ret = group_allocate(child);
|
ret = group_allocate(child, parent->flags);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
goto errout_with_tcb;
|
goto errout_with_tcb;
|
||||||
|
|||||||
Reference in New Issue
Block a user