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 when name begins with the slash character, then processes calling
11 * shm_open() with the same value of name refer to the same shared memory
12 * object, as long as that name has not been removed.
13 *
14 * Steps:
15 *  1. Create a child process.
16 * (The child process)
17 *  2. Open a shared memory file O_RDWR with a name beginning with slash.
18 *  3. Write a string in the file.
19 * (The father)
20 *  2. Open a shared memory file O_RDONLY with the same name.
21 *  3. Read into the file.
22 *  4. Check that it obtain the right string.
23 */
24
25/* ftruncate was formerly an XOPEN extension. We define _XOPEN_SOURCE here to
26   avoid warning if the implementation does not program ftruncate as a base
27   interface */
28#define _XOPEN_SOURCE 600
29
30#include <stdio.h>
31#include <sys/mman.h>
32#include <sys/stat.h>
33#include <sys/wait.h>
34#include <sys/types.h>
35#include <unistd.h>
36#include <stdlib.h>
37#include <string.h>
38#include <fcntl.h>
39#include <signal.h>
40#include "posixtest.h"
41
42#define BUF_SIZE 8
43#define SHM_NAME "/posixtest_5-1"
44
45char str[BUF_SIZE] = "qwerty";
46
47int child_process()
48{
49	int fd;
50	char *buf;
51
52	fd = shm_open(SHM_NAME, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
53	if (fd == -1) {
54		perror("An error occurs when calling shm_open()");
55		kill(getppid(), SIGUSR1);
56		return PTS_UNRESOLVED;
57	}
58
59	if (ftruncate(fd, BUF_SIZE) != 0) {
60		perror("An error occurs when calling ftruncate()");
61		kill(getppid(), SIGUSR1);
62		return PTS_UNRESOLVED;
63	}
64
65	buf = mmap(NULL, BUF_SIZE, PROT_WRITE, MAP_SHARED, fd, 0);
66	if (buf == MAP_FAILED) {
67		perror("An error occurs when calling mmap()");
68		kill(getppid(), SIGUSR1);
69		return PTS_UNRESOLVED;
70	}
71
72	strcpy(buf, str);
73
74	return PTS_PASS;
75}
76
77int main(void)
78{
79	int fd, child_pid;
80	char *buf;
81
82	child_pid = fork();
83	if (child_pid == -1) {
84		perror("An error occurs when calling fork()");
85		return PTS_UNRESOLVED;
86	} else if (child_pid == 0) {
87		return child_process();
88	}
89
90	wait(NULL);
91
92	fd = shm_open(SHM_NAME, O_RDONLY, S_IRUSR | S_IWUSR);
93	if (fd == -1) {
94		perror("An error occurs when calling shm_open()");
95		return PTS_UNRESOLVED;
96	}
97
98	buf = mmap(NULL, BUF_SIZE, PROT_READ, MAP_SHARED, fd, 0);
99	if (buf == MAP_FAILED) {
100		perror("An error occurs when calling mmap()");
101		return PTS_UNRESOLVED;
102	}
103
104	shm_unlink(SHM_NAME);
105
106	if (strcmp(buf, str) == 0) {
107		printf("Test PASSED\n");
108		return PTS_PASS;
109	}
110
111	printf("Test FAILED\n");
112	return PTS_FAIL;
113}
114