[Commits] c6041e48f4d: Make my_realpath work if only the file is missing

vicentiu vicentiu at mariadb.org
Fri Mar 3 13:22:05 EET 2017


revision-id: c6041e48f4d85de6a21c15f1ef0e546220dd9f99 (mariadb-10.0.29-54-gc6041e48f4d)
parent(s): 1acfa942edb72fedcf92dd017ae5fef8694382e5
author: Vicențiu Ciorbaru
committer: Vicențiu Ciorbaru
timestamp: 2017-03-03 13:14:21 +0200
message:

Make my_realpath work if only the file is missing

If a file that contains symlinks in it's path doesn't actually exist,
realpath fails with ENOENT. This causes problems later when running
openat with no symlink following. We can fix this by allowing
realpath to work even if the file doesn't exist. Just run realpath again
without the filename and if it works, append the filename.

Also, adjust test case to reveal correct error code after 5.5 merge.

---
 mysql-test/r/myisam-system.result |  2 +-
 mysys/my_symlink.c                | 27 ++++++++++++++++++++++++++-
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/mysql-test/r/myisam-system.result b/mysql-test/r/myisam-system.result
index 65684a3c07b..af5de8f2749 100644
--- a/mysql-test/r/myisam-system.result
+++ b/mysql-test/r/myisam-system.result
@@ -5,7 +5,7 @@ Warnings:
 Warning	2	Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory")
 create table t1 (a int) engine=myisam;
 select * from t1;
-ERROR HY000: Can't find file: './test/t1.MYI' (errno: 20 "Not a directory")
+ERROR HY000: Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory")
 drop table t1;
 Warnings:
 Warning	2	Can't find file: './test/t1.MYI' (errno: 2 "No such file or directory")
diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c
index ed35fff41e9..0e3a9681fbd 100644
--- a/mysys/my_symlink.c
+++ b/mysys/my_symlink.c
@@ -136,11 +136,36 @@ int my_realpath(char *to, const char *filename, myf MyFlags)
 #if defined(HAVE_REALPATH) && !defined(HAVE_BROKEN_REALPATH)
   int result=0;
   char buff[BUFF_LEN];
+  char buff2[BUFF_LEN];
   char *ptr;
   DBUG_ENTER("my_realpath");
 
   DBUG_PRINT("info",("executing realpath"));
-  if ((ptr=realpath(filename,buff)))
+  ptr= realpath(filename, buff);
+  if (!ptr && errno == ENOENT)
+  {
+    strcpy(buff2, filename);
+    int len= strlen(buff);
+    while (len > 0)
+    {
+      if (buff2[len - 1] == '/')
+      {
+        buff2[len - 1] = '\0';
+        break;
+      }
+      len--;
+    }
+    if (len > 0)
+    {
+      ptr= realpath(buff2, buff);
+      if (ptr)
+      {
+        strcat(buff, "/");
+        strcat(buff, buff2 + len);
+      }
+    }
+  }
+  if (ptr)
     strmake(to, ptr, FN_REFLEN-1);
   else
   {


More information about the commits mailing list