44
55#include < algorithm>
66#include < cstring>
7- #include < dirent.h>
87#include < fcntl.h>
8+ #include < filesystem>
99#include < string>
10+ #include < string_view>
1011#include < sys/ioctl.h>
1112#include < sys/select.h>
1213#include < termios.h>
@@ -110,8 +111,8 @@ intptr_t serialOpen(void* port, int baudrate, int dataBits, int parity, int stop
110111 return 0 ;
111112 }
112113
113- const char * port_name = static_cast <const char *>(port);
114- int fd = open (port_name, O_RDWR | O_NOCTTY | O_SYNC);
114+ auto port_name = std::string_view{ static_cast <const char *>(port)} ;
115+ int fd = open (port_name. data () , O_RDWR | O_NOCTTY | O_SYNC);
115116 if (fd < 0 )
116117 {
117118 invokeError (std::to_underlying (StatusCodes::INVALID_HANDLE_ERROR));
@@ -326,34 +327,48 @@ int serialReadUntil(int64_t handlePtr, void* buffer, int bufferSize, int timeout
326327
327328int serialGetPortsInfo (void * buffer, int bufferSize, void * separatorPtr)
328329{
329- const char * sep = static_cast <const char *>(separatorPtr);
330+ auto sep = std::string_view{ static_cast <const char *>(separatorPtr)} ;
330331 std::string result;
331332
332- DIR* dir = opendir (" /dev/serial/by-id" );
333- if (dir == nullptr )
333+ namespace fs = std::filesystem;
334+
335+ const fs::path by_id_dir{" /dev/serial/by-id" };
336+ if (!fs::exists (by_id_dir) || !fs::is_directory (by_id_dir))
334337 {
335338 invokeError (std::to_underlying (StatusCodes::NOT_FOUND_ERROR));
336339 return 0 ;
337340 }
338- struct dirent * entry = nullptr ;
339- while ((entry = readdir (dir)) != nullptr )
341+
342+ try
340343 {
341- if ( entry-> d_type == DT_LNK )
344+ for ( const auto & entry : fs::directory_iterator{by_id_dir} )
342345 {
343- std::string symlink_path = std::string (" /dev/serial/by-id/" ) + entry->d_name ;
344- char canonical_path[PATH_MAX];
345- if (realpath (symlink_path.c_str (), canonical_path) != nullptr )
346+ if (!entry.is_symlink ())
347+ {
348+ continue ;
349+ }
350+
351+ std::error_code ec;
352+ fs::path canonical = fs::canonical (entry.path (), ec);
353+ if (ec)
346354 {
347- result += canonical_path;
348- result += sep;
355+ continue ; // skip entries we cannot resolve
349356 }
357+
358+ result += canonical.string ();
359+ result += sep;
350360 }
351361 }
352- closedir (dir);
362+ catch (const fs::filesystem_error&)
363+ {
364+ invokeError (std::to_underlying (StatusCodes::NOT_FOUND_ERROR));
365+ return 0 ;
366+ }
353367
354368 if (!result.empty ())
355369 {
356- result.erase (result.size () - std::strlen (sep)); // remove trailing sep
370+ // Remove the trailing separator
371+ result.erase (result.size () - sep.size ());
357372 }
358373
359374 if (static_cast <int >(result.size ()) + 1 > bufferSize)
@@ -363,7 +378,7 @@ int serialGetPortsInfo(void* buffer, int bufferSize, void* separatorPtr)
363378 }
364379
365380 std::memcpy (buffer, result.c_str (), result.size () + 1 );
366- return ( result.empty () ? 0 : 1 ) ; // number of ports not easily counted here
381+ return result.empty () ? 0 : 1 ; // number of ports not easily counted here
367382}
368383
369384// Currently stubbed helpers (no-ops)
0 commit comments