// Lo scopo di questo esercizioè di scrivere msleep. msleep si comporta come // sleep(1) ma invece di attendere il numero di secondi indicati come parametro // deve aspettare il numero di millisecondi indicati come parametro.d es: msleep // 2340 completa la sua esecuzione in 2340 millisecondi alias 2.34 secondi. La // msleep deve essere implementata usando i timerfd (v. timerfd_create(2)). #include <errno.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <sys/timerfd.h> #include <unistd.h> int main(int argc, char *argv[]) { int fd; uint64_t time; size_t r; uint16_t exp; struct itimerspec new_value; struct timespec now; if (argc != 2) { printf("Usage: %s <time>\n", argv[0]); exit(EXIT_FAILURE); } char *endptr, *str = argv[1]; time = (uint64_t)strtol(str, &endptr, 10); if (errno != 0 || endptr == str) { perror("strol"); exit(EXIT_FAILURE); } if (clock_gettime(CLOCK_REALTIME, &now) == -1) { perror("timerfd_create"); exit(EXIT_FAILURE); } if ((fd = timerfd_create(CLOCK_REALTIME, 0)) == -1) { perror("timerfd_create"); exit(EXIT_FAILURE); } new_value.it_value.tv_nsec = (now.tv_nsec + (time * 1000000)) % 1000000000; new_value.it_value.tv_sec = (now.tv_sec + (time / 1000)) + ((now.tv_nsec + (time * 1000000)) / 1000000000); // expire only once new_value.it_interval.tv_nsec = 0; new_value.it_interval.tv_sec = 0; errno = 0; if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1) { perror("timerfd_settime"); exit(EXIT_FAILURE); } errno = 0; if ((r = read(fd, &exp, sizeof(uint64_t))) != sizeof(uint64_t)) { perror("read"); exit(EXIT_FAILURE); } return 0; }