aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/systemtap/systemtap/0001-sysroot-handle-symbolic-links-with-absolute-name-rel.patch
blob: 8a3d39a5b8367de6def2166b31bda18d3b226fe1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
From 2041085d1a700201dc088991ca8136e7935bf42f Mon Sep 17 00:00:00 2001
From: Victor Kamensky <kamensky@cisco.com>
Date: Wed, 21 Mar 2018 11:35:26 -0500
Subject: [PATCH] sysroot: handle symbolic links with absolute name relative to
 sysroot

In case of symbolic link found under sysroot point to absolute path,
instead of trying to look for such absolute path in host system,
apply sysroot prefix first.

Upstream-Status: Backport
Signed-off-by: Victor Kamensky <kamensky@cisco.com>
---
 util.cxx | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

Index: git/util.cxx
===================================================================
--- git.orig/util.cxx
+++ git/util.cxx
@@ -441,6 +441,64 @@ split_lines(const char *buf, size_t n)
   return lines;
 }
 
+static string
+follow_link(const string& name, const string& sysroot)
+{
+  char *linkname;
+  ssize_t r;
+  string retpath;
+  struct stat st;
+
+  const char *f = name.c_str();
+
+  lstat(f, &st);
+
+  linkname = (char *) malloc(st.st_size + 1);
+
+  if (linkname)
+    {
+      r = readlink(f, linkname, st.st_size + 1);
+      linkname[st.st_size] = '\0';
+      /*
+       * If we have non-empty sysroot and we got link that
+       * points to absolute path name, we need to look at
+       * this path relative to sysroot itself. access and
+       * stat will follow symbolic links correctly only in
+       * case with empty sysroot.
+       */
+      while (r != -1 && linkname && linkname[0] == '/')
+	{
+	  string fname1 = sysroot + linkname;
+	  const char *f1 = fname1.c_str();
+	  if (access(f1, X_OK) == 0
+	      && stat(f1, &st) == 0
+	      && S_ISREG(st.st_mode))
+	    {
+	      retpath = fname1;
+	      break;
+	    }
+	  else if (lstat(f1, &st) == 0
+		   && S_ISLNK(st.st_mode))
+	    {
+	      free(linkname);
+	      linkname = (char *) malloc(st.st_size + 1);
+	      if (linkname)
+		{
+		  r = readlink(f1, linkname, st.st_size + 1);
+		  linkname[st.st_size] = '\0';
+		}
+	    }
+	  else
+	    {
+	      break;
+	    }
+	}
+    }
+  free(linkname);
+
+  return retpath;
+}
+
 // Resolve an executable name to a canonical full path name, with the
 // same policy as execvp().  A program name not containing a slash
 // will be searched along the $PATH.
@@ -465,6 +523,14 @@ string find_executable(const string& nam
   if (name.find('/') != string::npos) // slash in the path already?
     {
       retpath = sysroot + name;
+
+      const char *f = retpath.c_str();
+      if (sysroot != ""
+	  && lstat(f, &st) == 0
+	  && S_ISLNK(st.st_mode))
+	{
+	  retpath = follow_link(f, sysroot);
+	}
     }
   else // Nope, search $PATH.
     {
@@ -493,6 +559,16 @@ string find_executable(const string& nam
                   retpath = fname;
                   break;
                 }
+              else if (sysroot != ""
+                       && lstat(f, &st) == 0
+                       && S_ISLNK(st.st_mode))
+		{
+		  retpath = follow_link(f, sysroot);
+		  if (retpath != "")
+		    {
+		      break;
+		    }
+		}
             }
         }
     }