1181834Sroberto/*
2181834SrobertoCopyright (C) 2004 Michael J. Silbersack. All rights reserved.
3181834Sroberto
4181834SrobertoRedistribution and use in source and binary forms, with or without
5181834Srobertomodification, are permitted provided that the following conditions
6181834Srobertoare met:
7181834Sroberto1. Redistributions of source code must retain the above copyright
8181834Sroberto   notice, this list of conditions and the following disclaimer.
9181834Sroberto2. Redistributions in binary form must reproduce the above copyright
10181834Sroberto   notice, this list of conditions and the following disclaimer in the
11181834Sroberto   documentation and/or other materials provided with the distribution.
12181834Sroberto
13181834SrobertoTHIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14181834SrobertoANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15280849ScyIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16181834SrobertoARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17330106SdelphijFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18181834SrobertoDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19330106SdelphijOR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20181834SrobertoHOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21181834SrobertoLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22181834SrobertoOUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23181834SrobertoSUCH DAMAGE.
24181834Sroberto*/
25181834Sroberto
26280849Scy#include <stdio.h>
27181834Sroberto#include <unistd.h>
28330106Sdelphij#include <sys/stat.h>
29181834Sroberto
30330106Sdelphij/*
31181834Sroberto * $FreeBSD$
32181834Sroberto * This program simply tests writing through the reverse direction of
33181834Sroberto * a pipe.  Nothing too fancy, it's only needed because most pipe-using
34181834Sroberto * programs never touch the reverse direction (it doesn't exist on
35181834Sroberto * Linux.)
36181834Sroberto */
37181834Sroberto
38181834Srobertoint main (void)
39181834Sroberto{
40181834Srobertochar buffer[65535], buffer2[65535];
41181834Srobertoint desc[2];
42280849Scyint buggy, error, i, successes, total;
43181834Srobertostruct stat status;
44181834Srobertopid_t new_pid;
45181834Sroberto
46181834Srobertobuggy = 0;
47181834Srobertototal = 0;
48181834Sroberto
49181834Srobertoerror = pipe(desc);
50181834Sroberto
51181834Srobertoif (error)
52181834Sroberto	err(0, "Couldn't allocate fds\n");
53181834Sroberto
54181834Srobertobuffer[0] = 'A';
55181834Sroberto
56181834Srobertofor (i = 1; i < 65535; i++) {
57181834Sroberto	buffer[i] = buffer[i - 1] + 1;
58280849Scy	if (buffer[i] > 'Z')
59280849Scy		buffer[i] = 'A';
60280849Scy	}
61181834Sroberto
62181834Srobertonew_pid = fork();
63181834Sroberto
64181834Srobertoif (new_pid == 0) {
65181834Sroberto	error = write(desc[0], &buffer, 4096);
66181834Sroberto	total += error;
67181834Sroberto	error = write(desc[0], &buffer[total], 4096);
68181834Sroberto	total += error;
69181834Sroberto	error = write(desc[0], &buffer[total], 4096);
70330106Sdelphij	total += error;
71181834Sroberto	error = write(desc[0], &buffer[total], 4096);
72181834Sroberto	total += error;
73181834Sroberto	error = write(desc[0], &buffer[total], 4096);
74280849Scy	total += error;
75280849Scy	error = write(desc[0], &buffer[total], 4096);
76280849Scy	total += error;
77280849Scy	error = write(desc[0], &buffer[total], 4096);
78280849Scy	total += error;
79280849Scy	error = write(desc[0], &buffer[total], 4096);
80280849Scy	total += error;
81280849Scy	printf("Wrote %d bytes, sleeping\n", total);
82280849Scy	usleep(1000000);
83280849Scy	error = write(desc[0], &buffer[total], 4096);
84280849Scy	total += error;
85280849Scy	error = write(desc[0], &buffer[total], 4096);
86280849Scy	total += error;
87280849Scy	printf("Wrote another 8192 bytes, %d total, done\n", total);
88280849Scy} else {
89181834Sroberto	usleep(500000);
90280849Scy	error = read(desc[1], &buffer2, 32768);
91280849Scy	total += error;
92280849Scy	printf("Read %d bytes, going back to sleep\n", error);
93280849Scy	usleep(1000000);
94280849Scy	error = read(desc[1], &buffer2[total], 8192);
95280849Scy	total += error;
96280849Scy	printf("Read %d bytes, done\n", error);
97280849Scy
98280849Scy	for (i = 0; i < total; i++) {
99280849Scy		if (buffer[i] != buffer2[i]) {
100280849Scy			buggy = 1;
101181834Sroberto			printf("Location %d input: %hhx output: %hhx\n",
102280849Scy					i, buffer[i], buffer2[i]);
103298695Sdelphij		}
104298695Sdelphij	}
105298695Sdelphij
106298695Sdelphijif ((buggy == 1) || (total != 40960))
107298695Sdelphij	printf("FAILURE\n");
108298695Sdelphijelse
109298695Sdelphij	printf("SUCCESS\n");
110298695Sdelphij
111298695Sdelphij}
112298695Sdelphij
113298695Sdelphij}
114298695Sdelphij