📄 semtool.c
字号:
#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#define SEM_RESOURCE_MAX 1#if defined(__GNU_LIBRARY__) && !defined(__SEM_SEMUN_UNDEFINED)/* union semun is defined by includeing <sys/sem.h>#else/* according to X/OPEN we have to define it ourselves */union semun { int val; struct semid_ds *buf; unsigned short int *array; struct seminfo *__buf;};#endifvoid opensem(int *sid,key_t key);void createsem(int *sid,key_t key,int members);void locksem(int sid,int member);void unlocksem(int sid,int member);void removesem(int sid);unsigned short get_member_count(int sid);int getval(int sid,int member);void dispval(int sid,int member);void changemode(int sid,char *mode);void usage();int main(int argc,char *argv[]){ key_t key; int semset_id; if (argc==1) usage(); key=ftok(".",'s'); switch (tolower(argv[1][0])) { case 'c': if (argc!=3) usage(); createsem(&semset_id,key,atoi(argv[2])); break; case 'l': if (argc!=3) usage(); opensem(&semset_id,key); locksem(semset_id,atoi(argv[2])); break; case 'u': if (argc!=3) usage(); opensem(&semset_id,key); unlocksem(semset_id,atoi(argv[2])); break; case 'd': opensem(&semset_id,key); removesem(semset_id); break; case 'm': opensem(&semset_id,key); changemode(semset_id,argv[2]); break; default: usage(); } return 0;}void opensem(int *sid,key_t key){ if ((*sid=semget(key,0,0666))==-1) { printf("Semaphore set does not exist\n"); exit(1); }}void createsem(int *sid,key_t key,int members){ int cntr; union semun semopts; printf("Attempting to create new semaphore set with %d members\n",members); if ((*sid=semget(key,members,IPC_CREAT|IPC_EXCL|0666))==-1) { fprintf(stderr,"Semaphore set already exists!\n"); exit(1); } semopts.val=SEM_RESOURCE_MAX; for (cntr=0;cntr<members;cntr++) semctl(*sid,cntr,SETVAL,semopts);}void locksem(int sid,int member){ struct sembuf sem_lock={0,-1,IPC_NOWAIT}; printf("get member count %d\n",get_member_count(sid)); if (member<0 || member>(get_member_count(sid)-1)) { fprintf(stderr,"semaphore member %d out of range\n",member); return; } if (!getval(sid,member)) { fprintf(stderr,"Semaphore resources exhausted (no lock)!\n"); exit(1); } sem_lock.sem_num=member; if ((semop(sid,&sem_lock,1))==-1) { fprintf(stderr,"Lock failed\n"); exit(1); } else printf("Semaphore resources decremented by one (locked)\n"); dispval(sid,member);}void unlocksem(int sid,int member){ struct sembuf sem_unlock={member,1,IPC_NOWAIT}; int semval; if (member<0 || member>(get_member_count(sid)-1)) { fprintf(stderr,"semaphore member %d out of range\n",member); return; } semval=getval(sid,member); if (semval==SEM_RESOURCE_MAX) { fprintf(stderr,"Semaphore not locked!\n"); exit(1); } sem_unlock.sem_num=member; if ((semop(sid,&sem_unlock,1))==-1) { fprintf(stderr,"Unlock failed\n"); exit(1); } else printf("Semaphore resources incremented by one (unlocked)\n"); dispval(sid,member);}void removesem(int sid){ semctl(sid,0,IPC_RMID,0); printf("Semaphore removed\n");}unsigned short get_member_count(int sid){ union semun semopts; struct semid_ds mysem_ds; semopts.buf=&mysem_ds; semctl(sid,0,IPC_STAT,semopts); return (semopts.buf->sem_nsems);}int getval(int sid,int member){ int semval; semval=semctl(sid,member,GETVAL,0); return semval;}void changemode(int sid,char *mode){ int rc; union semun semopts; struct semid_ds mysem_ds; semopts.buf=&mysem_ds; rc=semctl(sid,0,IPC_STAT,semopts); if (rc==-1) { perror("semctl"); exit(1); } printf("Old permissions were %o\n",semopts.buf->sem_perm.mode); sscanf(mode,"%ho",&semopts.buf->sem_perm.mode); semctl(sid,0,IPC_SET,semopts); printf("Updated...\n");}void dispval(int sid,int member){ int semval; semval=semctl(sid,member,GETVAL,0); printf("semval for member %d is %d\n",member,semval);}void usage(){ fprintf(stderr,"semtool-A utility for tinkering with semaphores\n"); fprintf(stderr,"Usage: semtool (c)reate <semcount>\n"); fprintf(stderr," (l)ock <sem #>\n"); fprintf(stderr," (u)nlock <sem #>\n"); fprintf(stderr," (d)elete\n"); fprintf(stderr," (m)ode <mode>\n"); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -