unix/modos: Add statvfs() function.

Another function (like stat) which is problematic to deal with on ABI level
(FFI), as struct statvfs layout may differ unpredictably between OSes and
even different versions of a same OS. So, implement it in C, returning a
10-element tuple of f_bsize, f_frsize, f_blocks, f_bfree, f_bavail, f_files,
f_ffree, f_favail, f_flag, f_namemax. This is exactly the order described
in Python3 docs, https://docs.python.org/3/library/os.html#os.statvfs
(but note that os.statvfs() should make these values available as
attributes).
This commit is contained in:
Paul Sokolovsky 2015-10-18 00:45:31 +03:00
parent 6ec6f51326
commit c3000b6f69
3 changed files with 33 additions and 0 deletions

View File

@ -30,6 +30,7 @@
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/statvfs.h>
#include "py/nlr.h" #include "py/nlr.h"
#include "py/runtime.h" #include "py/runtime.h"
@ -62,6 +63,31 @@ STATIC mp_obj_t mod_os_stat(mp_obj_t path_in) {
} }
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_stat_obj, mod_os_stat); STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_stat_obj, mod_os_stat);
#if MICROPY_PY_OS_STATVFS
STATIC mp_obj_t mod_os_statvfs(mp_obj_t path_in) {
struct statvfs sb;
mp_uint_t len;
const char *path = mp_obj_str_get_data(path_in, &len);
int res = statvfs(path, &sb);
RAISE_ERRNO(res, errno);
mp_obj_tuple_t *t = mp_obj_new_tuple(10, NULL);
t->items[0] = MP_OBJ_NEW_SMALL_INT(sb.f_bsize);
t->items[1] = MP_OBJ_NEW_SMALL_INT(sb.f_frsize);
t->items[2] = MP_OBJ_NEW_SMALL_INT(sb.f_blocks);
t->items[3] = MP_OBJ_NEW_SMALL_INT(sb.f_bfree);
t->items[4] = MP_OBJ_NEW_SMALL_INT(sb.f_bavail);
t->items[5] = MP_OBJ_NEW_SMALL_INT(sb.f_files);
t->items[6] = MP_OBJ_NEW_SMALL_INT(sb.f_ffree);
t->items[7] = MP_OBJ_NEW_SMALL_INT(sb.f_favail);
t->items[8] = MP_OBJ_NEW_SMALL_INT(sb.f_flag);
t->items[9] = MP_OBJ_NEW_SMALL_INT(sb.f_namemax);
return t;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_statvfs_obj, mod_os_statvfs);
#endif
STATIC mp_obj_t mod_os_unlink(mp_obj_t path_in) { STATIC mp_obj_t mod_os_unlink(mp_obj_t path_in) {
mp_uint_t len; mp_uint_t len;
const char *path = mp_obj_str_get_data(path_in, &len); const char *path = mp_obj_str_get_data(path_in, &len);
@ -88,6 +114,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_system_obj, mod_os_system);
STATIC const mp_map_elem_t mp_module_os_globals_table[] = { STATIC const mp_map_elem_t mp_module_os_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR__os) }, { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR__os) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&mod_os_stat_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_stat), (mp_obj_t)&mod_os_stat_obj },
#if MICROPY_PY_OS_STATVFS
{ MP_OBJ_NEW_QSTR(MP_QSTR_statvfs), (mp_obj_t)&mod_os_statvfs_obj },
#endif
{ MP_OBJ_NEW_QSTR(MP_QSTR_system), (mp_obj_t)&mod_os_system_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_system), (mp_obj_t)&mod_os_system_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_unlink),(mp_obj_t)&mod_os_unlink_obj}, { MP_OBJ_NEW_QSTR(MP_QSTR_unlink),(mp_obj_t)&mod_os_unlink_obj},
}; };

View File

@ -93,6 +93,7 @@
#define MICROPY_STACKLESS (0) #define MICROPY_STACKLESS (0)
#define MICROPY_STACKLESS_STRICT (0) #define MICROPY_STACKLESS_STRICT (0)
#define MICROPY_PY_OS_STATVFS (1)
#define MICROPY_PY_UCTYPES (1) #define MICROPY_PY_UCTYPES (1)
#define MICROPY_PY_UZLIB (1) #define MICROPY_PY_UZLIB (1)
#define MICROPY_PY_UJSON (1) #define MICROPY_PY_UJSON (1)

View File

@ -36,6 +36,9 @@ Q(flush)
Q(_os) Q(_os)
Q(stat) Q(stat)
#if MICROPY_PY_OS_STATVFS
Q(statvfs)
#endif
Q(system) Q(system)
Q(unlink) Q(unlink)