1/*
2 * Copyright (c) International Business Machines  Corp., 2002
3 * Copyright (c) 2013 Oracle and/or its affiliates. All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it would be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write the Free Software Foundation,
17 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20#include <errno.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <sys/stat.h>
25#include <sys/types.h>
26#include <sys/ipc.h>
27#include <sys/msg.h>
28#include "libmsgctl.h"
29
30int doreader(long key, int tid, long type, int child, int nreps)
31{
32	int i, size;
33	int id;
34	struct mbuffer buffer;
35
36	id = msgget(key, 0);
37	if (id < 0) {
38		printf("msgget() error in the reader of child group %d: %s\n",
39			child, strerror(errno));
40
41		return FAIL;
42	}
43	if (id != tid) {
44		printf("Message queue mismatch in the reader of child group %d for message queue id %d\n",
45			child, id);
46
47		return FAIL;
48	}
49	for (i = 0; i < nreps; i++) {
50		memset(&buffer, 0, sizeof(buffer));
51
52		size = msgrcv(id, &buffer, 100, type, 0);
53		if (size < 0) {
54			printf("msgrcv() error in child %d, read # = %d: %s\n",
55				child, (i + 1), strerror(errno));
56
57			return FAIL;
58		}
59		if (buffer.type != type) {
60			printf("Type mismatch in child %d, read #d = %d: ",
61				child, (i + 1));
62			printf("for message got %ld, expected - %ld\n",
63				buffer.type, type);
64
65			return FAIL;
66		}
67		if (buffer.data.len + 1 != size) {
68			printf("Size mismatch in child %d, read # = %d: ",
69				child, (i + 1));
70			printf("for message got %d, expected - %d\n",
71				buffer.data.len + 1, size);
72
73			return FAIL;
74		}
75		if (verify(buffer.data.pbytes, (key % 255), size - 1, child)) {
76			printf("Verify failed in child %d read # = %d, key = %lx\n",
77				child, (i + 1), key);
78
79			return FAIL;
80		}
81		key++;
82	}
83	return PASS;
84}
85
86int dowriter(long key, int tid, long type, int child, int nreps)
87{
88	int i, size;
89	int id;
90	struct mbuffer buffer;
91
92	id = msgget(key, 0);
93	if (id < 0) {
94		printf("msgget() error in the writer of child group %d: %s\n",
95			child, strerror(errno));
96
97		return FAIL;
98	}
99	if (id != tid) {
100		printf("Message queue mismatch in the reader of child group %d for message queue id %d\n",
101			child, id);
102
103		return FAIL;
104	}
105
106	for (i = 0; i < nreps; i++) {
107		memset(&buffer, 0, sizeof(buffer));
108
109		do {
110			size = (lrand48() % 99);
111		} while (size == 0);
112		fill_buffer(buffer.data.pbytes, (key % 255), size);
113		buffer.data.len = size;
114		buffer.type = type;
115		if (msgsnd(id, &buffer, size + 1, 0) < 0) {
116			printf("msgsnd() error in child %d, write # = %d, key = %lx: %s\n",
117				child, nreps, key, strerror(errno));
118
119			return FAIL;
120		}
121		key++;
122	}
123	return PASS;
124}
125
126int fill_buffer(char *buf, char val, int size)
127{
128	int i;
129
130	for (i = 0; i < size; i++)
131		buf[i] = val;
132	return 0;
133}
134
135/* Check a buffer for correct values */
136int verify(char *buf, char val, int size, int child)
137{
138	while (size-- > 0) {
139		if (*buf++ != val) {
140			printf("Verify error in child %d, *buf = %x, val = %x, size = %d\n",
141				child, *buf, val, size);
142
143			return FAIL;
144		}
145	}
146	return PASS;
147}
148