diff --git a/include/sys/wait.h b/include/sys/wait.h index 4f653a8fbe4..f693436cf42 100644 --- a/include/sys/wait.h +++ b/include/sys/wait.h @@ -96,6 +96,15 @@ pid_t wait(FAR int *stat_loc); int waitid(idtype_t idtype, id_t id, FAR siginfo_t *info, int options); pid_t waitpid(pid_t pid, FAR int *stat_loc, int options); +/* wait4() is waitpid() plus the reaped child's struct rusage in one call. + * struct rusage is forward-declared here (not #include ) + * since it is only ever used as a pointer type in this prototype. + */ + +struct rusage; +pid_t wait4(pid_t pid, FAR int *stat_loc, int options, + FAR struct rusage *rusage); + #undef EXTERN #if defined(__cplusplus) } diff --git a/libs/libc/unistd/CMakeLists.txt b/libs/libc/unistd/CMakeLists.txt index b85e65e54d6..7d1b1461439 100644 --- a/libs/libc/unistd/CMakeLists.txt +++ b/libs/libc/unistd/CMakeLists.txt @@ -73,6 +73,10 @@ set(SRCS lib_confstr.c lib_ulimit.c) +if(CONFIG_SCHED_WAITPID) + list(APPEND SRCS lib_wait4.c) +endif() + if(NOT CONFIG_SCHED_USER_IDENTITY) list( APPEND diff --git a/libs/libc/unistd/Make.defs b/libs/libc/unistd/Make.defs index 3e9c6dfeb21..c4a582292f4 100644 --- a/libs/libc/unistd/Make.defs +++ b/libs/libc/unistd/Make.defs @@ -36,6 +36,10 @@ CSRCS += lib_getsid.c lib_setpgid.c lib_setsid.c CSRCS += lib_lockf.c lib_flock.c lib_getpass.c CSRCS += lib_chdir.c lib_fchdir.c lib_confstr.c lib_ulimit.c +ifeq ($(CONFIG_SCHED_WAITPID),y) +CSRCS += lib_wait4.c +endif + ifneq ($(CONFIG_SCHED_USER_IDENTITY),y) CSRCS += lib_setuid.c lib_setgid.c lib_getuid.c lib_getgid.c CSRCS += lib_seteuid.c lib_setegid.c lib_geteuid.c lib_getegid.c diff --git a/libs/libc/unistd/lib_wait4.c b/libs/libc/unistd/lib_wait4.c new file mode 100644 index 00000000000..747eeb3d3f3 --- /dev/null +++ b/libs/libc/unistd/lib_wait4.c @@ -0,0 +1,64 @@ +/**************************************************************************** + * libs/libc/unistd/lib_wait4.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: wait4 + * + * Description: + * wait4() is waitpid() plus the reaped child's resource usage in one + * call. Built entirely on top of the existing waitpid()/getrusage() + * primitives (each already correctly proxied across build separation -- + * waitpid() is a real syscall, getrusage() is plain libc), so this needs + * no syscall plumbing of its own and works unmodified in flat, + * protected, and kernel builds alike. + * + * NuttX's getrusage() only supports RUSAGE_SELF/RUSAGE_CHILDREN (not a + * specific pid), so the returned usage is exact only when the caller has + * a single outstanding child at a time. + * + ****************************************************************************/ + +pid_t wait4(pid_t pid, FAR int *stat_loc, int options, + FAR struct rusage *rusage) +{ + pid_t ret = waitpid(pid, stat_loc, options); + + if (ret > 0 && rusage != NULL) + { + getrusage(RUSAGE_CHILDREN, rusage); + } + + return ret; +}