Fixed utimes segfault when given nullptr
This commit is contained in:
committed by
Jeremy Soller
parent
84de1e8234
commit
02780057f0
+20
-11
@@ -5,6 +5,7 @@ use crate::{
|
||||
header::time::timespec,
|
||||
platform::{types::*, Pal, PalSignal, Sys},
|
||||
};
|
||||
use core::ptr::null;
|
||||
|
||||
pub const ITIMER_REAL: c_int = 0;
|
||||
pub const ITIMER_VIRTUAL: c_int = 1;
|
||||
@@ -57,15 +58,23 @@ pub extern "C" fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int {
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn utimes(path: *const c_char, times: *const timeval) -> c_int {
|
||||
let path = CStr::from_ptr(path);
|
||||
let times_spec = [
|
||||
timespec {
|
||||
tv_sec: (*times.offset(0)).tv_sec,
|
||||
tv_nsec: ((*times.offset(0)).tv_usec as c_long) * 1000,
|
||||
},
|
||||
timespec {
|
||||
tv_sec: (*times.offset(1)).tv_sec,
|
||||
tv_nsec: ((*times.offset(1)).tv_usec as c_long) * 1000,
|
||||
},
|
||||
];
|
||||
Sys::utimens(path, times_spec.as_ptr())
|
||||
// Nullptr is valid here, it means "use current time"
|
||||
let times_spec = if times.is_null() {
|
||||
null()
|
||||
} else {
|
||||
{
|
||||
[
|
||||
timespec {
|
||||
tv_sec: (*times.offset(0)).tv_sec,
|
||||
tv_nsec: ((*times.offset(0)).tv_usec as c_long) * 1000,
|
||||
},
|
||||
timespec {
|
||||
tv_sec: (*times.offset(1)).tv_sec,
|
||||
tv_nsec: ((*times.offset(1)).tv_usec as c_long) * 1000,
|
||||
},
|
||||
]
|
||||
}
|
||||
.as_ptr()
|
||||
};
|
||||
Sys::utimens(path, times_spec)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use core::{slice, str};
|
||||
use syscall::{Error, Result, WaitFlags, EMFILE};
|
||||
|
||||
use crate::{
|
||||
header::{signal::sigaction, time::timespec},
|
||||
header::{signal::sigaction, sys_stat::UTIME_NOW, time::timespec},
|
||||
platform::types::*,
|
||||
};
|
||||
|
||||
@@ -77,10 +77,24 @@ pub unsafe fn fstatvfs(
|
||||
Ok(())
|
||||
}
|
||||
pub unsafe fn futimens(fd: usize, times: *const timespec) -> syscall::Result<()> {
|
||||
let times = times
|
||||
.cast::<[timespec; 2]>()
|
||||
.read()
|
||||
.map(|ts| syscall::TimeSpec::from(&ts));
|
||||
let times = if times.is_null() {
|
||||
// null means set to current time using special UTIME_NOW value (tv_sec is ignored in that case)
|
||||
[
|
||||
syscall::TimeSpec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: UTIME_NOW as c_int,
|
||||
},
|
||||
syscall::TimeSpec {
|
||||
tv_sec: 0,
|
||||
tv_nsec: UTIME_NOW as c_int,
|
||||
},
|
||||
]
|
||||
} else {
|
||||
times
|
||||
.cast::<[timespec; 2]>()
|
||||
.read()
|
||||
.map(|ts| syscall::TimeSpec::from(&ts))
|
||||
};
|
||||
syscall::futimens(fd as usize, ×)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user