sleep.c (1553B)
- // utils-std: Collection of commonly available Unix tools
- // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _POSIX_C_SOURCE 200809L
- #include "../libutils/strtodur.h"
- #include <errno.h> // errno
- #include <stdio.h> // fprintf, perror
- #include <string.h> // strerror
- #include <time.h> // nanosleep
- #include <unistd.h> // execvp
- const char *argv0 = "sleep";
- int
- main(int argc, char *argv[])
- {
- struct timespec dur = {.tv_sec = 0, .tv_nsec = 0};
- argc--, argv++;
- if(argc < 1)
- {
- fprintf(stderr, "sleep: error: No duration argument passed\n");
- return 1;
- }
- struct timespec arg_dur = {.tv_sec = 0, .tv_nsec = 0};
- if(strtodur(argv[0], &arg_dur) < 0) return 1;
- dur.tv_sec += arg_dur.tv_sec;
- dur.tv_nsec += arg_dur.tv_nsec;
- if(dur.tv_nsec > 999999999)
- {
- dur.tv_nsec = 0;
- dur.tv_sec += 1;
- }
- if(dur.tv_sec == 0 && dur.tv_nsec == 0)
- {
- fprintf(stderr, "sleep: error: Got a total duration of 0\n");
- return 1;
- }
- argc--, argv++;
- errno = 0;
- if(nanosleep(&dur, &dur) != 0)
- {
- if(errno == EINTR)
- {
- fprintf(stderr,
- "sleep: warning: Interrupted during sleep, still had %ld.%09ld seconds remaining\n",
- dur.tv_sec,
- dur.tv_nsec);
- }
- else
- {
- perror("sleep: error: nanosleep");
- return 1;
- }
- }
- if(argc > 0)
- {
- errno = 0;
- execvp(argv[0], argv);
- fprintf(stderr, "sleep: error: Failed executing command '%s': %s\n", argv[0], strerror(errno));
- return (errno == ENOENT) ? 127 : 126;
- }
- return 0;
- }