forked from emscripten-core/emscripten
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlibrary_noderawfs.js
207 lines (203 loc) · 7.83 KB
/
library_noderawfs.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/**
* @license
* Copyright 2018 The Emscripten Authors
* SPDX-License-Identifier: MIT
*/
mergeInto(LibraryManager.library, {
$NODERAWFS__deps: ['$ERRNO_CODES', '$FS', '$NODEFS', '$mmapAlloc'],
$NODERAWFS__postset: `
if (ENVIRONMENT_IS_NODE) {
var _wrapNodeError = function(func) {
return function() {
try {
return func.apply(this, arguments)
} catch (e) {
if (e.code) {
throw new FS.ErrnoError(ERRNO_CODES[e.code]);
}
throw e;
}
}
};
var VFS = Object.assign({}, FS);
for (var _key in NODERAWFS) {
FS[_key] = _wrapNodeError(NODERAWFS[_key]);
}
} else {
throw new Error("NODERAWFS is currently only supported on Node.js environment.")
}`,
$NODERAWFS: {
lookup: function(parent, name) {
#if ASSERTIONS
assert(parent)
assert(parent.path)
#endif
return FS.lookupPath(parent.path + '/' + name).node;
},
lookupPath: function(path, opts) {
opts = opts || {};
if (opts.parent) {
path = nodePath.dirname(path);
}
var st = fs.lstatSync(path);
var mode = NODEFS.getMode(path);
return { path: path, node: { id: st.ino, mode: mode, node_ops: NODERAWFS, path: path }};
},
createStandardStreams: function() {
FS.streams[0] = FS.createStream({ nfd: 0, position: 0, path: '', flags: 0, tty: true, seekable: false }, 0, 0);
for (var i = 1; i < 3; i++) {
FS.streams[i] = FS.createStream({ nfd: i, position: 0, path: '', flags: 577, tty: true, seekable: false }, i, i);
}
},
// generic function for all node creation
cwd: function() { return process.cwd(); },
chdir: function() { process.chdir.apply(void 0, arguments); },
mknod: function(path, mode) {
if (FS.isDir(path)) {
fs.mkdirSync(path, mode);
} else {
fs.writeFileSync(path, '', { mode: mode });
}
},
mkdir: function() { fs.mkdirSync.apply(void 0, arguments); },
symlink: function() { fs.symlinkSync.apply(void 0, arguments); },
rename: function() { fs.renameSync.apply(void 0, arguments); },
rmdir: function() { fs.rmdirSync.apply(void 0, arguments); },
readdir: function() { return ['.', '..'].concat(fs.readdirSync.apply(void 0, arguments)); },
unlink: function() { fs.unlinkSync.apply(void 0, arguments); },
readlink: function() { return fs.readlinkSync.apply(void 0, arguments); },
stat: function() { return fs.statSync.apply(void 0, arguments); },
lstat: function() { return fs.lstatSync.apply(void 0, arguments); },
chmod: function() { fs.chmodSync.apply(void 0, arguments); },
fchmod: function() { fs.fchmodSync.apply(void 0, arguments); },
chown: function() { fs.chownSync.apply(void 0, arguments); },
fchown: function() { fs.fchownSync.apply(void 0, arguments); },
truncate: function() { fs.truncateSync.apply(void 0, arguments); },
ftruncate: function(fd, len) {
// See https://github.com/nodejs/node/issues/35632
if (len < 0) {
throw new FS.ErrnoError({{{ cDefine('EINVAL') }}});
}
fs.ftruncateSync.apply(void 0, arguments);
},
utime: function(path, atime, mtime) { fs.utimesSync(path, atime/1000, mtime/1000); },
open: function(path, flags, mode, suggestFD) {
if (typeof flags == "string") {
flags = VFS.modeStringToFlags(flags)
}
var pathTruncated = path.split('/').map(function(s) { return s.substr(0, 255); }).join('/');
var nfd = fs.openSync(pathTruncated, NODEFS.flagsForNode(flags), mode);
var st = fs.fstatSync(nfd);
if (flags & {{{ cDefine('O_DIRECTORY') }}} && !st.isDirectory()) {
fs.closeSync(nfd);
throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
}
var newMode = NODEFS.getMode(pathTruncated);
var fd = suggestFD != null ? suggestFD : FS.nextfd(nfd);
var node = { id: st.ino, mode: newMode, node_ops: NODERAWFS, path: path }
var stream = FS.createStream({ nfd: nfd, position: 0, path: path, flags: flags, node: node, seekable: true }, fd, fd);
FS.streams[fd] = stream;
return stream;
},
createStream: function(stream, fd_start, fd_end){
// Call the original FS.createStream
var rtn = VFS.createStream(stream, fd_start, fd_end);
if (typeof rtn.shared.refcnt == 'undefined') {
rtn.shared.refcnt = 1;
} else {
rtn.shared.refcnt++;
}
return rtn;
},
closeStream: function(fd) {
if (FS.streams[fd]) {
FS.streams[fd].shared.refcnt--;
}
VFS.closeStream(fd);
},
close: function(stream) {
FS.closeStream(stream.fd);
if (!stream.stream_ops && stream.shared.refcnt === 0) {
// this stream is created by in-memory filesystem
fs.closeSync(stream.nfd);
}
},
llseek: function(stream, offset, whence) {
if (stream.stream_ops) {
// this stream is created by in-memory filesystem
return VFS.llseek(stream, offset, whence);
}
var position = offset;
if (whence === {{{ cDefine('SEEK_CUR') }}}) {
position += stream.position;
} else if (whence === {{{ cDefine('SEEK_END') }}}) {
position += fs.fstatSync(stream.nfd).size;
} else if (whence !== {{{ cDefine('SEEK_SET') }}}) {
throw new FS.ErrnoError({{{ cDefine('EINVAL') }}});
}
if (position < 0) {
throw new FS.ErrnoError({{{ cDefine('EINVAL') }}});
}
stream.position = position;
return position;
},
read: function(stream, buffer, offset, length, position) {
if (stream.stream_ops) {
// this stream is created by in-memory filesystem
return VFS.read(stream, buffer, offset, length, position);
}
var seeking = typeof position != 'undefined';
if (!seeking && stream.seekable) position = stream.position;
var bytesRead = fs.readSync(stream.nfd, Buffer.from(buffer.buffer), offset, length, position);
// update position marker when non-seeking
if (!seeking) stream.position += bytesRead;
return bytesRead;
},
write: function(stream, buffer, offset, length, position) {
if (stream.stream_ops) {
// this stream is created by in-memory filesystem
return VFS.write(stream, buffer, offset, length, position);
}
if (stream.flags & +"{{{ cDefine('O_APPEND') }}}") {
// seek to the end before writing in append mode
FS.llseek(stream, 0, +"{{{ cDefine('SEEK_END') }}}");
}
var seeking = typeof position != 'undefined';
if (!seeking && stream.seekable) position = stream.position;
var bytesWritten = fs.writeSync(stream.nfd, Buffer.from(buffer.buffer), offset, length, position);
// update position marker when non-seeking
if (!seeking) stream.position += bytesWritten;
return bytesWritten;
},
allocate: function() {
throw new FS.ErrnoError({{{ cDefine('EOPNOTSUPP') }}});
},
mmap: function(stream, length, position, prot, flags) {
if (stream.stream_ops) {
// this stream is created by in-memory filesystem
return VFS.mmap(stream, length, position, prot, flags);
}
var ptr = mmapAlloc(length);
FS.read(stream, HEAP8, ptr, length, position);
return { ptr: ptr, allocated: true };
},
msync: function(stream, buffer, offset, length, mmapFlags) {
if (stream.stream_ops) {
// this stream is created by in-memory filesystem
return VFS.msync(stream, buffer, offset, length, mmapFlags);
}
if (mmapFlags & {{{ cDefine('MAP_PRIVATE') }}}) {
// MAP_PRIVATE calls need not to be synced back to underlying fs
return 0;
}
FS.write(stream, buffer, 0, length, offset);
return 0;
},
munmap: function() {
return 0;
},
ioctl: function() {
throw new FS.ErrnoError({{{ cDefine('ENOTTY') }}});
}
}
});