|
35 | 35 | #include <limits.h> |
36 | 36 | #include <fixedmath.h> |
37 | 37 |
|
| 38 | +#if defined(CONFIG_SYSTEM_PING6) && defined(CONFIG_LIBC_EXECFUNCS) |
| 39 | +#include <spawn.h> |
| 40 | +#include <sys/wait.h> |
| 41 | +#endif |
| 42 | + |
38 | 43 | #include <nuttx/net/ip.h> |
39 | 44 |
|
40 | 45 | #include "netutils/icmp_ping.h" |
@@ -121,8 +126,10 @@ static void ping_result(FAR const struct ping_result_s *result) |
121 | 126 | switch (result->code) |
122 | 127 | { |
123 | 128 | case ICMP_E_HOSTIP: |
| 129 | +#ifndef CONFIG_SYSTEM_PING6 |
124 | 130 | fprintf(stderr, "ERROR: ping_gethostip(%s) failed\n", |
125 | 131 | result->info->hostname); |
| 132 | +#endif |
126 | 133 | break; |
127 | 134 |
|
128 | 135 | case ICMP_E_MEMORY: |
@@ -279,6 +286,60 @@ static void ping_result(FAR const struct ping_result_s *result) |
279 | 286 | } |
280 | 287 | } |
281 | 288 |
|
| 289 | +#if defined(CONFIG_SYSTEM_PING6) && defined(CONFIG_LIBC_EXECFUNCS) |
| 290 | +/**************************************************************************** |
| 291 | + * Name: ping6_fallback |
| 292 | + ****************************************************************************/ |
| 293 | + |
| 294 | +static int ping6_fallback(int argc, FAR char *argv[]) |
| 295 | +{ |
| 296 | + FAR char **child_argv; |
| 297 | + pid_t pid; |
| 298 | + int ret; |
| 299 | + int status; |
| 300 | + int i; |
| 301 | + |
| 302 | + child_argv = malloc(sizeof(FAR char *) * (argc + 1)); |
| 303 | + if (child_argv == NULL) |
| 304 | + { |
| 305 | + fprintf(stderr, "ERROR: Failed to allocate fallback argv\n"); |
| 306 | + return EXIT_FAILURE; |
| 307 | + } |
| 308 | + |
| 309 | + child_argv[0] = CONFIG_SYSTEM_PING6_PROGNAME; |
| 310 | + for (i = 1; i < argc; i++) |
| 311 | + { |
| 312 | + child_argv[i] = argv[i]; |
| 313 | + } |
| 314 | + |
| 315 | + child_argv[argc] = NULL; |
| 316 | + |
| 317 | + ret = posix_spawnp(&pid, CONFIG_SYSTEM_PING6_PROGNAME, NULL, NULL, |
| 318 | + child_argv, NULL); |
| 319 | + free(child_argv); |
| 320 | + if (ret != 0) |
| 321 | + { |
| 322 | + fprintf(stderr, "ERROR: posix_spawnp(%s) failed: %d\n", |
| 323 | + CONFIG_SYSTEM_PING6_PROGNAME, ret); |
| 324 | + return EXIT_FAILURE; |
| 325 | + } |
| 326 | + |
| 327 | + ret = waitpid(pid, &status, 0); |
| 328 | + if (ret < 0) |
| 329 | + { |
| 330 | + fprintf(stderr, "ERROR: waitpid() failed: %d\n", errno); |
| 331 | + return EXIT_FAILURE; |
| 332 | + } |
| 333 | + |
| 334 | + if (WIFEXITED(status)) |
| 335 | + { |
| 336 | + return WEXITSTATUS(status); |
| 337 | + } |
| 338 | + |
| 339 | + return EXIT_FAILURE; |
| 340 | +} |
| 341 | +#endif |
| 342 | + |
282 | 343 | /**************************************************************************** |
283 | 344 | * Public Functions |
284 | 345 | ****************************************************************************/ |
@@ -403,7 +464,15 @@ int main(int argc, FAR char *argv[]) |
403 | 464 |
|
404 | 465 | info.hostname = argv[optind]; |
405 | 466 | icmp_ping(&info); |
406 | | - return priv.code < 0 ? EXIT_FAILURE: EXIT_SUCCESS; |
| 467 | + |
| 468 | +#if defined(CONFIG_SYSTEM_PING6) && defined(CONFIG_LIBC_EXECFUNCS) |
| 469 | + if (priv.code == ICMP_E_HOSTIP) |
| 470 | + { |
| 471 | + return ping6_fallback(argc, argv); |
| 472 | + } |
| 473 | +#endif |
| 474 | + |
| 475 | + return priv.code < 0 ? EXIT_FAILURE : EXIT_SUCCESS; |
407 | 476 |
|
408 | 477 | errout_with_usage: |
409 | 478 | optind = 0; |
|
0 commit comments