123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- Program semtool;
- { Program to demonstrat the use of semaphores }
- Uses ipc;
- Const MaxSemValue = 5;
- Procedure DoError (Const Msg : String);
- begin
- Writeln ('Error : ',msg,' Code : ',IPCerror);
- Halt(1);
- end;
- Function getsemval (ID,Member : longint) : longint;
- Var S : TSEMun;
- begin
- GetSemVal:=SemCtl(id,member,GETVAL,S);
- end;
- Procedure DispVal (ID,member : longint);
- begin
- writeln ('Value for member ',member,' is ',GetSemVal(ID,Member));
- end;
- Function GetMemberCount (ID : Longint) : longint;
- Var opts : TSEMun;
- semds : TSEMid_ds;
- begin
- opts.buf:=@semds;
- If semctl(Id,0,IPC_STAT,opts)<>-1 then
- GetMemberCount:=semds.sem_nsems
- else
- GetMemberCount:=-1;
- end;
- Function OpenSem (Key : TKey) : Longint;
- begin
- OpenSem:=semget(Key,0,438);
- If OpenSem=-1 then
- DoError ('OpenSem');
- end;
- Function CreateSem (Key : TKey; Members : Longint) : Longint;
- Var Count : Longint;
- Semopts : TSemun;
-
- begin
- If members>semmsl then
- DoError ('Sorry, maximum number of semaphores in set exceeded');
- Writeln ('Trying to create a new semaphore set with ',members,' members.');
- CreateSem:=semget(key,members,IPC_CREAT or IPC_Excl or 438);
- If CreateSem=-1 then
- DoError ('Semaphore set already exists.');
- Semopts.val:=MaxSemValue; { Initial value of semaphores }
- For Count:=0 to Members-1 do
- semctl(CreateSem,count,setval,semopts);
- end;
- Procedure lockSem (ID,Member: Longint);
- Var lock : TSEMbuf;
- begin
- With lock do
- begin
- sem_num:=0;
- sem_op:=-1;
- sem_flg:=IPC_NOWAIT;
- end;
- if (member<0) or (member>GetMemberCount(ID)-1) then
- DoError ('semaphore member out of range');
- if getsemval(ID,member)=0 then
- DoError ('Semaphore resources exhausted (no lock)');
- lock.sem_num:=member;
- Writeln ('Attempting to lock member ',member, ' of semaphore ',ID);
- if not semop(Id,@lock,1) then
- DoError ('Lock failed')
- else
- Writeln ('Semaphore resources decremented by one');
- dispval(ID,Member);
- end;
- Procedure UnlockSem (ID,Member: Longint);
- Var Unlock : TSEMbuf;
- begin
- With Unlock do
- begin
- sem_num:=0;
- sem_op:=1;
- sem_flg:=IPC_NOWAIT;
- end;
- if (member<0) or (member>GetMemberCount(ID)-1) then
- DoError ('semaphore member out of range');
- if getsemval(ID,member)=MaxSemValue then
- DoError ('Semaphore not locked');
- Unlock.sem_num:=member;
- Writeln ('Attempting to unlock member ',member, ' of semaphore ',ID);
- if not semop(Id,@unlock,1) then
- DoError ('Unlock failed')
- else
- Writeln ('Semaphore resources incremented by one');
- dispval(ID,Member);
- end;
- Procedure RemoveSem (ID : longint);
- var S : TSemun;
- begin
- If semctl(Id,0,IPC_RMID,s)<>-1 then
- Writeln ('Semaphore removed')
- else
- DoError ('Couldn''t remove semaphore');
- end;
- Procedure ChangeMode (ID,Mode : longint);
- Var rc : longint;
- opts : TSEMun;
- semds : TSEMid_ds;
-
- begin
- opts.buf:=@semds;
- If not semctl (Id,0,IPC_STAT,opts)<>-1 then
- DoError ('Couldn''t stat semaphore');
- Writeln ('Old permissions were : ',semds.sem_perm.mode);
- semds.sem_perm.mode:=mode;
- If semctl(id,0,IPC_SET,opts)<>-1 then
- Writeln ('Set permissions to ',mode)
- else
- DoError ('Couldn''t set permissions');
- end;
- Procedure PrintSem (ID : longint);
- Var I,cnt : longint;
- begin
- cnt:=getmembercount(ID);
- Writeln ('Semaphore ',ID,' has ',cnt,' Members');
- For I:=0 to cnt-1 Do
- DispVal(id,i);
- end;
- Procedure USage;
- begin
- Writeln ('Usage : semtool c(reate) <count>');
- Writeln (' l(ock) <member>');
- Writeln (' u(nlock) <member>');
- Writeln (' d(elete)');
- Writeln (' m(ode) <mode>');
- halt(1);
- end;
- Function StrToInt (S : String): longint;
- Var M : longint;
- C : Integer;
- begin
- val (S,M,C);
- If C<>0 Then DoError ('StrToInt : '+S);
- StrToInt:=M;
- end;
- Var Key : TKey;
- ID : Longint;
- begin
- If ParamCount<1 then USage;
- key:=ftok('.','s');
- Case UpCase(Paramstr(1)[1]) of
- 'C' : begin
- if paramcount<>2 then usage;
- CreateSem (key,strtoint(paramstr(2)));
- end;
- 'L' : begin
- if paramcount<>2 then usage;
- ID:=OpenSem (key);
- LockSem (ID,strtoint(paramstr(2)));
- end;
- 'U' : begin
- if paramcount<>2 then usage;
- ID:=OpenSem (key);
- UnLockSem (ID,strtoint(paramstr(2)));
- end;
- 'M' : begin
- if paramcount<>2 then usage;
- ID:=OpenSem (key);
- ChangeMode (ID,strtoint(paramstr(2)));
- end;
- 'D' : Begin
- ID:=OpenSem(Key);
- RemoveSem(Id);
- end;
- 'P' : begin
- ID:=OpenSem(Key);
- PrintSem(Id);
- end;
- else
- Usage
- end;
- end.
|