Skip to content

Commit d024b0b

Browse files
committed
env/printenv: dedup the code
1 parent 502f3b1 commit d024b0b

File tree

3 files changed

+35
-24
lines changed

3 files changed

+35
-24
lines changed

src/uu/env/src/env.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ use nix::sys::signal::{SigHandler::SigIgn, Signal, signal};
2424
use std::borrow::Cow;
2525
use std::env;
2626
use std::ffi::{OsStr, OsString};
27-
use std::io::{self, Write};
27+
use std::io;
2828
#[cfg(unix)]
2929
use std::os::unix::ffi::OsStrExt;
3030
#[cfg(unix)]
3131
use std::os::unix::process::CommandExt;
3232

33-
use uucore::display::{OsWrite, Quotable};
33+
use uucore::display::{Quotable, print_all_env_vars};
3434
use uucore::error::{ExitCode, UError, UResult, USimpleError, UUsageError};
3535
use uucore::line_ending::LineEnding;
3636
#[cfg(unix)]
@@ -101,15 +101,7 @@ struct Options<'a> {
101101

102102
/// print `name=value` env pairs on screen
103103
fn print_env(line_ending: LineEnding) -> io::Result<()> {
104-
let stdout_raw = io::stdout();
105-
let mut stdout = stdout_raw.lock();
106-
for (n, v) in env::vars_os() {
107-
stdout.write_all_os(&n)?;
108-
stdout.write_all(b"=")?;
109-
stdout.write_all_os(&v)?;
110-
write!(stdout, "{line_ending}")?;
111-
}
112-
Ok(())
104+
print_all_env_vars(line_ending)
113105
}
114106

115107
fn parse_name_value_opt<'a>(opts: &mut Options<'a>, opt: &'a OsStr) -> UResult<bool> {

src/uu/printenv/src/printenv.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
// file that was distributed with this source code.
55

66
use std::env;
7-
use std::io::Write;
87

98
use clap::{Arg, ArgAction, Command};
109

10+
use uucore::display::{print_all_env_vars, print_env_var_value};
1111
use uucore::error::UResult;
1212
use uucore::line_ending::LineEnding;
13-
use uucore::{format_usage, os_str_as_bytes, translate};
13+
use uucore::{format_usage, translate};
1414

1515
static OPT_NULL: &str = "null";
1616

@@ -28,14 +28,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
2828
let separator = LineEnding::from_zero_flag(matches.get_flag(OPT_NULL));
2929

3030
if variables.is_empty() {
31-
for (env_var, value) in env::vars_os() {
32-
let env_bytes = os_str_as_bytes(&env_var)?;
33-
let val_bytes = os_str_as_bytes(&value)?;
34-
std::io::stdout().lock().write_all(env_bytes)?;
35-
print!("=");
36-
std::io::stdout().lock().write_all(val_bytes)?;
37-
print!("{separator}");
38-
}
31+
print_all_env_vars(separator)?;
3932
return Ok(());
4033
}
4134

@@ -47,9 +40,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
4740
continue;
4841
}
4942
if let Some(var) = env::var_os(env_var) {
50-
let val_bytes = os_str_as_bytes(&var)?;
51-
std::io::stdout().lock().write_all(val_bytes)?;
52-
print!("{separator}");
43+
print_env_var_value(&var, separator)?;
5344
} else {
5445
error_found = true;
5546
}

src/uucore/src/lib/mods/display.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
//! # Ok::<(), std::io::Error>(())
2525
//! ```
2626
27+
use std::env;
2728
use std::ffi::OsStr;
29+
use std::fmt;
2830
use std::fs::File;
2931
use std::io::{self, BufWriter, Stdout, StdoutLock, Write as IoWrite};
3032

@@ -117,3 +119,29 @@ impl OsWrite for Box<dyn OsWrite> {
117119
this.write_all_os(buf)
118120
}
119121
}
122+
123+
/// Print all environment variables in the format `name=value` with the specified line ending.
124+
///
125+
/// This function handles non-UTF-8 environment variable names and values correctly by using
126+
/// raw bytes on Unix systems.
127+
pub fn print_all_env_vars<T: fmt::Display>(line_ending: T) -> io::Result<()> {
128+
let mut stdout = io::stdout().lock();
129+
for (name, value) in env::vars_os() {
130+
stdout.write_all_os(&name)?;
131+
stdout.write_all(b"=")?;
132+
stdout.write_all_os(&value)?;
133+
write!(stdout, "{line_ending}")?;
134+
}
135+
Ok(())
136+
}
137+
138+
/// Print a single environment variable value with the specified line ending.
139+
///
140+
/// This function handles non-UTF-8 environment variable values correctly by using
141+
/// raw bytes on Unix systems.
142+
pub fn print_env_var_value<T: fmt::Display>(value: &OsStr, line_ending: T) -> io::Result<()> {
143+
let mut stdout = io::stdout().lock();
144+
stdout.write_all_os(value)?;
145+
write!(stdout, "{line_ending}")?;
146+
Ok(())
147+
}

0 commit comments

Comments
 (0)