Changeset View
Changeset View
Standalone View
Standalone View
ksysguardd/Linux/acpi.c
Show All 28 Lines | |||||
29 | #include <assert.h> | 29 | #include <assert.h> | ||
30 | 30 | | |||
31 | #include "Command.h" | 31 | #include "Command.h" | ||
32 | #include "ksysguardd.h" | 32 | #include "ksysguardd.h" | ||
33 | 33 | | |||
34 | #include "acpi.h" | 34 | #include "acpi.h" | ||
35 | 35 | | |||
36 | #define ACPIFILENAMELENGTHMAX 64 | 36 | #define ACPIFILENAMELENGTHMAX 64 | ||
37 | #define ACPIBATTERYNUMMAX 6 | | |||
38 | #define ACPIBATTERYINFOBUFSIZE 1024 | | |||
39 | #define ACPIBATTERYSTATEBUFSIZE 512 | | |||
40 | | ||||
41 | static int AcpiBatteryNum = 0; | | |||
42 | static char AcpiBatteryNames[ ACPIBATTERYNUMMAX ][ 8 ]; | | |||
43 | static int AcpiBatteryCharge[ ACPIBATTERYNUMMAX ]; | | |||
44 | static int AcpiBatteryUsage[ ACPIBATTERYNUMMAX ]; | | |||
45 | 37 | | |||
46 | static int AcpiBatteryOk = 1; | | |||
47 | /* | 38 | /* | ||
48 | ================================ public part ================================= | 39 | ================================ public part ================================= | ||
49 | */ | 40 | */ | ||
50 | 41 | | |||
51 | void initAcpi(struct SensorModul* sm) | 42 | void initAcpi(struct SensorModul* sm) | ||
52 | { | 43 | { | ||
53 | initAcpiBattery(sm); | 44 | initAcpiBattery(sm); | ||
54 | initAcpiThermal(sm); | 45 | initAcpiThermal(sm); | ||
55 | } | 46 | } | ||
56 | 47 | | |||
57 | int updateAcpi( void ) | 48 | void exitAcpi( void ) | ||
58 | { | 49 | { | ||
59 | if (AcpiBatteryOk && AcpiBatteryNum > 0) updateAcpiBattery(); | | |||
60 | return 0; | | |||
61 | } | 50 | } | ||
62 | 51 | | |||
63 | void exitAcpi( void ) | 52 | | ||
53 | /************ ACPI Battery **********/ | ||||
54 | void registerBatteryCharge(int number, struct SensorModul *sm) | ||||
55 | { | ||||
56 | char name[ ACPIFILENAMELENGTHMAX ]; | ||||
57 | readTypeFile("/sys/class/power_supply/BAT%d/type", number, name, sizeof(name)); | ||||
58 | | ||||
59 | char sensorName [ ACPIFILENAMELENGTHMAX ]; | ||||
60 | snprintf(sensorName, sizeof(sensorName), "acpi/Battery/%d-%s/Charge", number, name); | ||||
61 | | ||||
62 | registerMonitor(sensorName, "integer", printSysBatteryCharge, | ||||
63 | printSysBatteryChargeInfo, sm); | ||||
64 | } | ||||
65 | | ||||
66 | void registerBatteryChargeDesign(int number, struct SensorModul *sm) | ||||
64 | { | 67 | { | ||
65 | AcpiBatteryNum = -1; | 68 | char name[ ACPIFILENAMELENGTHMAX ]; | ||
66 | AcpiBatteryOk = 0; | 69 | readTypeFile("/sys/class/power_supply/BAT%d/type", number, name, sizeof(name)); | ||
70 | | ||||
71 | char sensorName [ ACPIFILENAMELENGTHMAX ]; | ||||
ahiemstra: Can you clean up the indentation of this function? It should use 4 spaces for indentation. | |||||
72 | snprintf(sensorName, sizeof(sensorName), "acpi/Battery/%d-%s/ChargeDesign", number, name); | ||||
73 | | ||||
74 | registerMonitor(sensorName, "integer", printSysBatteryChargeDesign, | ||||
75 | printSysBatteryChargeDesignInfo, sm); | ||||
67 | } | 76 | } | ||
68 | 77 | | |||
78 | void registerBatteryRate(int number, struct SensorModul *sm) | ||||
79 | { | ||||
80 | char name[ ACPIFILENAMELENGTHMAX ]; | ||||
81 | readTypeFile("/sys/class/power_supply/BAT%d/type", number, name, sizeof(name)); | ||||
69 | 82 | | |||
70 | /************ ACPI Battery **********/ | 83 | char sensorName [ ACPIFILENAMELENGTHMAX ]; | ||
84 | snprintf(sensorName, sizeof(sensorName), "acpi/Battery/%d-%s/Rate", number, name); | ||||
85 | | ||||
86 | registerMonitor(sensorName, "integer", printSysBatteryRate, | ||||
87 | printSysBatteryRateInfo, sm); | ||||
88 | } | ||||
71 | 89 | | |||
72 | void initAcpiBattery( struct SensorModul* sm ) | 90 | void initAcpiBattery( struct SensorModul* sm ) | ||
73 | { | 91 | { | ||
74 | DIR *d; | 92 | DIR *d; | ||
75 | struct dirent *de; | 93 | struct dirent *de; | ||
76 | char s[ ACPIFILENAMELENGTHMAX ]; | 94 | char s[ ACPIFILENAMELENGTHMAX ]; | ||
77 | 95 | | |||
78 | if ( ( d = opendir( "/proc/acpi/battery" ) ) == NULL ) { | 96 | d = opendir("/sys/class/power_supply/"); | ||
79 | AcpiBatteryNum = -1; | 97 | if (d != NULL) { | ||
80 | AcpiBatteryOk = 0; | 98 | while ( (de = readdir(d)) != NULL ) { | ||
81 | return; | 99 | if (!de->d_name || de->d_name[0] == '.') | ||
82 | } else { | 100 | continue; | ||
83 | AcpiBatteryNum = 0; | 101 | if (strncmp( de->d_name, "BAT", sizeof("BAT")-1) == 0) { | ||
84 | AcpiBatteryOk = 1; | 102 | int number = atoi(de->d_name + (sizeof("BAT")-1)); | ||
85 | while ( ( de = readdir( d ) ) ) | 103 | registerBatteryCharge(number, sm); | ||
86 | if ( ( strcmp( de->d_name, "." ) != 0 ) && ( strcmp( de->d_name, ".." ) != 0 ) ) { | 104 | registerBatteryChargeDesign(number, sm); | ||
87 | strncpy( AcpiBatteryNames[ AcpiBatteryNum ], de->d_name, 8 ); | 105 | registerBatteryRate(number, sm); | ||
88 | snprintf( s, sizeof( s ), "acpi/battery/%d/batterycharge", AcpiBatteryNum ); | 106 | } | ||
89 | registerMonitor( s, "integer", printAcpiBatFill, printAcpiBatFillInfo, sm ); | | |||
90 | snprintf( s, sizeof( s ), "acpi/battery/%d/batteryusage", AcpiBatteryNum ); | | |||
91 | registerMonitor( s, "integer", printAcpiBatUsage, printAcpiBatUsageInfo, sm); | | |||
92 | AcpiBatteryCharge[ AcpiBatteryNum ] = 0; | | |||
93 | AcpiBatteryNum++; | | |||
94 | } | 107 | } | ||
95 | closedir( d ); | 108 | closedir( d ); | ||
96 | } | 109 | } | ||
97 | } | 110 | } | ||
98 | 111 | | |||
99 | 112 | void printSysBatteryCharge(const char *cmd) | |||
100 | int updateAcpiBattery( void ) | | |||
101 | { | 113 | { | ||
102 | int i, fd; | 114 | int zone = 0; | ||
103 | char s[ ACPIFILENAMELENGTHMAX ]; | 115 | if (sscanf(cmd, "acpi/Battery/%d", &zone) <= 0) { | ||
104 | size_t n; | 116 | output("-1\n"); | ||
105 | char AcpiBatInfoBuf[ ACPIBATTERYINFOBUFSIZE ]; | 117 | return; | ||
ahiemstra: Braces on newline for function definitions please. | |||||
106 | char AcpiBatStateBuf[ ACPIBATTERYSTATEBUFSIZE ]; | 118 | } | ||
107 | char *p; | | |||
108 | int AcpiBatCapacity = 1; | | |||
109 | int AcpiBatRemainingCapacity = 0; | | |||
110 | | ||||
111 | if ( AcpiBatteryNum <= 0 ) | | |||
112 | return -1; | | |||
113 | 119 | | |||
114 | for ( i = 0; i < AcpiBatteryNum; i++ ) { | 120 | int charge = getSysFileValue("power_supply", "BAT", zone, "charge_now"); | ||
115 | /* get total capacity */ | 121 | int maximum = getSysFileValue("power_supply", "BAT", zone, "charge_full"); | ||
116 | snprintf( s, sizeof( s ), "/proc/acpi/battery/%s/info", AcpiBatteryNames[ i ] ); | 122 | int state = 0; | ||
117 | if ( ( fd = open( s, O_RDONLY ) ) < 0 ) { | 123 | if ( maximum > 0) { | ||
118 | print_error( "Cannot open file \'%s\'!\n" | 124 | state = charge * 100 / maximum; | ||
119 | "Load the battery ACPI kernel module or\n" | | |||
120 | "compile it into your kernel.\n", s ); | | |||
121 | AcpiBatteryOk = 0; | | |||
122 | return -1; | | |||
123 | } | 125 | } | ||
124 | if ( ( n = read( fd, AcpiBatInfoBuf, ACPIBATTERYINFOBUFSIZE - 1 ) ) == | 126 | if (state > 100) { | ||
125 | ACPIBATTERYINFOBUFSIZE - 1 ) { | 127 | state = 100; /* prevent insane numbers with bad hardware */ | ||
126 | log_error( "Internal buffer too small to read \'%s\'", s ); | 128 | } else if (state < 0) { | ||
127 | close( fd ); | 129 | state = 0; /* prevent insane numbers with bad hardware */ | ||
Are states > 100 or < 0 really well defined? Is it save to assume that a state > 100 can be associated with 100? alexde: Are states > 100 or < 0 really well defined? Is it save to assume that a state > 100 can be… | |||||
128 | AcpiBatteryOk = 0; | | |||
129 | return -1; | | |||
130 | } | 130 | } | ||
131 | close( fd ); | 131 | output( "%d\n", state); | ||
132 | p = AcpiBatInfoBuf; | | |||
133 | if ( p && strstr(p, "ERROR: Unable to read battery") ) | | |||
134 | return 0; /* If we can't read the battery, reuse the last value */ | | |||
135 | while ( ( p!= NULL ) && ( sscanf( p, "last full capacity: %d ", | | |||
136 | &AcpiBatCapacity ) != 1 ) ) { | | |||
137 | p = strchr( p, '\n' ); | | |||
138 | if ( p ) | | |||
139 | p++; | | |||
140 | } | | |||
141 | /* get remaining capacity */ | | |||
142 | snprintf( s, sizeof( s ), "/proc/acpi/battery/%s/state", AcpiBatteryNames[ i ] ); | | |||
143 | if ( ( fd = open( s, O_RDONLY ) ) < 0 ) { | | |||
144 | print_error( "Cannot open file \'%s\'!\n" | | |||
145 | "Load the battery ACPI kernel module or\n" | | |||
146 | "compile it into your kernel.\n", s ); | | |||
147 | AcpiBatteryOk = 0; | | |||
148 | return -1; | | |||
149 | } | 132 | } | ||
150 | if ( ( n = read( fd, AcpiBatStateBuf, ACPIBATTERYSTATEBUFSIZE - 1 ) ) == | 133 | | ||
151 | ACPIBATTERYSTATEBUFSIZE - 1 ) { | 134 | void printSysBatteryChargeInfo(const char *cmd) | ||
152 | log_error( "Internal buffer too small to read \'%s\'", s); | 135 | { | ||
153 | close( fd ); | 136 | char name [ 200 ]; | ||
154 | AcpiBatteryOk = 0; | 137 | if (sscanf(cmd, "acpi/Battery/%199[^/]", name) > 0) { | ||
155 | return -1; | 138 | output( "%s charge\t0\t100\t%%\n", name); | ||
139 | } else { | ||||
140 | output( "Current charge\t0\t100\t%%\n"); | ||||
156 | } | 141 | } | ||
157 | close( fd ); | | |||
158 | p = AcpiBatStateBuf; | | |||
159 | while ( ( p!= NULL ) && ( sscanf( p, "remaining capacity: %d ", | | |||
160 | &AcpiBatRemainingCapacity ) != 1 ) ) { | | |||
161 | p = strchr( p, '\n' ); | | |||
162 | if ( p ) | | |||
163 | p++; | | |||
164 | } | 142 | } | ||
165 | 143 | | |||
166 | /* get current battery usage, (current Current) */ | 144 | void printSysBatteryChargeDesign(const char *cmd) | ||
167 | p = AcpiBatStateBuf; | 145 | { | ||
168 | while ( ( p!= NULL ) && ( sscanf( p, "present rate: %d ", | 146 | int zone = 0; | ||
169 | &AcpiBatteryUsage[i] ) != 1 ) ) { | 147 | if (sscanf(cmd, "acpi/Battery/%d", &zone) <= 0) { | ||
170 | p = strchr( p, '\n' ); | 148 | output("-1\n"); | ||
171 | if ( p ) | 149 | return; | ||
172 | p++; | | |||
173 | } | 150 | } | ||
174 | 151 | | |||
175 | 152 | int charge = getSysFileValue("power_supply", "BAT", zone, "charge_now"); | |||
176 | /* calculate charge rate */ | 153 | int maximum = getSysFileValue("power_supply", "BAT", zone, "charge_full_design"); | ||
177 | if ( AcpiBatCapacity > 0 ) | 154 | int state = 0; | ||
178 | AcpiBatteryCharge[ i ] = AcpiBatRemainingCapacity * 100 / AcpiBatCapacity; | 155 | if (maximum > 0) { | ||
ahiemstra: I don't see why current needs to be >0 ? What if I have an empty battery? | |||||
179 | else | 156 | state = charge * 100 / maximum; | ||
180 | AcpiBatteryCharge[ i ] = 0; | | |||
181 | } | 157 | } | ||
182 | AcpiBatteryOk = 1; | 158 | if (state > 100) { | ||
183 | return 0; | 159 | state = 100; /* prevent insane numbers with bad hardware */ | ||
160 | } else if (state < 0) { | ||||
161 | state = 0; /* prevent insane numbers with bad hardware */ | ||||
Are states > 100 or < 0 really well defined? Is it save to assume that a state > 100 can be associated with 100 for example? alexde: Are states > 100 or < 0 really well defined? Is it save to assume that a state > 100 can be… | |||||
184 | } | 162 | } | ||
185 | 163 | output( "%d\n", state); | |||
186 | void printAcpiBatFill( const char* cmd ) | | |||
187 | { | | |||
188 | int i; | | |||
189 | | ||||
190 | sscanf( cmd + 13, "%d", &i ); | | |||
191 | output( "%d\n", AcpiBatteryCharge[ i ] ); | | |||
192 | } | 164 | } | ||
193 | 165 | | |||
194 | void printAcpiBatFillInfo( const char* cmd ) | 166 | void printSysBatteryChargeDesignInfo(const char *cmd) | ||
195 | { | 167 | { | ||
196 | int i; | 168 | char name [ 200 ]; | ||
197 | 169 | if (sscanf(cmd, "acpi/Battery/%199[^/]", name) > 0) { | |||
198 | sscanf( cmd + 13, "%d", &i ); | 170 | output( "%s charge (by design)\t0\t100\t%%\n", name); | ||
199 | output( "Battery %d charge\t0\t100\t%%\n", i ); | 171 | } else { | ||
172 | output( "Current charge (by design)\t0\t100\t%%\n"); | ||||
173 | } | ||||
200 | } | 174 | } | ||
201 | 175 | | |||
202 | void printAcpiBatUsage( const char* cmd) | 176 | void printSysBatteryRate(const char *cmd) | ||
203 | { | 177 | { | ||
204 | int i; | 178 | int zone = 0; | ||
179 | if (sscanf(cmd, "acpi/Battery/%d", &zone) <= 0) { | ||||
180 | output("-1\n"); | ||||
181 | return; | ||||
182 | } | ||||
ahiemstra: Braces on newline for function definitions please. | |||||
205 | 183 | | |||
206 | sscanf( cmd + 13, "%d", &i ); | 184 | output( "%d\n", getSysFileValue("power_supply", "BAT", zone, "current_now") / 1000); | ||
207 | output( "%d\n", AcpiBatteryUsage[ i ] ); | | |||
208 | } | 185 | } | ||
209 | 186 | | |||
210 | void printAcpiBatUsageInfo( const char* cmd) | 187 | void printSysBatteryRateInfo(const char *cmd) | ||
211 | { | 188 | { | ||
212 | 189 | char name [ 200 ]; | |||
213 | int i; | 190 | if (sscanf(cmd, "acpi/Battery/%199[^/]", name) > 0) { | ||
214 | 191 | output( "%s rate\t0\t0\tmA\n", name); | |||
215 | sscanf(cmd+13, "%d", &i); | 192 | } else { | ||
216 | 193 | output( "Current rate\t0\t0\tmA\n"); | |||
217 | output( "Battery %d usage\t0\t2500\tmA\n", i ); | | |||
218 | } | 194 | } | ||
195 | } | ||||
196 | | ||||
219 | 197 | | |||
220 | /************** ACPI Thermal *****************/ | 198 | /************** ACPI Thermal *****************/ | ||
221 | 199 | | |||
222 | #define OLD_THERMAL_ZONE_DIR "/proc/acpi/thermal_zone" | 200 | #define OLD_THERMAL_ZONE_DIR "/proc/acpi/thermal_zone" | ||
223 | #define OLD_TEMPERATURE_FILE "temperature" | 201 | #define OLD_TEMPERATURE_FILE "temperature" | ||
224 | #define OLD_TEMPERATURE_FILE_MAXLEN 255 | 202 | #define OLD_TEMPERATURE_FILE_MAXLEN 255 | ||
225 | 203 | | |||
226 | #define OLD_FAN_DIR "/proc/acpi/fan" | 204 | #define OLD_FAN_DIR "/proc/acpi/fan" | ||
▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Line(s) | 318 | if (d != NULL) { | |||
349 | } | 327 | } | ||
350 | closedir( d ); | 328 | closedir( d ); | ||
351 | } | 329 | } | ||
352 | } | 330 | } | ||
353 | 331 | | |||
354 | return; | 332 | return; | ||
355 | } | 333 | } | ||
356 | 334 | | |||
357 | static int getSysFileValue(const char *group, int value, const char *file) { | 335 | static int getSysFileValue(const char *className, const char *group, int value, const char *file) { | ||
Using class as name here seems a bit dangerous to me, if this code ever gets compiled with a C++ compiler it will trip over this name. Maybe use className instead? ahiemstra: Using `class` as name here seems a bit dangerous to me, if this code ever gets compiled with a… | |||||
358 | static int shownError = 0; | 336 | static int shownError = 0; | ||
359 | char th_file[ ACPIFILENAMELENGTHMAX ]; | 337 | char th_file[ ACPIFILENAMELENGTHMAX ]; | ||
360 | char input_buf[ 100 ]; | 338 | char input_buf[ 100 ]; | ||
361 | snprintf(th_file, sizeof(th_file), "/sys/class/thermal/%s%d/%s",group, value, file); | 339 | snprintf(th_file, sizeof(th_file), "/sys/class/%s/%s%d/%s", className, group, value, file); | ||
ahiemstra: Please add a space between , and class | |||||
362 | int fd = open(th_file, O_RDONLY); | 340 | int fd = open(th_file, O_RDONLY); | ||
363 | if (fd < 0) { | 341 | if (fd < 0) { | ||
364 | if (!shownError) | 342 | if (!shownError) | ||
365 | print_error( "Cannot open file \'%s\'!\n" | 343 | print_error( "Cannot open file \'%s\'!\n" | ||
366 | "Load the thermal ACPI kernel module or\n" | 344 | "Load the thermal ACPI kernel module or\n" | ||
367 | "compile it into your kernel.\n", th_file ); | 345 | "compile it into your kernel.\n", th_file ); | ||
368 | shownError = 1; | 346 | shownError = 1; | ||
369 | return -1; | 347 | return -1; | ||
Show All 15 Lines | |||||
385 | 363 | | |||
386 | void printSysThermalZoneTemperature(const char *cmd) { | 364 | void printSysThermalZoneTemperature(const char *cmd) { | ||
387 | int zone = 0; | 365 | int zone = 0; | ||
388 | if (sscanf(cmd, "acpi/Thermal_Zone/%d", &zone) <= 0) { | 366 | if (sscanf(cmd, "acpi/Thermal_Zone/%d", &zone) <= 0) { | ||
389 | output("-1\n"); | 367 | output("-1\n"); | ||
390 | return; | 368 | return; | ||
391 | } | 369 | } | ||
392 | 370 | | |||
393 | output( "%d\n", getSysFileValue("thermal_zone", zone, "temp") / 1000); | 371 | output( "%d\n", getSysFileValue("thermal", "thermal_zone", zone, "temp") / 1000); | ||
394 | } | 372 | } | ||
395 | void printSysCompatibilityThermalZoneTemperature(const char *cmd) { | 373 | void printSysCompatibilityThermalZoneTemperature(const char *cmd) { | ||
396 | int zone = 0; | 374 | int zone = 0; | ||
397 | if (sscanf(cmd, "acpi/thermal_zone/TZ%d", &zone) <= 0) { | 375 | if (sscanf(cmd, "acpi/thermal_zone/TZ%d", &zone) <= 0) { | ||
398 | output( "-1\n"); | 376 | output( "-1\n"); | ||
399 | return; | 377 | return; | ||
400 | } | 378 | } | ||
401 | output( "%d\n", getSysFileValue("thermal_zone", zone, "temp")/1000); | 379 | output( "%d\n", getSysFileValue("thermal", "thermal_zone", zone, "temp")/1000); | ||
402 | } | 380 | } | ||
403 | 381 | | |||
404 | void printCoolingDeviceStateInfo(const char *cmd) | 382 | void printCoolingDeviceStateInfo(const char *cmd) | ||
405 | { | 383 | { | ||
406 | (void)cmd; | 384 | (void)cmd; | ||
407 | char name [ 200 ]; | 385 | char name [ 200 ]; | ||
408 | if (sscanf(cmd, "acpi/Cooling_Device/%199[^/]", name) > 0) { | 386 | if (sscanf(cmd, "acpi/Cooling_Device/%199[^/]", name) > 0) { | ||
409 | output( "%s Cooling Activity\t0\t100\t%%\n", name); | 387 | output( "%s Cooling Activity\t0\t100\t%%\n", name); | ||
410 | } else { | 388 | } else { | ||
411 | output( "Cooling Device Activity\t0\t100\t%%\n"); | 389 | output( "Cooling Device Activity\t0\t100\t%%\n"); | ||
412 | } | 390 | } | ||
413 | } | 391 | } | ||
414 | 392 | | |||
415 | void printCoolingDeviceState(const char *cmd) { | 393 | void printCoolingDeviceState(const char *cmd) { | ||
416 | int fan = 0; | 394 | int fan = 0; | ||
417 | if (sscanf(cmd, "acpi/Cooling_Device/%d", &fan) <= 0) { | 395 | if (sscanf(cmd, "acpi/Cooling_Device/%d", &fan) <= 0) { | ||
418 | output( "-1\n"); | 396 | output( "-1\n"); | ||
419 | return; | 397 | return; | ||
420 | } | 398 | } | ||
421 | int current = getSysFileValue("cooling_device", fan, "cur_state"); | 399 | int current = getSysFileValue("thermal", "cooling_device", fan, "cur_state"); | ||
422 | int maximum = getSysFileValue("cooling_device", fan, "max_state"); | 400 | int maximum = getSysFileValue("thermal", "cooling_device", fan, "max_state"); | ||
423 | int state = 0; | 401 | int state = 0; | ||
424 | if (current > 0 && maximum > 0) { | 402 | if (current > 0 && maximum > 0) { | ||
425 | state = current / maximum; | 403 | state = (current * 100) / maximum; /* state is a percentage */ | ||
426 | } | 404 | } | ||
427 | output( "%d\n", state); | 405 | output( "%d\n", state); | ||
428 | } | 406 | } | ||
429 | 407 | | |||
430 | static int getCurrentTemperature(const char *cmd) | 408 | static int getCurrentTemperature(const char *cmd) | ||
431 | { | 409 | { | ||
432 | char th_file[ ACPIFILENAMELENGTHMAX ]; | 410 | char th_file[ ACPIFILENAMELENGTHMAX ]; | ||
433 | char input_buf[ OLD_TEMPERATURE_FILE_MAXLEN ]; | 411 | char input_buf[ OLD_TEMPERATURE_FILE_MAXLEN ]; | ||
▲ Show 20 Lines • Show All 104 Lines • Show Last 20 Lines |
Can you clean up the indentation of this function? It should use 4 spaces for indentation.