[posix] forkpty-arg value as a single argument (#5772)

This commit is contained in:
Yakun Xu
2020-11-08 23:31:11 -08:00
committed by GitHub
parent 59b4a51f99
commit 6fda0786ed
4 changed files with 33 additions and 26 deletions
+20 -22
View File
@@ -60,10 +60,6 @@
#include "common/code_utils.hpp"
#include "common/logging.hpp"
#ifndef SOCKET_UTILS_DEFAULT_SHELL
#define SOCKET_UTILS_DEFAULT_SHELL "/bin/sh"
#endif
#ifdef __APPLE__
#ifndef B230400
@@ -156,7 +152,7 @@ otError HdlcInterface::Init(const RadioUrl &aRadioUrl)
#if OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
else if (S_ISREG(st.st_mode))
{
mSockFd = ForkPty(aRadioUrl.GetPath(), aRadioUrl.GetValue("forkpty-arg"));
mSockFd = ForkPty(aRadioUrl);
VerifyOrExit(mSockFd != -1, error = OT_ERROR_INVALID_ARGS);
}
#endif // OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
@@ -586,7 +582,7 @@ exit:
}
#if OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
int HdlcInterface::ForkPty(const char *aCommand, const char *aRadioUrl)
int HdlcInterface::ForkPty(const RadioUrl &aRadioUrl)
{
int fd = -1;
int pid = -1;
@@ -599,38 +595,40 @@ int HdlcInterface::ForkPty(const char *aCommand, const char *aRadioUrl)
cfmakeraw(&tios);
tios.c_cflag = CS8 | HUPCL | CREAD | CLOCAL;
VerifyOrExit((pid = forkpty(&fd, nullptr, &tios, nullptr)) != -1, perror("forkpty()"));
VerifyOrDie((pid = forkpty(&fd, nullptr, &tios, nullptr)) != -1, OT_EXIT_ERROR_ERRNO);
}
if (0 == pid)
{
const int kMaxCommand = 255;
char cmd[kMaxCommand];
constexpr int kMaxArguments = 32;
char * argv[kMaxArguments + 1];
size_t index = 0;
if (aRadioUrl == nullptr)
argv[index++] = const_cast<char *>(aRadioUrl.GetPath());
for (const char *arg = nullptr;
index < OT_ARRAY_LENGTH(argv) && (arg = aRadioUrl.GetValue("forkpty-arg", arg)) != nullptr;
argv[index++] = const_cast<char *>(arg))
{
rval = snprintf(cmd, sizeof(cmd), "exec %s", aCommand);
}
if (index < OT_ARRAY_LENGTH(argv))
{
argv[index] = nullptr;
}
else
{
rval = snprintf(cmd, sizeof(cmd), "exec %s %s", aCommand, aRadioUrl);
DieNowWithMessage("Too many arguments!", OT_EXIT_INVALID_ARGUMENTS);
}
VerifyOrExit(rval > 0 && static_cast<size_t>(rval) < sizeof(cmd),
fprintf(stderr, "NCP file and configuration is too long!");
rval = -1);
VerifyOrExit((rval = execl(SOCKET_UTILS_DEFAULT_SHELL, SOCKET_UTILS_DEFAULT_SHELL, "-c", cmd,
static_cast<char *>(nullptr))) != -1,
perror("execl(OT_RCP)"));
VerifyOrDie((rval = execvp(argv[0], argv)) != -1, OT_EXIT_ERROR_ERRNO);
}
else
{
VerifyOrExit((rval = fcntl(fd, F_GETFL)) != -1, perror("fcntl(F_GETFL)"));
VerifyOrExit((rval = fcntl(fd, F_SETFL, rval | O_NONBLOCK | O_CLOEXEC)) != -1, perror("fcntl(F_SETFL)"));
VerifyOrDie((rval = fcntl(fd, F_GETFL)) != -1, OT_EXIT_ERROR_ERRNO);
VerifyOrDie((rval = fcntl(fd, F_SETFL, rval | O_NONBLOCK | O_CLOEXEC)) != -1, OT_EXIT_ERROR_ERRNO);
}
exit:
VerifyOrDie(rval == 0, OT_EXIT_ERROR_ERRNO);
return fd;
}
#endif // OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
+1 -1
View File
@@ -208,7 +208,7 @@ private:
int OpenFile(const RadioUrl &aRadioUrl);
#if OPENTHREAD_POSIX_CONFIG_RCP_PTY_ENABLE
static int ForkPty(const char *aCommand, const char *aRadioUrl);
static int ForkPty(const RadioUrl &aRadioUrl);
#endif
enum
+10 -1
View File
@@ -52,7 +52,16 @@ otInstance *otSysInit(otPlatformConfig *aPlatformConfig)
ot::Posix::RadioUrl radioUrl(aPlatformConfig->mRadioUrl);
#if OPENTHREAD_POSIX_VIRTUAL_TIME
virtualTimeInit(static_cast<uint16_t>(atoi(radioUrl.GetValue("forkpty-arg"))));
// The last argument must be the node id
{
const char *nodeId = nullptr;
for (const char *arg = nullptr; (arg = radioUrl.GetValue("forkpty-arg", arg)) != nullptr; nodeId = arg)
{
}
virtualTimeInit(static_cast<uint16_t>(atoi(nodeId)));
}
#endif
VerifyOrDie(radioUrl.GetPath() != nullptr, OT_EXIT_INVALID_ARGUMENTS);
@@ -29,7 +29,7 @@
source "tests/scripts/expect/_common.exp"
spawn $env(OT_POSIX_APPS)/ot-cli "spinel+hdlc+uart://$env(OT_SIMULATION_APPS)/ncp/ot-rcp?forkpty-arg=--sleep-to-tx 1"
spawn $env(OT_POSIX_APPS)/ot-cli "spinel+hdlc+uart://$env(OT_SIMULATION_APPS)/ncp/ot-rcp?forkpty-arg=--sleep-to-tx&forkpty-arg=1"
set node_1 $spawn_id
expect_after {
timeout { exit 1 }
@@ -75,7 +75,7 @@ expect -re {(\d+)}
set channel $expect_out(1,string)
expect "Done"
spawn $env(OT_POSIX_APPS)/ot-cli "spinel+hdlc+uart://$env(OT_SIMULATION_APPS)/ncp/ot-rcp?forkpty-arg=--sleep-to-tx 2"
spawn $env(OT_POSIX_APPS)/ot-cli "spinel+hdlc+uart://$env(OT_SIMULATION_APPS)/ncp/ot-rcp?forkpty-arg=--sleep-to-tx&forkpty-arg=2"
set node_2 $spawn_id
expect_after {
timeout { exit 1 }