@@ -1144,15 +1144,15 @@ fio_access(fio_location location, const char* path, int mode)
11441144{
11451145 if (fio_is_remote (location ))
11461146 {
1147- fio_header hdr ;
1148- size_t path_len = strlen ( path ) + 1 ;
1149- hdr . cop = FIO_ACCESS ;
1150- hdr . handle = -1 ;
1151- hdr . size = path_len ;
1152- hdr . arg = mode ;
1147+ fio_header hdr = {
1148+ . cop = FIO_ACCESS ,
1149+ . handle = -1 ,
1150+ . size = strlen ( path ) + 1 ,
1151+ . arg = mode ,
1152+ } ;
11531153
11541154 IO_CHECK (fio_write_all (fio_stdout , & hdr , sizeof (hdr )), sizeof (hdr ));
1155- IO_CHECK (fio_write_all (fio_stdout , path , path_len ), path_len );
1155+ IO_CHECK (fio_write_all (fio_stdout , path , hdr . size ), hdr . size );
11561156
11571157 IO_CHECK (fio_read_all (fio_stdin , & hdr , sizeof (hdr )), sizeof (hdr ));
11581158 Assert (hdr .cop == FIO_ACCESS );
@@ -1410,7 +1410,6 @@ fio_remove(fio_location location, const char* path, bool missing_ok)
14101410 return result ;
14111411}
14121412
1413-
14141413static void
14151414fio_remove_impl (const char * path , bool missing_ok , int out )
14161415{
@@ -1430,35 +1429,86 @@ fio_remove_impl(const char* path, bool missing_ok, int out)
14301429 IO_CHECK (fio_write_all (out , & hdr , sizeof (hdr )), sizeof (hdr ));
14311430}
14321431
1433- /* Create directory
1434- * TODO: add strict flag
1432+ /*
1433+ * Create directory, also create parent directories if necessary.
1434+ * In strict mode treat already existing directory as error.
1435+ * Return values:
1436+ * 0 - ok
1437+ * -1 - error (check errno)
1438+ */
1439+ static int
1440+ dir_create_dir (const char * dir , mode_t mode , bool strict )
1441+ {
1442+ char parent [MAXPGPATH ];
1443+
1444+ strncpy (parent , dir , MAXPGPATH );
1445+ get_parent_directory (parent );
1446+
1447+ /* Create parent first */
1448+ if (access (parent , F_OK ) == -1 )
1449+ dir_create_dir (parent , mode , false);
1450+
1451+ /* Create directory */
1452+ if (mkdir (dir , mode ) == -1 )
1453+ {
1454+ if (errno == EEXIST && !strict ) /* already exist */
1455+ return 0 ;
1456+ return -1 ;
1457+ }
1458+
1459+ return 0 ;
1460+ }
1461+
1462+ /*
1463+ * Create directory
14351464 */
14361465int
1437- fio_mkdir (fio_location location , const char * path , int mode )
1466+ fio_mkdir (fio_location location , const char * path , int mode , bool strict )
14381467{
14391468 if (fio_is_remote (location ))
14401469 {
1441- fio_header hdr ;
1442- size_t path_len = strlen ( path ) + 1 ;
1443- hdr . cop = FIO_MKDIR ;
1444- hdr . handle = -1 ;
1445- hdr . size = path_len ;
1446- hdr . arg = mode ;
1470+ fio_header hdr = {
1471+ . cop = FIO_MKDIR ,
1472+ . handle = strict ? 1 : 0 , /* ugly "hack" to pass more params*/
1473+ . size = strlen ( path ) + 1 ,
1474+ . arg = mode ,
1475+ } ;
14471476
14481477 IO_CHECK (fio_write_all (fio_stdout , & hdr , sizeof (hdr )), sizeof (hdr ));
1449- IO_CHECK (fio_write_all (fio_stdout , path , path_len ), path_len );
1478+ IO_CHECK (fio_write_all (fio_stdout , path , hdr . size ), hdr . size );
14501479
14511480 IO_CHECK (fio_read_all (fio_stdin , & hdr , sizeof (hdr )), sizeof (hdr ));
14521481 Assert (hdr .cop == FIO_MKDIR );
14531482
1454- return hdr .arg ;
1483+ if (hdr .arg != 0 )
1484+ {
1485+ errno = hdr .arg ;
1486+ return -1 ;
1487+ }
1488+ return 0 ;
14551489 }
14561490 else
14571491 {
1458- return dir_create_dir (path , mode , false );
1492+ return dir_create_dir (path , mode , strict );
14591493 }
14601494}
14611495
1496+ static void
1497+ fio_mkdir_impl (const char * path , int mode , bool strict , int out )
1498+ {
1499+ fio_header hdr = {
1500+ .cop = FIO_MKDIR ,
1501+ .handle = -1 ,
1502+ .size = 0 ,
1503+ .arg = 0 ,
1504+ };
1505+
1506+ if (dir_create_dir (path , mode , strict ) != 0 )
1507+ hdr .arg = errno ;
1508+
1509+ IO_CHECK (fio_write_all (out , & hdr , sizeof (hdr )), sizeof (hdr ));
1510+ }
1511+
14621512/* Change file mode */
14631513int
14641514fio_chmod (fio_location location , const char * path , int mode )
@@ -3835,9 +3885,7 @@ fio_communicate(int in, int out)
38353885 fio_remove_impl (buf , hdr .arg == 1 , out );
38363886 break ;
38373887 case FIO_MKDIR : /* Create directory */
3838- hdr .size = 0 ;
3839- hdr .arg = dir_create_dir (buf , hdr .arg , false);
3840- IO_CHECK (fio_write_all (out , & hdr , sizeof (hdr )), sizeof (hdr ));
3888+ fio_mkdir_impl (buf , hdr .arg , hdr .handle == 1 , out );
38413889 break ;
38423890 case FIO_CHMOD : /* Change file mode */
38433891 SYS_CHECK (chmod (buf , hdr .arg ));
0 commit comments