@@ -25,53 +25,56 @@ use libc::{semctl, semget, shmctl, shmget, shmid_ds};
2525struct Args {
2626 #[ arg(
2727 short = 's' ,
28- long ,
29- help = gettext( "Remove the shared memory identifier semid from the system" )
28+ action = clap :: ArgAction :: Append ,
29+ help = gettext( "Remove the semaphore identifier semid from the system" )
3030 ) ]
31- semid : Option < i32 > ,
31+ semid : Vec < i32 > ,
3232
3333 #[ arg(
3434 short = 'S' ,
35- long ,
36- help = gettext( "Remove the shared memory identifier, created with key semkey, from the system" )
35+ action = clap :: ArgAction :: Append ,
36+ help = gettext( "Remove the semaphore identifier, created with key semkey, from the system" )
3737 ) ]
38- semkey : Option < i32 > ,
38+ semkey : Vec < i32 > ,
3939
4040 #[ arg(
4141 short = 'm' ,
42- long ,
42+ action = clap :: ArgAction :: Append ,
4343 help = gettext( "Remove the shared memory identifier shmid from the system" )
4444 ) ]
45- shmid : Option < i32 > ,
45+ shmid : Vec < i32 > ,
4646
4747 #[ arg(
4848 short = 'M' ,
49- long ,
49+ action = clap :: ArgAction :: Append ,
5050 help = gettext( "Remove the shared memory identifier, created with key shmkey, from the system" )
5151 ) ]
52- shmkey : Option < i32 > ,
52+ shmkey : Vec < i32 > ,
5353
5454 #[ cfg( not( target_os = "macos" ) ) ]
5555 #[ arg(
5656 short = 'q' ,
57- long ,
57+ action = clap :: ArgAction :: Append ,
5858 help = gettext( "Remove the message queue identifier msgid from the system" )
5959 ) ]
60- msgid : Option < i32 > ,
60+ msgid : Vec < i32 > ,
6161
6262 #[ cfg( not( target_os = "macos" ) ) ]
6363 #[ arg(
6464 short = 'Q' ,
65- long ,
65+ action = clap :: ArgAction :: Append ,
6666 help = gettext( "Remove the message queue identifier, created with key msgkey, from the system" )
6767 ) ]
68- msgkey : Option < i32 > ,
68+ msgkey : Vec < i32 > ,
6969}
7070
7171#[ cfg( not( target_os = "macos" ) ) ]
7272fn msg_key_lookup ( msgkey : i32 ) -> io:: Result < i32 > {
7373 if msgkey == libc:: IPC_PRIVATE {
74- return Err ( Error :: new ( ErrorKind :: Other , "Invalid key" ) ) ;
74+ return Err ( Error :: new (
75+ ErrorKind :: InvalidInput ,
76+ gettext ( "invalid key: IPC_PRIVATE" ) ,
77+ ) ) ;
7578 }
7679 let res: i32 = unsafe { msgget ( msgkey, 0 ) } ;
7780
@@ -83,7 +86,7 @@ fn msg_key_lookup(msgkey: i32) -> io::Result<i32> {
8386}
8487
8588#[ cfg( not( target_os = "macos" ) ) ]
86- fn msg_rm ( msgid : i32 ) -> io:: Result < i32 > {
89+ fn msg_rm ( msgid : i32 ) -> io:: Result < ( ) > {
8790 let res: i32 = unsafe {
8891 msgctl (
8992 msgid,
@@ -95,13 +98,16 @@ fn msg_rm(msgid: i32) -> io::Result<i32> {
9598 if res < 0 {
9699 Err ( io:: Error :: last_os_error ( ) )
97100 } else {
98- Ok ( res )
101+ Ok ( ( ) )
99102 }
100103}
101104
102105fn shm_key_lookup ( shmkey : i32 ) -> io:: Result < i32 > {
103106 if shmkey == libc:: IPC_PRIVATE {
104- return Err ( Error :: new ( ErrorKind :: Other , "Invalid key" ) ) ;
107+ return Err ( Error :: new (
108+ ErrorKind :: InvalidInput ,
109+ gettext ( "invalid key: IPC_PRIVATE" ) ,
110+ ) ) ;
105111 }
106112 let res: i32 = unsafe { shmget ( shmkey, 0 , 0 ) } ;
107113
@@ -112,7 +118,7 @@ fn shm_key_lookup(shmkey: i32) -> io::Result<i32> {
112118 }
113119}
114120
115- fn shm_rm ( shmid : i32 ) -> io:: Result < i32 > {
121+ fn shm_rm ( shmid : i32 ) -> io:: Result < ( ) > {
116122 let res: i32 = unsafe {
117123 shmctl (
118124 shmid,
@@ -124,13 +130,16 @@ fn shm_rm(shmid: i32) -> io::Result<i32> {
124130 if res < 0 {
125131 Err ( io:: Error :: last_os_error ( ) )
126132 } else {
127- Ok ( res )
133+ Ok ( ( ) )
128134 }
129135}
130136
131137fn sem_key_lookup ( semkey : i32 ) -> io:: Result < i32 > {
132138 if semkey == libc:: IPC_PRIVATE {
133- return Err ( Error :: new ( ErrorKind :: Other , "Invalid key" ) ) ;
139+ return Err ( Error :: new (
140+ ErrorKind :: InvalidInput ,
141+ gettext ( "invalid key: IPC_PRIVATE" ) ,
142+ ) ) ;
134143 }
135144 let res: i32 = unsafe { semget ( semkey, 0 , 0 ) } ;
136145
@@ -141,59 +150,121 @@ fn sem_key_lookup(semkey: i32) -> io::Result<i32> {
141150 }
142151}
143152
144- // Define the union semun as per your requirements
153+ // Define the union semun as per POSIX requirements
145154#[ repr( C ) ]
146155union semun {
147156 val : c_int , // for SETVAL
148157 buf : * mut libc:: semid_ds , // for IPC_STAT and IPC_SET
149158 array : * mut c_ushort , // for GETALL and SETALL
150- // Depending on your platform, you might need to add other fields as well
151159}
152160
153- fn sem_rm ( semid : i32 ) -> io:: Result < i32 > {
161+ fn sem_rm ( semid : i32 ) -> io:: Result < ( ) > {
154162 let arg = semun { val : 0 } ;
155163
156164 let res: i32 = unsafe { semctl ( semid, 0 , libc:: IPC_RMID , arg) } ;
157165
158166 if res < 0 {
159167 Err ( io:: Error :: last_os_error ( ) )
160168 } else {
161- Ok ( res )
169+ Ok ( ( ) )
162170 }
163171}
164172
165- fn remove_ipcs ( args : & Args ) -> io:: Result < ( ) > {
166- // remove semaphores
167- if let Some ( semkey) = args. semkey {
168- let semid = sem_key_lookup ( semkey) ?;
169- sem_rm ( semid) ?;
173+ fn remove_ipcs ( args : & Args ) -> i32 {
174+ let mut exit_code = 0 ;
175+
176+ // Remove semaphores by key
177+ for semkey in & args. semkey {
178+ match sem_key_lookup ( * semkey) {
179+ Ok ( semid) => {
180+ if let Err ( e) = sem_rm ( semid) {
181+ eprintln ! ( "ipcrm: {}: {}" , gettext( "semaphore key" ) , e) ;
182+ exit_code = 1 ;
183+ }
184+ }
185+ Err ( e) => {
186+ eprintln ! (
187+ "ipcrm: {}: 0x{:x}: {}" ,
188+ gettext( "semaphore key" ) ,
189+ * semkey,
190+ e
191+ ) ;
192+ exit_code = 1 ;
193+ }
194+ }
170195 }
171- if let Some ( semid) = args. semid {
172- sem_rm ( semid) ?;
196+
197+ // Remove semaphores by ID
198+ for semid in & args. semid {
199+ if let Err ( e) = sem_rm ( * semid) {
200+ eprintln ! ( "ipcrm: {}: {}: {}" , gettext( "semaphore id" ) , semid, e) ;
201+ exit_code = 1 ;
202+ }
173203 }
174204
175- // remove shared memory segments
176- if let Some ( shmkey) = args. shmkey {
177- let shmid = shm_key_lookup ( shmkey) ?;
178- shm_rm ( shmid) ?;
205+ // Remove shared memory segments by key
206+ for shmkey in & args. shmkey {
207+ match shm_key_lookup ( * shmkey) {
208+ Ok ( shmid) => {
209+ if let Err ( e) = shm_rm ( shmid) {
210+ eprintln ! ( "ipcrm: {}: {}" , gettext( "shared memory key" ) , e) ;
211+ exit_code = 1 ;
212+ }
213+ }
214+ Err ( e) => {
215+ eprintln ! (
216+ "ipcrm: {}: 0x{:x}: {}" ,
217+ gettext( "shared memory key" ) ,
218+ * shmkey,
219+ e
220+ ) ;
221+ exit_code = 1 ;
222+ }
223+ }
179224 }
180- if let Some ( shmid) = args. shmid {
181- shm_rm ( shmid) ?;
225+
226+ // Remove shared memory segments by ID
227+ for shmid in & args. shmid {
228+ if let Err ( e) = shm_rm ( * shmid) {
229+ eprintln ! ( "ipcrm: {}: {}: {}" , gettext( "shared memory id" ) , shmid, e) ;
230+ exit_code = 1 ;
231+ }
182232 }
183233
184- // remove message queues
234+ // Remove message queues (Linux only)
185235 #[ cfg( not( target_os = "macos" ) ) ]
186236 {
187- if let Some ( msgkey) = args. msgkey {
188- let msgid = msg_key_lookup ( msgkey) ?;
189- msg_rm ( msgid) ?;
237+ // Remove message queues by key
238+ for msgkey in & args. msgkey {
239+ match msg_key_lookup ( * msgkey) {
240+ Ok ( msgid) => {
241+ if let Err ( e) = msg_rm ( msgid) {
242+ eprintln ! ( "ipcrm: {}: {}" , gettext( "message queue key" ) , e) ;
243+ exit_code = 1 ;
244+ }
245+ }
246+ Err ( e) => {
247+ eprintln ! (
248+ "ipcrm: {}: 0x{:x}: {}" ,
249+ gettext( "message queue key" ) ,
250+ * msgkey,
251+ e
252+ ) ;
253+ exit_code = 1 ;
254+ }
255+ }
190256 }
191- if let Some ( msgid) = args. msgid {
192- msg_rm ( msgid) ?;
257+
258+ // Remove message queues by ID
259+ for msgid in & args. msgid {
260+ if let Err ( e) = msg_rm ( * msgid) {
261+ eprintln ! ( "ipcrm: {}: {}: {}" , gettext( "message queue id" ) , msgid, e) ;
262+ exit_code = 1 ;
263+ }
193264 }
194265 }
195266
196- Ok ( ( ) )
267+ exit_code
197268}
198269
199270fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
@@ -203,12 +274,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
203274
204275 let args = Args :: parse ( ) ;
205276
206- let mut exit_code = 0 ;
207-
208- if let Err ( e) = remove_ipcs ( & args) {
209- exit_code = 1 ;
210- eprintln ! ( "{}" , e) ;
211- }
277+ let exit_code = remove_ipcs ( & args) ;
212278
213279 std:: process:: exit ( exit_code)
214280}
0 commit comments