1#!/bin/sh 2 3# 4# Copyright (c) 2012 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# Copy of callout_reset_on.sh. Waiting to see if this catches anything. 30 31. ../default.cfg 32 33rm -f /tmp/crwriter2 /tmp/crlogger2 || exit 1 34 35cat > /tmp/crwriter2.c <<EOF 36#include <stdio.h> 37#include <stdlib.h> 38#include <string.h> 39#include <time.h> 40#include <unistd.h> 41 42char *txt[] = { 43 "0 This is a line of text: abcdefghijklmnopqrstuvwxyz", 44 "1 Another line of text: ABCDEFGHIJKLMNOPQRSTUVWXYZ", 45 "2 A different line of text", 46 "3 A very, very different text", 47 "4 A much longer line with a lot of characters in the line", 48 "5 Now this is a quite long line of text, with both upper and lower case letters, and one digit!" 49}; 50 51#define RUNTIME (10 * 60) 52 53int 54main(void) 55{ 56 time_t start; 57 int j, n; 58 char help[256]; 59 60 start = time(NULL); 61 while (time(NULL) - start < RUNTIME) { 62 j = arc4random() % 6; 63 n = arc4random() % strlen(txt[j]); 64 strncpy(help, txt[j], n); 65 help[n] = 0; 66 printf("%s\n", txt[j]); 67 if ((arc4random() % 1000) == 1) 68 usleep(100000); 69 } 70 71 return (0); 72} 73EOF 74mycc -o /tmp/crwriter2 -Wall -Wextra -O2 -g /tmp/crwriter2.c 75rm -f /tmp/crwriter2.c 76 77cat > /tmp/crlogger2.c <<EOF 78#include <sys/param.h> 79#include <sys/mman.h> 80#include <sys/socket.h> 81#include <sys/wait.h> 82 83#include <machine/atomic.h> 84 85#include <err.h> 86#include <err.h> 87#include <errno.h> 88#include <fcntl.h> 89#include <netdb.h> 90#include <netinet/in.h> 91#include <signal.h> 92#include <stdio.h> 93#include <stdio.h> 94#include <stdlib.h> 95#include <string.h> 96#include <unistd.h> 97#include <unistd.h> 98 99volatile u_int *share; 100 101#define SYNC 0 102 103pid_t pid; 104int bufsize; 105int port; 106int alarm_exit; 107 108void 109killer(void) 110{ 111 setproctitle("killer"); 112 while (share[SYNC] == 0) 113 ; 114 alarm(120); 115 for (;;) { 116 if (pid == 0) 117 break; 118 if (kill(pid, SIGUSR1) == -1) 119 break; 120 usleep(arc4random() % 2000 + 10); 121 } 122 _exit(0); 123} 124 125void 126handler(int s __unused) 127{ 128} 129 130void 131ahandler(int s __unused) 132{ 133 if (alarm_exit) 134 _exit(0); 135} 136 137/* Read form socket, discard */ 138static void 139reader(void) { 140 int tcpsock, msgsock; 141 int on; 142 socklen_t len; 143 struct sockaddr_in inetaddr, inetpeer; 144 int n, *buf; 145 146 setproctitle("reader - init"); 147 on = 1; 148 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 149 err(1, "socket(), %s:%d", __FILE__, __LINE__); 150 151 if (setsockopt(tcpsock, 152 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 153 err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); 154 155 inetaddr.sin_family = AF_INET; 156 inetaddr.sin_addr.s_addr = INADDR_ANY; 157 inetaddr.sin_port = htons(port); 158 inetaddr.sin_len = sizeof(inetaddr); 159 160 signal(SIGUSR1, handler); 161 alarm(60); 162 if (bind(tcpsock, 163 (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) 164 err(1, "bind(), %s:%d", __FILE__, __LINE__); 165 166 if (listen(tcpsock, 5) < 0) 167 err(1, "listen(), %s:%d", __FILE__, __LINE__); 168 169 len = sizeof(inetpeer); 170 if ((msgsock = accept(tcpsock, 171 (struct sockaddr *)&inetpeer, &len)) < 0) 172 err(1, "accept(), %s:%d", __FILE__, __LINE__); 173 174 if ((buf = malloc(bufsize)) == NULL) 175 err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__); 176 setproctitle("reader"); 177 alarm(0); 178 signal(SIGALRM, ahandler); 179 for (;;) { 180 ualarm(arc4random() % 5000 + 100, 0); 181 if ((n = recvfrom(msgsock, buf, bufsize, 0, NULL, NULL)) < 0) { 182 if (errno == EAGAIN) 183 continue; 184 err(1, "read(), %s:%d", __FILE__, __LINE__); 185 } 186 if (n == 0) 187 break; 188 if (write(msgsock, "OK", 3) != 3) 189 err(1, "write ack. %s:%d", __FILE__, __LINE__); 190 191 } 192 close(msgsock); 193 _exit(0); 194} 195 196/* read from stdin, write to socket */ 197static void 198writer(void) { 199 int tcpsock, on; 200 struct sockaddr_in inetaddr; 201 struct hostent *hostent; 202 int i, r; 203 char line[1024], ack[80];; 204 pid_t ppid; 205 206 setproctitle("writer - init"); 207 share[SYNC] = 1; 208 ppid = getppid(); 209 signal(SIGUSR1, handler); 210 signal(SIGALRM, ahandler); 211 alarm(60); 212 on = 1; 213 for (i = 1; i < 5; i++) { 214 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 215 err(1, "socket(), %s:%d", __FILE__, __LINE__); 216 217 if (setsockopt(tcpsock, 218 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 219 err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); 220 221 hostent = gethostbyname ("localhost"); 222 bzero(&inetaddr, sizeof(inetaddr)); 223 memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr, 224 sizeof (struct in_addr)); 225 226 inetaddr.sin_family = AF_INET; 227 inetaddr.sin_port = htons(port); 228 inetaddr.sin_len = sizeof(inetaddr); 229 230 r = connect(tcpsock, (struct sockaddr *) &inetaddr, 231 sizeof(inetaddr)); 232 if (r == 0) 233 break; 234 sleep(1); 235 close(tcpsock); 236 } 237 if (r < 0) 238 err(1, "connect(), %s:%d", __FILE__, __LINE__); 239 240 setproctitle("writer"); 241 alarm(0); 242 while (fgets(line, sizeof(line), stdin) != NULL) { 243 alarm(10); 244 alarm_exit = 1; 245 if (write(tcpsock, line, strlen(line)) < 0) 246 err(1, "socket write(). %s:%d", __FILE__, __LINE__); 247 alarm_exit = 0; 248 ualarm(arc4random() % 5000 + 1000, 0); 249 if (recvfrom(tcpsock, ack, 4, 0, NULL, NULL) < 0) { 250 if (errno == EAGAIN) 251 continue; 252 err(1, "read(), %s:%d", __FILE__, __LINE__); 253 } 254 } 255 sleep(30); 256 return; 257} 258 259int 260main(int argc, char **argv) 261{ 262 263 pid_t kpid; 264 size_t len; 265 266 if (argc != 2) { 267 fprintf(stderr, "Usage: %s <port number>\n", argv[0]); 268 _exit(1); 269 } 270 port = atoi(argv[1]); 271 bufsize = 128; 272 273 len = PAGE_SIZE; 274 if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, 275 MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 276 err(1, "mmap"); 277 278 signal(SIGCHLD, SIG_IGN); 279 if ((pid = fork()) == 0) 280 reader(); 281 282 if ((kpid = fork()) == 0) 283 killer(); 284 285 writer(); 286 sleep(1); 287 kill(pid, SIGINT); 288 kill(kpid, SIGINT); 289 290 return (0); 291} 292EOF 293mycc -o /tmp/crlogger2 -Wall -Wextra -O2 -g /tmp/crlogger2.c 294rm -f /tmp/crlogger2.c 295 296N=50 297cd /tmp 298for j in `jot $N`; do 299 /tmp/crwriter2 | /tmp/crlogger2 1236$j & 300done 301wait 302rm -f /tmp/crwriter2 /tmp/crlogger2 303exit 0 304