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