1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2002 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 6f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 7f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 8f08c3bdfSopenharmony_ci * (at your option) any later version. 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 11f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 12f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 16f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software 17f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18f08c3bdfSopenharmony_ci */ 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci/* 21f08c3bdfSopenharmony_ci * NAME 22f08c3bdfSopenharmony_ci * diotest_routines.c 23f08c3bdfSopenharmony_ci * 24f08c3bdfSopenharmony_ci * DESCRIPTION 25f08c3bdfSopenharmony_ci * Functions that are used in diotest programs. 26f08c3bdfSopenharmony_ci * fillbuf(), bufcmp(), filecmp() 27f08c3bdfSopenharmony_ci * forkchldrn(), waitchldrn(), killchldrn() 28f08c3bdfSopenharmony_ci * 29f08c3bdfSopenharmony_ci * History 30f08c3bdfSopenharmony_ci * 04/10/2002 Narasimha Sharoff 31f08c3bdfSopenharmony_ci * 32f08c3bdfSopenharmony_ci * RESTRICTIONS 33f08c3bdfSopenharmony_ci * None 34f08c3bdfSopenharmony_ci*/ 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_ci#include <stdio.h> 37f08c3bdfSopenharmony_ci#include <stdlib.h> 38f08c3bdfSopenharmony_ci#include <string.h> 39f08c3bdfSopenharmony_ci#include <signal.h> 40f08c3bdfSopenharmony_ci#include <fcntl.h> 41f08c3bdfSopenharmony_ci#include <sys/types.h> 42f08c3bdfSopenharmony_ci#include <sys/wait.h> 43f08c3bdfSopenharmony_ci#include <sys/uio.h> 44f08c3bdfSopenharmony_ci#include <errno.h> 45f08c3bdfSopenharmony_ci#include <unistd.h> 46f08c3bdfSopenharmony_ci#include <ctype.h> 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci#include "diotest_routines.h" 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ci/* **** Routines for buffer actions, comparisions **** */ 51f08c3bdfSopenharmony_ci 52f08c3bdfSopenharmony_ci/* 53f08c3bdfSopenharmony_ci * fillbuf: Fill buffer of given size with given character value 54f08c3bdfSopenharmony_ci * vfillbuf: Fill the vector array 55f08c3bdfSopenharmony_ci*/ 56f08c3bdfSopenharmony_civoid fillbuf(char *buf, int count, char value) 57f08c3bdfSopenharmony_ci{ 58f08c3bdfSopenharmony_ci while (count > 0) { 59f08c3bdfSopenharmony_ci strncpy(buf, &value, 1); 60f08c3bdfSopenharmony_ci buf++; 61f08c3bdfSopenharmony_ci count = count - 1; 62f08c3bdfSopenharmony_ci } 63f08c3bdfSopenharmony_ci} 64f08c3bdfSopenharmony_ci 65f08c3bdfSopenharmony_civoid vfillbuf(struct iovec *iv, int vcnt, char value) 66f08c3bdfSopenharmony_ci{ 67f08c3bdfSopenharmony_ci int i; 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci for (i = 0; i < vcnt; iv++, i++) { 70f08c3bdfSopenharmony_ci fillbuf(iv->iov_base, iv->iov_len, (char)value); 71f08c3bdfSopenharmony_ci } 72f08c3bdfSopenharmony_ci} 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_ci/* 75f08c3bdfSopenharmony_ci * bufcmp: Compare two buffers 76f08c3bdfSopenharmony_ci * vbufcmp: Compare two buffers of two io arrays 77f08c3bdfSopenharmony_ci*/ 78f08c3bdfSopenharmony_ciint bufcmp(char *b1, char *b2, int bsize) 79f08c3bdfSopenharmony_ci{ 80f08c3bdfSopenharmony_ci int i; 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ci for (i = 0; i < bsize; i++) { 83f08c3bdfSopenharmony_ci if (strncmp(&b1[i], &b2[i], 1)) { 84f08c3bdfSopenharmony_ci fprintf(stderr, 85f08c3bdfSopenharmony_ci "bufcmp: offset %d: Expected: 0x%x, got 0x%x\n", 86f08c3bdfSopenharmony_ci i, b1[i], b2[i]); 87f08c3bdfSopenharmony_ci return (-1); 88f08c3bdfSopenharmony_ci } 89f08c3bdfSopenharmony_ci } 90f08c3bdfSopenharmony_ci return (0); 91f08c3bdfSopenharmony_ci} 92f08c3bdfSopenharmony_ci 93f08c3bdfSopenharmony_ciint vbufcmp(struct iovec *iv1, struct iovec *iv2, int vcnt) 94f08c3bdfSopenharmony_ci{ 95f08c3bdfSopenharmony_ci int i; 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_ci for (i = 0; i < vcnt; iv1++, iv2++, i++) { 98f08c3bdfSopenharmony_ci if (bufcmp(iv1->iov_base, iv2->iov_base, iv1->iov_len) < 0) { 99f08c3bdfSopenharmony_ci fprintf(stderr, "Vector: %d, iv1base=%s, iv2base=%s\n", 100f08c3bdfSopenharmony_ci i, (char *)iv1->iov_base, 101f08c3bdfSopenharmony_ci (char *)iv2->iov_base); 102f08c3bdfSopenharmony_ci return (-1); 103f08c3bdfSopenharmony_ci } 104f08c3bdfSopenharmony_ci } 105f08c3bdfSopenharmony_ci return 0; 106f08c3bdfSopenharmony_ci} 107f08c3bdfSopenharmony_ci 108f08c3bdfSopenharmony_ci/* 109f08c3bdfSopenharmony_ci * compare_files: Compares two files 110f08c3bdfSopenharmony_ci*/ 111f08c3bdfSopenharmony_ciint filecmp(char *f1, char *f2) 112f08c3bdfSopenharmony_ci{ 113f08c3bdfSopenharmony_ci int i; 114f08c3bdfSopenharmony_ci int fd1, fd2; 115f08c3bdfSopenharmony_ci int ret1, ret2 = 0; 116f08c3bdfSopenharmony_ci char buf1[BUFSIZ], buf2[BUFSIZ]; 117f08c3bdfSopenharmony_ci 118f08c3bdfSopenharmony_ci /* Open the file for read */ 119f08c3bdfSopenharmony_ci if ((fd1 = open(f1, O_RDONLY)) == -1) { 120f08c3bdfSopenharmony_ci fprintf(stderr, "compare_files: open failed %s: %s", 121f08c3bdfSopenharmony_ci f1, strerror(errno)); 122f08c3bdfSopenharmony_ci return (-1); 123f08c3bdfSopenharmony_ci } 124f08c3bdfSopenharmony_ci if ((fd2 = open(f2, O_RDONLY)) == -1) { 125f08c3bdfSopenharmony_ci fprintf(stderr, "compare_files: open failed %s: %s", 126f08c3bdfSopenharmony_ci f2, strerror(errno)); 127f08c3bdfSopenharmony_ci close(fd1); 128f08c3bdfSopenharmony_ci return (-1); 129f08c3bdfSopenharmony_ci } 130f08c3bdfSopenharmony_ci 131f08c3bdfSopenharmony_ci /* Compare the files */ 132f08c3bdfSopenharmony_ci while ((ret1 = read(fd1, buf1, BUFSIZ)) > 0) { 133f08c3bdfSopenharmony_ci ret2 = read(fd2, buf2, BUFSIZ); 134f08c3bdfSopenharmony_ci if (ret1 != ret2) { 135f08c3bdfSopenharmony_ci fprintf(stderr, "compare_file: file length mistmatch:"); 136f08c3bdfSopenharmony_ci fprintf(stderr, "read: %d from %s, %d from %s", 137f08c3bdfSopenharmony_ci ret1, f1, ret2, f2); 138f08c3bdfSopenharmony_ci close(fd1); 139f08c3bdfSopenharmony_ci close(fd2); 140f08c3bdfSopenharmony_ci return (-1); 141f08c3bdfSopenharmony_ci } 142f08c3bdfSopenharmony_ci for (i = 0; i < ret1; i++) { 143f08c3bdfSopenharmony_ci if (strncmp(&buf1[i], &buf2[i], 1)) { 144f08c3bdfSopenharmony_ci fprintf(stderr, "compare_file: char mismatch:"); 145f08c3bdfSopenharmony_ci fprintf(stderr, " %s offset %d: 0x%02x %c ", 146f08c3bdfSopenharmony_ci f1, i, buf1[i], 147f08c3bdfSopenharmony_ci isprint(buf1[i]) ? buf1[1] : '.'); 148f08c3bdfSopenharmony_ci fprintf(stderr, " %s offset %d: 0x%02x %c\n", 149f08c3bdfSopenharmony_ci f2, i, buf2[i], 150f08c3bdfSopenharmony_ci isprint(buf2[i]) ? buf2[i] : '.'); 151f08c3bdfSopenharmony_ci close(fd1); 152f08c3bdfSopenharmony_ci close(fd2); 153f08c3bdfSopenharmony_ci return (-1); 154f08c3bdfSopenharmony_ci } 155f08c3bdfSopenharmony_ci } 156f08c3bdfSopenharmony_ci } 157f08c3bdfSopenharmony_ci close(fd1); 158f08c3bdfSopenharmony_ci close(fd2); 159f08c3bdfSopenharmony_ci return 0; 160f08c3bdfSopenharmony_ci} 161f08c3bdfSopenharmony_ci 162f08c3bdfSopenharmony_ci/* **** Routines to create, wait and destroy child processes **** */ 163f08c3bdfSopenharmony_ci 164f08c3bdfSopenharmony_ci/* 165f08c3bdfSopenharmony_ci * forkchldrn: fork the given number of children and set the function 166f08c3bdfSopenharmony_ci * that child should execute. 167f08c3bdfSopenharmony_ci*/ 168f08c3bdfSopenharmony_ciint forkchldrn(int **pidlst, int numchld, int action, int (*chldfunc) ()) 169f08c3bdfSopenharmony_ci{ 170f08c3bdfSopenharmony_ci int i, cpid; 171f08c3bdfSopenharmony_ci 172f08c3bdfSopenharmony_ci if ((*pidlst = ((int *)malloc(sizeof(int) * numchld))) == 0) { 173f08c3bdfSopenharmony_ci fprintf(stderr, "forkchldrn: calloc failed for pidlst: %s\n", 174f08c3bdfSopenharmony_ci strerror(errno)); 175f08c3bdfSopenharmony_ci return (-1); 176f08c3bdfSopenharmony_ci } 177f08c3bdfSopenharmony_ci for (i = 0; i < numchld; i++) { 178f08c3bdfSopenharmony_ci if ((cpid = fork()) < 0) { 179f08c3bdfSopenharmony_ci fprintf(stderr, 180f08c3bdfSopenharmony_ci "forkchldrn: fork child %d failed, %s\n", i, 181f08c3bdfSopenharmony_ci strerror(errno)); 182f08c3bdfSopenharmony_ci killchldrn(pidlst, i, SIGTERM); 183f08c3bdfSopenharmony_ci return (-1); 184f08c3bdfSopenharmony_ci } 185f08c3bdfSopenharmony_ci if (cpid == 0) 186f08c3bdfSopenharmony_ci exit((*chldfunc) (i, action)); 187f08c3bdfSopenharmony_ci else 188f08c3bdfSopenharmony_ci *(*pidlst + i) = cpid; 189f08c3bdfSopenharmony_ci } 190f08c3bdfSopenharmony_ci return 0; 191f08c3bdfSopenharmony_ci} 192f08c3bdfSopenharmony_ci 193f08c3bdfSopenharmony_ci/* 194f08c3bdfSopenharmony_ci * killchldrn: signal the children listed in pidlst with the given signal 195f08c3bdfSopenharmony_ci * 196f08c3bdfSopenharmony_ci*/ 197f08c3bdfSopenharmony_ciint killchldrn(int **pidlst, int numchld, int sig) 198f08c3bdfSopenharmony_ci{ 199f08c3bdfSopenharmony_ci int i, cpid, errflag = 0; 200f08c3bdfSopenharmony_ci 201f08c3bdfSopenharmony_ci for (i = 0; i < numchld; i++) { 202f08c3bdfSopenharmony_ci cpid = *(*pidlst + i); 203f08c3bdfSopenharmony_ci if (cpid > 0) { 204f08c3bdfSopenharmony_ci if (kill(cpid, sig) < 0) { 205f08c3bdfSopenharmony_ci fprintf(stderr, 206f08c3bdfSopenharmony_ci "killchldrn: kill %d failed, %s\n", 207f08c3bdfSopenharmony_ci cpid, strerror(errno)); 208f08c3bdfSopenharmony_ci errflag--; 209f08c3bdfSopenharmony_ci } 210f08c3bdfSopenharmony_ci } 211f08c3bdfSopenharmony_ci } 212f08c3bdfSopenharmony_ci return (errflag); 213f08c3bdfSopenharmony_ci} 214f08c3bdfSopenharmony_ci 215f08c3bdfSopenharmony_ci/* 216f08c3bdfSopenharmony_ci * waitchldrn: wait for child process listed in pidlst to finish. 217f08c3bdfSopenharmony_ci*/ 218f08c3bdfSopenharmony_ciint waitchldrn(int **pidlst, int numchld) 219f08c3bdfSopenharmony_ci{ 220f08c3bdfSopenharmony_ci int i, cpid, ret, errflag = 0; 221f08c3bdfSopenharmony_ci int status; 222f08c3bdfSopenharmony_ci 223f08c3bdfSopenharmony_ci for (i = 0; i < numchld; i++) { 224f08c3bdfSopenharmony_ci cpid = *(*pidlst + i); 225f08c3bdfSopenharmony_ci if (cpid == 0) 226f08c3bdfSopenharmony_ci continue; 227f08c3bdfSopenharmony_ci if ((ret = waitpid(cpid, &status, 0)) != cpid) { 228f08c3bdfSopenharmony_ci fprintf(stderr, 229f08c3bdfSopenharmony_ci "waitchldrn: wait failed for child %d, pid %d: %s\n", 230f08c3bdfSopenharmony_ci i, cpid, strerror(errno)); 231f08c3bdfSopenharmony_ci errflag--; 232f08c3bdfSopenharmony_ci } 233f08c3bdfSopenharmony_ci if (status) 234f08c3bdfSopenharmony_ci errflag = -1; 235f08c3bdfSopenharmony_ci } 236f08c3bdfSopenharmony_ci return (errflag); 237f08c3bdfSopenharmony_ci} 238