1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 * $FreeBSD$
21 */
22
23/*
24 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
25 * Use is subject to license terms.
26 */
27
28#pragma ident	"@(#)readmmap.c	1.4	07/05/25 SMI"
29
30/*
31 * --------------------------------------------------------------
32 *	BugId 5047993 : Getting bad read data.
33 *
34 *	Usage: readmmap <filename>
35 *
36 *	where:
37 *		filename is an absolute path to the file name.
38 *
39 *	Return values:
40 *		1 : error
41 *		0 : no errors
42 * --------------------------------------------------------------
43 */
44#include <stdio.h>
45#include <stdlib.h>
46#include <unistd.h>
47#include <fcntl.h>
48#include <errno.h>
49#include <sys/mman.h>
50
51int
52main(int argc, char **argv)
53{
54	char *filename = "badfile";
55	size_t size = 4395;
56	size_t idx = 0;
57	char *buf = NULL;
58	char *map = NULL;
59	int fd = -1, bytes, retval = 0;
60	unsigned seed;
61
62	if (argc < 2 || optind == argc) {
63		(void) fprintf(stderr,
64		    "usage: %s <file name>\n", argv[0]);
65		exit(1);
66	}
67
68	if ((buf = calloc(1, size)) == NULL) {
69		perror("calloc");
70		exit(1);
71	}
72
73	filename = argv[optind];
74
75	(void) remove(filename);
76
77	fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
78	if (fd == -1) {
79		perror("open to create");
80		retval = 1;
81		goto end;
82	}
83
84	bytes = write(fd, buf, size);
85	if (bytes != size) {
86		(void) printf("short write: %d != %ud\n", bytes, size);
87		retval = 1;
88		goto end;
89	}
90
91	map = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
92	if (map == MAP_FAILED) {
93		perror("mmap");
94		retval = 1;
95		goto end;
96	}
97	seed = time(NULL);
98	srandom(seed);
99
100	idx = random() % size;
101	map[idx] = 1;
102
103	if (msync(map, size, MS_SYNC) != 0) {
104		perror("msync");
105		retval = 1;
106		goto end;
107	}
108
109	if (munmap(map, size) != 0) {
110		perror("munmap");
111		retval = 1;
112		goto end;
113	}
114
115	bytes = pread(fd, buf, size, 0);
116	if (bytes != size) {
117		(void) printf("short read: %d != %ud\n", bytes, size);
118		retval = 1;
119		goto end;
120	}
121
122	if (buf[idx] != 1) {
123		(void) printf(
124		    "bad data from read!  got buf[%ud]=%d, expected 1\n",
125		    idx, buf[idx]);
126		retval = 1;
127		goto end;
128	}
129
130	(void) printf("good data from read: buf[%ud]=1\n", idx);
131end:
132	if (fd != -1) {
133		(void) close(fd);
134	}
135	if (buf != NULL) {
136		free(buf);
137	}
138
139	return (retval);
140}
141