1#!/bin/sh 2 3# 4# Copyright (c) 2008 Peter Holm <pho@FreeBSD.org> 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27# 28 29# Test scenario by marcus@freebsd.org 30 31[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 32 33. ../default.cfg 34 35odir=`pwd` 36cd /tmp 37sed '1,/^EOF/d' < $odir/$0 > kinfo2.c 38mycc -o kinfo2 -Wall -Wextra kinfo2.c -lutil || exit 1 39rm -f kinfo2.c 40 41mount | grep -q procfs || mount -t procfs procfs /proc 42s=0 43for i in `jot 15`; do 44 pids="" 45 for j in `jot 5`; do 46 /tmp/kinfo2 & 47 pids="$pids $!" 48 done 49 for p in $pids; do 50 wait $p 51 [ $? -ne 0 ] && s=1 52 done 53done 54 55rm -f /tmp/kinfo2 56exit $s 57EOF 58 59#include <sys/types.h> 60#include <sys/signal.h> 61#include <sys/stat.h> 62#include <sys/wait.h> 63 64#include <dirent.h> 65#include <err.h> 66#include <fcntl.h> 67#include <libutil.h> 68#include <stdio.h> 69#include <stdlib.h> 70#include <strings.h> 71#include <unistd.h> 72 73static char buf[8096]; 74 75static void 76handler(int i __unused) { 77 _exit(0); 78} 79 80/* Stir /dev/proc */ 81static void 82churning(void) { 83 pid_t r; 84 int fd, status; 85 86 for (;;) { 87 r = fork(); 88 if (r == 0) { 89 if ((fd = open("/proc/curproc/mem", O_RDONLY)) == -1) 90 err(1, "open(/proc/curproc/mem)"); 91 bzero(buf, sizeof(buf)); 92 _exit(0); 93 } 94 if (r < 0) { 95 perror("fork"); 96 exit(2); 97 } 98 wait(&status); 99 } 100} 101 102/* Get files for each proc */ 103void 104list(void) 105{ 106 struct dirent *dp; 107 struct kinfo_file *freep; 108 struct kinfo_vmentry *freep_vm; 109 struct stat sb; 110 pid_t pid; 111 off_t base; 112 long l; 113 int cnt, fd, n; 114 int space = sizeof(buf); 115 char *bp = buf; 116 char *dummy; 117 118 if ((fd = open("/proc", O_RDONLY)) == -1) 119 err(1, "open(%s)", "/proc"); 120 121 if (fstat(fd, &sb) == -1) 122 err(1, "fstat()"); 123 do { 124 if ((n = getdirentries(fd, bp, space, &base)) == -1) 125 err(1, "getdirentries"); 126 space = space - n; 127 if (space < sb.st_blksize) 128 break; 129 bp = bp + n; 130 } while (n != 0); 131 close(fd); 132 133 bp = buf; 134 dp = (struct dirent *)bp; 135 for (;;) { 136#if defined(DEBUG) 137 printf("name: %-10s, inode %7ju, type %2d, namelen %d, " 138 "d_reclen %d\n", 139 dp->d_name, (uintmax_t)dp->d_fileno, dp->d_type, 140 dp->d_namlen, dp->d_reclen); fflush(stdout); 141#endif 142 143 if (dp->d_type == DT_DIR && 144 (dp->d_name[0] >= '0' && dp->d_name[0] <= '9')) { 145 l = strtol(dp->d_name, &dummy, 10); 146 pid = l; 147 148 /* The tests start here */ 149 freep = kinfo_getfile(pid, &cnt); 150 free(freep); 151 152 freep_vm = kinfo_getvmmap(pid, &cnt); 153 free(freep_vm); 154 /* End test */ 155 } 156 157 bp = bp + dp->d_reclen; 158 dp = (struct dirent *)bp; 159 if (dp->d_reclen <= 0) 160 break; 161 } 162} 163 164int 165main(void) 166{ 167 pid_t r; 168 169 signal(SIGALRM, handler); 170 alarm(60); 171 172 if ((r = fork()) == 0) { 173 alarm(60); 174 for (;;) 175 churning(); 176 } 177 if (r < 0) { 178 perror("fork"); 179 exit(2); 180 } 181 182 for (;;) 183 list(); 184 185 return (0); 186} 187