1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2002
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /* 12/20/2002 Port to LTP robbiew@us.ibm.com */
21 /* 06/30/2001 Port to Linux nsharoff@us.ibm.com */
22
23 /*
24 * NAME
25 * shmt09
26 *
27 * CALLS
28 * sbrk(2) shmctl(2) shmget(2)
29 *
30 * ALGORITHM
31 * Create a shared memory segment and attach at the default address.
32 * Increase the size of the data segment.
33 * Attach at an address that is less than the break value: should FAIL.
34 * decrease the size of the data segment.
35 * Attach at 4K past the break value: should SUCCEED.
36 * Sbrk() past the attached segment: should FAIL.
37 *
38 */
39
40 #include <stdio.h>
41 #include <sys/types.h>
42 #include <sys/ipc.h>
43 #include <sys/shm.h>
44 #include <errno.h>
45 #include <unistd.h>
46
47 #define K_1 1024
48
49 #define SHMBYTES (SHMLBA - 1)
50 #define SHMALIGN(p) (((unsigned long)(p) + SHMBYTES) & ~SHMBYTES)
51
52 /** LTP Port **/
53 #include "test.h"
54
55 char *TCID = "shmt09"; /* Test program identifier. */
56 int TST_TOTAL = 4; /* Total number of test cases. */
57 /**************/
58
59 #ifdef __ia64__
60 #define INCREMENT 8388608 /* 8Mb */
61 #elif defined (__mips__) || defined (__hppa__) || defined (__sparc__)
62 #define INCREMENT 262144 /* 256Kb */
63 #elif defined __sh__ || defined (__arm__) || defined(__aarch64__)
64 #define INCREMENT 16384 /* 16kb */
65 #else
66 #define INCREMENT SHMLBA
67 #endif
68
69 static int rm_shm(int);
70
main(void)71 int main(void)
72 {
73 char *c1 = NULL, *c2 = NULL, *c3 = NULL;
74 void *vp;
75 int shmid;
76 key_t key;
77
78 key = (key_t) getpid();
79
80 /*-----------------------------------------------------------*/
81
82 if ((unsigned long)sbrk(16384) >= (-4095UL)) {
83 perror("sbrk");
84 tst_brkm(TFAIL, NULL, "Error: sbrk failed, errno = %d\n",
85 errno);
86 }
87
88 if ((unsigned long)sbrk(-4097) >= (-4095UL)) {
89 perror("sbrk");
90 tst_brkm(TFAIL, NULL, "Error: sbrk failed, errno = %d\n",
91 errno);
92 }
93
94 if ((shmid = shmget(key, 10 * K_1, IPC_CREAT | 0666)) < 0) {
95 perror("shmget");
96 tst_brkm(TFAIL,
97 NULL,
98 "Error: shmget Failed, shmid = %d, errno = %d\n",
99 shmid, errno);
100 }
101
102 c1 = shmat(shmid, NULL, 0);
103 if (c1 == (char *)-1) {
104 perror("shmat");
105 tst_resm(TFAIL,
106 "Error: shmat Failed, shmid = %d, errno = %d\n",
107 shmid, errno);
108 rm_shm(shmid);
109 tst_exit();
110 }
111
112 tst_resm(TPASS, "sbrk, sbrk, shmget, shmat");
113
114 /*--------------------------------------------------------*/
115
116 if ((unsigned long)sbrk(32 * K_1) >= (-4095UL)) {
117 perror("sbrk");
118 tst_resm(TFAIL, "Error: sbrk failed, errno = %d\n", errno);
119 rm_shm(shmid);
120 tst_exit();
121 }
122 vp = (void *)((char *)sbrk(0) - 2 * K_1);
123 c2 = shmat(shmid, vp, 0);
124 if (c2 != (char *)-1) {
125 tst_resm(TFAIL,
126 "ERROR: shmat: succeeded!: shmid = %d, shmaddr = %p, "
127 "att_addr = %p", shmid, c2, vp);
128 rm_shm(shmid);
129 tst_exit();
130 }
131
132 tst_resm(TPASS, "sbrk, shmat");
133
134 /*---------------------------------------------------------*/
135
136 if ((unsigned long)sbrk(-16000) >= (-4095UL)) {
137 perror("sbrk");
138 tst_resm(TFAIL, "Error: sbrk failed, errno = %d\n", errno);
139 rm_shm(shmid);
140 tst_exit();
141 }
142 #ifdef __mips__
143 vp = (void *)((char *)sbrk(0) + 256 * K_1);
144 #elif defined(__powerpc__) || defined(__powerpc64__)
145 vp = (void *)((char *)sbrk(0) + getpagesize());
146 #else
147 /* SHM_RND rounds vp on the nearest multiple of SHMLBA */
148 vp = (void *)SHMALIGN((char *)sbrk(0) + 1);
149 #endif
150
151 c3 = shmat(shmid, vp, SHM_RND);
152 if (c3 == (char *)-1) {
153 perror("shmat1");
154 tst_resm(TFAIL,
155 "Error: shmat Failed, shmid = %d, errno = %d\n",
156 shmid, errno);
157 rm_shm(shmid);
158 tst_exit();
159 }
160
161 tst_resm(TPASS, "sbrk, shmat");
162
163 /*--------------------------------------------------------*/
164 #if defined (__ia64__) || defined(__mips__) || defined(__hppa__) || defined(__arm__) || defined(__aarch64__)
165 while ((vp = sbrk(INCREMENT)) != (void *)-1) ;
166 if (errno != ENOMEM) {
167 tst_resm(TFAIL, "Error: sbrk failed, errno = %d\n", errno);
168 rm_shm(shmid);
169 tst_exit();
170 }
171 #else
172 if ((vp = sbrk(INCREMENT)) != (void *)-1) {
173 tst_resm(TFAIL,
174 "Error: sbrk succeeded! ret = %p, curbrk = %p, ",
175 vp, sbrk(0));
176 rm_shm(shmid);
177 tst_exit();
178 }
179 #endif
180
181 tst_resm(TPASS, "sbrk");
182
183 /*------------------------------------------------------*/
184
185 rm_shm(shmid);
186 tst_exit();
187 }
188
rm_shm(int shmid)189 static int rm_shm(int shmid)
190 {
191 if (shmctl(shmid, IPC_RMID, NULL) == -1) {
192 perror("shmctl");
193 tst_brkm(TFAIL,
194 NULL,
195 "shmctl Failed to remove: shmid = %d, errno = %d\n",
196 shmid, errno);
197 }
198 return (0);
199 }
200