linux_stat 2.5.2 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c9155ed8b1f6161a8bafcb9fbd9f1a1d9f70b018ca62aabf49ad1c7439030ee2
4
- data.tar.gz: 22e52732cd8c8a2fca1f34ca9ece06178373c800ddbc200c42d1a61d49c29995
3
+ metadata.gz: c2aa2fadafde1932205250a8c9ac30d823a9eadab17bb13ae9f5a49a2217f773
4
+ data.tar.gz: '080da5da8cb063f1be4811cffb1d81fea4db65816435fc2351dc030588dedd2a'
5
5
  SHA512:
6
- metadata.gz: d1f781908039e1946676f8a1502321b530538aef6d303976b07930c6d8933e7a45ca671e1aa3438fc774caa68c1b939f1ee12f47a5a6399523700b46cfb0c9f5
7
- data.tar.gz: cd51272b3c145c9a57a5b3ae444c21119430106436e29c843420269cbad47044fdc4e3836bf86e61404c6df20f462164dc673ec5e6d76b4acacfcc37effc61c8
6
+ metadata.gz: fb8800524cb7d515c9a2505ad5a02f6a0f9696746960e99d8ee209d7714e756d43770156526e8996be39524722c24065316dfee74240b650376bff7825c6e69d
7
+ data.tar.gz: cf5795f0e99c58948a0ce3b185d24de576c3f2172326164f280370ef842145423d39dfc25358cd0f79d3a5a7c571a4f566e4c8bf42a406ea09d643633d498b6e
data/README.md CHANGED
@@ -147,6 +147,7 @@ So LinuxStat::USB can be replaced with LS::USB for example.
147
147
  | [LinuxStat::CPU](https://github.com/Souravgoswami/linux_stat/blob/master/Usages.md#linuxstatcpu) | System's CPU usage and other related information |
148
148
  | [LinuxStat::FS](https://github.com/Souravgoswami/linux_stat/blob/master/Usages.md#linuxstatfs) | System's file system related information. It's used by Filesystem module. |
149
149
  | [LinuxStat::Filesystem](https://github.com/Souravgoswami/linux_stat/blob/master/Usages.md#linuxstatfilesystem) | System's file system usage and other related information |
150
+ | [LinuxStat::FTW](https://github.com/Souravgoswami/linux_stat/blob/master/Usages.md#linuxstatftw) | File Tree Walk: Walks through a file and gives you data related to it's own and sub files and directories |
150
151
  | [LinuxStat::Kernel](https://github.com/Souravgoswami/linux_stat/blob/master/Usages.md#linuxstatkernel) | System's kernel related information |
151
152
  | [LinuxStat::Memory](https://github.com/Souravgoswami/linux_stat/blob/master/Usages.md#linuxstatmemory) | System's memory (RAM) usage and other related information |
152
153
  | [LinuxStat::Mounts](https://github.com/Souravgoswami/linux_stat/blob/master/Usages.md#linuxstatmounts) | System's mount point related information |
data/exe/linuxstat.rb CHANGED
@@ -97,6 +97,7 @@ constants = LinuxStat.constants
97
97
  # Modules to delete from documentation and testing
98
98
  %i(
99
99
  Nproc
100
+ NFTW
100
101
  ).each(&constants.method(:delete))
101
102
 
102
103
  execute = constants.map(&:downcase).map.with_index { |x, i|
@@ -0,0 +1,8 @@
1
+ require 'mkmf'
2
+
3
+ unless have_const('linux') || RbConfig::CONFIG['arch'].to_s[/linux/]
4
+ abort('Platform is not linux')
5
+ end
6
+
7
+ abort('Missing header') unless have_header('ftw.h')
8
+ create_makefile 'linux_stat/nftw'
data/ext/nftw/nftw.c ADDED
@@ -0,0 +1,316 @@
1
+ #if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)
2
+ #pragma GCC optimize ("O3")
3
+ #pragma GCC diagnostic warning "-Wall"
4
+ #elif defined(__clang__)
5
+ #pragma clang optimize on
6
+ #pragma clang diagnostic warning "-Wall"
7
+ #elif defined(__INTEL_COMPILER)
8
+ #pragma intel optimization_level 3
9
+ #endif
10
+
11
+ #define _GNU_SOURCE 1
12
+
13
+ #include <ftw.h>
14
+ #include <stdint.h>
15
+ #include <string.h>
16
+
17
+ #include "ruby.h"
18
+
19
+ VALUE LIST ;
20
+ intmax_t TOTAL_FILES ;
21
+
22
+ static int storeInfo(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf) {
23
+ VALUE hash = rb_hash_new() ;
24
+
25
+ // Raw type flag
26
+ VALUE typeFlag = (tflag == FTW_D) ? ID2SYM(rb_intern("FTW_D")) : (tflag == FTW_DNR) ? ID2SYM(rb_intern("FTW_DNR")) :
27
+ (tflag == FTW_DP) ? ID2SYM(rb_intern("FTW_DP")) : (tflag == FTW_F) ? ID2SYM(rb_intern("FTW_F")) :
28
+ (tflag == FTW_NS) ? ID2SYM(rb_intern("FTW_NS")) : (tflag == FTW_SL) ? ID2SYM(rb_intern("FTW_SL")) :
29
+ (tflag == FTW_SLN) ? ID2SYM(rb_intern("FTW_SLN")) : Qnil ;
30
+
31
+ rb_hash_aset(
32
+ hash,
33
+ ID2SYM(rb_intern("type_flag")),
34
+ typeFlag
35
+ );
36
+
37
+ // Depth
38
+ rb_hash_aset(
39
+ hash,
40
+ ID2SYM(rb_intern("level")),
41
+ INT2FIX(ftwbuf -> level)
42
+ );
43
+
44
+ // Size
45
+ rb_hash_aset(
46
+ hash,
47
+ ID2SYM(rb_intern("st_size")),
48
+ INT2FIX((intmax_t) sb->st_size)
49
+ );
50
+
51
+ // Path
52
+ rb_hash_aset(
53
+ hash,
54
+ ID2SYM(rb_intern("path")),
55
+ rb_str_new_cstr(fpath)
56
+ );
57
+
58
+ // Basename
59
+ rb_hash_aset(
60
+ hash,
61
+ ID2SYM(rb_intern("basename")),
62
+ rb_str_new_cstr(fpath + ftwbuf->base)
63
+ );
64
+
65
+ rb_ary_push(LIST, hash) ;
66
+ return 0 ;
67
+ }
68
+
69
+ static int storeFilesInfo(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf) {
70
+ if (!(tflag == FTW_F || tflag == FTW_SL || tflag == FTW_SLN))
71
+ return 0 ;
72
+
73
+ VALUE hash = rb_hash_new() ;
74
+
75
+ // Raw type flag
76
+ VALUE typeFlag = (tflag == FTW_F) ? ID2SYM(rb_intern("FTW_F")) :
77
+ (tflag == FTW_SL) ? ID2SYM(rb_intern("FTW_SL")) :
78
+ (tflag == FTW_SLN) ? ID2SYM(rb_intern("FTW_SLN")) : Qnil ;
79
+
80
+ rb_hash_aset(
81
+ hash,
82
+ ID2SYM(rb_intern("type_flag")),
83
+ typeFlag
84
+ );
85
+
86
+ // Depth
87
+ rb_hash_aset(
88
+ hash,
89
+ ID2SYM(rb_intern("level")),
90
+ INT2FIX(ftwbuf -> level)
91
+ );
92
+
93
+ // Size
94
+ rb_hash_aset(
95
+ hash,
96
+ ID2SYM(rb_intern("st_size")),
97
+ INT2FIX((intmax_t) sb->st_size)
98
+ );
99
+
100
+ // Path
101
+ rb_hash_aset(
102
+ hash,
103
+ ID2SYM(rb_intern("path")),
104
+ rb_str_new_cstr(fpath)
105
+ );
106
+
107
+ // Dirname
108
+ char dirname[ftwbuf->base] ;
109
+ *dirname = '\0' ;
110
+ strncat(dirname, fpath, ftwbuf->base - 1) ;
111
+
112
+ rb_hash_aset(
113
+ hash,
114
+ ID2SYM(rb_intern("dirname")),
115
+ rb_str_new_cstr(dirname)
116
+ );
117
+
118
+ // Basename
119
+ rb_hash_aset(
120
+ hash,
121
+ ID2SYM(rb_intern("basename")),
122
+ rb_str_new_cstr(fpath + ftwbuf->base)
123
+ );
124
+
125
+ rb_ary_push(LIST, hash) ;
126
+ return 0 ;
127
+ }
128
+
129
+ static int countChildren(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf) {
130
+ TOTAL_FILES++ ;
131
+ return 0 ;
132
+ }
133
+
134
+ static int countFiles(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf) {
135
+ if(tflag == FTW_F || tflag == FTW_SL || tflag == FTW_SLN) TOTAL_FILES++ ;
136
+ return 0 ;
137
+ }
138
+
139
+ static int countDirectories(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf) {
140
+ if(tflag == FTW_D || tflag == FTW_DNR) TOTAL_FILES++ ;
141
+ return 0 ;
142
+ }
143
+
144
+ VALUE getChildrenCount(volatile VALUE obj, volatile VALUE rb_dir, volatile VALUE rb_flags) {
145
+ TOTAL_FILES = 0 ;
146
+ rb_ary_clear(LIST) ;
147
+
148
+ int flags = FIX2INT(rb_flags);
149
+ char *dir = StringValuePtr(rb_dir) ;
150
+ VALUE returnValue = rb_hash_new() ;
151
+
152
+ if (nftw(dir, countChildren, 20, flags) == -1) {
153
+ rb_hash_aset(returnValue, ID2SYM(rb_intern("value")), ULL2NUM(TOTAL_FILES)) ;
154
+ rb_hash_aset(returnValue, ID2SYM(rb_intern("error")), Qtrue) ;
155
+ } else {
156
+ rb_hash_aset(returnValue, ID2SYM(rb_intern("value")), ULL2NUM(TOTAL_FILES)) ;
157
+ rb_hash_aset(returnValue, ID2SYM(rb_intern("error")), Qfalse) ;
158
+ }
159
+
160
+ return returnValue ;
161
+ }
162
+
163
+ VALUE getFilesCount(volatile VALUE obj, volatile VALUE rb_dir) {
164
+ TOTAL_FILES = 0 ;
165
+
166
+ int flags = FTW_PHYS ;
167
+ #ifdef FTW_CONTINUE
168
+ flags |= FTW_CONTINUE ;
169
+ #endif
170
+
171
+ if (nftw(StringValuePtr(rb_dir), countFiles, 20, flags) == -1)
172
+ return Qnil ;
173
+
174
+ return ULL2NUM(TOTAL_FILES) ;
175
+ }
176
+
177
+ VALUE getDirectoriesCount(volatile VALUE obj, volatile VALUE rb_dir) {
178
+ TOTAL_FILES = 0 ;
179
+
180
+ int flags = FTW_PHYS ;
181
+ #ifdef FTW_CONTINUE
182
+ flags |= FTW_CONTINUE ;
183
+ #endif
184
+
185
+ if (nftw(StringValuePtr(rb_dir), countDirectories, 20, flags) == -1)
186
+ return Qnil ;
187
+
188
+ return ULL2NUM(--TOTAL_FILES) ;
189
+ }
190
+
191
+ VALUE getStat(volatile VALUE obj, volatile VALUE rb_dir, volatile VALUE rb_flags) {
192
+ rb_ary_clear(LIST) ;
193
+
194
+ int flags = FIX2INT(rb_flags);
195
+ char *dir = StringValuePtr(rb_dir) ;
196
+ VALUE returnValue = rb_hash_new() ;
197
+
198
+ if (nftw(dir, storeInfo, 20, flags) == -1) {
199
+ rb_hash_aset(returnValue, ID2SYM(rb_intern("value")), LIST) ;
200
+ rb_hash_aset(returnValue, ID2SYM(rb_intern("error")), Qtrue) ;
201
+ } else {
202
+ rb_hash_aset(returnValue, ID2SYM(rb_intern("value")), LIST) ;
203
+ rb_hash_aset(returnValue, ID2SYM(rb_intern("error")), Qfalse) ;
204
+ }
205
+
206
+ return returnValue ;
207
+ }
208
+
209
+ VALUE getFilesStat(volatile VALUE obj, volatile VALUE rb_dir) {
210
+ rb_ary_clear(LIST) ;
211
+
212
+ int flags = FTW_PHYS ;
213
+ #ifdef FTW_CONTINUE
214
+ flags |= FTW_CONTINUE ;
215
+ #endif
216
+
217
+ char *dir = StringValuePtr(rb_dir) ;
218
+ VALUE returnValue = rb_hash_new() ;
219
+
220
+ if (nftw(dir, storeFilesInfo, 20, flags) == -1) {
221
+ rb_hash_aset(returnValue, ID2SYM(rb_intern("value")), LIST) ;
222
+ rb_hash_aset(returnValue, ID2SYM(rb_intern("error")), Qtrue) ;
223
+ } else {
224
+ rb_hash_aset(returnValue, ID2SYM(rb_intern("value")), LIST) ;
225
+ rb_hash_aset(returnValue, ID2SYM(rb_intern("error")), Qfalse) ;
226
+ }
227
+
228
+ return returnValue ;
229
+ }
230
+
231
+ // Return all flags as hash
232
+ VALUE flags_hash(VALUE nftw) {
233
+ VALUE all_flags = rb_hash_new() ;
234
+ rb_ary_clear(LIST) ;
235
+
236
+ // All Flags
237
+ VALUE flags = rb_hash_new() ;
238
+ #ifdef FTW_ACTIONRETVAL
239
+ rb_hash_aset(flags, ID2SYM(rb_intern("FTW_ACTIONRETVAL")), INT2FIX(FTW_ACTIONRETVAL)) ;
240
+ #endif
241
+
242
+ rb_hash_aset(flags, ID2SYM(rb_intern("FTW_CHDIR")), INT2FIX(FTW_CHDIR)) ;
243
+ rb_hash_aset(flags, ID2SYM(rb_intern("FTW_DEPTH")), INT2FIX(FTW_DEPTH)) ;
244
+ rb_hash_aset(flags, ID2SYM(rb_intern("FTW_MOUNT")), INT2FIX(FTW_MOUNT)) ;
245
+ rb_hash_aset(flags, ID2SYM(rb_intern("FTW_PHYS")), INT2FIX(FTW_PHYS)) ;
246
+ rb_hash_aset(all_flags, ID2SYM(rb_intern("flags")), flags) ;
247
+
248
+ // Actionretval Flags
249
+ #ifdef FTW_ACTIONRETVAL
250
+ VALUE actionretval_flags = rb_hash_new() ;
251
+ rb_hash_aset(actionretval_flags, ID2SYM(rb_intern("FTW_CONTINUE")), INT2FIX(FTW_CONTINUE)) ;
252
+ rb_hash_aset(actionretval_flags, ID2SYM(rb_intern("FTW_SKIP_SIBLINGS")), INT2FIX(FTW_SKIP_SIBLINGS)) ;
253
+ rb_hash_aset(actionretval_flags, ID2SYM(rb_intern("FTW_SKIP_SUBTREE")), INT2FIX(FTW_SKIP_SUBTREE)) ;
254
+ rb_hash_aset(actionretval_flags, ID2SYM(rb_intern("FTW_STOP")), INT2FIX(FTW_STOP)) ;
255
+ rb_hash_aset(all_flags, ID2SYM(rb_intern("actionretval_flags")), actionretval_flags) ;
256
+ #endif
257
+
258
+ // Type Flags
259
+ VALUE type_flags = rb_hash_new() ;
260
+ rb_hash_aset(type_flags, ID2SYM(rb_intern("FTW_D")), INT2FIX(FTW_D)) ;
261
+ rb_hash_aset(type_flags, ID2SYM(rb_intern("FTW_DNR")), INT2FIX(FTW_DNR)) ;
262
+ rb_hash_aset(type_flags, ID2SYM(rb_intern("FTW_DP")), INT2FIX(FTW_DP)) ;
263
+ rb_hash_aset(type_flags, ID2SYM(rb_intern("FTW_F")), INT2FIX(FTW_F)) ;
264
+ rb_hash_aset(type_flags, ID2SYM(rb_intern("FTW_NS")), INT2FIX(FTW_NS)) ;
265
+ rb_hash_aset(type_flags, ID2SYM(rb_intern("FTW_SL")), INT2FIX(FTW_SL)) ;
266
+ rb_hash_aset(type_flags, ID2SYM(rb_intern("FTW_SLN")), INT2FIX(FTW_SLN)) ;
267
+ rb_hash_aset(all_flags, ID2SYM(rb_intern("type_flags")), type_flags) ;
268
+
269
+ return all_flags ;
270
+ }
271
+
272
+ void Init_nftw() {
273
+ // Initialize globals
274
+ LIST = rb_ary_new() ;
275
+ rb_global_variable(&LIST) ;
276
+
277
+ // Initialize main LinuxStat and NFTW modules
278
+ VALUE _linux_stat = rb_define_module("LinuxStat") ;
279
+ VALUE nftw = rb_define_module_under(_linux_stat, "NFTW");
280
+
281
+ // Methods
282
+ rb_define_module_function(nftw, "stat", getStat, 2) ;
283
+ rb_define_module_function(nftw, "stat_files", getFilesStat, 1) ;
284
+ rb_define_module_function(nftw, "count_children", getChildrenCount, 2) ;
285
+ rb_define_module_function(nftw, "count_files", getFilesCount, 1) ;
286
+ rb_define_module_function(nftw, "count_directories", getDirectoriesCount, 1) ;
287
+
288
+ // Constants
289
+ rb_define_const(nftw, "FLAGS", flags_hash(nftw)) ;
290
+
291
+ // Flags
292
+ #ifdef FTW_ACTIONRETVAL
293
+ rb_define_const(nftw, "FTW_ACTIONRETVAL", INT2FIX(FTW_ACTIONRETVAL)) ;
294
+ #endif
295
+ rb_define_const(nftw, "FTW_CHDIR", INT2FIX(FTW_CHDIR)) ;
296
+ rb_define_const(nftw, "FTW_DEPTH", INT2FIX(FTW_DEPTH)) ;
297
+ rb_define_const(nftw, "FTW_MOUNT", INT2FIX(FTW_MOUNT)) ;
298
+ rb_define_const(nftw, "FTW_PHYS", INT2FIX(FTW_PHYS)) ;
299
+
300
+ // ActionRetval flags
301
+ #ifdef FTW_ACTIONRETVAL
302
+ rb_define_const(nftw, "FTW_CONTINUE", INT2FIX(FTW_CONTINUE)) ;
303
+ rb_define_const(nftw, "FTW_SKIP_SIBLINGS", INT2FIX(FTW_SKIP_SIBLINGS)) ;
304
+ rb_define_const(nftw, "FTW_SKIP_SUBTREE", INT2FIX(FTW_SKIP_SUBTREE)) ;
305
+ rb_define_const(nftw, "FTW_STOP", INT2FIX(FTW_STOP)) ;
306
+ #endif
307
+
308
+ // typeflags
309
+ rb_define_const(nftw, "FTW_D", INT2FIX(FTW_D)) ;
310
+ rb_define_const(nftw, "FTW_DNR", INT2FIX(FTW_DNR)) ;
311
+ rb_define_const(nftw, "FTW_DP", INT2FIX(FTW_DP)) ;
312
+ rb_define_const(nftw, "FTW_F", INT2FIX(FTW_F)) ;
313
+ rb_define_const(nftw, "FTW_NS", INT2FIX(FTW_NS)) ;
314
+ rb_define_const(nftw, "FTW_SL", INT2FIX(FTW_SL)) ;
315
+ rb_define_const(nftw, "FTW_SLN", INT2FIX(FTW_SLN)) ;
316
+ }
@@ -344,7 +344,7 @@ module LinuxStat
344
344
  physical_cores = []
345
345
  hyperthreaded = {}
346
346
 
347
- return [] unless File.readable?('/sys/devices/system/cpu/'.freeze)
347
+ return [] unless File.executable?('/sys/devices/system/cpu/'.freeze)
348
348
  entries = Dir.entries('/sys/devices/system/cpu/'.freeze)
349
349
  entries.delete(?..freeze)
350
350
  entries.delete('..'.freeze)
@@ -384,7 +384,7 @@ module LinuxStat
384
384
  def hyperthreaded_core_list
385
385
  hyperthreaded = {}
386
386
 
387
- return [] unless File.readable?('/sys/devices/system/cpu/'.freeze)
387
+ return [] unless File.executable?('/sys/devices/system/cpu/'.freeze)
388
388
  entries = Dir.entries('/sys/devices/system/cpu/'.freeze)
389
389
  entries.delete(?..freeze)
390
390
  entries.delete('..'.freeze)
@@ -0,0 +1,101 @@
1
+ module LinuxStat
2
+ # Walks through directory and lists files, directories, symbolic links with their sizes.
3
+ # Can also count children (files + directories), files, and directories
4
+
5
+ module FTW
6
+ class << self
7
+ ##
8
+ # Show info about all directories and files in a given path and under its subdirectories.
9
+ # It accepts two arguments:
10
+ # * path: Path is the expanded path that you want to walk through.
11
+ # * flags: Flags will give you the ability to tune the output as you desire.
12
+ # Each flag value can be obtained through LinuxStat::NFTW.constants().
13
+ # Or you can use LinuxStat::NFTW::FLAGS for readable flags in hash format.
14
+ # You can do Or-ing to add multiple flags. More info here:
15
+ # https://man7.org/linux/man-pages/man3/ftw.3.html
16
+ # If no flags or nil were given as the second argument,
17
+ # it will use LS::NFTW::FTW_DEPTH | LS::NFTW::FTW_CONTINUE by default.
18
+ #
19
+ # The return value contains a Hash.
20
+ # The hash contains two keys: `error` and a `value`.
21
+ # * error: If there were any exceptions, the key will be set to true, otherwise false.
22
+ # Having an error means not all values are listed in the `value` array.
23
+ # * value: Is an array, it can or cannot be empty regardless of errors.
24
+ # The `value` key contains an array of Hashes. Each hash contains the following information about a file:
25
+ # 1. type_flag: Type of the file.
26
+ # 2. level: Depth of the file.
27
+ # 3. st_size: Size of the file in bytes.
28
+ # 4. path: Full path of the file.
29
+ # 5. basename: basename of the file.
30
+ #
31
+ # Usage Example:
32
+ # LinuxStat::FTW.stat_all(File.expand_path('~/.rvm/lib/'), LS::NFTW::FTW_DEPTH | LS::NFTW::FTW_CONTINUE)
33
+ # => {:value=>[{:type_flag=>:FTW_F, :level=>1, :st_size=>278, :path=>"/home/user/.rvm/lib/rvm.rb", :basename=>"rvm.rb"}, {:type_flag=>:FTW_F, :level=>2, :st_size=>286, :path=>"/home/user/.rvm/lib/rvm/capistrano.rb", :basename=>"capistrano.rb"}, {:type_flag=>:FTW_DP, :level=>1, :st_size=>27, :path=>"/home/user/.rvm/lib/rvm", :basename=>"rvm"}, {:type_flag=>:FTW_DP, :level=>0, :st_size=>31, :path=>"/home/user/.rvm/lib", :basename=>"lib"}], :error=>false}
34
+ #
35
+ # Internally calls LinuxStat::NFTW.stat(path, flag).
36
+ def stat_all(path = __dir__, flags = nil)
37
+ LS::NFTW.stat(
38
+ path,
39
+ flags ? flags : LS::NFTW::FTW_DEPTH | LS::NFTW::FTW_CONTINUE
40
+ )
41
+ end
42
+
43
+ ##
44
+ # Show info about all files in a given path and under its subdirectories.
45
+ # It accepts one argument:
46
+ # * path: Path is the expanded path that you want to walk through.
47
+ #
48
+ # The return value contains a Hash.
49
+ # The hash contains two keys: `error` and a `value`.
50
+ # * error: If there were any exceptions, the key will be set to true, otherwise false.
51
+ # Having an error means not all values are listed in the `value` array.
52
+ # * value: Is an array, it can or cannot be empty regardless of errors.
53
+ # The `value` key contains an array of Hashes. Each hash contains the following information about a file:
54
+ # 1. type_flag: Type of the file.
55
+ # 2. level: Depth of the file.
56
+ # 3. st_size: Size of the file in bytes.
57
+ # 4. path: Full path of the file.
58
+ # 5. dirname: directory of the file.
59
+ # 6. basename: basename of the file.
60
+ #
61
+ # Usage Example:
62
+ # LinuxStat::FTW.stat_files(File.expand_path('~/.rvm/lib/'))
63
+ # => {:value=>[{:type_flag=>:FTW_F, :level=>1, :st_size=>278, :path=>"/home/user/.rvm/lib/rvm.rb", :dirname=>"/home/user/.rvm/lib", :basename=>"rvm.rb"}, {:type_flag=>:FTW_F, :level=>2, :st_size=>286, :path=>"/home/user/.rvm/lib/rvm/capistrano.rb", :dirname=>"/home/user/.rvm/lib/rvm", :basename=>"capistrano.rb"}], :error=>false}
64
+ #
65
+ # Internally calls LinuxStat::NFTW.stat_files(path).
66
+ def stat_files(path = __dir__)
67
+ LS::NFTW.stat_files(path)
68
+ end
69
+
70
+ ##
71
+ # Count only files in a given path and under its subdirectories.
72
+ # It accepts one argument:
73
+ # * path: Path is the expanded path that you want to walk through.
74
+ #
75
+ # The return value is an Integer.
76
+ # Usage Example:
77
+ # LinuxStat::FTW.count_files(File.expand_path '~/.rvm/lib')
78
+ # => 2
79
+ #
80
+ # Internally calls LinuxStat::NFTW.count_files(path).
81
+ def count_files(path = __dir__)
82
+ LS::NFTW.count_files(path)
83
+ end
84
+
85
+ ##
86
+ # Count only directories in a given path and under its subdirectories.
87
+ # It accepts one argument:
88
+ # * path: Path is the expanded path that you want to walk through.
89
+ #
90
+ # The return value is an Integer.
91
+ # Usage Example:
92
+ # LinuxStat::FTW.count_directories(File.expand_path '~/.rvm/lib')
93
+ # => 1
94
+ #
95
+ # Internally calls LinuxStat::NFTW.count_directories(path).
96
+ def count_directories(path = __dir__)
97
+ LS::NFTW.count_directories(path)
98
+ end
99
+ end
100
+ end
101
+ end
@@ -128,7 +128,7 @@ module LinuxStat
128
128
  # Also note that if there's no info available or no PCI enabled devices, it will return an empty
129
129
  # Hash.
130
130
  def devices_stat(hwdata: true)
131
- @@sys_pci_readable ||= File.readable?('/sys/bus/pci/devices/')
131
+ @@sys_pci_readable ||= File.executable?('/sys/bus/pci/devices/')
132
132
  return devices_info(hwdata: hwdata) unless @@sys_pci_readable
133
133
 
134
134
  Dir['/sys/bus/pci/devices/*/'.freeze].sort!.map! { |x|
@@ -215,7 +215,7 @@ module LinuxStat
215
215
  # But if the information isn't available, it will return nil.
216
216
  def count
217
217
  @@proc_pci_readable ||= File.readable?('/proc/bus/pci/devices')
218
- @@sys_pci_readable ||= File.readable?('/sys/bus/pci/devices/')
218
+ @@sys_pci_readable ||= File.executable?('/sys/bus/pci/devices/')
219
219
 
220
220
  if @@proc_pci_readable
221
221
  IO.readlines('/proc/bus/pci/devices'.freeze).length
@@ -64,7 +64,7 @@ module LinuxStat
64
64
 
65
65
  private
66
66
  def hwmon_readable?
67
- @@hwmon_readable ||= File.readable?("/sys/class/hwmon/")
67
+ @@hwmon_readable ||= File.executable?("/sys/class/hwmon/")
68
68
  end
69
69
 
70
70
  def query_hwmon(mon, key, div = false)
@@ -78,20 +78,46 @@ module LinuxStat
78
78
 
79
79
  while x = files[i += 1]
80
80
  splitted = File.split(x)
81
- path = File.join(splitted[0..-2])
82
-
83
- n = splitted[-1][/.*_/]
81
+ n = splitted.pop[/.*_/]
82
+ path = File.join(splitted)
84
83
 
85
84
  label_f = "#{path}/#{n}label"
86
- label = File.readable?(label_f) ? IO.read(label_f, encoding: 'ASCII-8BIT'.freeze).strip : nil
85
+
86
+ # Some of the files may have no content
87
+ # They can also raise Errno::EIO, Errno::ENODATA as well.
88
+ label = if File.readable?(label_f)
89
+ begin
90
+ IO.read(label_f, encoding: 'ASCII-8BIT'.freeze).strip
91
+ rescue Errno::EIO, Errno::ENODEV, Errno::ENODATA
92
+ nil
93
+ end
94
+ end
87
95
 
88
96
  temp_crit_f = "#{path}/#{n}crit"
89
- temp_crit = File.readable?(temp_crit_f) ? IO.read(temp_crit_f, encoding: 'ASCII-8BIT'.freeze).to_i : nil
97
+ temp_crit = if File.readable?(temp_crit_f)
98
+ begin
99
+ IO.read(temp_crit_f, encoding: 'ASCII-8BIT'.freeze).to_i
100
+ rescue Errno::EIO, Errno::ENODEV, Errno::ENODATA
101
+ nil
102
+ end
103
+ end
90
104
 
91
105
  temp_max_f = "#{path}/#{n}max"
92
- temp_max = File.readable?(temp_max_f) ? IO.read(temp_max_f, encoding: 'ASCII-8BIT'.freeze).to_i : nil
106
+ temp_max = if File.readable?(temp_max_f)
107
+ begin
108
+ IO.read(temp_max_f, encoding: 'ASCII-8BIT'.freeze).to_i
109
+ rescue Errno::EIO, Errno::ENODEV, Errno::ENODATA
110
+ nil
111
+ end
112
+ end
93
113
 
94
- value = File.readable?(x) ? IO.read(x).to_i : nil
114
+ value = if File.readable?(x)
115
+ begin
116
+ IO.read(x).to_i
117
+ rescue Errno::EIO, Errno::ENODEV, Errno::ENODATA
118
+ nil
119
+ end
120
+ end
95
121
 
96
122
  if dir != path
97
123
  dir = path
@@ -100,17 +126,17 @@ module LinuxStat
100
126
  end
101
127
 
102
128
  if div
103
- value /= 1000.0
129
+ value /= 1000.0 if value
104
130
  temp_max /= 1000.0 if temp_max
105
131
  temp_crit /= 1000.0 if temp_crit
106
132
  end
107
133
 
108
134
  h = {path: path, name: name}
109
135
 
110
- h.store(:label, label) if label
136
+ h.store(:label, label)
111
137
  h.store(key, value)
112
- h.store(:temp_crit, temp_crit) if temp_crit
113
- h.store(:temp_crit, temp_max) if temp_max
138
+ h.store(:temp_crit, temp_crit)
139
+ h.store(:temp_crit, temp_max)
114
140
 
115
141
  ret.push(h)
116
142
  end
@@ -47,7 +47,7 @@ module LinuxStat
47
47
  # Also note that if there's no info available or no USB devices, it will return an empty
48
48
  # Hash.
49
49
  def devices_stat(hwdata: true)
50
- @@sys_usb_readable ||= File.readable?('/sys/bus/usb/devices/')
50
+ @@sys_usb_readable ||= File.executable?('/sys/bus/usb/devices/')
51
51
  return [] unless @@sys_usb_readable
52
52
 
53
53
  Dir['/sys/bus/usb/devices/*/'.freeze].sort!.map! { |x|
@@ -137,7 +137,7 @@ module LinuxStat
137
137
  #
138
138
  # But if the information isn't available, it will return nil.
139
139
  def count
140
- @@sys_usb_readable ||= File.readable?('/sys/bus/usb/devices/')
140
+ @@sys_usb_readable ||= File.executable?('/sys/bus/usb/devices/')
141
141
  return nil unless @@sys_usb_readable
142
142
 
143
143
  Dir['/sys/bus/usb/devices/*/'.freeze].count { |x|
@@ -1,3 +1,3 @@
1
1
  module LinuxStat
2
- VERSION = "2.5.2"
2
+ VERSION = "2.6.0"
3
3
  end
data/lib/linux_stat.rb CHANGED
@@ -60,5 +60,9 @@ require "linux_stat/kernel"
60
60
  require 'linux_stat/user'
61
61
  require "linux_stat/process_info"
62
62
 
63
+ # LinuxStat::NFTW dependent modules
64
+ require "linux_stat/nftw"
65
+ require "linux_stat/ftw"
66
+
63
67
  # A short alias to LinuxStat
64
68
  LS = LinuxStat
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: linux_stat
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.5.2
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sourav Goswami
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-23 00:00:00.000000000 Z
11
+ date: 2022-10-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Linux only, efficient linux system utilization reporting and system monitoring
14
14
  gem
@@ -19,6 +19,7 @@ executables:
19
19
  extensions:
20
20
  - ext/fs_stat/extconf.rb
21
21
  - ext/misc/integer/extconf.rb
22
+ - ext/nftw/extconf.rb
22
23
  - ext/nproc/extconf.rb
23
24
  - ext/procfs/extconf.rb
24
25
  - ext/sysconf/extconf.rb
@@ -38,6 +39,8 @@ files:
38
39
  - ext/fs_stat/sector_size.h
39
40
  - ext/misc/integer/extconf.rb
40
41
  - ext/misc/integer/integer?.c
42
+ - ext/nftw/extconf.rb
43
+ - ext/nftw/nftw.c
41
44
  - ext/nproc/extconf.rb
42
45
  - ext/nproc/nproc.c
43
46
  - ext/procfs/extconf.rb
@@ -57,6 +60,7 @@ files:
57
60
  - lib/linux_stat/bios.rb
58
61
  - lib/linux_stat/cpu.rb
59
62
  - lib/linux_stat/filesystem.rb
63
+ - lib/linux_stat/ftw.rb
60
64
  - lib/linux_stat/kernel.rb
61
65
  - lib/linux_stat/memory.rb
62
66
  - lib/linux_stat/mounts.rb
@@ -90,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
94
  - !ruby/object:Gem::Version
91
95
  version: '0'
92
96
  requirements: []
93
- rubygems_version: 3.2.29
97
+ rubygems_version: 3.3.23
94
98
  signing_key:
95
99
  specification_version: 4
96
100
  summary: Efficient linux system reporting gem