OLD | NEW |
1 // Copyright 2017 The LUCI Authors. All rights reserved. | 1 // Copyright 2017 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Package prober exports Probe, which implements logic to identify a wrapper's | 5 // Package prober exports Probe, which implements logic to identify a wrapper's |
6 // wrapped target. In addition to basic PATH/filename lookup, Prober contains | 6 // wrapped target. In addition to basic PATH/filename lookup, Prober contains |
7 // logic to ensure that the wrapper is not the same software as the current | 7 // logic to ensure that the wrapper is not the same software as the current |
8 // running instance, and enables optional hard-coded wrap target paths and | 8 // running instance, and enables optional hard-coded wrap target paths and |
9 // runtime checks. | 9 // runtime checks. |
10 package prober | 10 package prober |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 // If this process was invoked via symlink, the path to the symlink will be | 78 // If this process was invoked via symlink, the path to the symlink will be |
79 // returned if possible. | 79 // returned if possible. |
80 func (p *Probe) ResolveSelf(argv0 string) error { | 80 func (p *Probe) ResolveSelf(argv0 string) error { |
81 if p.Self != "" { | 81 if p.Self != "" { |
82 return nil | 82 return nil |
83 } | 83 } |
84 | 84 |
85 // Get the authoritative executable from the system. | 85 // Get the authoritative executable from the system. |
86 exec, err := os.Executable() | 86 exec, err := os.Executable() |
87 if err != nil { | 87 if err != nil { |
88 » » return errors.Annotate(err).Reason("failed to get executable").E
rr() | 88 » » return errors.Annotate(err, "failed to get executable").Err() |
89 } | 89 } |
90 | 90 |
91 execStat, err := os.Stat(exec) | 91 execStat, err := os.Stat(exec) |
92 if err != nil { | 92 if err != nil { |
93 » » return errors.Annotate(err).Reason("failed to stat executable: %
(path)s"). | 93 » » return errors.Annotate(err, "failed to stat executable: %s", exe
c).Err() |
94 » » » D("path", exec). | |
95 » » » Err() | |
96 } | 94 } |
97 | 95 |
98 // Before using "os.Executable" result, which is known to resolve symlin
ks on | 96 // Before using "os.Executable" result, which is known to resolve symlin
ks on |
99 // Linux, try and identify via argv0. | 97 // Linux, try and identify via argv0. |
100 if argv0 != "" && filesystem.AbsPath(&argv0) == nil { | 98 if argv0 != "" && filesystem.AbsPath(&argv0) == nil { |
101 if st, err := os.Stat(argv0); err == nil && os.SameFile(execStat
, st) { | 99 if st, err := os.Stat(argv0); err == nil && os.SameFile(execStat
, st) { |
102 // argv[0] is the same file as our executable, but may b
e an unresolved | 100 // argv[0] is the same file as our executable, but may b
e an unresolved |
103 // symlink. Prefer it. | 101 // symlink. Prefer it. |
104 p.Self, p.SelfStat = argv0, st | 102 p.Self, p.SelfStat = argv0, st |
105 return nil | 103 return nil |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 } | 179 } |
182 checked[dir] = struct{}{} | 180 checked[dir] = struct{}{} |
183 | 181 |
184 path := p.checkDir(c, dir, selfDirStat, env) | 182 path := p.checkDir(c, dir, selfDirStat, env) |
185 if path != "" { | 183 if path != "" { |
186 return path, nil | 184 return path, nil |
187 } | 185 } |
188 } | 186 } |
189 | 187 |
190 return "", errors.Reason("could not find target in system"). | 188 return "", errors.Reason("could not find target in system"). |
191 » » D("target", p.Target). | 189 » » InternalReason("target(%s)/dirs(%v)", p.Target, pathDirs).Err() |
192 » » D("dirs", pathDirs). | |
193 » » Err() | |
194 } | 190 } |
195 | 191 |
196 // checkDir checks "checkDir" for our Target executable. It ignores | 192 // checkDir checks "checkDir" for our Target executable. It ignores |
197 // executables whose target is the same file or shares the same parent directory | 193 // executables whose target is the same file or shares the same parent directory |
198 // as "self". | 194 // as "self". |
199 func (p *Probe) checkDir(c context.Context, dir string, selfDir os.FileInfo, env
environ.Env) string { | 195 func (p *Probe) checkDir(c context.Context, dir string, selfDir os.FileInfo, env
environ.Env) string { |
200 // If we have a self directory defined, ensure that "dir" isn't the same | 196 // If we have a self directory defined, ensure that "dir" isn't the same |
201 // directory. If it is, we will ignore this option, since we are looking
for | 197 // directory. If it is, we will ignore this option, since we are looking
for |
202 // something outside of the wrapper directory. | 198 // something outside of the wrapper directory. |
203 if selfDir != nil { | 199 if selfDir != nil { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 return "" | 252 return "" |
257 | 253 |
258 case isWrapper: | 254 case isWrapper: |
259 logging.Debugf(c, "Candidate is a wrapper: %s", t) | 255 logging.Debugf(c, "Candidate is a wrapper: %s", t) |
260 return "" | 256 return "" |
261 } | 257 } |
262 } | 258 } |
263 | 259 |
264 return t | 260 return t |
265 } | 261 } |
OLD | NEW |