| OLD | NEW |
| (Empty) |
| 1 /* | |
| 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 | |
| 4 * found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 /* Define a typical entry point for command line tools spawned by bash | |
| 8 * (e.g., ls, objdump, and objdump). */ | |
| 9 | |
| 10 #include <assert.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" | |
| 23 #include "ppapi_simple/ps_main.h" | |
| 24 | |
| 25 extern int nacl_main(int argc, char *argv[]); | |
| 26 | |
| 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 | |
| 60 extern "C" int cli_main(int argc, char* argv[]) { | |
| 61 umount("/"); | |
| 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); | |
| 147 } | |
| 148 | |
| 149 PPAPI_SIMPLE_REGISTER_MAIN(cli_main) | |
| OLD | NEW |