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