From 9f18eedb6b82cf5877c58ba29a59b35955ba16cd Mon Sep 17 00:00:00 2001
From: Maria <marianneliash@gmail.com>
Date: Mon, 9 Sep 2019 16:28:02 +0300
Subject: [PATCH] Proper error handling for fio.mktree

Method fio.mktree is used to create given path unconditionally -
without checking if it was a directory or something else. This
led to inappropriate error messages or even inconsistent behavior.
Now check the type of a given path.

Closes #4439

(cherry picked from commit 8ccfc6914801605daed938f543b73a8a6f5e3030)
---
 src/lua/fio.lua       |  7 ++++++-
 test/app/fio.result   | 13 +++++++++++++
 test/app/fio.test.lua |  6 ++++++
 3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/lua/fio.lua b/src/lua/fio.lua
index 321ae8b2d5..cb224f3d0f 100644
--- a/src/lua/fio.lua
+++ b/src/lua/fio.lua
@@ -4,6 +4,7 @@ local fio = require('fio')
 local ffi = require('ffi')
 local buffer = require('buffer')
 local fiber = require('fiber')
+local errno = require('errno')
 
 ffi.cdef[[
     int umask(int mask);
@@ -360,12 +361,16 @@ fio.mktree = function(path, mode)
     local current_dir = "/"
     for i, dir in ipairs(dirs) do
         current_dir = fio.pathjoin(current_dir, dir)
-        if not fio.stat(current_dir) then
+        local stat = fio.stat(current_dir)
+        if stat == nil then
             local st, err = fio.mkdir(current_dir, mode)
             if err ~= nil  then
                 return false, string.format("Error creating directory %s: %s",
                     current_dir, tostring(err))
             end
+        elseif not stat:is_dir() then
+            return false, string.format("Error creating directory %s: %s",
+                current_dir, errno.strerror(errno.EEXIST))
         end
     end
     return true
diff --git a/test/app/fio.result b/test/app/fio.result
index 34f58d6bc8..f83c43f440 100644
--- a/test/app/fio.result
+++ b/test/app/fio.result
@@ -1443,3 +1443,16 @@ test_run:cmd("clear filter")
 ---
 - true
 ...
+--
+-- gh-4439: mktree error handling fix - creation of existing file/directory
+--
+fio.mktree('/dev/null')
+---
+- false
+- 'Error creating directory /dev/null: File exists'
+...
+fio.mktree('/dev/null/dir')
+---
+- false
+- 'Error creating directory /dev/null: File exists'
+...
diff --git a/test/app/fio.test.lua b/test/app/fio.test.lua
index be735e4f33..56c957d8a0 100644
--- a/test/app/fio.test.lua
+++ b/test/app/fio.test.lua
@@ -468,3 +468,9 @@ fio.rmtree(1)
 fio.copytree(nil, nil)
 fio.copytree(nil, nil)
 test_run:cmd("clear filter")
+
+--
+-- gh-4439: mktree error handling fix - creation of existing file/directory
+--
+fio.mktree('/dev/null')
+fio.mktree('/dev/null/dir')
-- 
GitLab