From 4af18b34f4193eb1ffa0415d50f952aa781ef2da Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 11 Oct 2018 10:51:21 +0200 Subject: Support O_DIRECTORY open() flag Close #3545. --- cpukit/libcsupport/src/open.c | 15 +++++++++++++-- testsuites/psxtests/psxfile01/test.c | 25 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/cpukit/libcsupport/src/open.c b/cpukit/libcsupport/src/open.c index 8558e207d3..554311c5aa 100644 --- a/cpukit/libcsupport/src/open.c +++ b/cpukit/libcsupport/src/open.c @@ -73,6 +73,7 @@ static int do_open( bool make = (oflag & O_CREAT) == O_CREAT; bool exclusive = (oflag & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL); bool truncate = (oflag & O_TRUNC) == O_TRUNC; + bool open_dir; int eval_flags = RTEMS_FS_FOLLOW_LINK | (read_access ? RTEMS_FS_PERMS_READ : 0) | (write_access ? RTEMS_FS_PERMS_WRITE : 0) @@ -86,14 +87,24 @@ static int do_open( create_regular_file( &ctx, mode ); } - if ( write_access ) { +#ifdef O_DIRECTORY + open_dir = ( oflag & O_DIRECTORY ) == O_DIRECTORY; +#else + open_dir = false; +#endif + + if ( write_access || open_dir ) { const rtems_filesystem_location_info_t *currentloc = rtems_filesystem_eval_path_get_currentloc( &ctx ); mode_t type = rtems_filesystem_location_type( currentloc ); - if ( S_ISDIR( type ) ) { + if ( write_access && S_ISDIR( type ) ) { rtems_filesystem_eval_path_error( &ctx, EISDIR ); } + + if ( open_dir && !S_ISDIR( type ) ) { + rtems_filesystem_eval_path_error( &ctx, ENOTDIR ); + } } rtems_filesystem_eval_path_extract_currentloc( &ctx, &iop->pathinfo ); diff --git a/testsuites/psxtests/psxfile01/test.c b/testsuites/psxtests/psxfile01/test.c index 4f53c1de8a..dbdce86be8 100644 --- a/testsuites/psxtests/psxfile01/test.c +++ b/testsuites/psxtests/psxfile01/test.c @@ -130,6 +130,29 @@ void stat_a_file( } +static void test_open_directory(void) +{ + static const char file[] = "somefile"; + int status; + int fd; + + fd = open( file, O_CREAT, S_IRWXU ); + rtems_test_assert( fd >= 0 ); + + status = close( fd ); + rtems_test_assert( status == 0 ); + +#ifdef O_DIRECTORY + errno = 0; + fd = open( file, O_DIRECTORY, S_IRWXU ); + rtems_test_assert( fd == -1 ); + rtems_test_assert( errno == ENOTDIR ); +#endif + + status = unlink( file ); + rtems_test_assert( status == 0 ); +} + /* * Main entry point of the test */ @@ -161,6 +184,8 @@ int main( TEST_BEGIN(); + test_open_directory(); + /* * Grab the maximum size of an in-memory file. */ -- cgit v1.2.3