Skip to content

Commit 94bc512

Browse files
committed
pinky: fix panic when outputting to /dev/full (#10562)
- fixes panic by replacing all println with writeln
1 parent 52e1bc1 commit 94bc512

2 files changed

Lines changed: 63 additions & 38 deletions

File tree

src/uu/pinky/src/platform/openbsd.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ use uucore::translate;
1010

1111
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
1212
let _matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?;
13-
println!("{}", translate!("pinky-unsupported-openbsd"));
13+
writeln!(
14+
stdout().lock(),
15+
"{}",
16+
translate!("pinky-unsupported-openbsd")
17+
)?;
1418
Ok(())
1519
}

src/uu/pinky/src/platform/unix.rs

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use uucore::utmpx::{self, Utmpx, UtmpxRecord, time};
1717

1818
use std::io::BufReader;
1919
use std::io::prelude::*;
20+
use std::io::stdout;
2021

2122
use std::fs::File;
2223
use std::os::unix::fs::MetadataExt;
@@ -96,9 +97,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
9697
};
9798

9899
if do_short_format {
99-
pk.short_pinky();
100+
pk.short_pinky()?;
100101
} else {
101-
pk.long_pinky();
102+
pk.long_pinky()?;
102103
}
103104
Ok(())
104105
}
@@ -167,7 +168,7 @@ fn gecos_to_fullname(pw: &Passwd) -> Option<String> {
167168
}
168169

