servoshell/resources/mod.rs
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::env;
6use std::path::PathBuf;
7use std::sync::Mutex;
8
9use cfg_if::cfg_if;
10
11static CMD_RESOURCE_DIR: Mutex<Option<PathBuf>> = Mutex::new(None);
12
13pub(crate) fn resource_protocol_dir_path() -> PathBuf {
14 resource_root_dir_path().join("resource_protocol")
15}
16
17fn resource_root_dir_path() -> PathBuf {
18 // This needs to be called before the process is sandboxed
19 // as we only give permission to read inside the resources directory,
20 // not the permissions the "search" for the resources directory.
21 let mut dir = CMD_RESOURCE_DIR.lock().unwrap();
22 if let Some(ref path) = *dir {
23 return PathBuf::from(path);
24 }
25
26 // Try ./resources and ./Resources relative to the directory containing the
27 // canonicalized executable path, then each of its ancestors.
28 let mut path = env::current_exe().unwrap().canonicalize().unwrap();
29 while path.pop() {
30 path.push("resources");
31 if path.is_dir() {
32 *dir = Some(path);
33 return dir.clone().unwrap();
34 }
35 path.pop();
36
37 // Check for Resources on mac when using a case sensitive filesystem.
38 path.push("Resources");
39 if path.is_dir() {
40 *dir = Some(path);
41 return dir.clone().unwrap();
42 }
43 path.pop();
44 }
45
46 cfg_if! {
47 if #[cfg(servo_production)] {
48 panic!("Can't find resources directory")
49 } else {
50 // Static assert that this is really a non-production build, rather
51 // than a failure of the build script's production check.
52 const _: () = assert!(cfg!(servo_do_not_use_in_production));
53
54 // Try ./resources in the current directory, then each of its ancestors.
55 // Not to be used in production builds without considering the security implications!
56 let mut path = std::env::current_dir().unwrap();
57 loop {
58 path.push("resources");
59 if path.is_dir() {
60 *dir = Some(path);
61 return dir.clone().unwrap();
62 }
63 path.pop();
64
65 if !path.pop() {
66 panic!("Can't find resources directory")
67 }
68 }
69 }
70 }
71}