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