169170
impl Pinky {
170-
fn print_entry(&self, ut: &UtmpxRecord) {
171+
fn print_entry(&self, ut: &UtmpxRecord) -> UResult<()> {
171172
let mut pts_path = PathBuf::from("/dev");
172173
pts_path.push(ut.tty_device().as_str());
173174

@@ -187,7 +188,7 @@ impl Pinky {
187188
last_change = 0;
188189
}
189190

190-
print!("{1:<8.0$}", utmpx::UT_NAMESIZE, ut.user());
191+
write!(stdout().lock(), "{1:<8.0$}", utmpx::UT_NAMESIZE, ut.user())?;
191192

192193
if self.include_fullname {
193194
let fullname = if let Ok(pw) = Passwd::locate(ut.user().as_ref()) {
@@ -196,23 +197,28 @@ impl Pinky {
196197
None
197198
};
198199
if let Some(fullname) = fullname {
199-
print!(" {fullname:<19.19}");
200+
write!(stdout().lock(), " {fullname:<19.19}")?;
200201
} else {
201-
print!(" {:19}", " ???");
202+
write!(stdout().lock(), " {:19}", " ???")?;
202203
}
203204
}
204205

205-
print!(" {mesg}{:<8.*}", utmpx::UT_LINESIZE, ut.tty_device());
206+
write!(
207+
stdout().lock(),
208+
" {mesg}{:<8.*}",
209+
utmpx::UT_LINESIZE,
210+
ut.tty_device()
211+
)?;
206212

207213
if self.include_idle {
208214
if last_change == 0 {
209-
print!(" {:<6}", "?????");
215+
write!(stdout().lock(), " {:<6}", "?????")?;
210216
} else {
211-
print!(" {:<6}", idle_string(last_change));
217+
write!(stdout().lock(), " {:<6}", idle_string(last_change))?;
212218
}
213219
}
214220

215-
print!(" {}", time_string(ut));
221+
writeln!(stdout().lock(), " {}", time_string(ut))?;
216222

217223
if self.include_where {
218224
let s: String = if self.do_lookup {
@@ -222,86 +228,101 @@ impl Pinky {
222228
};
223229

224230
if !s.is_empty() {
225-
print!(" {s}");
231+
write!(stdout().lock(), " {s}")?;
226232
}
227233
}
228234

229-
println!();
235+
writeln!(stdout().lock(), "")?;
236+
Ok(())
230237
}
231238

232-
fn print_heading(&self) {
233-
print!("{:<8}", translate!("pinky-column-login"));
239+
fn print_heading(&self) -> UResult<()> {
240+
write!(stdout().lock(), "{:<8}", translate!("pinky-column-login"))?;
234241
if self.include_fullname {
235-
print!(" {:<19}", translate!("pinky-column-name"));
242+
write!(stdout().lock(), " {:<19}", translate!("pinky-column-name"))?;
236243
}
237-
print!(" {:<9}", translate!("pinky-column-tty"));
244+
write!(stdout().lock(), " {:<9}", translate!("pinky-column-tty"))?;
238245
if self.include_idle {
239-
print!(" {:<6}", translate!("pinky-column-idle"));
246+
write!(stdout().lock(), " {:<6}", translate!("pinky-column-idle"))?;
240247
}
241-
print!(" {:<16}", translate!("pinky-column-when"));
248+
write!(stdout().lock(), " {:<16}", translate!("pinky-column-when"))?;
242249
if self.include_where {
243-
print!(" {}", translate!("pinky-column-where"));
250+
write!(stdout().lock(), " {}", translate!("pinky-column-where"))?;
244251
}
245-
println!();
252+
writeln!(stdout().lock())?;
253+
Ok(())
246254
}
247255

248-
fn short_pinky(&self) {
256+
fn short_pinky(&self) -> UResult<()> {
249257
if self.include_heading {
250-
self.print_heading();
258+
self.print_heading()?;
251259
}
252260
for ut in Utmpx::iter_all_records() {
253261
if ut.is_user_process()
254262
&& (self.names.is_empty() || self.names.iter().any(|n| n.as_str() == ut.user()))
255263
{
256-
self.print_entry(&ut);
264+
self.print_entry(&ut)?;
257265
}
258266
}
267+
Ok(())
259268
}
260269

261-
fn long_pinky(&self) {
270+
fn long_pinky(&self) -> UResult<()> {
262271
for u in &self.names {
263-
print!(
272+
write!(
273+
stdout().lock(),
264274
"{} {u:<28}{} ",
265275
translate!("pinky-login-name-label"),
266276
translate!("pinky-real-life-label")
267-
);
277+
)?;
268278
if let Ok(pw) = Passwd::locate(u.as_str()) {
269279
let fullname = gecos_to_fullname(&pw).unwrap_or_default();
270280
let user_dir = pw.user_dir.unwrap_or_default();
271281
let user_shell = pw.user_shell.unwrap_or_default();
272-
println!(" {fullname}");
282+
writeln!(stdout().lock(), " {fullname}")?;
273283
if self.include_home_and_shell {
274-
print!("{} {user_dir:<29}", translate!("pinky-directory-label"));
275-
println!("{} {user_shell}", translate!("pinky-shell-label"));
284+
write!(
285+
stdout().lock(),
286+
"{} {user_dir:<29}",
287+
translate!("pinky-directory-label")
288+
)?;
289+
writeln!(
290+
stdout().lock(),
291+
"{} {user_shell}",
292+
translate!("pinky-shell-label")
293+
)?;
276294
}
277295
if self.include_project {
278296
let mut p = PathBuf::from(&user_dir);
279297
p.push(".project");
280298
if let Ok(f) = File::open(p) {
281-
print!("{} ", translate!("pinky-project-label"));
282-
read_to_console(f);
299+
write!(stdout().lock(), "{} ", translate!("pinky-project-label"))?;
300+
read_to_console(f)?;
283301
}
284302
}
285303
if self.include_plan {
286304
let mut p = PathBuf::from(&user_dir);
287305
p.push(".plan");
288306
if let Ok(f) = File::open(p) {
289-
println!("{}:", translate!("pinky-plan-label"));
290-
read_to_console(f);
307+
writeln!(stdout().lock(), "{}:", translate!("pinky-plan-label"))?;
308+
read_to_console(f)?;
291309
}
292310
}
293-
println!();
311+
writeln!(stdout().lock())?;
294312
} else {
295-
println!(" ???");
313+
writeln!(stdout().lock(), " ???")?;
296314
}
297315
}
316+
Ok(())
298317
}
299318
}
300319

301-
fn read_to_console<F: Read>(f: F) {
320+
fn read_to_console<F: Read>(f: F) -> UResult<()> {
302321
let mut reader = BufReader::new(f);
303322
let mut iobuf = Vec::new();
304323
if reader.read_to_end(&mut iobuf).is_ok() {
305-
print!("{}", String::from_utf8_lossy(&iobuf));
324+
write!(stdout().lock(), "{}", String::from_utf8_lossy(&iobuf))?;
306325
}
326+
327+
Ok(())
307328
}

0 commit comments

Comments
 (0)