Use fopencookie() to attach the popen fd and shell pid to the returned FILE stream instead of copying FILE into the popen container.
Keep the upstream dpopen()/dpclose() implementation as the process and descriptor backend, and make pclose() close the cookie-backed stream directly.
Fixes#2937.
Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com>
Introduce a new CONFIG_UORB_FORMAT Kconfig option to control whether
uORB format strings are compiled in. UORB_LISTENER, UORB_GENERATOR,
and DEBUG_UORB all select UORB_FORMAT automatically, so format strings
are included when any of these features are enabled.
This replaces the previous approach of guarding format strings with
CONFIG_DEBUG_UORB, which prevented uorb_listener from displaying
sensor data when debug output was disabled.
Signed-off-by: hanzhijian <hanzhijian@zepp.com>
listener_update() only prints topic data when delta_generation is
non-zero (i.e., new data arrived since last check). In listener_top,
the first call adds objects to the list, and subsequent calls only
print if new data was published between iterations. This results in
listener_top -T showing only the header with no topic rows.
Fix by always printing the current topic state in listener_update,
setting frequency to 0 when no new data arrives. This ensures
listener_top displays all topics every iteration.
Fixesapache/nuttx-apps#3202
Signed-off-by: hanzj <hanzhijian@zepp.com>
Fix argument parsing in init_parse_arguments() to properly handle
multiple quoted arguments like 'echo "arg1" "arg2"' by skipping
quote characters after processing them.
Signed-off-by: fangpeina <fangpeina@xiaomi.com>
The init process has blocked all signals, spawned services would
inherit that mask. This could cause services to miss important
signals like SIGTERM during graceful shutdown.
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Pending all signals(SIGCHLD) when ppoll() is not invoked to
avoid race conditions.
Case reproduction
Set examples/hello as a service that exits immediately after startup.
```init.rc
on boot
start hello
service hello hello
restart_period 0
```
Log - without this patch:
# Service hello only restarts about 100 times, ppoll is not woken up
# after the hello process with PID 119 exits.
[ 4.391274] [ 2] [ 0] init_main: service 'hello' pid 118 exited status 0
[ 4.401423] [ 2] [ 0] init_main: started service 'hello' pid 119
Log - with this patch:
# ppoll() can still be woken up normally after tens of thousands of
# restarts of service hello in stress test.
[ 268.447747] [ 2] [ 0] init_main: service 'hello' pid 34503 exited status 0
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Any string ending with whitespace passed to init_parse_arguments()
could cause the parser to advance past the string boundary and read
unintended memory content.
- " echo "A" \0& echo "B" should be parsed
as a command with two argvs instand of five.
- "command arg " may lead to uncertain results.
Signed-off-by: fangpeina <fangpeina@xiaomi.com>
reap_process() referenced an undeclared identifier 'wtatus' on
the WIFSIGNALED branch (typo of 'wstatus'). Some toolchains then
flagged a -Wmaybe-uninitialized on the surrounding wstatus use.
Correct the typo so WIFSIGNALED/WTERMSIG operate on the actual
wstatus value returned by waitpid().
Signed-off-by: fangpeina <fangpeina@xiaomi.com>
action.c uses clock_gettime(CLOCK_MONOTONIC, ...) but did not
pull in <nuttx/clock.h> directly, which fails to build on
configurations where the header is not transitively included.
Add the missing #include.
Signed-off-by: fangpeina <fangpeina@xiaomi.com>
When ETC_ROMFS is disabled to reduce the bin size, we can provide the init.rc
file via a pseudo-file in the boards/vendor directory. For example:
- CONFIG_ETC_ROMFS=n
- CONFIG_PSEUDOFS_FILE=y
- CONFIG_DISABLE_PSEUDOFS_OPERATIONS=n
```C
FAR const char *init_rc =
"on init\n"
" start console\n";
"service console sh\n"
" restart_period 100\n";
int fd = open("/etc/init.d/init.rc", O_WRONLY | O_CREAT);
/* ... */
ssize_t n = write(fd, init_rc, strlen(init_rc) + 1);
/* ... */
close(fd);
```
The last character '\0' in the file content will be treated as a new line,
and the number of parsed parameters will be zero (abnormal, there should be
at least one keyword).
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Empty lines in init.rc caused parsing to fail with -EINVAL because init_parse_arguments() returns 0 for empty strings, triggering the 'argc < 1' error path in init_action_parse() and accessing uninitialized argv[0] in init_service_parse().
Fix by skipping empty lines and lines containing only whitespace before attempting to match section keywords or calling parser callbacks.
Fixesapache/nuttx-apps#3513
Signed-off-by: hanzj <hanzhijian@zepp.com>
When NSH_LIBRARY is not available, dpopen()/popen() can still execute
commands by splitting the command string by whitespace and calling
posix_spawnp() directly. Shell syntax (pipes, redirects, globbing)
is not supported in this mode.
Add CONFIG_SYSTEM_POPEN_MAXARGUMENTS (default 7) to control the
argv array size for the no-shell path.
Remove the hard dependency on NSH_LIBRARY from SYSTEM_POPEN so the
feature can be used in minimal configurations without a shell.
Signed-off-by: cuiziwei <cuiziwei@xiaomi.com>
Add dpopen()/dpclose() as the descriptor-based counterpart of
popen()/pclose(), analogous to how dprintf() relates to fprintf().
dpopen() returns a raw file descriptor instead of a FILE stream,
avoiding the stdio.h dependency for callers that only need an fd.
Refactor popen() as a thin wrapper: dpopen() + fdopen() + FILE
container. All pipe creation and process spawning logic now lives
in dpopen.c.
Also remove the hard dependency on NSH_LIBRARY from SYSTEM_POPEN.
When NSH is available, commands are executed through sh -c with full
shell syntax support. When NSH is not available, commands are split
by whitespace and executed directly via posix_spawnp().
Add CONFIG_SYSTEM_POPEN_MAXARGUMENTS (default 7) to control the
argv array size for the no-shell path.
Signed-off-by: cuiziwei <cuiziwei@xiaomi.com>
Micro XRCE-DDS expects the application to supply open/close/write/read
callbacks for the wire transport. Add a single dispatcher that
registers the selected backend via rmw_uros_set_custom_transport(),
plus two backends:
transport/microros_transport_udp.c
BSD-socket UDP backend. Opens an AF_INET/SOCK_DGRAM socket,
resolves CONFIG_MICROROS_AGENT_IP/PORT, connect()s it, and uses
send/recv. The socket fd is stashed in uxrCustomTransport->args
so no module-level state is needed.
transport/microros_transport_serial.c
termios serial backend. Opens CONFIG_MICROROS_SERIAL_DEVICE with
O_RDWR|O_NOCTTY|O_CLOEXEC, switches to raw 8N1 at
CONFIG_MICROROS_SERIAL_BAUD, and uses poll/read/write. Fd is
again stashed in uxrCustomTransport->args.
Both backends are mutually exclusive at compile time via Kconfig;
the dispatcher selects which set of callbacks to register. Wired
into both the legacy Make build (CSRCS in system/microros/Makefile)
and the CMake build (separate microros_transport static library
with the transport directory only exposed to its INTERFACE).
Signed-off-by: Arjav Patel <arjav1528@gmail.com>
libmicroros is installed by colcon under include/<pkg>/<pkg>/file.h
for ament-packaged headers (e.g. rcl, rmw, rosidl) and the flat
include/<pkg>/file.h for a few others (e.g. rclc). A single
-I include/ therefore resolves <rclc/rclc.h> but not <rcl/rcl.h>.
Enumerate every immediate subdirectory of include/ in addition to
include/ itself so both layouts resolve.
Switch the library hand-off from LDLIBS to EXTRA_LIBS. The sim
target's final link pulls EXTRA_LIBS, not LDLIBS, so the previous
form left rcl/rclc/rcutils symbols unresolved.
Signed-off-by: Arjav Patel <arjav1528@gmail.com>
micro_ros_lib/toolchain.cmake.in initialised C and CXX flags with
-D'__attribute__(x)=' to silence GCC attributes the upstream ament
build is not aware of. The strip also removed __gnu_inline__ and
__always_inline__ from NuttX's libc string.h inlines, so each
micro-ROS translation unit emitted external definitions of strcmp,
strcpy, strlen and friends. Sim final link then failed with ~50
multiple-definition errors.
Drop the define from both flag init lines so the attributes survive
and the inlines collapse as intended.
Signed-off-by: Arjav Patel <arjav1528@gmail.com>
Fix a missing space in the Kconfig help text for SYSTEM_LZF:
'Enable theLZF' → 'Enable the LZF'.
Signed-off-by: Zepp-Hanzj <Zepp-Hanzj@users.noreply.github.com>
Signed-off-by: hanzj <hanzjian@zepp.com>
Use configured key, value, and filename limits while loading and saving settings storage data.
The text backend now builds backup filenames with a sized buffer and bounded formatting, and both text and binary loading reject keys or string values that are not terminated within their configured field sizes. This completes #3109 without changing the storage formats.
Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com>
Use strnlen() for public key, value, and storage path length checks so user-provided settings strings are validated against the configured maximum sizes before they are scanned.
Use bounded key comparisons and strlcpy() for fixed-size settings fields. This addresses part of #3109 without changing the settings API or storage formats.
Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com>
Without debug enabled, the code would not compile due to checking
`WIFEXITED(wstatus)` when `wstatus` was uninitialized.
Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
The init.rc file path is now configurable to allow users to choose where
to put the startup script. This is useful for devices that mount
external media to a special directory like `/sd`.
Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
Would not compile due to typo in macro describing service name length.
Change ensures that:
* We do not malloc an extra `len` bytes since this is already allocated
as part of the struct
* The name string always has a null terminating byte
Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
FIx
Add support for the reboot_on_failure option to the service.
When the execution of a command within a certain action fails (returning
a non-zero status code), NxInit will continue to execute subsequent commands or
actions and will not proactively terminate the startup process. To implement
the functionality of "terminating the startup process after a command
execution fails", there are two methods:
a. Execute conditional statements (if/then/else/fi) via exec command,
but this depends on sh:
```
on init
exec -- set +e; \
mount -t fatfs /dev/data /data ; \
if [ $? -ne 0 ] ; \
then \
echo "failed" ; \
reboot ; \
else \
echo "succeed" ; \
fi;
```
b. Via service's oneshot + reboot_on_failure:
/* Although the example uses sh, it does not depend on it and can be
* replaced with any other Builtin Apps.
*/
```
on init
exec_start mkdir_tmp
ls /tmp
service mkdir_tmp sh -c "mkdir /tmp"
reboot_on_failure 0
oneshot
```
Test
- RC
service console sh
class core
override
> reboot_on_failure 0
restart_period 10000
- Runtime
[ 0.150000] [ 3] [ 0] init_main: == Dump Services ==
...
[ 0.170000] [ 3] [ 0] init_main: Service 0x40486ea0 name 'console' path 'sh'
[ 0.170000] [ 3] [ 0] init_main: pid: 0
[ 0.170000] [ 3] [ 0] init_main: arguments:
[ 0.170000] [ 3] [ 0] init_main: [0] 'service'
[ 0.170000] [ 3] [ 0] init_main: [1] 'console'
[ 0.170000] [ 3] [ 0] init_main: [2] 'sh'
[ 0.170000] [ 3] [ 0] init_main: classes:
[ 0.170000] [ 3] [ 0] init_main: 'core'
[ 0.170000] [ 3] [ 0] init_main: restart_period: 10000
> [ 0.170000] [ 3] [ 0] init_main: reboot_on_failure: 0
[ 0.170000] [ 3] [ 0] init_main: flags:
[ 0.170000] [ 3] [ 0] init_main: 'override'
...
[ 0.380000] [ 3] [ 0] init_main: started service 'console' pid 4
...
nsh> kill -9 4
[ 8.060000] [ 3] [ 0] init_main: service 'console' flag 0x20000004 add 0x4
[ 8.060000] [ 3] [ 0] init_main: -flag 'running'
[ 8.060000] [ 3] [ 0] init_main: service 'console' flag 0x20000000 add 0x8
[ 8.060000] [ 3] [ 0] init_main: +flag 'restarting'
> [ 8.060000] [ 3] [ 0] init_main: Error reboot on failure of service 'console' reason 0
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
Format: exec_start <service>
Start the specified service and pause the processing of any additional
initialization commands until the service completes its execution. This
command operates similarly to the `exec` command; the key difference is
that it utilizes an existing service definition rather than requiring
the `exec` argument vector.
This feature is particularly intended for use with the `reboot_on_failure`
built-in command to perform all types of essential checks during system boot.
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
This component (abbreviated as "NxInit") is specifically developed
for NuttX and intended for system initialization. While we have
adopted the Android Init Language among various syntax options,
this is a brand-new implementation—it is not a port or variant of
Android Init.
Refer to the implementation of Android Init Language, consists of five broad
classes of statements: Actions, Commands, Services, Options, and Imports.
Actions support two types of triggers: event and action. Action triggers also
support runtime triggering. Services support lifecycle management, including
automatic restart (at specified intervals), and starting/stopping
individually or by class. Import supports files or directories, and we may
add a static method in the future. The following are some differences:
1. The Android Init Language treats lines starting with `#` as comments,
while we use a preprocessor to handle comments.
2. For action commands, we can omit "exec" and directly execute
built-in apps or nsh builtins.
3. Regarding the property service, users can either adapt it by self or
directly use the preset NVS-based properties.
4. Only part of standard action commands and service options are
implemented currlently.
To enable system/nxinit:
```diff
-CONFIG_INIT_ENTRYPOINT="nsh_main"
+CONFIG_INIT_ENTRYPOINT="init_main"
+CONFIG_SYSTEM_NXINIT=y
```
For format and additional details, refer to:
https://android.googlesource.com/platform/system/core/+/
master/init/README.md
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
POSIX specifies strcasecmp/strncasecmp in <strings.h>, not <string.h>.
On NuttX (and other strict POSIX environments) rcutils/src/strcasecmp.c
only includes <string.h>, causing an implicit-declaration error for
strcasecmp when cross-compiling.
Patch 0003 adds #include <strings.h> guarded by !_WIN32, matching the
existing Windows/POSIX split in the file.
Signed-off-by: Arjav Patel <arjav1528@gmail.com>
Add -D__NuttX__ to CMAKE_C_FLAGS_INIT and CMAKE_CXX_FLAGS_INIT in
toolchain.cmake.in so that all cross-compiled micro-ROS packages see the
NuttX target macro. Without this, rcutils/src/process.c follows the
__linux__ branch and references program_invocation_name, a glibc-only
extension absent from the NuttX C library.
Pair with 0002-rcutils-process-nuttx-compat.patch which additionally
guards the linux branch with !defined(__NuttX__), ensuring the embedded
fallback path is taken on NuttX even if the host compiler defines any
linux-flavoured macros.
Signed-off-by: Arjav Patel <arjav1528@gmail.com>
Mirror the Makefile build pipeline into CMakeLists.txt using
ExternalProject_Add so that CMake-based NuttX builds (cmake --build)
can also produce libmicroros.a. The external project delegates to the
existing Makefile targets, then exposes the result via an IMPORTED
STATIC library target with correct INTERFACE_INCLUDE_DIRECTORIES.
Signed-off-by: Arjav Patel <arjav1528@gmail.com>
NuttX defines DIR as a struct type in dirent.h. The rcutils filesystem
source has a bare typedef int DIR that triggers a redefinition error when
NuttX system headers are on the include path. Guard it with #ifndef DIR
so the typedef is skipped when the type is already defined.
Applied automatically during the micro_ros_src/src fetch step with
patch -p1 --forward --ignore-whitespace ... || true
so the build is idempotent if the upstream ever merges a fix.
Signed-off-by: Arjav Patel <arjav1528@gmail.com>
When CONFIG_SYSTEM_MICROROS=y, add the prebuilt libmicroros.a to LDLIBS
and the colcon-installed include/ tree to CFLAGS/CXXFLAGS so that any
application in nuttx-apps can include micro-ROS headers and link against
the library without extra flags.
Signed-off-by: Arjav Patel <arjav1528@gmail.com>
Add toolchain.cmake.in and include_override/assert.h for the colcon
cross-build. Key differences from the old robertobucher port:
- Drop -DCLOCK_MONOTONIC=0: NuttX defines CLOCK_MONOTONIC=1 and
the override broke nanosleep() on newer kernels.
- CMAKE_SYSTEM_PROCESSOR is a placeholder substituted per-arch.
- include_override/assert.h works around the rosidl NDEBUG issue
(https://github.com/ros2/rosidl/pull/739).
Signed-off-by: Arjav Patel <arjav1528@gmail.com>
Add a colcon.meta.in template that is substituted at build time with
Kconfig values. Key settings:
- Custom transport only (UCLIENT_PROFILE_CUSTOM_TRANSPORT=ON,
UCLIENT_PROFILE_STREAM_FRAMING=ON) -- actual UDP/serial callbacks
are wired in Phase 4.
- RCL_MICROROS=ON (Jazzy/Kilted renamed flag replacing the old
RCL_COMMAND_LINE_ENABLED/RCL_LOGGING_ENABLED pair).
- RCUTILS_NO_FILESYSTEM=OFF -- NuttX provides POSIX filesystem.
- Resource limits use @MAX_NODES@/@MAX_PUBLISHERS@ etc. placeholders
substituted from CONFIG_MICROROS_MAX_* Kconfig values.
Signed-off-by: Arjav Patel <arjav1528@gmail.com>
Add micro_ros_lib/ subdirectory with a .keep sentinel so the directory
is tracked by git before any generated build artifacts appear. All
colcon/fetch outputs land here and are gitignored by the parent .gitignore.
Signed-off-by: Arjav Patel <arjav1528@gmail.com>
The settings save path no longer re-enters g_settings.mtx, so the mutex does not need to be initialized as PTHREAD_MUTEX_RECURSIVE.
This keeps the #3105 fix independent of CONFIG_PTHREAD_MUTEX_TYPES and destroys the temporary mutex attribute object after initialization.
Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com>