Skip to content

Commit a65f6b9

Browse files
authored
[hal] Radio LED: Properly close files and improve error messages (#7181)
1 parent d97a749 commit a65f6b9

File tree

1 file changed

+41
-18
lines changed

1 file changed

+41
-18
lines changed

hal/src/main/native/athena/LEDs.cpp

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66

77
#include <unistd.h>
88

9+
#include <cstring>
910
#include <fstream>
1011

12+
#include <fmt/format.h>
13+
#include <fmt/std.h>
1114
#include <wpi/fs.h>
1215

16+
#include "HALInternal.h"
1317
#include "hal/Errors.h"
1418

1519
namespace hal::init {
@@ -28,19 +32,56 @@ static const fs::path radioLEDRedFilePath =
2832
static const char* onStr = "1";
2933
static const char* offStr = "0";
3034

35+
static bool ReadStateFromFile(fs::path path, int32_t* status) {
36+
std::error_code ec;
37+
fs::file_t file = fs::OpenFileForRead(path, ec, fs::OF_Text);
38+
if (ec) {
39+
hal::SetLastError(status, fmt::format("Could not open '{}' for read: {}",
40+
path, ec.message()));
41+
*status = INCOMPATIBLE_STATE;
42+
return false;
43+
}
44+
// We only need to read one byte because the file won't have leading zeros.
45+
char buf[1]{};
46+
ssize_t count = read(file, buf, 1);
47+
// save errno, always close file.
48+
int err = errno;
49+
fs::CloseFile(file);
50+
if (count <= 0) {
51+
*status = INCOMPATIBLE_STATE;
52+
if (count == 0) {
53+
hal::SetLastError(status,
54+
fmt::format("Read from '{}' returned no data.", path));
55+
} else {
56+
hal::SetLastError(status, fmt::format("Failed to read from '{}': {}",
57+
path, std::strerror(err)));
58+
}
59+
return false;
60+
}
61+
// If the brightness is not zero, the LED is on.
62+
return buf[0] != '0';
63+
}
64+
3165
extern "C" {
3266
void HAL_SetRadioLEDState(HAL_RadioLEDState state, int32_t* status) {
3367
std::error_code ec;
3468
fs::file_t greenFile = fs::OpenFileForWrite(radioLEDGreenFilePath, ec,
3569
fs::CD_OpenExisting, fs::OF_Text);
3670
if (ec) {
71+
// not opened, nothing to clean up
3772
*status = INCOMPATIBLE_STATE;
73+
hal::SetLastError(status, fmt::format("Could not open '{}' for write: {}",
74+
greenFile, ec.message()));
3875
return;
3976
}
4077
fs::file_t redFile = fs::OpenFileForWrite(radioLEDRedFilePath, ec,
4178
fs::CD_OpenExisting, fs::OF_Text);
4279
if (ec) {
80+
// green file opened successfully, need to close it
81+
fs::CloseFile(greenFile);
4382
*status = INCOMPATIBLE_STATE;
83+
hal::SetLastError(status, fmt::format("Could not open '{}' for write: {}",
84+
greenFile, ec.message()));
4485
return;
4586
}
4687

@@ -51,24 +92,6 @@ void HAL_SetRadioLEDState(HAL_RadioLEDState state, int32_t* status) {
5192
fs::CloseFile(redFile);
5293
}
5394

54-
bool ReadStateFromFile(fs::path path, int32_t* status) {
55-
std::error_code ec;
56-
fs::file_t file = fs::OpenFileForRead(path, ec, fs::OF_Text);
57-
if (ec) {
58-
*status = INCOMPATIBLE_STATE;
59-
return false;
60-
}
61-
// We only need to read one byte because the file won't have leading zeros.
62-
char buf[1]{};
63-
size_t count = read(file, buf, 1);
64-
if (count == 0) {
65-
*status = INCOMPATIBLE_STATE;
66-
return false;
67-
}
68-
// If the brightness is not zero, the LED is on.
69-
return buf[0] != '0';
70-
}
71-
7295
HAL_RadioLEDState HAL_GetRadioLEDState(int32_t* status) {
7396
bool green = ReadStateFromFile(radioLEDGreenFilePath, status);
7497
bool red = ReadStateFromFile(radioLEDRedFilePath, status);

0 commit comments

Comments
 (0)