@@ -1224,15 +1224,15 @@ fio_access(fio_location location, const char* path, int mode)
12241224{
12251225 if (fio_is_remote (location ))
12261226 {
1227- fio_header hdr ;
1228- size_t path_len = strlen ( path ) + 1 ;
1229- hdr . cop = FIO_ACCESS ;
1230- hdr . handle = -1 ;
1231- hdr . size = path_len ;
1232- hdr . arg = mode ;
1227+ fio_header hdr = {
1228+ . cop = FIO_ACCESS ,
1229+ . handle = -1 ,
1230+ . size = strlen ( path ) + 1 ,
1231+ . arg = mode ,
1232+ } ;
12331233
12341234 IO_CHECK (fio_write_all (fio_stdout , & hdr , sizeof (hdr )), sizeof (hdr ));
1235- IO_CHECK (fio_write_all (fio_stdout , path , path_len ), path_len );
1235+ IO_CHECK (fio_write_all (fio_stdout , path , hdr . size ), hdr . size );
12361236
12371237 IO_CHECK (fio_read_all (fio_stdin , & hdr , sizeof (hdr )), sizeof (hdr ));
12381238 Assert (hdr .cop == FIO_ACCESS );
@@ -1460,7 +1460,6 @@ fio_remove(fio_location location, const char* path, bool missing_ok)
14601460 return result ;
14611461}
14621462
1463-
14641463static void
14651464fio_remove_impl (const char * path , bool missing_ok , int out )
14661465{
@@ -1480,35 +1479,86 @@ fio_remove_impl(const char* path, bool missing_ok, int out)
14801479 IO_CHECK (fio_write_all (out , & hdr , sizeof (hdr )), sizeof (hdr ));
14811480}
14821481
1483- /* Create directory
1484- * TODO: add strict flag
1482+ /*
1483+ * Create directory, also create parent directories if necessary.
1484+ * In strict mode treat already existing directory as error.
1485+ * Return values:
1486+ * 0 - ok
1487+ * -1 - error (check errno)
1488+ */
1489+ static int
1490+ dir_create_dir (const char * dir , mode_t mode , bool strict )
1491+ {
1492+ char parent [MAXPGPATH ];
1493+
1494+ strncpy (parent , dir , MAXPGPATH );
1495+ get_parent_directory (parent );
1496+
1497+ /* Create parent first */
1498+ if (access (parent , F_OK ) == -1 )
1499+ dir_create_dir (parent , mode , false);
1500+
1501+ /* Create directory */
1502+ if (mkdir (dir , mode ) == -1 )
1503+ {
1504+ if (errno == EEXIST && !strict ) /* already exist */
1505+ return 0 ;
1506+ return -1 ;
1507+ }
1508+
1509+ return 0 ;
1510+ }
1511+
1512+ /*
1513+ * Create directory
14851514 */
14861515int
1487- fio_mkdir (fio_location location , const char * path , int mode )
1516+ fio_mkdir (fio_location location , const char * path , int mode , bool strict )
14881517{
14891518 if (fio_is_remote (location ))
14901519 {
1491- fio_header hdr ;
1492- size_t path_len = strlen ( path ) + 1 ;
1493- hdr . cop = FIO_MKDIR ;
1494- hdr . handle = -1 ;
1495- hdr . size = path_len ;
1496- hdr . arg = mode ;
1520+ fio_header hdr = {
1521+ . cop = FIO_MKDIR ,
1522+ . handle = strict ? 1 : 0 , /* ugly "hack" to pass more params*/
1523+ . size = strlen ( path ) + 1 ,
1524+ . arg = mode ,
1525+ } ;
14971526
14981527 IO_CHECK (fio_write_all (fio_stdout , & hdr , sizeof (hdr )), sizeof (hdr ));
1499- IO_CHECK (fio_write_all (fio_stdout , path , path_len ), path_len );
1528+ IO_CHECK (fio_write_all (fio_stdout , path , hdr . size ), hdr . size );
15001529
15011530 IO_CHECK (fio_read_all (fio_stdin , & hdr , sizeof (hdr )), sizeof (hdr ));
15021531 Assert (hdr .cop == FIO_MKDIR );
15031532
1504- return hdr .arg ;
1533+ if (hdr .arg != 0 )
1534+ {
1535+ errno = hdr .arg ;
1536+ return -1 ;
1537+ }
1538+ return 0 ;
15051539 }
15061540 else
15071541 {
1508- return dir_create_dir (path , mode , false );
1542+ return dir_create_dir (path , mode , strict );
15091543 }
15101544}
15111545
1546+ static void
1547+ fio_mkdir_impl (const char * path , int mode , bool strict , int out )
1548+ {
1549+ fio_header hdr = {
1550+ .cop = FIO_MKDIR ,
1551+ .handle = -1 ,
1552+ .size = 0 ,
1553+ .arg = 0 ,
1554+ };
1555+
1556+ if (dir_create_dir (path , mode , strict ) != 0 )
1557+ hdr .arg = errno ;
1558+
1559+ IO_CHECK (fio_write_all (out , & hdr , sizeof (hdr )), sizeof (hdr ));
1560+ }
1561+
15121562/* Change file mode */
15131563int
15141564fio_chmod (fio_location location , const char * path , int mode )
@@ -3384,9 +3434,7 @@ fio_communicate(int in, int out)
33843434 fio_remove_impl (buf , hdr .arg == 1 , out );
33853435 break ;
33863436 case FIO_MKDIR : /* Create directory */
3387- hdr .size = 0 ;
3388- hdr .arg = dir_create_dir (buf , hdr .arg , false);
3389- IO_CHECK (fio_write_all (out , & hdr , sizeof (hdr )), sizeof (hdr ));
3437+ fio_mkdir_impl (buf , hdr .arg , hdr .handle == 1 , out );
33903438 break ;
33913439 case FIO_CHMOD : /* Change file mode */
33923440 SYS_CHECK (chmod (buf , hdr .arg ));
0 commit comments