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