OLD | NEW |
---|---|
1 // Copyright (c) 2014 The Native Client Authors. All rights reserved. | 1 // Copyright (c) 2014 The Native Client 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 // Emulates spawning/waiting process by asking JavaScript to do so. | 5 // Emulates spawning/waiting process by asking JavaScript to do so. |
6 | 6 |
7 // Include quoted spawn.h first so we can build in the presence of an installed | 7 // Include quoted spawn.h first so we can build in the presence of an installed |
8 // copy of nacl-spawn. | 8 // copy of nacl-spawn. |
9 #define IN_NACL_SPAWN_CC | 9 #define IN_NACL_SPAWN_CC |
10 #include "spawn.h" | 10 #include "spawn.h" |
11 | 11 |
12 #include "nacl_main.h" | 12 #include "nacl_main.h" |
13 | 13 |
14 #include <netinet/in.h> | 14 #include <netinet/in.h> |
15 #include <assert.h> | 15 #include <assert.h> |
16 #include <errno.h> | 16 #include <errno.h> |
17 #include <fcntl.h> | 17 #include <fcntl.h> |
18 #include <libgen.h> | 18 #include <libgen.h> |
19 #include <limits.h> | 19 #include <limits.h> |
20 #include <locale.h> | |
20 #include <irt.h> | 21 #include <irt.h> |
21 #include <irt_dev.h> | 22 #include <irt_dev.h> |
22 #include <netinet/in.h> | 23 #include <netinet/in.h> |
23 #include <setjmp.h> | 24 #include <setjmp.h> |
24 #include <stdint.h> | 25 #include <stdint.h> |
25 #include <stdio.h> | 26 #include <stdio.h> |
26 #include <stdlib.h> | 27 #include <stdlib.h> |
27 #include <string.h> | 28 #include <string.h> |
29 #include <sys/mount.h> | |
28 #include <sys/socket.h> | 30 #include <sys/socket.h> |
29 #include <sys/stat.h> | 31 #include <sys/stat.h> |
30 #include <sys/types.h> | 32 #include <sys/types.h> |
31 #include <sys/wait.h> | 33 #include <sys/wait.h> |
32 #include <unistd.h> | 34 #include <unistd.h> |
33 | 35 |
34 #include <string> | 36 #include <string> |
35 #include <vector> | 37 #include <vector> |
36 | 38 |
37 #include "ppapi/cpp/instance.h" | 39 #include "ppapi/cpp/instance.h" |
38 #include "ppapi/cpp/var.h" | 40 #include "ppapi/cpp/var.h" |
39 #include "ppapi/cpp/var_array.h" | 41 #include "ppapi/cpp/var_array.h" |
40 #include "ppapi/cpp/var_dictionary.h" | 42 #include "ppapi/cpp/var_dictionary.h" |
41 #include "ppapi_simple/ps_instance.h" | 43 #include "ppapi_simple/ps_instance.h" |
42 | 44 |
43 #include "library_dependencies.h" | 45 #include "library_dependencies.h" |
44 #include "path_util.h" | 46 #include "path_util.h" |
45 | 47 |
46 | 48 |
47 extern char** environ; | 49 extern char** environ; |
48 extern int nacl_spawn_pid; | 50 |
49 extern int nacl_spawn_ppid; | 51 int nacl_spawn_pid; |
52 int nacl_spawn_ppid; | |
50 | 53 |
51 struct NaClSpawnReply { | 54 struct NaClSpawnReply { |
52 pthread_mutex_t mu; | 55 pthread_mutex_t mu; |
53 pthread_cond_t cond; | 56 pthread_cond_t cond; |
54 | 57 |
55 pp::VarDictionary result; | 58 pp::VarDictionary result; |
56 }; | 59 }; |
57 | 60 |
61 | |
62 // Get an environment variable as an int, or return -1 if the value cannot | |
63 // be converted to an int. | |
64 static int getenv_as_int(const char *env) { | |
65 const char* env_str = getenv(env); | |
66 if (!env_str) { | |
67 return -1; | |
68 } | |
69 errno = 0; | |
70 int env_int = strtol(env_str, NULL, 0); | |
71 if (errno) { | |
72 return -1; | |
73 } | |
74 return env_int; | |
75 } | |
76 | |
77 static int mkdir_checked(const char* dir) { | |
78 int rtn = mkdir(dir, S_IRWXU | S_IRWXG | S_IRWXO); | |
79 if (rtn != 0) { | |
80 fprintf(stderr, "mkdir '%s' failed: %s\n", dir, strerror(errno)); | |
81 } | |
82 return rtn; | |
83 } | |
84 | |
85 static int do_mount(const char *source, const char *target, | |
86 const char *filesystemtype, unsigned long mountflags, | |
87 const void *data) { | |
88 NACL_LOG("mount[%s] '%s' at '%s'\n", filesystemtype, source, target); | |
89 return mount(source, target, filesystemtype, mountflags, data); | |
90 } | |
91 | |
92 extern "C" void setup_nacl_spawn_env() { | |
Sam Clegg
2015/02/17 18:22:45
Don't need the "extern C" if you declare this in t
gdeepti
2015/02/17 21:06:49
Done.
| |
93 umount("/"); | |
94 do_mount("", "/", "memfs", 0, NULL); | |
95 | |
96 // Setup common environment variables, but don't override those | |
97 // set already by ppapi_simple. | |
98 setenv("HOME", "/home/user", 0); | |
99 setenv("PATH", "/bin", 0); | |
100 setenv("USER", "user", 0); | |
101 setenv("LOGNAME", "user", 0); | |
102 | |
103 const char* home = getenv("HOME"); | |
104 mkdir_checked("/home"); | |
105 mkdir_checked(home); | |
106 mkdir_checked("/tmp"); | |
107 mkdir_checked("/bin"); | |
108 mkdir_checked("/etc"); | |
109 mkdir_checked("/mnt"); | |
110 mkdir_checked("/mnt/http"); | |
111 mkdir_checked("/mnt/html5"); | |
112 | |
113 const char* data_url = getenv("NACL_DATA_URL"); | |
114 if (!data_url) | |
115 data_url = "./"; | |
116 NACL_LOG("NACL_DATA_URL=%s\n", data_url); | |
117 | |
118 const char* mount_flags = getenv("NACL_DATA_MOUNT_FLAGS"); | |
119 if (!mount_flags) | |
120 mount_flags = ""; | |
121 NACL_LOG("NACL_DATA_MOUNT_FLAGS=%s\n", mount_flags); | |
122 | |
123 if (do_mount(data_url, "/mnt/http", "httpfs", 0, mount_flags) != 0) { | |
124 perror("mounting http filesystem at /mnt/http failed"); | |
125 } | |
126 | |
127 if (do_mount("/", "/mnt/html5", "html5fs", 0, "type=PERSISTENT") != 0) { | |
128 perror("Mounting HTML5 filesystem in /mnt/html5 failed"); | |
129 } else { | |
130 mkdir("/mnt/html5/home", 0777); | |
131 struct stat st; | |
132 if (stat("/mnt/html5/home", &st) < 0 || !S_ISDIR(st.st_mode)) { | |
133 perror("Unable to create home directory in persistent storage"); | |
134 } else { | |
135 if (do_mount("/home", home, "html5fs", 0, "type=PERSISTENT") != 0) { | |
136 fprintf(stderr, "Mounting HTML5 filesystem in %s failed.\n", home); | |
137 } | |
138 } | |
139 } | |
140 | |
141 if (do_mount("/", "/tmp", "html5fs", 0, "type=TEMPORARY") != 0) { | |
142 perror("Mounting HTML5 filesystem in /tmp failed"); | |
143 } | |
144 | |
145 /* naclprocess.js sends the current working directory using this | |
146 * environment variable. */ | |
147 const char* pwd = getenv("PWD"); | |
148 if (pwd != NULL) { | |
149 if (chdir(pwd)) { | |
150 fprintf(stderr, "chdir() to %s failed: %s\n", pwd, strerror(errno)); | |
151 } | |
152 } | |
153 | |
154 // Tell the NaCl architecture to /etc/bashrc of mingn. | |
155 #if defined(__x86_64__) | |
156 static const char kNaClArch[] = "x86_64"; | |
157 #elif defined(__i686__) | |
158 static const char kNaClArch[] = "i686"; | |
159 #elif defined(__arm__) | |
160 static const char kNaClArch[] = "arm"; | |
161 #elif defined(__pnacl__) | |
162 static const char kNaClArch[] = "pnacl"; | |
163 #else | |
164 # error "Unknown architecture" | |
165 #endif | |
166 // Set NACL_ARCH with a guess if not set (0 == set if not already). | |
167 setenv("NACL_ARCH", kNaClArch, 0); | |
168 // Set NACL_BOOT_ARCH if not inherited from a parent (0 == set if not already | |
169 // set). This will let us prefer PNaCl if we started with PNaCl (for tests | |
170 // mainly). | |
171 setenv("NACL_BOOT_ARCH", kNaClArch, 0); | |
172 | |
173 setlocale(LC_CTYPE, ""); | |
174 | |
175 nacl_spawn_pid = getenv_as_int("NACL_PID"); | |
176 nacl_spawn_ppid = getenv_as_int("NACL_PPID"); | |
177 } | |
178 | |
58 static std::string GetCwd() { | 179 static std::string GetCwd() { |
59 char cwd[PATH_MAX] = "."; | 180 char cwd[PATH_MAX] = "."; |
60 if (!getcwd(cwd, PATH_MAX)) { | 181 if (!getcwd(cwd, PATH_MAX)) { |
61 NACL_LOG("getcwd failed: %s\n", strerror(errno)); | 182 NACL_LOG("getcwd failed: %s\n", strerror(errno)); |
62 assert(0); | 183 assert(0); |
63 } | 184 } |
64 return cwd; | 185 return cwd; |
65 } | 186 } |
66 | 187 |
67 static std::string GetAbsPath(const std::string& path) { | 188 static std::string GetAbsPath(const std::string& path) { |
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
856 return spawnve_impl(P_OVERLAY, path, argv, envp); | 977 return spawnve_impl(P_OVERLAY, path, argv, envp); |
857 } | 978 } |
858 | 979 |
859 int execlpe(const char *path, const char *arg, ...) { /* char* const envp[] */ | 980 int execlpe(const char *path, const char *arg, ...) { /* char* const envp[] */ |
860 VARG_TO_ARGV_ENVP; | 981 VARG_TO_ARGV_ENVP; |
861 // TODO(bradnelson): Limit path resolution to 'p' variants. | 982 // TODO(bradnelson): Limit path resolution to 'p' variants. |
862 return spawnve_impl(P_OVERLAY, path, argv, envp); | 983 return spawnve_impl(P_OVERLAY, path, argv, envp); |
863 } | 984 } |
864 | 985 |
865 }; // extern "C" | 986 }; // extern "C" |
OLD | NEW |