Chromium Code Reviews| Index: ports/nacl-spawn/nacl_spawn.cc |
| diff --git a/ports/nacl-spawn/nacl_spawn.cc b/ports/nacl-spawn/nacl_spawn.cc |
| index 6e38de0858f04aab23cba2fdd989c332c969074b..8a0b5bcb2484f2691d4365a6bb386868a81ebe40 100644 |
| --- a/ports/nacl-spawn/nacl_spawn.cc |
| +++ b/ports/nacl-spawn/nacl_spawn.cc |
| @@ -17,6 +17,7 @@ |
| #include <fcntl.h> |
| #include <libgen.h> |
| #include <limits.h> |
| +#include <locale.h> |
| #include <irt.h> |
| #include <irt_dev.h> |
| #include <netinet/in.h> |
| @@ -25,6 +26,7 @@ |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| +#include <sys/mount.h> |
| #include <sys/socket.h> |
| #include <sys/stat.h> |
| #include <sys/types.h> |
| @@ -45,8 +47,9 @@ |
| extern char** environ; |
| -extern int nacl_spawn_pid; |
| -extern int nacl_spawn_ppid; |
| + |
| +int nacl_spawn_pid; |
| +int nacl_spawn_ppid; |
| struct NaClSpawnReply { |
| pthread_mutex_t mu; |
| @@ -55,6 +58,124 @@ struct NaClSpawnReply { |
| pp::VarDictionary result; |
| }; |
| + |
| +// Get an environment variable as an int, or return -1 if the value cannot |
| +// be converted to an int. |
| +static int getenv_as_int(const char *env) { |
| + const char* env_str = getenv(env); |
| + if (!env_str) { |
| + return -1; |
| + } |
| + errno = 0; |
| + int env_int = strtol(env_str, NULL, 0); |
| + if (errno) { |
| + return -1; |
| + } |
| + return env_int; |
| +} |
| + |
| +static int mkdir_checked(const char* dir) { |
| + int rtn = mkdir(dir, S_IRWXU | S_IRWXG | S_IRWXO); |
| + if (rtn != 0) { |
| + fprintf(stderr, "mkdir '%s' failed: %s\n", dir, strerror(errno)); |
| + } |
| + return rtn; |
| +} |
| + |
| +static int do_mount(const char *source, const char *target, |
| + const char *filesystemtype, unsigned long mountflags, |
| + const void *data) { |
| + NACL_LOG("mount[%s] '%s' at '%s'\n", filesystemtype, source, target); |
| + return mount(source, target, filesystemtype, mountflags, data); |
| +} |
| + |
| +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.
|
| + umount("/"); |
| + do_mount("", "/", "memfs", 0, NULL); |
| + |
| + // Setup common environment variables, but don't override those |
| + // set already by ppapi_simple. |
| + setenv("HOME", "/home/user", 0); |
| + setenv("PATH", "/bin", 0); |
| + setenv("USER", "user", 0); |
| + setenv("LOGNAME", "user", 0); |
| + |
| + const char* home = getenv("HOME"); |
| + mkdir_checked("/home"); |
| + mkdir_checked(home); |
| + mkdir_checked("/tmp"); |
| + mkdir_checked("/bin"); |
| + mkdir_checked("/etc"); |
| + mkdir_checked("/mnt"); |
| + mkdir_checked("/mnt/http"); |
| + mkdir_checked("/mnt/html5"); |
| + |
| + const char* data_url = getenv("NACL_DATA_URL"); |
| + if (!data_url) |
| + data_url = "./"; |
| + NACL_LOG("NACL_DATA_URL=%s\n", data_url); |
| + |
| + const char* mount_flags = getenv("NACL_DATA_MOUNT_FLAGS"); |
| + if (!mount_flags) |
| + mount_flags = ""; |
| + NACL_LOG("NACL_DATA_MOUNT_FLAGS=%s\n", mount_flags); |
| + |
| + if (do_mount(data_url, "/mnt/http", "httpfs", 0, mount_flags) != 0) { |
| + perror("mounting http filesystem at /mnt/http failed"); |
| + } |
| + |
| + if (do_mount("/", "/mnt/html5", "html5fs", 0, "type=PERSISTENT") != 0) { |
| + perror("Mounting HTML5 filesystem in /mnt/html5 failed"); |
| + } else { |
| + mkdir("/mnt/html5/home", 0777); |
| + struct stat st; |
| + if (stat("/mnt/html5/home", &st) < 0 || !S_ISDIR(st.st_mode)) { |
| + perror("Unable to create home directory in persistent storage"); |
| + } else { |
| + if (do_mount("/home", home, "html5fs", 0, "type=PERSISTENT") != 0) { |
| + fprintf(stderr, "Mounting HTML5 filesystem in %s failed.\n", home); |
| + } |
| + } |
| + } |
| + |
| + if (do_mount("/", "/tmp", "html5fs", 0, "type=TEMPORARY") != 0) { |
| + perror("Mounting HTML5 filesystem in /tmp failed"); |
| + } |
| + |
| + /* naclprocess.js sends the current working directory using this |
| + * environment variable. */ |
| + const char* pwd = getenv("PWD"); |
| + if (pwd != NULL) { |
| + if (chdir(pwd)) { |
| + fprintf(stderr, "chdir() to %s failed: %s\n", pwd, strerror(errno)); |
| + } |
| + } |
| + |
| + // Tell the NaCl architecture to /etc/bashrc of mingn. |
| +#if defined(__x86_64__) |
| + static const char kNaClArch[] = "x86_64"; |
| +#elif defined(__i686__) |
| + static const char kNaClArch[] = "i686"; |
| +#elif defined(__arm__) |
| + static const char kNaClArch[] = "arm"; |
| +#elif defined(__pnacl__) |
| + static const char kNaClArch[] = "pnacl"; |
| +#else |
| +# error "Unknown architecture" |
| +#endif |
| + // Set NACL_ARCH with a guess if not set (0 == set if not already). |
| + setenv("NACL_ARCH", kNaClArch, 0); |
| + // Set NACL_BOOT_ARCH if not inherited from a parent (0 == set if not already |
| + // set). This will let us prefer PNaCl if we started with PNaCl (for tests |
| + // mainly). |
| + setenv("NACL_BOOT_ARCH", kNaClArch, 0); |
| + |
| + setlocale(LC_CTYPE, ""); |
| + |
| + nacl_spawn_pid = getenv_as_int("NACL_PID"); |
| + nacl_spawn_ppid = getenv_as_int("NACL_PPID"); |
| +} |
| + |
| static std::string GetCwd() { |
| char cwd[PATH_MAX] = "."; |
| if (!getcwd(cwd, PATH_MAX)) { |