• 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 	if (sem_id == -1) {	/* no semaphore to remove */
126 		return;
127 	}
128 
129 	if (semctl(sem_id, 0, IPC_RMID) == -1) {
130 		tst_resm(TINFO, "WARNING: semaphore deletion failed.");
131 		tst_resm(TINFO, "This could lead to IPC resource problems.");
132 		tst_resm(TINFO, "id = %d", sem_id);
133 	}
134 }
135 
136 /*
137  * getuserid() - return the integer value for the "user" id
138  */
getuserid(char * user)139 int getuserid(char *user)
140 {
141 	struct passwd *ent;
142 
143 	/* get the uid value for the user */
144 	if ((ent = getpwnam(user)) == NULL) {
145 		tst_brkm(TBROK, cleanup, "Couldn't get password entry for %s",
146 			 user);
147 	}
148 
149 	return (ent->pw_uid);
150 }
151 
152 /*
153  * rm_shm() - removes a shared memory segment.
154  */
rm_shm(int shm_id)155 void rm_shm(int shm_id)
156 {
157 	if (shm_id == -1) {	/* no segment to remove */
158 		return;
159 	}
160 
161 	/*
162 	 * check for # of attaches ?
163 	 */
164 
165 	if (shmctl(shm_id, IPC_RMID, NULL) == -1) {
166 		tst_resm(TINFO, "WARNING: shared memory deletion failed.");
167 		tst_resm(TINFO, "This could lead to IPC resource problems.");
168 		tst_resm(TINFO, "id = %d", shm_id);
169 	}
170 }
171 
172 #define BUFSIZE 512
173 
174 /*
175  * Get the number of message queues already in use
176  */
get_used_msgqueues(void)177 int get_used_msgqueues(void)
178 {
179 	FILE *f;
180 	int used_queues;
181 	char buff[BUFSIZE];
182 
183 	f = popen("ipcs -q", "r");
184 	if (!f) {
185 		tst_brkm(TBROK | TERRNO, NULL, "pipe failed");
186 	}
187 	/* FIXME: Start at -4 because ipcs prints four lines of header */
188 	for (used_queues = -4; fgets(buff, BUFSIZE, f); used_queues++) ;
189 	pclose(f);
190 	if (used_queues < 0) {
191 		tst_brkm(TBROK, NULL, "Could not read output of 'ipcs' to "
192 			 "calculate used message queues");
193 	}
194 	return used_queues;
195 }
196 
197 /*
198  * Get the max number of message queues allowed on system
199  */
get_max_msgqueues(void)200 int get_max_msgqueues(void)
201 {
202 	FILE *f;
203 	char buff[BUFSIZE];
204 
205 	/* Get the max number of message queues allowed on system */
206 	f = fopen("/proc/sys/kernel/msgmni", "r");
207 	if (!f) {
208 		tst_resm(TBROK, "Could not open /proc/sys/kernel/msgmni");
209 		return -1;
210 	}
211 	if (!fgets(buff, BUFSIZE, f)) {
212 		fclose(f);
213 		tst_resm(TBROK, "Could not read /proc/sys/kernel/msgmni");
214 		return -1;
215 	}
216 	fclose(f);
217 	return atoi(buff);
218 }
219