1 /* 2 * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 /* Test that /proc/loadavg correctly reports last pid in pid namespace. */ 17 #define _GNU_SOURCE 18 #include <errno.h> 19 #include <sched.h> 20 #include <sys/types.h> 21 #include <sys/stat.h> 22 #include <fcntl.h> 23 #include <unistd.h> 24 #include <sys/wait.h> 25 26 int main(void) 27 { 28 pid_t pid; 29 int wstatus; 30 31 if (unshare(CLONE_NEWPID) == -1) { 32 if (errno == ENOSYS || errno == EPERM) 33 return 2; 34 return 1; 35 } 36 37 pid = fork(); 38 if (pid == -1) 39 return 1; 40 if (pid == 0) { 41 char buf[128], *p; 42 int fd; 43 ssize_t rv; 44 45 fd = open("/proc/loadavg" , O_RDONLY); 46 if (fd == -1) 47 return 1; 48 rv = read(fd, buf, sizeof(buf)); 49 if (rv < 3) 50 return 1; 51 p = buf + rv; 52 53 /* pid 1 */ 54 if (!(p[-3] == ' ' && p[-2] == '1' && p[-1] == '\n')) 55 return 1; 56 57 pid = fork(); 58 if (pid == -1) 59 return 1; 60 if (pid == 0) 61 return 0; 62 if (waitpid(pid, NULL, 0) == -1) 63 return 1; 64 65 lseek(fd, 0, SEEK_SET); 66 rv = read(fd, buf, sizeof(buf)); 67 if (rv < 3) 68 return 1; 69 p = buf + rv; 70 71 /* pid 2 */ 72 if (!(p[-3] == ' ' && p[-2] == '2' && p[-1] == '\n')) 73 return 1; 74 75 return 0; 76 } 77 78 if (waitpid(pid, &wstatus, 0) == -1) 79 return 1; 80 if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0) 81 return 0; 82 return 1; 83 } 84