logo

utils-std

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

sleep.c (1553B)


  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 <stdio.h> // fprintf, perror
  8. #include <string.h> // strerror
  9. #include <time.h> // nanosleep
  10. #include <unistd.h> // execvp
  11. const char *argv0 = "sleep";
  12. int
  13. main(int argc, char *argv[])
  14. {
  15. struct timespec dur = {.tv_sec = 0, .tv_nsec = 0};
  16. argc--, argv++;
  17. if(argc < 1)
  18. {
  19. fprintf(stderr, "sleep: error: No duration argument passed\n");
  20. return 1;
  21. }
  22. struct timespec arg_dur = {.tv_sec = 0, .tv_nsec = 0};
  23. if(strtodur(argv[0], &arg_dur) < 0) return 1;
  24. dur.tv_sec += arg_dur.tv_sec;
  25. dur.tv_nsec += arg_dur.tv_nsec;
  26. if(dur.tv_nsec > 999999999)
  27. {
  28. dur.tv_nsec = 0;
  29. dur.tv_sec += 1;
  30. }
  31. if(dur.tv_sec == 0 && dur.tv_nsec == 0)
  32. {
  33. fprintf(stderr, "sleep: error: Got a total duration of 0\n");
  34. return 1;
  35. }
  36. argc--, argv++;
  37. errno = 0;
  38. if(nanosleep(&dur, &dur) != 0)
  39. {
  40. if(errno == EINTR)
  41. {
  42. fprintf(stderr,
  43. "sleep: warning: Interrupted during sleep, still had %ld.%09ld seconds remaining\n",
  44. dur.tv_sec,
  45. dur.tv_nsec);
  46. }
  47. else
  48. {
  49. perror("sleep: error: nanosleep");
  50. return 1;
  51. }
  52. }
  53. if(argc > 0)
  54. {
  55. errno = 0;
  56. execvp(argv[0], argv);
  57. fprintf(stderr, "sleep: error: Failed executing command '%s': %s\n", argv[0], strerror(errno));
  58. return (errno == ENOENT) ? 127 : 126;
  59. }
  60. return 0;
  61. }