1/*
2 *  This program is free software; you can redistribute it and/or modify
3 *  it under the terms of the GNU General Public License version 2.
4 *
5 *  This program is distributed in the hope that it will be useful,
6 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
7 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8 *  GNU General Public License for more details.
9 *
10 * Test that shm_open does not open the shared memory object for writing when
11 * calling shm_open with O_RDONLY even if the mode set write permission.
12 *
13 * The test use ftruncate to check the object is not open for writing.
14 */
15
16/* ftruncate was formerly an XOPEN extension. We define _XOPEN_SOURCE here to
17   avoid warning if the implementation does not program ftruncate as a base
18   interface */
19#define _XOPEN_SOURCE 600
20
21#include <stdio.h>
22#include <sys/mman.h>
23#include <sys/stat.h>
24#include <unistd.h>
25#include <fcntl.h>
26#include <errno.h>
27#include "posixtest.h"
28
29#define BUF_SIZE 8
30#define SHM_NAME "posixtest_20-1"
31
32int main() {
33	int fd, result;
34
35	result = shm_unlink(SHM_NAME);
36	if(result != 0 && errno != ENOENT) {
37		/* The shared memory object exist and shm_unlink can not
38		   remove it. */
39		perror("An error occurs when calling shm_unlink()");
40		return PTS_UNRESOLVED;
41	}
42
43	fd = shm_open(SHM_NAME, O_RDONLY|O_CREAT, S_IRUSR);
44	if(fd == -1) {
45		perror("An error occurs when calling shm_open()");
46		return PTS_UNRESOLVED;
47	}
48
49	result = ftruncate(fd, BUF_SIZE);
50
51	if(result == -1 && errno == EINVAL) {
52		printf("Test PASSED\n");
53		shm_unlink(SHM_NAME);
54		return PTS_PASS;
55	} else if(result == 0){
56		printf("The shared memory object is opened for writing.\n");
57		shm_unlink(SHM_NAME);
58		return PTS_FAIL;
59	}
60
61	perror("ftruncate");
62	shm_unlink(SHM_NAME);
63	return PTS_FAIL;
64}
65