logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git/

sleep.c (1640B)


  1. // utils-std: Collection of commonly available Unix tools
  2. // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: MPL-2.0
  4. #define _POSIX_C_SOURCE 200809L
  5. #include "../libutils/strtodur.h"
  6. #include <errno.h> // errno
  7. #include <inttypes.h> // PRId64
  8. #include <stdio.h> // fprintf, perror
  9. #include <string.h> // strerror
  10. #include <time.h> // nanosleep
  11. #include <unistd.h> // execvp
  12. const char *argv0 = "sleep";
  13. int
  14. main(int argc, char *argv[])
  15. {
  16. struct timespec dur = {.tv_sec = 0, .tv_nsec = 0};
  17. argc--, argv++;
  18. if(argc < 1)
  19. {
  20. fprintf(stderr, "sleep: error: No duration argument passed\n");
  21. return 1;
  22. }
  23. struct timespec arg_dur = {.tv_sec = 0, .tv_nsec = 0};
  24. if(strtodur(argv[0], &arg_dur) < 0) return 1;
  25. dur.tv_sec += arg_dur.tv_sec;
  26. dur.tv_nsec += arg_dur.tv_nsec;
  27. if(dur.tv_nsec > 999999999)
  28. {
  29. dur.tv_nsec = 0;
  30. dur.tv_sec += 1;
  31. }
  32. if(dur.tv_sec == 0 && dur.tv_nsec == 0)
  33. {
  34. fprintf(stderr, "sleep: error: Got a total duration of 0\n");
  35. return 1;
  36. }
  37. argc--, argv++;
  38. errno = 0;
  39. if(nanosleep(&dur, &dur) != 0)
  40. {
  41. if(errno == EINTR)
  42. {
  43. fprintf(stderr,
  44. "sleep: warning: Interrupted during sleep, still had %" PRId64 ".%09" PRId64
  45. " seconds remaining\n",
  46. (int64_t)dur.tv_sec,
  47. (int64_t)dur.tv_nsec);
  48. }
  49. else
  50. {
  51. perror("sleep: error: nanosleep");
  52. return 1;
  53. }
  54. }
  55. if(argc > 0)
  56. {
  57. errno = 0;
  58. execvp(argv[0], argv);
  59. fprintf(stderr, "sleep: error: Failed executing command '%s': %s\n", argv[0], strerror(errno));
  60. return (errno == ENOENT) ? 127 : 126;
  61. }
  62. return 0;
  63. }