1 /* Test 75 - getrusage and wait4 test.
4 #include <sys/resource.h>
15 #define CHECK_ZERO_FIELD(rusage, field) \
16 if (rusage.field != 0) \
17 em(1, #field " must be zero");
19 #define CHECK_NOT_ZERO_FIELD(rusage, field) \
20 if (rusage.field == 0) \
21 em(1, #field " can't be zero");
23 #define CHECK_EQUAL_FIELD(rusage1, rusage2, field) \
24 if (rusage1.field != rusage2.field) \
25 em(1, #field " of " #rusage1 " doesn't equal to " \
26 #field " of " #rusage2);
31 struct timeval start_time
;
32 struct timeval end_time
;
33 unsigned int loop
= 0;
34 if (gettimeofday(&start_time
, NULL
) == -1) e(1);
35 end_time
= start_time
;
37 if ((++loop
% 3000000000) == 0) {
38 if (gettimeofday(&end_time
, NULL
) == -1) e(1);
40 } while (start_time
.tv_sec
+ 10 > end_time
.tv_sec
);
49 struct rusage r_usage1
;
50 struct rusage r_usage2
;
51 struct rusage r_usage3
;
55 if ((getrusage(RUSAGE_SELF
+ 1, &r_usage1
) != -1 || errno
!= EINVAL
) ||
56 (getrusage(RUSAGE_CHILDREN
- 1, &r_usage1
) != -1 ||
57 errno
!= EINVAL
) || (getrusage(RUSAGE_SELF
, NULL
) != -1 ||
62 if (getrusage(RUSAGE_SELF
, &r_usage1
) != 0) e(1);
63 CHECK_NOT_ZERO_FIELD(r_usage1
, ru_utime
.tv_sec
);
64 CHECK_NOT_ZERO_FIELD(r_usage1
, ru_maxrss
);
65 if (getrusage(RUSAGE_CHILDREN
, &r_usage2
) != 0) e(1);
67 if ((child
= fork()) == 0) {
69 * We cannot do this part of the test in the parent, since
70 * start() calls system() which spawns a child process.
72 if (getrusage(RUSAGE_CHILDREN
, &r_usage1
) != 0) e(1);
73 CHECK_ZERO_FIELD(r_usage1
, ru_utime
.tv_sec
);
74 CHECK_ZERO_FIELD(r_usage1
, ru_utime
.tv_usec
);
78 if (child
!= waitpid(child
, &status
, 0)) e(1);
79 if (WEXITSTATUS(status
) != 0) e(1);
80 if (getrusage(RUSAGE_CHILDREN
, &r_usage3
) != 0) e(1);
81 CHECK_NOT_ZERO_FIELD(r_usage3
, ru_utime
.tv_sec
);
86 * Test the wait4 system call with good and bad rusage pointers, and with the
87 * wait4 either being satisfied immediately or blocking until the child exits:
88 * - mode 0: child has exited when parent calls wait4;
89 * - mode 1: parent blocks waiting for child, using a bad rusage pointer;
90 * - mode 2: parent blocks waiting for child, using a good rusage pointer.
93 sub75b(int mode
, void * bad_ptr
)
95 struct rusage r_usage
;
115 * Try with a bad pointer. This call may fail only
116 * once the child has exited, but it must not clean up
119 if (wait4(-1, &status
, 0, bad_ptr
) != -1) e(0);
120 if (errno
!= EFAULT
) e(0);
123 r_usage
.ru_nsignals
= 1234; /* see if it's written at all */
125 /* Wait for the actual process. */
126 if (wait4(-1, &status
, 0, &r_usage
) != pid
) e(0);
127 if (!WIFEXITED(status
)) e(0);
128 if (WEXITSTATUS(status
) != 0) e(0);
130 if (r_usage
.ru_nsignals
!= 0) e(0);
132 /* Only check for actual time spent if the child spun. */
134 CHECK_NOT_ZERO_FIELD(r_usage
, ru_utime
.tv_sec
);
146 if ((ptr
= mmap(NULL
, sizeof(struct rusage
), PROT_READ
,
147 MAP_PRIVATE
| MAP_ANON
, -1, 0)) == MAP_FAILED
) e(0);
148 if (munmap(ptr
, sizeof(struct rusage
)) != 0) e(0);
149 /* "ptr" is now a known-bad pointer */
157 main(int argc
, char *argv
[])