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