sleep.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. #include "libbb.h"
  19. /* Do not make this applet NOFORK. It breaks ^C-ing of pauses in shells */
  20. #if ENABLE_FEATURE_FANCY_SLEEP || ENABLE_FEATURE_FLOAT_SLEEP
  21. static const struct suffix_mult sfx[] = {
  22. { "s", 1 },
  23. { "m", 60 },
  24. { "h", 60*60 },
  25. { "d", 24*60*60 },
  26. { "", 0 }
  27. };
  28. #endif
  29. int sleep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  30. int sleep_main(int argc UNUSED_PARAM, char **argv)
  31. {
  32. #if ENABLE_FEATURE_FLOAT_SLEEP
  33. double duration;
  34. struct timespec ts;
  35. #else
  36. unsigned duration;
  37. #endif
  38. ++argv;
  39. if (!*argv)
  40. bb_show_usage();
  41. #if ENABLE_FEATURE_FLOAT_SLEEP
  42. # if ENABLE_LOCALE_SUPPORT
  43. /* undo busybox.c setlocale */
  44. setlocale(LC_NUMERIC, "C");
  45. # endif
  46. duration = 0;
  47. do {
  48. char *arg = *argv;
  49. if (strchr(arg, '.')) {
  50. double d;
  51. char *pp;
  52. int len = strspn(arg, "0123456789.");
  53. char sv = arg[len];
  54. arg[len] = '\0';
  55. errno = 0;
  56. d = strtod(arg, &pp);
  57. if (errno || *pp)
  58. bb_show_usage();
  59. arg += len;
  60. *arg-- = sv;
  61. sv = *arg;
  62. *arg = '1';
  63. duration += d * xatoul_sfx(arg, sfx);
  64. *arg = sv;
  65. } else {
  66. duration += xatoul_sfx(arg, sfx);
  67. }
  68. } while (*++argv);
  69. ts.tv_sec = MAXINT(typeof(ts.tv_sec));
  70. ts.tv_nsec = 0;
  71. if (duration >= 0 && duration < ts.tv_sec) {
  72. ts.tv_sec = duration;
  73. ts.tv_nsec = (duration - ts.tv_sec) * 1000000000;
  74. }
  75. do {
  76. errno = 0;
  77. nanosleep(&ts, &ts);
  78. } while (errno == EINTR);
  79. #elif ENABLE_FEATURE_FANCY_SLEEP
  80. duration = 0;
  81. do {
  82. duration += xatou_range_sfx(*argv, 0, UINT_MAX - duration, sfx);
  83. } while (*++argv);
  84. sleep(duration);
  85. #else /* simple */
  86. duration = xatou(*argv);
  87. sleep(duration);
  88. // Off. If it's really needed, provide example why
  89. //if (sleep(duration)) {
  90. // bb_perror_nomsg_and_die();
  91. //}
  92. #endif
  93. return EXIT_SUCCESS;
  94. }