|
3 | 3 | // For the full copyright and license information, please view the LICENSE |
4 | 4 | // file that was distributed with this source code. |
5 | 5 | // spell-checker:ignore winsize Openpty openpty xpixel ypixel ptyprocess |
| 6 | +#[cfg(unix)] |
| 7 | +use std::os::unix::fs::PermissionsExt; |
6 | 8 | use std::thread::sleep; |
| 9 | +use uutests::at_and_ts; |
7 | 10 | use uutests::at_and_ucmd; |
8 | 11 | use uutests::new_ucmd; |
9 | 12 | use uutests::util::TestScenario; |
@@ -148,7 +151,6 @@ fn test_nohup_appends_to_existing_file() { |
148 | 151 | ))] |
149 | 152 | fn test_nohup_fallback_to_home() { |
150 | 153 | use std::fs; |
151 | | - use std::os::unix::fs::PermissionsExt; |
152 | 154 |
|
153 | 155 | // Skip test when running as root (permissions bypassed via CAP_DAC_OVERRIDE) |
154 | 156 | // This is common in Docker/Podman containers but won't happen in CI |
@@ -248,96 +250,39 @@ fn test_nohup_stderr_to_stdout() { |
248 | 250 | assert!(content.contains("stderr message")); |
249 | 251 | } |
250 | 252 |
|
251 | | -// Test nohup.out has 0600 permissions |
252 | 253 | #[test] |
253 | | -#[cfg(any( |
254 | | - target_os = "linux", |
255 | | - target_os = "android", |
256 | | - target_os = "freebsd", |
257 | | - target_os = "openbsd", |
258 | | - target_vendor = "apple" |
259 | | -))] |
| 254 | +#[cfg(unix)] |
260 | 255 | fn test_nohup_output_permissions() { |
261 | | - use std::os::unix::fs::PermissionsExt; |
| 256 | + if uucore::process::geteuid() == 0 { |
| 257 | + return; |
| 258 | + } |
262 | 259 |
|
263 | | - let ts = TestScenario::new(util_name!()); |
264 | | - let at = &ts.fixtures; |
| 260 | + let (at, ts) = at_and_ts!(); |
265 | 261 |
|
| 262 | + // CWD nohup.out should be 0600 |
266 | 263 | ts.ucmd() |
267 | 264 | .terminal_simulation(true) |
268 | 265 | .args(&["echo", "perms"]) |
269 | 266 | .succeeds(); |
270 | 267 |
|
271 | | - sleep(std::time::Duration::from_millis(10)); |
| 268 | + assert_eq!(at.metadata("nohup.out").permissions().mode() & 0o777, 0o600); |
272 | 269 |
|
273 | | - let metadata = std::fs::metadata(at.plus("nohup.out")).unwrap(); |
274 | | - let mode = metadata.permissions().mode(); |
275 | | - |
276 | | - assert_eq!( |
277 | | - mode & 0o777, |
278 | | - 0o600, |
279 | | - "nohup.out should have 0600 permissions" |
280 | | - ); |
281 | | -} |
282 | | - |
283 | | -// Test that the fallback nohup.out (in $HOME) also has 0600 permissions |
284 | | -#[test] |
285 | | -#[cfg(any( |
286 | | - target_os = "linux", |
287 | | - target_os = "android", |
288 | | - target_os = "freebsd", |
289 | | - target_os = "openbsd" |
290 | | -))] |
291 | | -fn test_nohup_fallback_output_permissions() { |
292 | | - use std::fs; |
293 | | - use std::os::unix::fs::PermissionsExt; |
294 | | - |
295 | | - // Skip if root |
296 | | - if unsafe { libc::geteuid() } == 0 { |
297 | | - println!("Skipping test when running as root"); |
298 | | - return; |
299 | | - } |
300 | | - |
301 | | - let ts = TestScenario::new(util_name!()); |
302 | | - let at = &ts.fixtures; |
303 | | - |
304 | | - // Create a fake HOME directory |
| 270 | + // $HOME fallback nohup.out should also be 0600 |
305 | 271 | at.mkdir("home"); |
306 | | - let home_dir_str = at.plus_as_string("home"); |
307 | | - |
308 | | - // Create a read-only directory |
309 | 272 | at.mkdir("readonly_dir"); |
310 | | - let readonly_path = at.plus("readonly_dir"); |
311 | | - |
312 | | - // Make directory read-only |
313 | | - let mut perms = fs::metadata(&readonly_path).unwrap().permissions(); |
314 | | - perms.set_mode(0o555); |
315 | | - fs::set_permissions(&readonly_path, perms).unwrap(); |
| 273 | + at.set_mode("readonly_dir", 0o555); |
316 | 274 |
|
317 | | - // Run nohup inside the read-only dir |
318 | | - // This forces it to fail writing to CWD and fall back to custom HOME |
319 | 275 | ts.ucmd() |
320 | | - .env("HOME", &home_dir_str) |
321 | | - .current_dir(&readonly_path) |
| 276 | + .env("HOME", &at.plus_as_string("home")) |
| 277 | + .current_dir(at.plus("readonly_dir")) |
322 | 278 | .terminal_simulation(true) |
323 | 279 | .arg("true") |
324 | 280 | .run(); |
325 | 281 |
|
326 | | - // Restore permissions so the test runner can delete the folder later! |
327 | | - let mut perms = fs::metadata(&readonly_path).unwrap().permissions(); |
328 | | - perms.set_mode(0o755); |
329 | | - fs::set_permissions(&readonly_path, perms).unwrap(); |
330 | | - |
331 | | - sleep(std::time::Duration::from_millis(50)); |
332 | | - |
333 | | - // Verify the file exists in HOME and has 0600 permissions |
334 | | - let home_nohup = at.plus("home/nohup.out"); |
335 | | - let metadata = fs::metadata(home_nohup).expect("nohup.out should have been created in HOME"); |
336 | | - let mode = metadata.permissions().mode(); |
| 282 | + at.set_mode("readonly_dir", 0o755); |
337 | 283 |
|
338 | 284 | assert_eq!( |
339 | | - mode & 0o777, |
340 | | - 0o600, |
341 | | - "Fallback nohup.out should have 0600 permissions" |
| 285 | + at.metadata("home/nohup.out").permissions().mode() & 0o777, |
| 286 | + 0o600 |
342 | 287 | ); |
343 | 288 | } |
0 commit comments