Skip to main content

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}