Coverage for linuxpy/statfs.py: 76%
36 statements
« prev ^ index » next coverage.py v7.6.1, created at 2024-10-18 07:40 +0200
« prev ^ index » next coverage.py v7.6.1, created at 2024-10-18 07:40 +0200
1#
2# This file is part of the linuxpy project
3#
4# Copyright (c) 2023 Tiago Coutinho
5# Distributed under the GPLv3 license. See LICENSE for more info.
7import enum
8import functools
10from .ctypes import (
11 POINTER,
12 Struct,
13 c,
14 ccharp,
15 cint,
16 cuint,
17 culong,
18 fsblkcnt,
19 fsfilcnt,
20 pointer,
21)
22from .magic import Magic
25class fsid(Struct):
26 _fields_ = [("val", cint * 2)]
29class statfs(Struct):
30 _fields_ = [
31 ("f_type", cuint), # Type of filesystem (see below)
32 ("f_bsize", cuint), # Optimal transfer block size
33 ("f_blocks", fsblkcnt), # Total data blocks in filesystem
34 ("f_bfree", fsblkcnt), # Free blocks in filesystem
35 ("f_bavail", fsblkcnt), # Free blocks available to unprivileged user
36 ("f_files", fsfilcnt), # Total file nodes in filesystem
37 ("f_ffree", fsfilcnt), # Free file nodes in filesystem
38 ("f_fsid", fsid), # Filesystem ID
39 ("f_namelen", cuint), # Maximum length of filenames
40 ("f_frsize", cuint), # Fragment size (since Linux 2.6)
41 ("f_flags", cuint), # Mount flags of filesystem (since Linux 2.6.36)
42 # Setting f_spare to 4 * int was giving me segfault
43 ("f_spare", cuint * 16), # Padding bytes reserved for future use
44 ]
47class statvfs(Struct):
48 _fields_ = [
49 ("f_bsize", culong), # Filesystem block size
50 ("f_frsize", culong), # Fragment size
51 ("f_blocks", fsblkcnt), # Size of fs in f_frsize units
52 ("f_bfree", fsblkcnt), # Number of free blocks
53 ("f_bavail", fsblkcnt), # Number of free blocks for unprivileged user
54 ("f_files", fsfilcnt), # Number of inodes
55 ("f_ffree", fsfilcnt), # Number of free inodes
56 ("f_favail", fsfilcnt), # Number of free inodes for unprivileged user
57 ("f_fsid", culong), # Filesystem ID
58 ("f_flag", culong), # Mount flags
59 ("f_namemax", culong), # Maximum filename length
60 ]
63class Flag(enum.IntFlag):
64 RDONLY = 0x0001 # mount read-only
65 NOSUID = 0x0002 # ignore suid and sgid bits
66 NODEV = 0x0004 # disallow access to device special files
67 NOEXEC = 0x0008 # disallow program execution
68 SYNCHRONOUS = 0x0010 # writes are synced at once
69 VALID = 0x0020 # f_flags support is implemented
70 MANDLOCK = 0x0040 # allow mandatory locks on an FS
71 # 0x0080 used for ST_WRITE in glibc
72 # 0x0100 used for ST_APPEND in glibc
73 # 0x0200 used for ST_IMMUTABLE in glibc
74 NOATIME = 0x0400 # do not update access times
75 NODIRATIME = 0x0800 # do not update directory access times
76 RELATIME = 0x1000 # update atime relative to mtime/ctime
77 NOSYMFOLLOW = 0x2000 # do not follow symlinks
80c.statfs.argtypes = [ccharp, POINTER(statfs)]
81c.statfs.restype = cint
83c.statvfs.argtypes = [ccharp, POINTER(statvfs)]
84c.statvfs.restype = cint
87def get_statfs_raw(path) -> statfs:
88 if not isinstance(path, (bytes, ccharp)):
89 path = str(path).encode()
90 result = statfs()
91 c.statfs(path, pointer(result))
92 return result
95@functools.lru_cache
96def get_fs_type(path) -> Magic:
97 ftype = get_statfs_raw(path).f_type
98 return None if not ftype else Magic(ftype)