| 2121 | } |
| 2122 | |
| 2123 | fileRead(fd: number, err: any, bytesRead: number, buf: Buffer): void { |
| 2124 | // we don't care about errors, just releasing resources |
| 2125 | this.kernel.fs.close(fd, function(e?: any): void {}); |
| 2126 | |
| 2127 | if (err) { |
| 2128 | this.onRunnable(err, undefined); |
| 2129 | this.exit(-1); |
| 2130 | return; |
| 2131 | } |
| 2132 | |
| 2133 | function isShebang(buf: Buffer): boolean { |
| 2134 | return buf.length > 2 |
| 2135 | && buf.readUInt8(0) === 0x23 /*'#'*/ |
| 2136 | && buf.readUInt8(1) === 0x21 /*'!'*/; |
| 2137 | } |
| 2138 | |
| 2139 | function isWasm(buf: Buffer): boolean { |
| 2140 | return buf.length > 4 |
| 2141 | && buf.readUInt8(0) === 0x00 /*null*/ |
| 2142 | && buf.readUInt8(1) === 0x61 /*'a'*/ |
| 2143 | && buf.readUInt8(2) === 0x73 /*'s'*/ |
| 2144 | && buf.readUInt8(3) === 0x6d /*'m'*/; |
| 2145 | } |
| 2146 | |
| 2147 | // Some executables (typically scripts) have a shebang |
| 2148 | // line that specifies an interpreter to use on the |
| 2149 | // rest of the file. Check for that here, and adjust |
| 2150 | // things accordingly. |
| 2151 | // |
| 2152 | // TODO: abstract this into something like a binfmt |
| 2153 | // handler |
| 2154 | if (isShebang(buf)) { |
| 2155 | let newlinePos = buf.indexOf('\n'); |
| 2156 | if (newlinePos < 0) |
| 2157 | throw new Error('shebang with no newline: ' + buf); |
| 2158 | let shebang = buf.slice(2, newlinePos).toString(); |
| 2159 | buf = buf.slice(newlinePos+1); |
| 2160 | |
| 2161 | let parts = shebang.match(/\S+/g); |
| 2162 | let cmd = parts[0]; |
| 2163 | |
| 2164 | // many commands don't want to hardcode the |
| 2165 | // path to the interpreter (for example - on |
| 2166 | // OSX node is located at /usr/local/bin/node |
| 2167 | // and on Linux it is typically at |
| 2168 | // /usr/bin/node). This type of issue is |
| 2169 | // worked around by using /usr/bin/env $EXE, |
| 2170 | // which consults your $PATH. We special case |
| 2171 | // that here for 2 reasons - to avoid |
| 2172 | // implementing env (minor), and as a |
| 2173 | // performance improvement (major). |
| 2174 | if (parts.length === 2 && (parts[0] === '/usr/bin/env' || parts[0] === '/bin/env')) { |
| 2175 | cmd = '/usr/bin/' + parts[1]; |
| 2176 | } |
| 2177 | |
| 2178 | // make sure this argument is an |
| 2179 | // absolute-valued path. |
| 2180 | this.pendingArgs[0] = this.pendingExePath; |