1/*
2 *  shared_memory_tests.c
3 *  xnu_quick_test
4 *
5 *  Created by Jerry Cottingham on 6/2/2005.
6 *  Copyright 2005 Apple Computer Inc. All rights reserved.
7 *
8 */
9
10#include "tests.h"
11#include <sys/ipc.h>
12#include <sys/mman.h>
13#include <sys/shm.h>
14
15extern char  g_target_path[ PATH_MAX ];
16
17
18/*  **************************************************************************************************************
19 *	Test shmat, shmctl, shmdt, shmget system calls.
20 *  **************************************************************************************************************
21 */
22int shm_tests( void * the_argp )
23{
24#if !TARGET_OS_EMBEDDED
25	int					my_err;
26	int					my_shm_id;
27	void *				my_shm_addr = NULL;
28	struct shmid_ds		my_shmid_ds;
29
30	my_shm_id = shmget( IPC_PRIVATE, 4096, (IPC_CREAT | IPC_R | IPC_W) );
31	if ( my_shm_id == -1 ) {
32		printf( "shmget failed with error %d - \"%s\" \n", errno, strerror( errno) );
33		goto test_failed_exit;
34	}
35
36	my_shm_addr = shmat( my_shm_id, NULL, SHM_RND );
37	if ( my_shm_addr == (void *) -1 ) {
38		my_shm_addr = NULL;
39		printf( "shmat failed with error %d - \"%s\" \n", errno, strerror( errno) );
40		goto test_failed_exit;
41	}
42
43	/* try writing to the shared segment */
44	*((char *) my_shm_addr) = 'A';
45
46	my_err = shmctl( my_shm_id, IPC_STAT, &my_shmid_ds );
47	if ( my_err == -1 ) {
48		printf( "shmctl failed with error %d - \"%s\" \n", errno, strerror( errno) );
49		goto test_failed_exit;
50	}
51	if ( my_shmid_ds.shm_segsz != 4096 ) {
52		printf( "shmctl failed get correct shared segment size \n" );
53		goto test_failed_exit;
54	}
55	if ( getpid( ) != my_shmid_ds.shm_cpid ) {
56		printf( "shmctl failed get correct creator pid \n" );
57		goto test_failed_exit;
58	}
59
60	if (my_shmid_ds.shm_internal != (void *) 0){
61		/*
62		 * The shm_internal field is a pointer reserved for kernel
63		 * use only.  It should not be leaked to user space.
64		 * (PR-15642873)
65		 */
66		printf( "shmctl failed to sanitize kernel internal pointer \n" );
67		goto test_failed_exit;
68	}
69
70	my_err = shmdt( my_shm_addr );
71	if ( my_err == -1 ) {
72		printf( "shmdt failed with error %d - \"%s\" \n", errno, strerror( errno) );
73		goto test_failed_exit;
74	}
75
76	my_err = shmctl( my_shm_id, IPC_RMID, NULL );
77	if ( my_err == -1 ) {
78		printf("shmctl failed to delete memory segment.\n");
79		goto test_failed_exit;
80	}
81
82	my_shm_addr = NULL;
83
84	my_err = 0;
85	goto test_passed_exit;
86
87test_failed_exit:
88	my_err = -1;
89
90test_passed_exit:
91	if ( my_shm_addr != NULL ) {
92		shmdt( my_shm_addr );
93		shmctl( my_shm_id, IPC_RMID, NULL);
94	}
95	return( my_err );
96#else
97	printf( "\t--> Not supported on EMBEDDED TARGET\n" );
98	return 0;
99#endif
100}
101
102
103/*  **************************************************************************************************************
104 *	Test BSD shared memory system calls.
105 *  **************************************************************************************************************
106 */
107int bsd_shm_tests( void * the_argp )
108{
109	int			my_err, i;
110	int			my_fd = -1;
111	char *		my_addr = NULL;
112	char		my_name[ 64 ];
113
114	for ( i = 0; i < 100; i++ ) {
115		sprintf( &my_name[0], "bsd_shm_tests_%d", i );
116		my_fd = shm_open( &my_name[0], (O_RDWR | O_CREAT | O_EXCL), S_IRWXU );
117		if ( my_fd != -1 )
118			break;
119		my_err = errno;
120		if ( my_err != EEXIST ) {
121			printf( "shm_open failed with error %d - \"%s\" \n", my_err, strerror( my_err) );
122			goto test_failed_exit;
123		}
124	}
125	if ( my_fd == -1 ) {
126		printf( "shm_open failed to open a shared memory object with name \"%s\" \n", &my_name[0] );
127		goto test_failed_exit;
128	}
129
130	/* grow shared memory object */
131	my_err = ftruncate( my_fd, 4096 );
132	if ( my_err == -1 ) {
133		printf( "ftruncate call failed with error %d - \"%s\" \n", errno, strerror( errno) );
134		goto test_failed_exit;
135	}
136
137	my_err = shm_unlink( &my_name[0] );
138	if ( my_err == -1 ) {
139		printf( "shm_unlink failed with error %d - \"%s\" \n", errno, strerror( errno) );
140		goto test_failed_exit;
141	}
142
143	/* unlinking a non existent path */
144	my_err = shm_unlink ( "/tmp/anonexistent_shm_oject" );
145	my_err = errno;
146	if ( my_err != ENOENT ) {
147		printf( "shm_unlink of non existent path failed with error %d - \"%s\" \n", errno, strerror( errno) );
148		goto test_failed_exit;
149	}
150
151	my_addr = (char *) mmap( NULL, 4096, (PROT_READ | PROT_WRITE), (MAP_FILE | MAP_SHARED), my_fd, 0 );
152	if ( my_addr == (char *) -1 ) {
153		printf( "mmap call failed with error %d - \"%s\" \n", errno, strerror( errno) );
154		goto test_failed_exit;
155	}
156
157	my_err = 0;
158	goto test_passed_exit;
159
160test_failed_exit:
161	my_err = -1;
162
163test_passed_exit:
164	if ( my_fd != -1 )
165		close( my_fd );
166	return( my_err );
167}
168
169