You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2020/12/20 19:40:22 UTC

[incubator-nuttx] branch master updated: libc: Implement getppid

This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 085619d  libc: Implement getppid
085619d is described below

commit 085619d3957c0577d427ec764d3a2eb463dfeea4
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Mon Dec 14 20:07:42 2020 +0800

    libc: Implement getppid
    
    as specified here:
    https://pubs.opengroup.org/onlinepubs/009695399/functions/getppid.html
    
    Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
 include/sys/syscall_lookup.h |   4 ++
 include/unistd.h             |   3 ++
 sched/task/Make.defs         |   4 ++
 sched/task/task_getppid.c    | 104 +++++++++++++++++++++++++++++++++++++++++++
 syscall/syscall.csv          |   1 +
 5 files changed, 116 insertions(+)

diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h
index 1b3b372..ed74007 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 627eb1a..16764ce 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 1fa00c7..f14ef47 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 0000000..ba1fc29
--- /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 <sys/types.h>
+#include <unistd.h>
+#include <sched.h>
+#include <errno.h>
+
+#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 981855a..cd592d2 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"