sleep.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * sleep implementation for busybox
  4. *
  5. * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  8. */
  9. /* BB_AUDIT SUSv3 compliant */
  10. /* BB_AUDIT GNU issues -- fancy version matches except args must be ints. */
  11. /* http://www.opengroup.org/onlinepubs/007904975/utilities/sleep.html */
  12. /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
  13. *
  14. * Rewritten to do proper arg and error checking.
  15. * Also, added a 'fancy' configuration to accept multiple args with
  16. * time suffixes for seconds, minutes, hours, and days.
  17. */
  18. //usage:#define sleep_trivial_usage
  19. //usage: IF_FEATURE_FANCY_SLEEP("[") "N" IF_FEATURE_FANCY_SLEEP("]...")
  20. //usage:#define sleep_full_usage "\n\n"
  21. //usage: IF_NOT_FEATURE_FANCY_SLEEP("Pause for N seconds")
  22. //usage: IF_FEATURE_FANCY_SLEEP(
  23. //usage: "Pause for a time equal to the total of the args given, where each arg can\n"
  24. //usage: "have an optional suffix of (s)econds, (m)inutes, (h)ours, or (d)ays")
  25. //usage:
  26. //usage:#define sleep_example_usage
  27. //usage: "$ sleep 2\n"
  28. //usage: "[2 second delay results]\n"
  29. //usage: IF_FEATURE_FANCY_SLEEP(
  30. //usage: "$ sleep 1d 3h 22m 8s\n"
  31. //usage: "[98528 second delay results]\n")
  32. #include "libbb.h"
  33. /* Do not make this applet NOFORK. It breaks ^C-ing of pauses in shells */
  34. #if ENABLE_FEATURE_FANCY_SLEEP || ENABLE_FEATURE_FLOAT_SLEEP
  35. static const struct suffix_mult sfx[] = {
  36. { "s", 1 },
  37. { "m", 60 },
  38. { "h", 60*60 },
  39. { "d", 24*60*60 },
  40. { "", 0 }
  41. };
  42. #endif
  43. int sleep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  44. int sleep_main(int argc UNUSED_PARAM, char **argv)
  45. {
  46. #if ENABLE_FEATURE_FLOAT_SLEEP
  47. double duration;
  48. struct timespec ts;
  49. #else
  50. unsigned duration;
  51. #endif
  52. ++argv;
  53. if (!*argv)
  54. bb_show_usage();
  55. #if ENABLE_FEATURE_FLOAT_SLEEP
  56. # if ENABLE_LOCALE_SUPPORT
  57. /* undo busybox.c setlocale */
  58. setlocale(LC_NUMERIC, "C");
  59. # endif
  60. duration = 0;
  61. do {
  62. char *arg = *argv;
  63. if (strchr(arg, '.')) {
  64. double d;
  65. char *pp;
  66. int len = strspn(arg, "0123456789.");
  67. char sv = arg[len];
  68. arg[len] = '\0';
  69. errno = 0;
  70. d = strtod(arg, &pp);
  71. if (errno || *pp)
  72. bb_show_usage();
  73. arg += len;
  74. *arg-- = sv;
  75. sv = *arg;
  76. *arg = '1';
  77. duration += d * xatoul_sfx(arg, sfx);
  78. *arg = sv;
  79. } else {
  80. duration += xatoul_sfx(arg, sfx);
  81. }
  82. } while (*++argv);
  83. ts.tv_sec = MAXINT(typeof(ts.tv_sec));
  84. ts.tv_nsec = 0;
  85. if (duration >= 0 && duration < ts.tv_sec) {
  86. ts.tv_sec = duration;
  87. ts.tv_nsec = (duration - ts.tv_sec) * 1000000000;
  88. }
  89. do {
  90. errno = 0;
  91. nanosleep(&ts, &ts);
  92. } while (errno == EINTR);
  93. #elif ENABLE_FEATURE_FANCY_SLEEP
  94. duration = 0;
  95. do {
  96. duration += xatou_range_sfx(*argv, 0, UINT_MAX - duration, sfx);
  97. } while (*++argv);
  98. sleep(duration);
  99. #else /* simple */
  100. duration = xatou(*argv);
  101. sleep(duration);
  102. // Off. If it's really needed, provide example why
  103. //if (sleep(duration)) {
  104. // bb_perror_nomsg_and_die();
  105. //}
  106. #endif
  107. return EXIT_SUCCESS;
  108. }