OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2014 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2014 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
Sam Clegg
2015/02/13 18:35:18
How hard would it be to turn this back into a .c f
gdeepti
2015/02/13 21:43:55
It shouldn't be hard, will check it in with the ne
| |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 /* Define a typical entry point for command line tools spawned by bash | 7 /* Define a typical entry point for command line tools spawned by bash |
8 * (e.g., ls, objdump, and objdump). */ | 8 * (e.g., ls, objdump, and objdump). */ |
9 | 9 |
10 #include <assert.h> | 10 #include "ppapi_simple/ps_main.h" |
11 #include <errno.h> | |
12 #include <fcntl.h> | |
13 #include <locale.h> | |
14 #include <stdio.h> | |
15 #include <stdlib.h> | |
16 #include <string.h> | |
17 #include <sys/mount.h> | |
18 #include <sys/stat.h> | |
19 #include <sys/types.h> | |
20 #include <unistd.h> | |
21 | |
22 #include "nacl_main.h" | 11 #include "nacl_main.h" |
23 #include "ppapi_simple/ps_main.h" | |
24 | 12 |
25 extern int nacl_main(int argc, char *argv[]); | 13 extern int nacl_main(int argc, char *argv[]); |
26 | 14 void setup_env(); |
27 int nacl_spawn_pid; | |
28 int nacl_spawn_ppid; | |
29 | |
30 // Get an environment variable as an int, or return -1 if the value cannot | |
31 // be converted to an int. | |
32 static int getenv_as_int(const char *env) { | |
33 const char* env_str = getenv(env); | |
34 if (!env_str) { | |
35 return -1; | |
36 } | |
37 errno = 0; | |
38 int env_int = strtol(env_str, NULL, 0); | |
39 if (errno) { | |
40 return -1; | |
41 } | |
42 return env_int; | |
43 } | |
44 | |
45 static int mkdir_checked(const char* dir) { | |
46 int rtn = mkdir(dir, S_IRWXU | S_IRWXG | S_IRWXO); | |
47 if (rtn != 0) { | |
48 fprintf(stderr, "mkdir '%s' failed: %s\n", dir, strerror(errno)); | |
49 } | |
50 return rtn; | |
51 } | |
52 | |
53 static int do_mount(const char *source, const char *target, | |
54 const char *filesystemtype, unsigned long mountflags, | |
55 const void *data) { | |
56 NACL_LOG("mount[%s] '%s' at '%s'\n", filesystemtype, source, target); | |
57 return mount(source, target, filesystemtype, mountflags, data); | |
58 } | |
59 | 15 |
60 extern "C" int cli_main(int argc, char* argv[]) { | 16 extern "C" int cli_main(int argc, char* argv[]) { |
61 umount("/"); | 17 setup_env(); |
62 do_mount("", "/", "memfs", 0, NULL); | |
63 | |
64 // Setup common environment variables, but don't override those | |
65 // set already by ppapi_simple. | |
66 setenv("HOME", "/home/user", 0); | |
67 setenv("PATH", "/bin", 0); | |
68 setenv("USER", "user", 0); | |
69 setenv("LOGNAME", "user", 0); | |
70 | |
71 const char* home = getenv("HOME"); | |
72 mkdir_checked("/home"); | |
73 mkdir_checked(home); | |
74 mkdir_checked("/tmp"); | |
75 mkdir_checked("/bin"); | |
76 mkdir_checked("/etc"); | |
77 mkdir_checked("/mnt"); | |
78 mkdir_checked("/mnt/http"); | |
79 mkdir_checked("/mnt/html5"); | |
80 | |
81 const char* data_url = getenv("NACL_DATA_URL"); | |
82 if (!data_url) | |
83 data_url = "./"; | |
84 NACL_LOG("NACL_DATA_URL=%s\n", data_url); | |
85 | |
86 const char* mount_flags = getenv("NACL_DATA_MOUNT_FLAGS"); | |
87 if (!mount_flags) | |
88 mount_flags = ""; | |
89 NACL_LOG("NACL_DATA_MOUNT_FLAGS=%s\n", mount_flags); | |
90 | |
91 if (do_mount(data_url, "/mnt/http", "httpfs", 0, mount_flags) != 0) { | |
92 perror("mounting http filesystem at /mnt/http failed"); | |
93 } | |
94 | |
95 if (do_mount("/", "/mnt/html5", "html5fs", 0, "type=PERSISTENT") != 0) { | |
96 perror("Mounting HTML5 filesystem in /mnt/html5 failed"); | |
97 } else { | |
98 mkdir("/mnt/html5/home", 0777); | |
99 struct stat st; | |
100 if (stat("/mnt/html5/home", &st) < 0 || !S_ISDIR(st.st_mode)) { | |
101 perror("Unable to create home directory in persistent storage"); | |
102 } else { | |
103 if (do_mount("/home", home, "html5fs", 0, "type=PERSISTENT") != 0) { | |
104 fprintf(stderr, "Mounting HTML5 filesystem in %s failed.\n", home); | |
105 } | |
106 } | |
107 } | |
108 | |
109 if (do_mount("/", "/tmp", "html5fs", 0, "type=TEMPORARY") != 0) { | |
110 perror("Mounting HTML5 filesystem in /tmp failed"); | |
111 } | |
112 | |
113 /* naclprocess.js sends the current working directory using this | |
114 * environment variable. */ | |
115 const char* pwd = getenv("PWD"); | |
116 if (pwd != NULL) { | |
117 if (chdir(pwd)) { | |
118 fprintf(stderr, "chdir() to %s failed: %s\n", pwd, strerror(errno)); | |
119 } | |
120 } | |
121 | |
122 // Tell the NaCl architecture to /etc/bashrc of mingn. | |
123 #if defined(__x86_64__) | |
124 static const char kNaClArch[] = "x86_64"; | |
125 #elif defined(__i686__) | |
126 static const char kNaClArch[] = "i686"; | |
127 #elif defined(__arm__) | |
128 static const char kNaClArch[] = "arm"; | |
129 #elif defined(__pnacl__) | |
130 static const char kNaClArch[] = "pnacl"; | |
131 #else | |
132 # error "Unknown architecture" | |
133 #endif | |
134 // Set NACL_ARCH with a guess if not set (0 == set if not already). | |
135 setenv("NACL_ARCH", kNaClArch, 0); | |
136 // Set NACL_BOOT_ARCH if not inherited from a parent (0 == set if not already | |
137 // set). This will let us prefer PNaCl if we started with PNaCl (for tests | |
138 // mainly). | |
139 setenv("NACL_BOOT_ARCH", kNaClArch, 0); | |
140 | |
141 setlocale(LC_CTYPE, ""); | |
142 | |
143 nacl_spawn_pid = getenv_as_int("NACL_PID"); | |
144 nacl_spawn_ppid = getenv_as_int("NACL_PPID"); | |
145 | |
146 return nacl_main(argc, argv); | 18 return nacl_main(argc, argv); |
147 } | 19 } |
148 | 20 |
149 PPAPI_SIMPLE_REGISTER_MAIN(cli_main) | 21 PPAPI_SIMPLE_REGISTER_MAIN(cli_main) |
OLD | NEW |