os: handle fread errors (#9687)
parent
6d2d956c80
commit
7ba13a415a
|
@ -21,6 +21,10 @@ fn C.open(&char, int, ...int) int
|
||||||
|
|
||||||
fn C.fdopen(fd int, mode &char) &C.FILE
|
fn C.fdopen(fd int, mode &char) &C.FILE
|
||||||
|
|
||||||
|
fn C.ferror(stream &C.FILE) int
|
||||||
|
|
||||||
|
fn C.feof(stream &C.FILE) int
|
||||||
|
|
||||||
fn C.CopyFile(&u16, &u16, bool) int
|
fn C.CopyFile(&u16, &u16, bool) int
|
||||||
|
|
||||||
// fn C.lstat(charptr, voidptr) u64
|
// fn C.lstat(charptr, voidptr) u64
|
||||||
|
@ -101,11 +105,24 @@ pub fn read_file(path string) ?string {
|
||||||
unsafe {
|
unsafe {
|
||||||
mut str := malloc(fsize + 1)
|
mut str := malloc(fsize + 1)
|
||||||
nelements := int(C.fread(str, fsize, 1, fp))
|
nelements := int(C.fread(str, fsize, 1, fp))
|
||||||
if nelements == 0 && fsize > 0 {
|
is_eof := int(C.feof(fp))
|
||||||
|
is_error := int(C.ferror(fp))
|
||||||
|
if is_eof == 0 && is_error != 0 {
|
||||||
free(str)
|
free(str)
|
||||||
return error('fread failed')
|
return error('fread failed')
|
||||||
}
|
}
|
||||||
str[fsize] = 0
|
str[fsize] = 0
|
||||||
|
if nelements == 0 {
|
||||||
|
// It is highly likely that the file was a virtual file from
|
||||||
|
// /sys or /proc, with information generated on the fly, so
|
||||||
|
// fsize was not reliably reported. Using vstring() here is
|
||||||
|
// slower (it calls strlen internally), but will return more
|
||||||
|
// consistent results.
|
||||||
|
// For example reading from /sys/class/sound/card0/id produces
|
||||||
|
// a `PCH\n` string, but fsize is 4096, and otherwise you would
|
||||||
|
// get a V string with .len = 4096 and .str = "PCH\n\\000".
|
||||||
|
return str.vstring()
|
||||||
|
}
|
||||||
return str.vstring_with_len(fsize)
|
return str.vstring_with_len(fsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue