This commit was generated by cvs2svn to track changes on a CVS vendor
[unix-history] / usr.bin / ipcs / ipcs.c
CommitLineData
24fd64ab
DG
1/*
2 * Simplified implementation of SYSV ipcs.
3 */
4
5#include <nlist.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <unistd.h>
9#include <paths.h>
10
11#include <sys/types.h>
12#include <sys/param.h>
13#include <sys/proc.h>
14#define KERNEL
15#include <sys/ipc.h>
16#include <sys/sem.h>
17#include <sys/shm.h>
18#include <sys/msg.h>
19
20static kmem_fd;
21
22getsymbol(struct nlist *symbols, char *symname, void *dptr, int len)
23{
24 int i, rlen;
25
26 for ( i = 0; symbols[i].n_name != NULL; i += 1 ) {
27 if ( strcmp(symbols[i].n_name,symname) == 0 ) {
28 break;
29 }
30 }
31
32 if ( symbols[i].n_name == NULL ) {
33 fprintf(stderr,"ipcs(getsymbol): symbol %s not in local symbols list\n",
34 symname);
35 exit(1);
36 }
37
38 if ( symbols[i].n_value == NULL ) {
39 fprintf(stderr,"ipcs(getsymbol): symbol %s not in %s\n",
40 symname,_PATH_UNIX);
41 return(0);
42 }
43
44 if ( kmem_fd == 0 ) {
45 kmem_fd = open("/dev/kmem",0);
46 if ( kmem_fd < 0 ) {
47 perror("ipcs(getsymbol(open /dev/kmem))");
48 exit(1);
49 }
50 }
51
52 lseek(kmem_fd,symbols[i].n_value,SEEK_SET);
53 if ( (rlen = read(kmem_fd,dptr,len)) != len ) {
54 fprintf(stderr,"ipcs(getsymbol): can't fetch symbol %s from /dev/kmem\n",symname);
55 exit(1);
56 }
57 return(1);
58}
59
60void
61getlocation(void *addr, void *dptr, int len)
62{
63 int i, rlen;
64
65 if ( kmem_fd == 0 ) {
66 kmem_fd = open("/dev/kmem",0);
67 if ( kmem_fd < 0 ) {
68 perror("ipcs(getlocation(open /dev/kmem))");
69 exit(1);
70 }
71 }
72
73 lseek(kmem_fd,(long)addr,SEEK_SET);
74 if ( (rlen = read(kmem_fd,dptr,len)) != len ) {
75 fprintf(stderr,"ipcs(getlocation): can't fetch location %08x from /dev/kmem\n",addr);
76 exit(1);
77 }
78}
79
80char *
81fmt_perm(ushort mode)
82{
83 static char buffer[100];
84
85 buffer[0] = '-';
86 buffer[1] = '-';
87 buffer[2] = ((mode & 0400) ? 'r' : '-');
88 buffer[3] = ((mode & 0200) ? 'w' : '-');
89 buffer[4] = ((mode & 0100) ? 'a' : '-');
90 buffer[5] = ((mode & 0040) ? 'r' : '-');
91 buffer[6] = ((mode & 0020) ? 'w' : '-');
92 buffer[7] = ((mode & 0010) ? 'a' : '-');
93 buffer[8] = ((mode & 0004) ? 'r' : '-');
94 buffer[9] = ((mode & 0002) ? 'w' : '-');
95 buffer[10] = ((mode & 0001) ? 'a' : '-');
96 buffer[11] = '\0';
97 return(&buffer[0]);
98}
99
100void
101cvt_time(time_t t,char *buf)
102{
103 struct tm tms;
104 static char *months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
105 if ( t == 0 ) {
106 strcpy(buf,"<not set>");
107 } else {
108 tms = *localtime(&t);
109 if ( t > time(0) - 6 * 30 * 24 * 3600 ) { /* less than about 6 months ago? */
110 sprintf(buf,"%s %2d %2d:%2d",
111 months[tms.tm_mon],tms.tm_mday,tms.tm_hour,tms.tm_min);
112 } else {
113 sprintf(buf,"%s %2d %5d",
114 months[tms.tm_mon],tms.tm_mday,tms.tm_year+1900);
115 }
116 }
117}
118
119main()
120{
121 static struct nlist symbols[] = {
122 { "_sema" },
123 { "_seminfo" },
124 { "_semu" },
125 { "_msginfo" },
126 { "_msqids" },
127 { NULL }
128 };
129 int i;
130 int show_sem_values = 1;
131 int show_undo_values = 1;
132
133 switch ( nlist(_PATH_UNIX,&symbols[0]) ) {
134 case 0: break;
135 case -1:
136 fprintf(stderr,"ipcs: can't open %s - bye!\n",_PATH_UNIX);
137 exit(1);
138 default:
139 fprintf(stderr,"ipcs: nlist failed\n");
140 for ( i = 0; symbols[i].n_name != NULL; i += 1 ) {
141 if ( symbols[i].n_value == 0 ) {
142 fprintf(stderr,"\tsymbol %s not found\n",symbols[i].n_name);
143 }
144 }
145 break;
146 }
147
148 /*
149 for ( i = 0; symbols[i].n_name != NULL; i += 1 ) {
150 fprintf(stderr,"\t%s : %08x\n",symbols[i].n_name,symbols[i].n_value);
151 }
152 */
153
154 if ( getsymbol(symbols,"_seminfo",&seminfo,sizeof(seminfo)) ) {
155 struct semid_ds *xsema;
156
157 printf("seminfo:\n");
158 printf("\tsemmap: %6d\t(# of entries in semaphore map)\n",seminfo.semmap);
159 printf("\tsemmni: %6d\t(# of semaphore identifiers)\n",seminfo.semmni);
160 printf("\tsemmns: %6d\t(# of semaphores in system)\n",seminfo.semmns);
161 printf("\tsemmnu: %6d\t(# of undo structures in system)\n",seminfo.semmnu);
162 printf("\tsemmsl: %6d\t(max # of semaphores per id)\n",seminfo.semmsl);
163 printf("\tsemopm: %6d\t(max # of operations per semop call)\n",seminfo.semopm);
164 printf("\tsemume: %6d\t(max # of undo entries per process)\n",seminfo.semume);
165 printf("\tsemusz: %6d\t(size in bytes of undo structure)\n",seminfo.semusz);
166 printf("\tsemvmx: %6d\t(semaphore maximum value)\n",seminfo.semvmx);
167 printf("\tsemaem: %6d\t(adjust on exit max value)\n",seminfo.semaem);
168
169 /*
170 * Lock out other users of the semaphore facility
171 */
172
173 if ( semconfig(SEM_CONFIG_FREEZE) != 0 ) {
174 perror("semconfig");
175 fprintf(stderr,"Can't lock semaphore facility - winging it...\n");
176 }
177
178 getsymbol(symbols,"_sema",&sema,sizeof(sema));
179 xsema = malloc(sizeof(struct semid_ds) * seminfo.semmni);
180 getlocation(sema,xsema,sizeof(struct semid_ds) * seminfo.semmni);
181
182 for ( i = 0; i < seminfo.semmni; i += 1 ) {
183 if ( (xsema[i].sem_perm.mode & SEM_ALLOC) != 0 ) {
184 char ctime_buf[100], otime_buf[100];
185 struct semid_ds *semaptr = &xsema[i];
186 cvt_time(semaptr->sem_ctime,ctime_buf);
187 cvt_time(semaptr->sem_otime,otime_buf);
188
189 printf("\nsema id: %d key: 0x%08x:\n",
190 IXSEQ_TO_IPCID(i,semaptr->sem_perm),
191 semaptr->sem_perm.key);
192
193 printf(" cuid: %6d cgid: %6d ctime: %s\n",
194 semaptr->sem_perm.cuid,semaptr->sem_perm.cgid,ctime_buf);
195
196 printf(" uid: %6d gid: %6d otime: %s\n",
197 semaptr->sem_perm.uid,semaptr->sem_perm.gid,otime_buf);
198
199 printf(" nsems: %6d perm: %s\n",
200 semaptr->sem_nsems,fmt_perm(semaptr->sem_perm.mode));
201
202 if ( show_sem_values ) {
203 int j, value;
204 union semun junk;
205 for ( j = 0; j < semaptr->sem_nsems; j += 1 ) {
206 if ( (value = semctl( IXSEQ_TO_IPCID(i,semaptr->sem_perm), j, GETVAL, junk )) < 0 ) {
207 printf("can't get semaphore values\n");
208 break;
209 }
210 if ( j % 5 == 0 ) {
211 if ( j == 0 ) {
212 printf(" values: {");
213 } else {
214 printf("\n");
215 printf(" ");
216 }
217 }
218 printf(" %d",value);
219 if ( j == semaptr->sem_nsems - 1 ) {
220 printf(" }\n");
221 } else {
222 printf(", ");
223 }
224 }
225 }
226
227 }
228
229 }
230
231 if ( show_undo_values ) {
232 int j;
233 int *ksemu, *semu;
234 int semu_size;
235 int got_one_undo = 0;
236
237 semu = 0;
238 semu_size = (int)SEMU(seminfo.semmnu);
239 semu = (int *)malloc( semu_size );
240 getsymbol(symbols,"_semu",&ksemu,sizeof(ksemu));
241 getlocation(ksemu,semu,semu_size);
242
243 printf("\nsem undos:\n");
244 for ( j = 0; j < seminfo.semmnu; j += 1 ) {
245 struct sem_undo *suptr;
246 int k;
247
248 suptr = SEMU(j);
249 if ( suptr->un_proc != NULL ) {
250 struct proc proc;
251 getlocation(suptr->un_proc,&proc,sizeof(proc));
252 got_one_undo = 1;
253 printf(" pid %d: semid semnum adjval\n",proc.p_pid);
254 for ( k = 0; k < suptr->un_cnt; k += 1 ) {
255 printf(" %10d %5d %6d\n",
256 IXSEQ_TO_IPCID(suptr->un_ent[k].un_id,xsema[suptr->un_ent[k].un_id].sem_perm),
257 suptr->un_ent[k].un_num,
258 suptr->un_ent[k].un_adjval);
259 }
260 }
261 }
262 if ( !got_one_undo ) {
263 printf(" none allocated\n");
264 }
265 }
266
267 (void)semconfig(SEM_CONFIG_THAW);
268
269 } else {
270 fprintf(stderr,"SVID semaphores facility not configured in the system\n");
271 }
272
273 if ( getsymbol(symbols,"_msginfo",&msginfo,sizeof(msginfo)) ) {
274 struct msqid_ds *xmsqids;
275
276 printf("\nmsginfo:\n");
277 printf("\tmsgmax: %6d\t(max characters in a message)\n",msginfo.msgmax);
278 printf("\tmsgmni: %6d\t(# of message queues)\n",msginfo.msgmni);
279 printf("\tmsgmnb: %6d\t(max characters in a message queue)\n",msginfo.msgmnb);
280 printf("\tmsgtql: %6d\t(max # of messages in system)\n",msginfo.msgtql);
281 printf("\tmsgssz: %6d\t(size of a message segment)\n",msginfo.msgssz);
282 printf("\tmsgseg: %6d\t(# of message segments in system)\n",msginfo.msgseg);
283
284 getsymbol(symbols,"_msqids",&msqids,sizeof(msqids));
285 xmsqids = malloc(sizeof(struct msqid_ds) * msginfo.msgmni);
286 getlocation(msqids,xmsqids,sizeof(struct msqid_ds) * msginfo.msgmni);
287
288 for ( i = 0; i < msginfo.msgmni; i += 1 ) {
289 if ( xmsqids[i].msg_qbytes != 0 ) {
290 char stime_buf[100], rtime_buf[100], ctime_buf[100];
291 struct msqid_ds *msqptr = &xmsqids[i];
292
293 cvt_time(msqptr->msg_stime,stime_buf);
294 cvt_time(msqptr->msg_rtime,rtime_buf);
295 cvt_time(msqptr->msg_ctime,ctime_buf);
296
297 printf("\nmsgq id: %d key: 0x%08x\n",
298 IXSEQ_TO_IPCID(i,msqptr->msg_perm),
299 msqptr->msg_perm.key);
300
301 printf(" cuid: %6d cgid: %6d ctime: %s\n",
302 msqptr->msg_perm.cuid,msqptr->msg_perm.cgid,ctime_buf);
303
304 printf(" uid: %6d gid: %6d\n",
305 msqptr->msg_perm.uid,msqptr->msg_perm.gid);
306
307 printf(" lspid: %6d stime: %s\n",
308 msqptr->msg_lspid,stime_buf);
309
310 printf(" lrpid: %6d qnum: %6d rtime: %s\n",
311 msqptr->msg_lrpid,msqptr->msg_qnum,rtime_buf);
312
313 printf(" cbytes:%6d qbytes:%6d perm: %s\n",
314 msqptr->msg_cbytes,msqptr->msg_qbytes,fmt_perm(msqptr->msg_perm.mode));
315
316 }
317 }
318
319 } else {
320 fprintf(stderr,"SVID messages facility not configured in the system\n");
321 }
322
323 exit(0);
324}