Skip to content

Commit 4379661

Browse files
committed
revert to working version
1 parent 691fc38 commit 4379661

1 file changed

Lines changed: 39 additions & 47 deletions

File tree

native/diskspace/src/lib.rs

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
use rustler::{Atom, Binary, Env, Error, NifResult, Term};
22
use std::ffi::CString;
3+
34
#[cfg(unix)]
45
use std::io;
5-
// Unix-specific imports
6+
67
#[cfg(unix)]
78
use std::ffi::OsStr;
89
#[cfg(unix)]
910
use std::os::unix::ffi::OsStrExt;
1011
#[cfg(unix)]
1112
use std::path::Path;
1213

13-
// Windows-specific imports
1414
#[cfg(windows)]
15-
use windows::core::{PCWSTR, PWSTR};
15+
use std::ptr;
16+
#[cfg(windows)]
17+
use windows::core::PCWSTR;
18+
#[cfg(windows)]
19+
use windows::core::PWSTR;
1620
#[cfg(windows)]
1721
use windows::Win32::Foundation::{GetLastError, LocalFree, HLOCAL};
1822
#[cfg(windows)]
@@ -25,7 +29,6 @@ use windows::Win32::System::Diagnostics::Debug::{
2529
FORMAT_MESSAGE_IGNORE_INSERTS,
2630
};
2731

28-
// nix imports with proper cfg to avoid unused warnings
2932
#[cfg(all(unix, target_os = "linux"))]
3033
use nix::sys::statfs::{statfs, Statfs};
3134
#[cfg(all(unix, not(target_os = "linux")))]
@@ -37,6 +40,7 @@ mod atoms {
3740
error,
3841
wrong_arity,
3942
invalid_path,
43+
alloc_failed,
4044
path_conversion_failed,
4145
not_directory,
4246
winapi_failed,
@@ -81,42 +85,35 @@ fn make_errno_error_tuple<'a>(env: Env<'a>, reason: Atom, err: io::Error) -> Nif
8185
#[cfg(windows)]
8286
// Helper: Create error tuple with WinAPI error details
8387
fn make_winapi_error_tuple<'a>(env: Env<'a>, reason: Atom, errnum: u32) -> NifResult<Term<'a>> {
84-
use windows::core::PWSTR;
85-
use windows::Win32::Foundation::GetLastError;
86-
use windows::Win32::System::Diagnostics::Debug::{
87-
FormatMessageW, FORMAT_MESSAGE_ALLOCATE_BUFFER, FORMAT_MESSAGE_FROM_SYSTEM,
88-
FORMAT_MESSAGE_IGNORE_INSERTS,
89-
};
90-
91-
let mut buffer_ptr: *mut u16 = std::ptr::null_mut();
88+
let mut buffer_ptr: *mut u16 = ptr::null_mut();
9289
let flags =
9390
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
91+
let lang: u32 = 0;
9492

9593
let len = unsafe {
9694
FormatMessageW(
9795
flags,
9896
None,
9997
errnum,
100-
0,
101-
PWSTR(&mut buffer_ptr as *mut _ as *mut u16),
98+
lang,
99+
PWSTR(&mut buffer_ptr as *mut _ as *mut _),
102100
0,
103101
None,
104102
)
105103
};
106104

107105
let errstr = if len == 0 {
108-
format!("Unknown WinAPI error: code {}", errnum)
106+
"Unknown WinAPI error".to_string()
109107
} else {
110-
let slice = unsafe { std::slice::from_raw_parts(buffer_ptr, len as usize) };
111-
widestring::U16Str::from_slice(slice)
112-
.to_string_lossy()
113-
.trim_end()
114-
.to_string()
108+
let message_slice = unsafe { std::slice::from_raw_parts(buffer_ptr, len as usize) };
109+
110+
let wide_str = widestring::U16Str::from_slice(message_slice);
111+
wide_str.to_string_lossy().trim_end().to_string()
115112
};
116113

117114
if !buffer_ptr.is_null() {
118115
unsafe {
119-
windows::Win32::Foundation::LocalFree(buffer_ptr as isize);
116+
let _ = LocalFree(HLOCAL(buffer_ptr as isize));
120117
}
121118
}
122119

@@ -126,7 +123,7 @@ fn make_winapi_error_tuple<'a>(env: Env<'a>, reason: Atom, errnum: u32) -> NifRe
126123
make_error_tuple3(env, reason, detail)
127124
}
128125

