diff --git a/sched/environ/env_dup.c b/sched/environ/env_dup.c index 1745385daf..08b0e1b617 100644 --- a/sched/environ/env_dup.c +++ b/sched/environ/env_dup.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/environ/env_dup.c * - * Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011, 2013, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -82,7 +82,7 @@ int env_dup(FAR struct task_group_s *group) size_t envlen; int ret = OK; - DEBUGASSERT(group && ptcb && ptcb->group); + DEBUGASSERT(group != NULL && ptcb != NULL && ptcb->group != NULL); /* Pre-emption must be disabled throughout the following because the * environment may be shared. @@ -92,22 +92,44 @@ int env_dup(FAR struct task_group_s *group) /* Does the parent task have an environment? */ - if (ptcb->group && ptcb->group->tg_envp) + if (ptcb->group != NULL && ptcb->group->tg_envp != NULL) { - /* Yes..The parent task has an environment, duplicate it */ + /* Yes.. The parent task has an environment allocation. */ envlen = ptcb->group->tg_envsize; - envp = (FAR char *)kumm_malloc(envlen); - if (!envp) + envp = NULL; + + /* A special case is that the parent has an "empty" environment + * allocation, i.e., there is an allocation in place but it + * contains no variable definitions and, hence, envlen == 0. + */ + + if (envlen > 0) { - ret = -ENOMEM; - } - else - { - group->tg_envsize = envlen; - group->tg_envp = envp; - memcpy(envp, ptcb->group->tg_envp, envlen); + /* There is an environment, duplicate it */ + + envp = (FAR char *)kumm_malloc(envlen); + if (envp == NULL) + { + /* The parent's environment can not be inherited due to a + * failure in the allocation of the child environment. + */ + + envlen = 0; + ret = -ENOMEM; + } + else + { + /* Duplicate the parent environment. */ + + memcpy(envp, ptcb->group->tg_envp, envlen); + } } + + /* Save the size and child environment allocation. */ + + group->tg_envsize = envlen; + group->tg_envp = envp; } sched_unlock();