xref: /freebsd/bin/sleep/sleep.c (revision f078c492a9b57877c723586db26d789cda1b98ea)
1  /*-
2   * Copyright (c) 1988, 1993, 1994
3   *	The Regents of the University of California.  All rights reserved.
4   *
5   * Redistribution and use in source and binary forms, with or without
6   * modification, are permitted provided that the following conditions
7   * are met:
8   * 1. Redistributions of source code must retain the above copyright
9   *    notice, this list of conditions and the following disclaimer.
10   * 2. Redistributions in binary form must reproduce the above copyright
11   *    notice, this list of conditions and the following disclaimer in the
12   *    documentation and/or other materials provided with the distribution.
13   * 3. Neither the name of the University nor the names of its contributors
14   *    may be used to endorse or promote products derived from this software
15   *    without specific prior written permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20   * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27   * SUCH DAMAGE.
28   */
29  
30  #if 0
31  #ifndef lint
32  static char const copyright[] =
33  "@(#) Copyright (c) 1988, 1993, 1994\n\
34  	The Regents of the University of California.  All rights reserved.\n";
35  #endif /* not lint */
36  
37  #ifndef lint
38  static char sccsid[] = "@(#)sleep.c	8.3 (Berkeley) 4/2/94";
39  #endif /* not lint */
40  #endif
41  #include <sys/cdefs.h>
42  __FBSDID("$FreeBSD$");
43  
44  #include <capsicum_helpers.h>
45  #include <ctype.h>
46  #include <err.h>
47  #include <errno.h>
48  #include <limits.h>
49  #include <signal.h>
50  #include <stdint.h>
51  #include <stdio.h>
52  #include <stdlib.h>
53  #include <time.h>
54  
55  static void usage(void);
56  
57  static volatile sig_atomic_t report_requested;
58  static void
59  report_request(int signo __unused)
60  {
61  
62  	report_requested = 1;
63  }
64  
65  int
66  main(int argc, char *argv[])
67  {
68  	struct timespec time_to_sleep;
69  	double d;
70  	time_t original;
71  	char buf[2];
72  
73  	if (caph_limit_stdio() < 0 || caph_enter() < 0)
74  		err(1, "capsicum");
75  
76  	if (argc != 2)
77  		usage();
78  
79  	if (sscanf(argv[1], "%lf%1s", &d, buf) != 1)
80  		usage();
81  	if (d > INT_MAX)
82  		usage();
83  	if (d <= 0)
84  		return (0);
85  	original = time_to_sleep.tv_sec = (time_t)d;
86  	time_to_sleep.tv_nsec = 1e9 * (d - time_to_sleep.tv_sec);
87  
88  	signal(SIGINFO, report_request);
89  
90  	/*
91  	 * Note: [EINTR] is supposed to happen only when a signal was handled
92  	 * but the kernel also returns it when a ptrace-based debugger
93  	 * attaches. This is a bug but it is hard to fix.
94  	 */
95  	while (nanosleep(&time_to_sleep, &time_to_sleep) != 0) {
96  		if (report_requested) {
97  			/* Reporting does not bother with nanoseconds. */
98  			warnx("about %d second(s) left out of the original %d",
99  			    (int)time_to_sleep.tv_sec, (int)original);
100  			report_requested = 0;
101  		} else if (errno != EINTR)
102  			err(1, "nanosleep");
103  	}
104  	return (0);
105  }
106  
107  static void
108  usage(void)
109  {
110  
111  	fprintf(stderr, "usage: sleep seconds\n");
112  	exit(1);
113  }
114