semtool.pp 4.7 KB

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