2
0

semtool.pp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. Program semtool;
  2. { Program to demonstrat the use of semaphores }
  3. Uses ipc;
  4. Const MaxSemValue = 5;
  5. Procedure DoError (Const Msg : String);
  6. begin
  7. Writeln ('Error : ',msg,' Code : ',IPCerror);
  8. Halt(1);
  9. end;
  10. Function getsemval (ID,Member : longint) : longint;
  11. Var S : TSEMun;
  12. begin
  13. GetSemVal:=SemCtl(id,member,GETVAL,S);
  14. end;
  15. Procedure DispVal (ID,member : longint);
  16. begin
  17. writeln ('Value for member ',member,' is ',GetSemVal(ID,Member));
  18. end;
  19. Function GetMemberCount (ID : Longint) : longint;
  20. Var opts : TSEMun;
  21. semds : TSEMid_ds;
  22. begin
  23. opts.buf:=@semds;
  24. If semctl(Id,0,IPC_STAT,opts)<>-1 then
  25. GetMemberCount:=semds.sem_nsems
  26. else
  27. GetMemberCount:=-1;
  28. end;
  29. Function OpenSem (Key : TKey) : Longint;
  30. begin
  31. OpenSem:=semget(Key,0,438);
  32. If OpenSem=-1 then
  33. DoError ('OpenSem');
  34. end;
  35. Function CreateSem (Key : TKey; Members : Longint) : Longint;
  36. Var Count : Longint;
  37. Semopts : TSemun;
  38. begin
  39. If members>semmsl then
  40. DoError ('Sorry, maximum number of semaphores in set exceeded');
  41. Writeln ('Trying to create a new semaphore set with ',members,' members.');
  42. CreateSem:=semget(key,members,IPC_CREAT or IPC_Excl or 438);
  43. If CreateSem=-1 then
  44. DoError ('Semaphore set already exists.');
  45. Semopts.val:=MaxSemValue; { Initial value of semaphores }
  46. For Count:=0 to Members-1 do
  47. semctl(CreateSem,count,setval,semopts);
  48. end;
  49. Procedure lockSem (ID,Member: Longint);
  50. Var lock : TSEMbuf;
  51. begin
  52. With lock do
  53. begin
  54. sem_num:=0;
  55. sem_op:=-1;
  56. sem_flg:=IPC_NOWAIT;
  57. end;
  58. if (member<0) or (member>GetMemberCount(ID)-1) then
  59. DoError ('semaphore member out of range');
  60. if getsemval(ID,member)=0 then
  61. DoError ('Semaphore resources exhausted (no lock)');
  62. lock.sem_num:=member;
  63. Writeln ('Attempting to lock member ',member, ' of semaphore ',ID);
  64. if not semop(Id,@lock,1) then
  65. DoError ('Lock failed')
  66. else
  67. Writeln ('Semaphore resources decremented by one');
  68. dispval(ID,Member);
  69. end;
  70. Procedure UnlockSem (ID,Member: Longint);
  71. Var Unlock : TSEMbuf;
  72. begin
  73. With Unlock do
  74. begin
  75. sem_num:=0;
  76. sem_op:=1;
  77. sem_flg:=IPC_NOWAIT;
  78. end;
  79. if (member<0) or (member>GetMemberCount(ID)-1) then
  80. DoError ('semaphore member out of range');
  81. if getsemval(ID,member)=MaxSemValue then
  82. DoError ('Semaphore not locked');
  83. Unlock.sem_num:=member;
  84. Writeln ('Attempting to unlock member ',member, ' of semaphore ',ID);
  85. if not semop(Id,@unlock,1) then
  86. DoError ('Unlock failed')
  87. else
  88. Writeln ('Semaphore resources incremented by one');
  89. dispval(ID,Member);
  90. end;
  91. Procedure RemoveSem (ID : longint);
  92. var S : TSemun;
  93. begin
  94. If semctl(Id,0,IPC_RMID,s)<>-1 then
  95. Writeln ('Semaphore removed')
  96. else
  97. DoError ('Couldn''t remove semaphore');
  98. end;
  99. Procedure ChangeMode (ID,Mode : longint);
  100. Var rc : longint;
  101. opts : TSEMun;
  102. semds : TSEMid_ds;
  103. begin
  104. opts.buf:=@semds;
  105. If not semctl (Id,0,IPC_STAT,opts)<>-1 then
  106. DoError ('Couldn''t stat semaphore');
  107. Writeln ('Old permissions were : ',semds.sem_perm.mode);
  108. semds.sem_perm.mode:=mode;
  109. If semctl(id,0,IPC_SET,opts)<>-1 then
  110. Writeln ('Set permissions to ',mode)
  111. else
  112. DoError ('Couldn''t set permissions');
  113. end;
  114. Procedure PrintSem (ID : longint);
  115. Var I,cnt : longint;
  116. begin
  117. cnt:=getmembercount(ID);
  118. Writeln ('Semaphore ',ID,' has ',cnt,' Members');
  119. For I:=0 to cnt-1 Do
  120. DispVal(id,i);
  121. end;
  122. Procedure USage;
  123. begin
  124. Writeln ('Usage : semtool c(reate) <count>');
  125. Writeln (' l(ock) <member>');
  126. Writeln (' u(nlock) <member>');
  127. Writeln (' d(elete)');
  128. Writeln (' m(ode) <mode>');
  129. halt(1);
  130. end;
  131. Function StrToInt (S : String): longint;
  132. Var M : longint;
  133. C : Integer;
  134. begin
  135. val (S,M,C);
  136. If C<>0 Then DoError ('StrToInt : '+S);
  137. StrToInt:=M;
  138. end;
  139. Var Key : TKey;
  140. ID : Longint;
  141. begin
  142. If ParamCount<1 then USage;
  143. key:=ftok('.','s');
  144. Case UpCase(Paramstr(1)[1]) of
  145. 'C' : begin
  146. if paramcount<>2 then usage;
  147. CreateSem (key,strtoint(paramstr(2)));
  148. end;
  149. 'L' : begin
  150. if paramcount<>2 then usage;
  151. ID:=OpenSem (key);
  152. LockSem (ID,strtoint(paramstr(2)));
  153. end;
  154. 'U' : begin
  155. if paramcount<>2 then usage;
  156. ID:=OpenSem (key);
  157. UnLockSem (ID,strtoint(paramstr(2)));
  158. end;
  159. 'M' : begin
  160. if paramcount<>2 then usage;
  161. ID:=OpenSem (key);
  162. ChangeMode (ID,strtoint(paramstr(2)));
  163. end;
  164. 'D' : Begin
  165. ID:=OpenSem(Key);
  166. RemoveSem(Id);
  167. end;
  168. 'P' : begin
  169. ID:=OpenSem(Key);
  170. PrintSem(Id);
  171. end;
  172. else
  173. Usage
  174. end;
  175. end.