1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 4f08c3bdfSopenharmony_ci * Ported to LTP: Wayne Boyer 5f08c3bdfSopenharmony_ci * Copyright (c) 2018 Cyril Hrubis <chrubis@suse.cz> 6f08c3bdfSopenharmony_ci */ 7f08c3bdfSopenharmony_ci 8f08c3bdfSopenharmony_ci/* 9f08c3bdfSopenharmony_ci * Check if many children can read what is written to a pipe by the parent. 10f08c3bdfSopenharmony_ci * 11f08c3bdfSopenharmony_ci * ALGORITHM 12f08c3bdfSopenharmony_ci * For a different nchilds number: 13f08c3bdfSopenharmony_ci * 1. Open a pipe and write nchilds * (PIPE_BUF/nchilds) bytes into it 14f08c3bdfSopenharmony_ci * 2. Fork nchilds children 15f08c3bdfSopenharmony_ci * 3. Each child reads PIPE_BUF/nchilds characters and checks that the 16f08c3bdfSopenharmony_ci * bytes read are correct 17f08c3bdfSopenharmony_ci */ 18f08c3bdfSopenharmony_ci#include <stdlib.h> 19f08c3bdfSopenharmony_ci#include "tst_test.h" 20f08c3bdfSopenharmony_ci 21f08c3bdfSopenharmony_cistatic int fds[2]; 22f08c3bdfSopenharmony_cistatic unsigned char buf[PIPE_BUF]; 23f08c3bdfSopenharmony_cistatic size_t read_per_child; 24f08c3bdfSopenharmony_ci 25f08c3bdfSopenharmony_civoid do_child(void) 26f08c3bdfSopenharmony_ci{ 27f08c3bdfSopenharmony_ci size_t nread; 28f08c3bdfSopenharmony_ci unsigned char rbuf[read_per_child]; 29f08c3bdfSopenharmony_ci unsigned int i; 30f08c3bdfSopenharmony_ci 31f08c3bdfSopenharmony_ci SAFE_CLOSE(fds[1]); 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci nread = SAFE_READ(0, fds[0], rbuf, sizeof(rbuf)); 34f08c3bdfSopenharmony_ci 35f08c3bdfSopenharmony_ci if (nread != read_per_child) { 36f08c3bdfSopenharmony_ci tst_res(TFAIL, "Invalid read size child %i size %zu", 37f08c3bdfSopenharmony_ci getpid(), nread); 38f08c3bdfSopenharmony_ci return; 39f08c3bdfSopenharmony_ci } 40f08c3bdfSopenharmony_ci 41f08c3bdfSopenharmony_ci for (i = 0; i < read_per_child; i++) { 42f08c3bdfSopenharmony_ci if (rbuf[i] != (i % 256)) { 43f08c3bdfSopenharmony_ci tst_res(TFAIL, 44f08c3bdfSopenharmony_ci "Invalid byte read child %i byte %i have %i expected %i", 45f08c3bdfSopenharmony_ci getpid(), i, rbuf[i], i % 256); 46f08c3bdfSopenharmony_ci return; 47f08c3bdfSopenharmony_ci } 48f08c3bdfSopenharmony_ci } 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ci tst_res(TPASS, "Child %i read pipe buffer correctly", getpid()); 51f08c3bdfSopenharmony_ci} 52f08c3bdfSopenharmony_ci 53f08c3bdfSopenharmony_cistatic unsigned int childs[] = { 54f08c3bdfSopenharmony_ci 1, 55f08c3bdfSopenharmony_ci 2, 56f08c3bdfSopenharmony_ci 3, 57f08c3bdfSopenharmony_ci 4, 58f08c3bdfSopenharmony_ci 10, 59f08c3bdfSopenharmony_ci 50 60f08c3bdfSopenharmony_ci}; 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_cistatic void run(unsigned int tcase) 63f08c3bdfSopenharmony_ci{ 64f08c3bdfSopenharmony_ci pid_t pid; 65f08c3bdfSopenharmony_ci unsigned int nchilds = childs[tcase]; 66f08c3bdfSopenharmony_ci read_per_child = PIPE_BUF/nchilds; 67f08c3bdfSopenharmony_ci unsigned int i, j; 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci tst_res(TINFO, "Reading %zu per each of %u children", 70f08c3bdfSopenharmony_ci read_per_child, nchilds); 71f08c3bdfSopenharmony_ci 72f08c3bdfSopenharmony_ci for (i = 0; i < nchilds; i++) { 73f08c3bdfSopenharmony_ci for (j = 0; j < read_per_child; j++) { 74f08c3bdfSopenharmony_ci buf[i * read_per_child + j] = j % 256; 75f08c3bdfSopenharmony_ci } 76f08c3bdfSopenharmony_ci } 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_ci SAFE_PIPE(fds); 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_ci SAFE_WRITE(SAFE_WRITE_ALL, fds[1], buf, read_per_child * nchilds); 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ci for (i = 0; i < nchilds; i++) { 83f08c3bdfSopenharmony_ci pid = SAFE_FORK(); 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_ci if (!pid) { 86f08c3bdfSopenharmony_ci do_child(); 87f08c3bdfSopenharmony_ci exit(0); 88f08c3bdfSopenharmony_ci } 89f08c3bdfSopenharmony_ci } 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ci tst_reap_children(); 92f08c3bdfSopenharmony_ci 93f08c3bdfSopenharmony_ci SAFE_CLOSE(fds[0]); 94f08c3bdfSopenharmony_ci SAFE_CLOSE(fds[1]); 95f08c3bdfSopenharmony_ci} 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_cistatic struct tst_test test = { 98f08c3bdfSopenharmony_ci .forks_child = 1, 99f08c3bdfSopenharmony_ci .test = run, 100f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(childs), 101f08c3bdfSopenharmony_ci}; 102