Skip to content

Commit 8f5d6bc

Browse files
authored
Fix filesystem iteration on Windows (#469)
* Get rid of unnecessary casts in rcutils_dir_iter_t. Instead of using a void pointer, use the forward-declared pointer type. While this won't make a difference for the generated code, it will let us remove unnecessary casts. * Remove unnecessary FindClose on error. In particular, if we failed to find the next file on Windows, we shouldn't necessarily close the handle; that's the job of rcutils_dir_iter_end. * Remove completely unnecessary #ifdef __cplusplus header. Signed-off-by: Chris Lalancette <[email protected]>
1 parent ebb174d commit 8f5d6bc

File tree

2 files changed

+23
-32
lines changed

2 files changed

+23
-32
lines changed

include/rcutils/filesystem.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ RCUTILS_PUBLIC
245245
size_t
246246
rcutils_get_file_size(const char * file_path);
247247

248+
struct rcutils_dir_iter_state_s;
249+
248250
/// An iterator used for enumerating directory contents
249251
typedef struct rcutils_dir_iter_s
250252
{
@@ -253,7 +255,7 @@ typedef struct rcutils_dir_iter_s
253255
/// The allocator used internally by iteration functions
254256
rcutils_allocator_t allocator;
255257
/// The platform-specific iteration state
256-
void * state;
258+
struct rcutils_dir_iter_state_s * state;
257259
} rcutils_dir_iter_t;
258260

259261
/// Begin iterating over the contents of the specified directory.

src/filesystem.c

+20-31
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
#ifdef __cplusplus
16-
extern "C"
17-
{
18-
#endif
1915
#include "rcutils/filesystem.h"
2016

2117
#include <errno.h>
@@ -54,7 +50,7 @@ extern "C"
5450
# define RCUTILS_PATH_DELIMITER "/"
5551
#endif // _WIN32
5652

57-
typedef struct rcutils_dir_iter_state_t
53+
typedef struct rcutils_dir_iter_state_s
5854
{
5955
#ifdef _WIN32
6056
HANDLE handle;
@@ -417,49 +413,48 @@ rcutils_dir_iter_start(const char * directory_path, const rcutils_allocator_t al
417413
RCUTILS_CHECK_ALLOCATOR_WITH_MSG(
418414
&allocator, "allocator is invalid", return NULL);
419415

420-
rcutils_dir_iter_t * iter = (rcutils_dir_iter_t *)allocator.zero_allocate(
416+
rcutils_dir_iter_t * iter = allocator.zero_allocate(
421417
1, sizeof(rcutils_dir_iter_t), allocator.state);
422418
if (NULL == iter) {
423419
return NULL;
424420
}
425421
iter->allocator = allocator;
426422

427-
rcutils_dir_iter_state_t * state = (rcutils_dir_iter_state_t *)allocator.zero_allocate(
423+
iter->state = allocator.zero_allocate(
428424
1, sizeof(rcutils_dir_iter_state_t), allocator.state);
429-
if (NULL == state) {
425+
if (NULL == iter->state) {
430426
RCUTILS_SET_ERROR_MSG(
431427
"Failed to allocate memory.\n");
432428
goto rcutils_dir_iter_start_fail;
433429
}
434-
iter->state = (void *)state;
435430

436431
#ifdef _WIN32
437432
char * search_path = rcutils_join_path(directory_path, "*", allocator);
438433
if (NULL == search_path) {
439434
goto rcutils_dir_iter_start_fail;
440435
}
441-
state->handle = FindFirstFile(search_path, &state->data);
436+
iter->state->handle = FindFirstFile(search_path, &iter->state->data);
442437
allocator.deallocate(search_path, allocator.state);
443-
if (INVALID_HANDLE_VALUE == state->handle) {
438+
if (INVALID_HANDLE_VALUE == iter->state->handle) {
444439
DWORD error = GetLastError();
445440
if (ERROR_FILE_NOT_FOUND != error || !rcutils_is_directory(directory_path)) {
446441
RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(
447442
"Can't open directory %s. Error code: %d\n", directory_path, error);
448443
goto rcutils_dir_iter_start_fail;
449444
}
450445
} else {
451-
iter->entry_name = state->data.cFileName;
446+
iter->entry_name = iter->state->data.cFileName;
452447
}
453448
#else
454-
state->dir = opendir(directory_path);
455-
if (NULL == state->dir) {
449+
iter->state->dir = opendir(directory_path);
450+
if (NULL == iter->state->dir) {
456451
RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(
457452
"Can't open directory %s. Error code: %d\n", directory_path, errno);
458453
goto rcutils_dir_iter_start_fail;
459454
}
460455

461456
errno = 0;
462-
struct dirent * entry = readdir(state->dir);
457+
struct dirent * entry = readdir(iter->state->dir);
463458
if (NULL != entry) {
464459
iter->entry_name = entry->d_name;
465460
} else if (0 != errno) {
@@ -480,17 +475,15 @@ bool
480475
rcutils_dir_iter_next(rcutils_dir_iter_t * iter)
481476
{
482477
RCUTILS_CHECK_ARGUMENT_FOR_NULL(iter, false);
483-
rcutils_dir_iter_state_t * state = (rcutils_dir_iter_state_t *)iter->state;
484-
RCUTILS_CHECK_FOR_NULL_WITH_MSG(state, "iter is invalid", false);
478+
RCUTILS_CHECK_FOR_NULL_WITH_MSG(iter->state, "iter is invalid", false);
485479

486480
#ifdef _WIN32
487-
if (FindNextFile(state->handle, &state->data)) {
488-
iter->entry_name = state->data.cFileName;
481+
if (FindNextFile(iter->state->handle, &iter->state->data)) {
482+
iter->entry_name = iter->state->data.cFileName;
489483
return true;
490484
}
491-
FindClose(state->handle);
492485
#else
493-
struct dirent * entry = readdir(state->dir);
486+
struct dirent * entry = readdir(iter->state->dir);
494487
if (NULL != entry) {
495488
iter->entry_name = entry->d_name;
496489
return true;
@@ -511,17 +504,17 @@ rcutils_dir_iter_end(rcutils_dir_iter_t * iter)
511504
rcutils_allocator_t allocator = iter->allocator;
512505
RCUTILS_CHECK_ALLOCATOR_WITH_MSG(
513506
&allocator, "allocator is invalid", return );
514-
rcutils_dir_iter_state_t * state = (rcutils_dir_iter_state_t *)iter->state;
515-
if (NULL != state) {
507+
508+
if (NULL != iter->state) {
516509
#ifdef _WIN32
517-
FindClose(state->handle);
510+
FindClose(iter->state->handle);
518511
#else
519-
if (NULL != state->dir) {
520-
closedir(state->dir);
512+
if (NULL != iter->state->dir) {
513+
closedir(iter->state->dir);
521514
}
522515
#endif
523516

524-
allocator.deallocate(state, allocator.state);
517+
allocator.deallocate(iter->state, allocator.state);
525518
}
526519

527520
allocator.deallocate(iter, allocator.state);
@@ -540,7 +533,3 @@ rcutils_get_file_size(const char * file_path)
540533
int rc = stat(file_path, &stat_buffer);
541534
return rc == 0 ? (size_t)(stat_buffer.st_size) : 0;
542535
}
543-
544-
#ifdef __cplusplus
545-
}
546-
#endif

0 commit comments

Comments
 (0)