129-
// Helper: Convert Elixir term to a path (as bytes). For Windows we later turn UTF-8 -> UTF-16.
126+
// Helper: Convert Elixir term to a path
130127
fn get_path_from_term<'a>(_env: Env<'a>, term: Term<'a>) -> NifResult<CString> {
131128
// Try binary first
132129
let binary = match term.decode::<Binary>() {
@@ -143,11 +140,9 @@ fn get_path_from_term<'a>(_env: Env<'a>, term: Term<'a>) -> NifResult<CString> {
143140
}
144141
}
145142
};
146-
147143
if binary.is_empty() {
148144
return Err(Error::BadArg);
149145
}
150-
151146
match CString::new(binary.as_slice()) {
152147
Ok(cstr) => Ok(cstr),
153148
Err(_) => Err(Error::BadArg),
@@ -163,37 +158,30 @@ fn stat_fs<'a>(env: Env<'a>, path_term: Term<'a>) -> NifResult<Term<'a>> {
163158

164159
#[cfg(windows)]
165160
{
166-
// The NIF expects UTF-8 input; Windows APIs require UTF-16.
167161
let path_str = match path_cstr.to_str() {
168162
Ok(s) => s,
169163
Err(_) => return make_error_tuple(env, atoms::path_conversion_failed()),
170164
};
171165

172-
// Long-path handling. Preserve existing \?\ prefix; convert UNC to \\?\UNC\...
173166
let is_unc = path_str.starts_with("\\\\") && !path_str.starts_with("\\\\?\\");
174-
let mut long_path_str = if is_unc {
167+
let long_path_str = if is_unc {
175168
format!("\\\\?\\UNC{}", &path_str[2..])
176169
} else if !path_str.starts_with("\\\\?\\") {
177170
format!("\\\\?\\{}", path_str)
178171
} else {
179172
path_str.to_string()
180173
};
181174

182-
// Normalize bare drive roots like "\\?\C:" -> "\\?\C:\" for more predictable API behavior.
183-
if long_path_str.len() == 6 && long_path_str.ends_with(':') {
184-
long_path_str.push('\\');
185-
}
186-
187175
let wide_str = match widestring::WideCString::from_str(&long_path_str) {
188176
Ok(ws) => ws,
189177
Err(_) => return make_error_tuple(env, atoms::path_conversion_failed()),
190178
};
191-
let wpath = PCWSTR(wide_str.as_ptr());
179+
let long_wpath = PCWSTR::from_raw(wide_str.as_ptr());
192180

193-
let attr = unsafe { GetFileAttributesW(wpath) };
181+
let attr = unsafe { GetFileAttributesW(long_wpath) };
194182
if attr == INVALID_FILE_ATTRIBUTES {
195183
let err = unsafe { GetLastError() };
196-
return make_winapi_error_tuple(env, atoms::winapi_failed(), err.0);
184+
return make_winapi_error_tuple(env, atoms::not_directory(), err.0);
197185
}
198186
if (attr & FILE_ATTRIBUTE_DIRECTORY.0) == 0 {
199187
return make_error_tuple(env, atoms::not_directory());
@@ -202,11 +190,15 @@ fn stat_fs<'a>(env: Env<'a>, path_term: Term<'a>) -> NifResult<Term<'a>> {
202190
let mut avail: u64 = 0;
203191
let mut total: u64 = 0;
204192
let mut free: u64 = 0;
205-
206-
let ok = unsafe {
207-
GetDiskFreeSpaceExW(wpath, Some(&mut avail), Some(&mut total), Some(&mut free))
193+
let success = unsafe {
194+
GetDiskFreeSpaceExW(
195+
long_wpath,
196+
Some(&mut avail),
197+
Some(&mut total),
198+
Some(&mut free),
199+
)
208200
};
209-
if let Err(e) = ok {
201+
if let Err(e) = success {
210202
return make_winapi_error_tuple(env, atoms::winapi_failed(), e.code().0 as u32);
211203
}
212204

@@ -216,10 +208,10 @@ fn stat_fs<'a>(env: Env<'a>, path_term: Term<'a>) -> NifResult<Term<'a>> {
216208
.map_put(atoms::free().to_term(env), free)?
217209
.map_put(atoms::total().to_term(env), total)?
218210
.map_put(atoms::used().to_term(env), used)?;
219-
return Ok(rustler::types::tuple::make_tuple(
211+
Ok(rustler::types::tuple::make_tuple(
220212
env,
221213
&[atoms::ok().to_term(env), map],
222-
));
214+
))
223215
}
224216

225217
#[cfg(unix)]
@@ -238,7 +230,7 @@ fn stat_fs<'a>(env: Env<'a>, path_term: Term<'a>) -> NifResult<Term<'a>> {
238230
let statfs_buf: Statfs = match statfs(os_path) {
239231
Ok(buf) => buf,
240232
Err(err) => {
241-
let io_err = io::Error::from_raw_os_error(err as i32); // nix Errno layout matches C errno
233+
let io_err = io::Error::from_raw_os_error(err as i32);
242234
return make_errno_error_tuple(env, atoms::statfs_failed(), io_err);
243235
}
244236
};
@@ -252,18 +244,18 @@ fn stat_fs<'a>(env: Env<'a>, path_term: Term<'a>) -> NifResult<Term<'a>> {
252244
.map_put(atoms::free().to_term(env), free)?
253245
.map_put(atoms::total().to_term(env), total)?
254246
.map_put(atoms::used().to_term(env), used)?;
255-
return Ok(rustler::types::tuple::make_tuple(
247+
Ok(rustler::types::tuple::make_tuple(
256248
env,
257249
&[atoms::ok().to_term(env), map],
258-
));
250+
))
259251
}
260252

261253
#[cfg(not(target_os = "linux"))]
262254
{
263255
let statvfs_buf: Statvfs = match statvfs(os_path) {
264256
Ok(buf) => buf,
265257
Err(err) => {
266-
let io_err = io::Error::from_raw_os_error(err as i32); // nix Errno layout matches C errno
258+
let io_err = io::Error::from_raw_os_error(err as i32);
267259
return make_errno_error_tuple(env, atoms::statvfs_failed(), io_err);
268260
}
269261
};
@@ -277,10 +269,10 @@ fn stat_fs<'a>(env: Env<'a>, path_term: Term<'a>) -> NifResult<Term<'a>> {
277269
.map_put(atoms::free().to_term(env), free)?
278270
.map_put(atoms::total().to_term(env), total)?
279271
.map_put(atoms::used().to_term(env), used)?;
280-
return Ok(rustler::types::tuple::make_tuple(
272+
Ok(rustler::types::tuple::make_tuple(
281273
env,
282274
&[atoms::ok().to_term(env), map],
283-
));
275+
))
284276
}
285277
}
286278
}

0 commit comments

Comments
 (0)