diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h index 1b3b3727a8f..ed740073dca 100644 --- a/include/sys/syscall_lookup.h +++ b/include/sys/syscall_lookup.h @@ -28,6 +28,10 @@ SYSCALL_LOOKUP1(_exit, 1) SYSCALL_LOOKUP(exit, 1) SYSCALL_LOOKUP(getpid, 0) +#ifdef CONFIG_SCHED_HAVE_PARENT + SYSCALL_LOOKUP(getppid, 0) +#endif + SYSCALL_LOOKUP(sched_getparam, 2) SYSCALL_LOOKUP(sched_getscheduler, 1) SYSCALL_LOOKUP(sched_lock, 0) diff --git a/include/unistd.h b/include/unistd.h index 627eb1a7b44..16764ce8092 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -315,6 +315,9 @@ EXTERN int optopt; /* Unrecognized option character */ pid_t vfork(void); pid_t getpid(void); pid_t gettid(void); +#ifdef CONFIG_SCHED_HAVE_PARENT +pid_t getppid(void); +#endif void _exit(int status) noreturn_function; unsigned int sleep(unsigned int seconds); int usleep(useconds_t usec); diff --git a/sched/task/Make.defs b/sched/task/Make.defs index 1fa00c78342..f14ef470790 100644 --- a/sched/task/Make.defs +++ b/sched/task/Make.defs @@ -39,6 +39,10 @@ CSRCS += task_getgroup.c task_getpid.c task_prctl.c task_recover.c CSRCS += task_restart.c task_spawnparms.c task_setcancelstate.c CSRCS += task_cancelpt.c task_terminate.c exit.c +ifeq ($(CONFIG_SCHED_HAVE_PARENT),y) +CSRCS += task_getppid.c +endif + ifeq ($(CONFIG_ARCH_HAVE_VFORK),y) ifeq ($(CONFIG_SCHED_WAITPID),y) CSRCS += task_vfork.c diff --git a/sched/task/task_getppid.c b/sched/task/task_getppid.c new file mode 100644 index 00000000000..ba1fc298ded --- /dev/null +++ b/sched/task/task_getppid.c @@ -0,0 +1,104 @@ +/**************************************************************************** + * sched/task/task_getppid.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include "sched/sched.h" +#include "task/task.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: getppid + * + * Description: + * Get the parent task ID of the currently executing task. + * + * Input parameters: + * None + * + * Returned Value: + * Normally when called from user applications, getppid() will return the + * parent task ID of the currently executing task, that is, the task at the + * head of the ready-to-run list. There is no specification for any errors + * returned from getppid(). + * + * getppid(), however, may be called from within the OS in some cases. + * There are certain situations during context switching when the OS data + * structures are in flux and where the current task at the head of the + * ready-to-run task list is not actually running. In that case, + * getppid() will return the error: -ESRCH + * + ****************************************************************************/ + +pid_t getppid(void) +{ + FAR struct tcb_s *rtcb; + + /* Get the TCB at the head of the ready-to-run task list. That + * will usually be the currently executing task. There is are two + * exceptions to this: + * + * 1. Early in the start-up sequence, the ready-to-run list may be + * empty! In this case, of course, the CPU0 start-up/IDLE thread with + * pid == 0 must be running, and + * 2. As described above, during certain context-switching conditions the + * task at the head of the ready-to-run list may not actually be + * running. + */ + + rtcb = this_task(); + if (rtcb != NULL) + { + /* Check if the task is actually running */ + + if (rtcb->task_state == TSTATE_TASK_RUNNING) + { + /* Yes.. Return the parent task ID from the TCB at the head of the + * ready-to-run task list + */ + +#ifdef HAVE_GROUP_MEMBERS + return rtcb->group->tg_pgrpid; +#else + return rtcb->group->tg_ppid; +#endif + } + + /* No.. return -ESRCH to indicate this condition */ + + return (pid_t)-ESRCH; + } + + /* We must have been called earlier in the start up sequence from the + * start-up/IDLE thread before the ready-to-run list has been initialized. + */ + + return (pid_t)0; +} diff --git a/syscall/syscall.csv b/syscall/syscall.csv index 981855a65a4..cd592d2b11a 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -36,6 +36,7 @@ "getitimer","sys/time.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","int","int","FAR struct itimerval *" "getpeername","sys/socket.h","defined(CONFIG_NET)","int","int","FAR struct sockaddr *","FAR socklen_t *" "getpid","unistd.h","","pid_t" +"getppid","unistd.h","defined(CONFIG_SCHED_HAVE_PARENT)","pid_t" "getsockname","sys/socket.h","defined(CONFIG_NET)","int","int","FAR struct sockaddr *","FAR socklen_t *" "getsockopt","sys/socket.h","defined(CONFIG_NET)","int","int","int","int","FAR void *","FAR socklen_t *" "getuid","unistd.h","defined(CONFIG_SCHED_USER_IDENTITY)","uid_t"