• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2001
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 /*
21  * NAME
22  *	libmsg.c
23  *
24  * DESCRIPTION
25  *	common routines for the IPC system call tests.
26  *
27  *	The library contains the following routines:
28  *
29  *	getipckey()
30  *	rm_queue()
31  *	init_buf()
32  *	rm_sema()
33  *	getuserid()
34  *	rm_shm()
35  */
36 
37 #define LIBIPC
38 #include "ipcmsg.h"
39 #include "ipcsem.h"
40 
41 #include <pwd.h>
42 #include <sys/ipc.h>
43 #include <sys/shm.h>
44 
45 /*
46  * getipckey() - generates and returns a message key used by the "get"
47  *		 calls to create an IPC resource.
48  */
getipckey(void)49 key_t getipckey(void)
50 {
51 	const char a = 'a';
52 	int ascii_a = (int)a;
53 	char *curdir = NULL;
54 	size_t size = 0;
55 	key_t ipc_key;
56 	int proj_id;
57 	static int count = 0;
58 
59 	if (NULL == (curdir = getcwd(curdir, size))) {
60 		tst_brkm(TBROK, cleanup, "Can't get current directory "
61 			 "in getipckey()");
62 	}
63 
64 	/*
65 	 * Get a Sys V IPC key
66 	 *
67 	 * ftok() requires a character as a second argument.  This is
68 	 * refered to as a "project identifier" in the man page.
69 	 */
70 	proj_id = count % 26 + ascii_a;
71 	count++;
72 
73 	if ((ipc_key = ftok(curdir, proj_id)) == -1) {
74 		tst_brkm(TBROK, cleanup, "Can't get msgkey from ftok()");
75 	}
76 
77 	return (ipc_key);
78 }
79 
80 /*
81  * rm_queue() - removes a message queue.
82  */
rm_queue(int queue_id)83 void rm_queue(int queue_id)
84 {
85 	if (queue_id == -1) {	/* no queue to remove */
86 		return;
87 	}
88 
89 	if (msgctl(queue_id, IPC_RMID, NULL) == -1) {
90 		tst_resm(TINFO, "WARNING: message queue deletion failed.");
91 		tst_resm(TINFO, "This could lead to IPC resource problems.");
92 		tst_resm(TINFO, "id = %d", queue_id);
93 	}
94 }
95 
96 /*
97  * init_buf() - initialize the message buffer with some text and a type.
98  */
init_buf(MSGBUF * m_buf,int type,int size)99 void init_buf(MSGBUF * m_buf, int type, int size)
100 {
101 	int i;
102 	int ascii_a = (int)'a';	/* the ascii value for 'a' */
103 
104 	/* this fills the message with a repeating alphabet string */
105 	for (i = 0; i < size; i++) {
106 		m_buf->mtext[i] = ascii_a + (i % 26);
107 	}
108 
109 	/* terminate the message */
110 	m_buf->mtext[i] = '\0';
111 
112 	/* if the type isn't valid, set it to 1 */
113 	if (type < 1) {
114 		m_buf->mtype = 1;
115 	} else {
116 		m_buf->mtype = type;
117 	}
118 }
119 
120 /*
121  * rm_sema() - removes a semaphore.
122  */
rm_sema(int sem_id)123 void rm_sema(int sem_id)
124 {
125 	union semun arr;
126 
127 	if (sem_id == -1) {	/* no semaphore to remove */
128 		return;
129 	}
130 
131 	if (semctl(sem_id, 0, IPC_RMID, arr) == -1) {
132 		tst_resm(TINFO, "WARNING: semaphore deletion failed.");
133 		tst_resm(TINFO, "This could lead to IPC resource problems.");
134 		tst_resm(TINFO, "id = %d", sem_id);
135 	}
136 }
137 
138 /*
139  * getuserid() - return the integer value for the "user" id
140  */
getuserid(char * user)141 int getuserid(char *user)
142 {
143 	struct passwd *ent;
144 
145 	/* get the uid value for the user */
146 	if ((ent = getpwnam(user)) == NULL) {
147 		tst_brkm(TBROK, cleanup, "Couldn't get password entry for %s",
148 			 user);
149 	}
150 
151 	return (ent->pw_uid);
152 }
153 
154 /*
155  * rm_shm() - removes a shared memory segment.
156  */
rm_shm(int shm_id)157 void rm_shm(int shm_id)
158 {
159 	if (shm_id == -1) {	/* no segment to remove */
160 		return;
161 	}
162 
163 	/*
164 	 * check for # of attaches ?
165 	 */
166 
167 	if (shmctl(shm_id, IPC_RMID, NULL) == -1) {
168 		tst_resm(TINFO, "WARNING: shared memory deletion failed.");
169 		tst_resm(TINFO, "This could lead to IPC resource problems.");
170 		tst_resm(TINFO, "id = %d", shm_id);
171 	}
172 }
173 
174 #define BUFSIZE 512
175 
176 /*
177  * Get the number of message queues already in use
178  */
get_used_msgqueues(void)179 int get_used_msgqueues(void)
180 {
181 	FILE *f;
182 	int used_queues;
183 	char buff[BUFSIZE];
184 
185 	f = popen("ipcs -q", "r");
186 	if (!f) {
187 		tst_brkm(TBROK | TERRNO, NULL, "pipe failed");
188 	}
189 	/* FIXME: Start at -4 because ipcs prints four lines of header */
190 	for (used_queues = -4; fgets(buff, BUFSIZE, f); used_queues++) ;
191 	pclose(f);
192 	if (used_queues < 0) {
193 		tst_brkm(TBROK, NULL, "Could not read output of 'ipcs' to "
194 			 "calculate used message queues");
195 	}
196 	return used_queues;
197 }
198 
199 /*
200  * Get the max number of message queues allowed on system
201  */
get_max_msgqueues(void)202 int get_max_msgqueues(void)
203 {
204 	FILE *f;
205 	char buff[BUFSIZE];
206 
207 	/* Get the max number of message queues allowed on system */
208 	f = fopen("/proc/sys/kernel/msgmni", "r");
209 	if (!f) {
210 		tst_resm(TBROK, "Could not open /proc/sys/kernel/msgmni");
211 		return -1;
212 	}
213 	if (!fgets(buff, BUFSIZE, f)) {
214 		fclose(f);
215 		tst_resm(TBROK, "Could not read /proc/sys/kernel/msgmni");
216 		return -1;
217 	}
218 	fclose(f);
219 	return atoi(buff);
220 }
221