Skip to content

Commit 00e92fe

Browse files
authored
Merge pull request #430 from rustcoreutils/updates
[ipcs, ipcrm] lots of review fixes, add tests
2 parents de6efb5 + 956b07c commit 00e92fe

File tree

5 files changed

+896
-211
lines changed

5 files changed

+896
-211
lines changed

sys/ipcrm.rs

Lines changed: 117 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -25,53 +25,56 @@ use libc::{semctl, semget, shmctl, shmget, shmid_ds};
2525
struct 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"))]
7272
fn 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

102105
fn 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

131137
fn 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)]
146155
union 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

199270
fn 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

Comments
 (0)