162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright © 2018 Alexey Dobriyan <adobriyan@gmail.com> 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Permission to use, copy, modify, and distribute this software for any 562306a36Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above 662306a36Sopenharmony_ci * copyright notice and this permission notice appear in all copies. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 962306a36Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1062306a36Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1162306a36Sopenharmony_ci * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1262306a36Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1362306a36Sopenharmony_ci * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1462306a36Sopenharmony_ci * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1562306a36Sopenharmony_ci */ 1662306a36Sopenharmony_ci/* Test that /proc/loadavg correctly reports last pid in pid namespace. */ 1762306a36Sopenharmony_ci#include <errno.h> 1862306a36Sopenharmony_ci#include <sched.h> 1962306a36Sopenharmony_ci#include <sys/types.h> 2062306a36Sopenharmony_ci#include <sys/stat.h> 2162306a36Sopenharmony_ci#include <fcntl.h> 2262306a36Sopenharmony_ci#include <unistd.h> 2362306a36Sopenharmony_ci#include <sys/wait.h> 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ciint main(void) 2662306a36Sopenharmony_ci{ 2762306a36Sopenharmony_ci pid_t pid; 2862306a36Sopenharmony_ci int wstatus; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci if (unshare(CLONE_NEWPID) == -1) { 3162306a36Sopenharmony_ci if (errno == ENOSYS || errno == EPERM) 3262306a36Sopenharmony_ci return 4; 3362306a36Sopenharmony_ci return 1; 3462306a36Sopenharmony_ci } 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci pid = fork(); 3762306a36Sopenharmony_ci if (pid == -1) 3862306a36Sopenharmony_ci return 1; 3962306a36Sopenharmony_ci if (pid == 0) { 4062306a36Sopenharmony_ci char buf[128], *p; 4162306a36Sopenharmony_ci int fd; 4262306a36Sopenharmony_ci ssize_t rv; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci fd = open("/proc/loadavg" , O_RDONLY); 4562306a36Sopenharmony_ci if (fd == -1) 4662306a36Sopenharmony_ci return 1; 4762306a36Sopenharmony_ci rv = read(fd, buf, sizeof(buf)); 4862306a36Sopenharmony_ci if (rv < 3) 4962306a36Sopenharmony_ci return 1; 5062306a36Sopenharmony_ci p = buf + rv; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci /* pid 1 */ 5362306a36Sopenharmony_ci if (!(p[-3] == ' ' && p[-2] == '1' && p[-1] == '\n')) 5462306a36Sopenharmony_ci return 1; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci pid = fork(); 5762306a36Sopenharmony_ci if (pid == -1) 5862306a36Sopenharmony_ci return 1; 5962306a36Sopenharmony_ci if (pid == 0) 6062306a36Sopenharmony_ci return 0; 6162306a36Sopenharmony_ci if (waitpid(pid, NULL, 0) == -1) 6262306a36Sopenharmony_ci return 1; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci lseek(fd, 0, SEEK_SET); 6562306a36Sopenharmony_ci rv = read(fd, buf, sizeof(buf)); 6662306a36Sopenharmony_ci if (rv < 3) 6762306a36Sopenharmony_ci return 1; 6862306a36Sopenharmony_ci p = buf + rv; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci /* pid 2 */ 7162306a36Sopenharmony_ci if (!(p[-3] == ' ' && p[-2] == '2' && p[-1] == '\n')) 7262306a36Sopenharmony_ci return 1; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci return 0; 7562306a36Sopenharmony_ci } 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci if (waitpid(pid, &wstatus, 0) == -1) 7862306a36Sopenharmony_ci return 1; 7962306a36Sopenharmony_ci if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0) 8062306a36Sopenharmony_ci return 0; 8162306a36Sopenharmony_ci return 1; 8262306a36Sopenharmony_ci} 83