mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-22 09:01:57 -05:00
Webclient: Avoid strerror for printing error code descriptions and use custom implementation instead
Because the error codes hardcoded in interop_web.js no longer match the error codes in emscripten, strerror would print unexpected descriptions due to assuming the provided value used emscripten error codes values (E.g. 'ENOENT' returned by interop_web.js would output 'Operation not permitted' from strerror)
This commit is contained in:
parent
b5f0076d46
commit
6f754a1187
3 changed files with 116 additions and 99 deletions
|
@ -22,20 +22,28 @@
|
|||
#define O_EXCL 0x080
|
||||
#define O_TRUNC 0x200
|
||||
|
||||
/* Unfortunately, errno constants are different in some older emscripten versions */
|
||||
/* (linux errno numbers compared to WASI errno numbers) */
|
||||
/* So just use the same errono numbers as interop_web.js */
|
||||
#define _ENOENT 2
|
||||
#define _EAGAIN 6 /* same as EWOULDBLOCK */
|
||||
#define _EEXIST 17
|
||||
#define _EHOSTUNREACH 23
|
||||
#define _EINPROGRESS 26
|
||||
/* General error codes */
|
||||
#define E_INVALID_VALUE 1
|
||||
/* File I/O specific errors */
|
||||
#define E_ENTRY_NOT_FOUND 2
|
||||
#define E_ENTRY_EXISTS 3
|
||||
#define E_FD_CLOSED 4
|
||||
#define E_TOO_MANY_FDS 5
|
||||
#define E_READONLY_FILE 6
|
||||
#define E_WRITEONLY_FILE 7
|
||||
/* Socket specific errors */
|
||||
#define E_IS_CONN 8
|
||||
#define E_NOT_CONN 9
|
||||
#define E_WOULD_BLOCK 10
|
||||
#define E_INVALID_HOST 11
|
||||
#define E_CONN_INPROGRESS 12
|
||||
#define E_CONN_REFUSED 13
|
||||
|
||||
const cc_result ReturnCode_FileShareViolation = 1000000000; /* Not used in web filesystem backend */
|
||||
const cc_result ReturnCode_FileNotFound = _ENOENT;
|
||||
const cc_result ReturnCode_SocketInProgess = _EINPROGRESS;
|
||||
const cc_result ReturnCode_SocketWouldBlock = _EAGAIN;
|
||||
const cc_result ReturnCode_DirectoryExists = _EEXIST;
|
||||
const cc_result ReturnCode_FileNotFound = E_ENTRY_NOT_FOUND;
|
||||
const cc_result ReturnCode_SocketInProgess = E_CONN_INPROGRESS;
|
||||
const cc_result ReturnCode_SocketWouldBlock = E_WOULD_BLOCK;
|
||||
const cc_result ReturnCode_DirectoryExists = E_ENTRY_EXISTS;
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
|
@ -123,7 +131,7 @@ EMSCRIPTEN_KEEPALIVE void Directory_IterCallback(const char* src) {
|
|||
enum_callback(&path, enum_obj);
|
||||
}
|
||||
|
||||
extern int interop_DirectoryIter(const char* path);
|
||||
extern int interop_DirectoryIterate(const char* path);
|
||||
cc_result Directory_Enum(const cc_string* path, void* obj, Directory_EnumCallback callback) {
|
||||
char str[NATIVE_STR_LEN];
|
||||
String_EncodeUtf8(str, path);
|
||||
|
@ -131,7 +139,7 @@ cc_result Directory_Enum(const cc_string* path, void* obj, Directory_EnumCallbac
|
|||
enum_obj = obj;
|
||||
enum_callback = callback;
|
||||
/* returned result is negative for error */
|
||||
return -interop_DirectoryIter(str);
|
||||
return -interop_DirectoryIterate(str);
|
||||
}
|
||||
|
||||
extern int interop_FileCreate(const char* path, int mode);
|
||||
|
@ -266,7 +274,7 @@ cc_result Socket_Connect(cc_socket* s, const cc_string* address, int port, cc_bo
|
|||
res = -interop_SocketConnect(*s, addr, port);
|
||||
|
||||
/* error returned when invalid address provided */
|
||||
if (res == _EHOSTUNREACH) return ERR_INVALID_ARGUMENT;
|
||||
if (res == E_INVALID_HOST) return ERR_INVALID_ARGUMENT;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -284,8 +292,8 @@ cc_result Socket_Read(cc_socket s, cc_uint8* data, cc_uint32 count, cc_uint32* r
|
|||
*read += res;
|
||||
data += res; count -= res;
|
||||
} else {
|
||||
/* EAGAIN when no more data available */
|
||||
if (res == -_EAGAIN) return *read == 0 ? _EAGAIN : 0;
|
||||
/* E_WOULD_BLOCK when no more data available */
|
||||
if (res == -E_WOULD_BLOCK) return *read == 0 ? E_WOULD_BLOCK : 0;
|
||||
|
||||
return -res;
|
||||
}
|
||||
|
@ -301,11 +309,11 @@ cc_result Socket_Write(cc_socket s, const cc_uint8* data, cc_uint32 count, cc_ui
|
|||
if (res >= 0) {
|
||||
*modified = res; return 0;
|
||||
} else {
|
||||
*modified = 0; return -res;
|
||||
*modified = 0; return -res;
|
||||
}
|
||||
}
|
||||
|
||||
extern int interop_SocketClose(int sock);
|
||||
extern void interop_SocketClose(int sock);
|
||||
void Socket_Close(cc_socket s) {
|
||||
interop_SocketClose(s);
|
||||
}
|
||||
|
@ -343,20 +351,37 @@ cc_result Process_StartOpen(const cc_string* args) {
|
|||
/*########################################################################################################################*
|
||||
*--------------------------------------------------------Platform---------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static const char* const error_descs[] = {
|
||||
NULL,
|
||||
"Invalid argument", /* E_INVALID_VALUE */
|
||||
|
||||
"No such file or directory", /* E_ENTRY_NOT_FOUND */
|
||||
"File or directory already exists", /* E_ENTRY_EXISTS */
|
||||
"File descriptor already closed", /* E_FD_CLOSED */
|
||||
"Too many open File descriptors", /* E_TOO_MANY_FDS */
|
||||
"Write to readonly file", /* E_READONLY_FILE */
|
||||
"Read on writeonly file", /* E_WRITEONLY_FILE */
|
||||
|
||||
"Socket already connecting", /* E_IS_CONN */
|
||||
"Socket not connected", /* E_NOT_CONN */
|
||||
"Operation would block", /* E_WOULD_BLOCK */
|
||||
"Invalid host provided", /* E_INVALID_HOST */
|
||||
"Connection in progress", /* E_CONN_INPROGRESS */
|
||||
"Connection refused", /* E_CONN_REFUSED */
|
||||
};
|
||||
|
||||
cc_bool Platform_DescribeError(cc_result res, cc_string* dst) {
|
||||
char* str;
|
||||
int len;
|
||||
|
||||
/* For unrecognised error codes, strerror might return messages */
|
||||
/* such as 'No error information', which is not very useful */
|
||||
if (res >= 1000) return false;
|
||||
if (res > 0 && res < Array_Elems(error_descs)) {
|
||||
str = error_descs[res];
|
||||
len = String_CalcLen(str, NATIVE_STR_LEN);
|
||||
|
||||
str = strerror(res);
|
||||
if (!str) return false;
|
||||
|
||||
len = String_CalcLen(str, NATIVE_STR_LEN);
|
||||
String_AppendUtf8(dst, str, len);
|
||||
return true;
|
||||
String_AppendUtf8(dst, str, len);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Platform_LogError(const char* msg) {
|
||||
|
|
|
@ -585,7 +585,8 @@ cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args) {
|
|||
fileBuffer[file.length] = '\0';
|
||||
|
||||
/* Calls Window_OnFileUploaded on success */
|
||||
return interop_DownloadFile(fileBuffer, args->filters, args->titles);
|
||||
/* returned result is negative for error */
|
||||
return -interop_DownloadFile(fileBuffer, args->filters, args->titles);
|
||||
}
|
||||
|
||||
void Window_AllocFramebuffer(struct Bitmap* bmp) { }
|
||||
|
|
|
@ -235,24 +235,20 @@ mergeInto(LibraryManager.library, {
|
|||
var path = UTF8ToString(raw);
|
||||
CCFS.chdir(path);
|
||||
},
|
||||
interop_DirectoryIter: function(raw) {
|
||||
var path = UTF8ToString(raw);
|
||||
try {
|
||||
var entries = CCFS.readdir(path);
|
||||
for (var i = 0; i < entries.length; i++)
|
||||
{
|
||||
var path = entries[i];
|
||||
// absolute path to root relative path
|
||||
if (path.indexOf(CCFS.currentPath) === 0) {
|
||||
path = path.substring(CCFS.currentPath.length + 1);
|
||||
}
|
||||
ccall('Directory_IterCallback', 'void', ['string'], [path]);
|
||||
interop_DirectoryIterate: function(raw) {
|
||||
var root = UTF8ToString(raw);
|
||||
var entries = CCFS.getDirEntries(root);
|
||||
|
||||
for (var i = 0; i < entries.length; i++)
|
||||
{
|
||||
var path = entries[i];
|
||||
// absolute path to root relative path
|
||||
if (path.indexOf(CCFS.currentPath) === 0) {
|
||||
path = path.substring(CCFS.currentPath.length + 1);
|
||||
}
|
||||
return 0;
|
||||
} catch (e) {
|
||||
if (!(e instanceof CCFS.ErrnoError)) abort(e);
|
||||
return -e.errno;
|
||||
ccall('Directory_IterCallback', 'void', ['string'], [path]);
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
interop_FileExists: function (raw) {
|
||||
var path = UTF8ToString(raw);
|
||||
|
@ -267,7 +263,7 @@ mergeInto(LibraryManager.library, {
|
|||
return stream.fd|0;
|
||||
} catch (e) {
|
||||
if (!(e instanceof CCFS.ErrnoError)) abort(e);
|
||||
return -e.errno;
|
||||
return e.errno;
|
||||
}
|
||||
},
|
||||
interop_FileRead: function(fd, dst, count) {
|
||||
|
@ -276,7 +272,7 @@ mergeInto(LibraryManager.library, {
|
|||
return CCFS.read(stream, HEAP8, dst, count)|0;
|
||||
} catch (e) {
|
||||
if (!(e instanceof CCFS.ErrnoError)) abort(e);
|
||||
return -e.errno;
|
||||
return e.errno;
|
||||
}
|
||||
},
|
||||
interop_FileWrite: function(fd, src, count) {
|
||||
|
@ -285,7 +281,7 @@ mergeInto(LibraryManager.library, {
|
|||
return CCFS.write(stream, HEAP8, src, count)|0;
|
||||
} catch (e) {
|
||||
if (!(e instanceof CCFS.ErrnoError)) abort(e);
|
||||
return -e.errno;
|
||||
return e.errno;
|
||||
}
|
||||
},
|
||||
interop_FileSeek: function(fd, offset, whence) {
|
||||
|
@ -294,17 +290,12 @@ mergeInto(LibraryManager.library, {
|
|||
return CCFS.llseek(stream, offset, whence)|0;
|
||||
} catch (e) {
|
||||
if (!(e instanceof CCFS.ErrnoError)) abort(e);
|
||||
return -e.errno;
|
||||
return e.errno;
|
||||
}
|
||||
},
|
||||
interop_FileLength: function(fd) {
|
||||
try {
|
||||
var stream = CCFS.getStream(fd);
|
||||
return stream.node.usedBytes|0;
|
||||
} catch (e) {
|
||||
if (!(e instanceof CCFS.ErrnoError)) abort(e);
|
||||
return -e.errno;
|
||||
}
|
||||
var stream = CCFS.getStream(fd);
|
||||
return stream.node.usedBytes|0;
|
||||
},
|
||||
interop_FileClose: function(fd) {
|
||||
try {
|
||||
|
@ -315,7 +306,7 @@ mergeInto(LibraryManager.library, {
|
|||
return 0;
|
||||
} catch (e) {
|
||||
if (!(e instanceof CCFS.ErrnoError)) abort(e);
|
||||
return -e.errno;
|
||||
return e.errno;
|
||||
}
|
||||
},
|
||||
interop_FileClose__deps: ['interop_SaveNode'],
|
||||
|
@ -346,7 +337,7 @@ mergeInto(LibraryManager.library, {
|
|||
ccall('Platform_LogError', 'void', ['string'], [' &c' + err]);
|
||||
};
|
||||
|
||||
var stat, node, entry;
|
||||
var node, entry;
|
||||
try {
|
||||
var lookup = CCFS.lookupPath(path);
|
||||
node = lookup.node;
|
||||
|
@ -429,7 +420,7 @@ mergeInto(LibraryManager.library, {
|
|||
db.onclose = function(ev) {
|
||||
console.log('IndexedDB connection closed unexpectedly!');
|
||||
window.IDBFS_db = null;
|
||||
}
|
||||
};
|
||||
callback(null, db);
|
||||
};
|
||||
req.onerror = function(e) {
|
||||
|
@ -547,7 +538,8 @@ mergeInto(LibraryManager.library, {
|
|||
//########################################################################################################################
|
||||
interop_InitSockets: function() {
|
||||
window.SOCKETS = {
|
||||
EBADF:-8,EISCONN:-30,ENOTCONN:-53,EAGAIN:-6,EHOSTUNREACH:-23,EINPROGRESS:-26,EALREADY:-7,ECONNRESET:-15,EINVAL:-28,ECONNREFUSED:-14,
|
||||
E_INVALID_VALUE:-1,E_IS_CONN:-8,E_NOT_CONN:-9,E_WOULD_BLOCK:-10,
|
||||
E_INVALID_HOST:-11,E_CONN_INPROGRESS:-12,E_CONN_REFUSED:-13,
|
||||
sockets: [],
|
||||
};
|
||||
},
|
||||
|
@ -564,14 +556,10 @@ mergeInto(LibraryManager.library, {
|
|||
interop_SocketConnect: function(sockFD, raw, port) {
|
||||
var addr = UTF8ToString(raw);
|
||||
var sock = SOCKETS.sockets[sockFD];
|
||||
if (!sock) return SOCKETS.EBADF;
|
||||
|
||||
// already connecting or connected
|
||||
var ws = sock.socket;
|
||||
if (ws) {
|
||||
if (ws.readyState === ws.CONNECTING) return SOCKETS.EALREADY;
|
||||
return SOCKETS.EISCONN;
|
||||
}
|
||||
if (ws) return SOCKETS.E_IS_CONN;
|
||||
|
||||
// create the actual websocket object and connect
|
||||
try {
|
||||
|
@ -582,7 +570,7 @@ mergeInto(LibraryManager.library, {
|
|||
ws = new WebSocket(url, 'ClassiCube');
|
||||
ws.binaryType = 'arraybuffer';
|
||||
} catch (e) {
|
||||
return SOCKETS.EHOSTUNREACH;
|
||||
return SOCKETS.E_INVALID_HOST;
|
||||
}
|
||||
sock.socket = ws;
|
||||
|
||||
|
@ -609,31 +597,30 @@ mergeInto(LibraryManager.library, {
|
|||
ws.onerror = function(error) {
|
||||
// The WebSocket spec only allows a 'simple event' to be thrown on error,
|
||||
// so we only really know as much as ECONNREFUSED.
|
||||
sock.error = SOCKETS.ECONNREFUSED; // Used by interop_SocketWritable
|
||||
sock.error = SOCKETS.E_CONN_REFUSED; // Used by interop_SocketWritable
|
||||
};
|
||||
// always "fail" in non-blocking mode
|
||||
return SOCKETS.EINPROGRESS;
|
||||
return SOCKETS.E_CONN_INPROGRESS;
|
||||
},
|
||||
interop_SocketClose: function(sockFD) {
|
||||
var sock = SOCKETS.sockets[sockFD];
|
||||
if (!sock) return SOCKETS.EBADF;
|
||||
if (!sock) return;
|
||||
|
||||
try {
|
||||
sock.socket.close();
|
||||
} catch (e) {
|
||||
}
|
||||
delete sock.socket;
|
||||
return 0;
|
||||
return;
|
||||
},
|
||||
interop_SocketSend: function(sockFD, src, length) {
|
||||
var sock = SOCKETS.sockets[sockFD];
|
||||
if (!sock) return SOCKETS.EBADF;
|
||||
var ws = sock.socket;
|
||||
|
||||
var ws = sock.socket;
|
||||
if (!ws || ws.readyState === ws.CLOSING || ws.readyState === ws.CLOSED) {
|
||||
return SOCKETS.ENOTCONN;
|
||||
return SOCKETS.E_NOT_CONN;
|
||||
} else if (ws.readyState === ws.CONNECTING) {
|
||||
return SOCKETS.EAGAIN;
|
||||
return SOCKETS.E_CONN_INPROGRESS;
|
||||
}
|
||||
|
||||
// var data = HEAP8.slice(src, src + length); unsupported in IE11
|
||||
|
@ -646,22 +633,21 @@ mergeInto(LibraryManager.library, {
|
|||
ws.send(data);
|
||||
return length;
|
||||
} catch (e) {
|
||||
return SOCKETS.EINVAL;
|
||||
return SOCKETS.E_INVALID_VALUE;
|
||||
}
|
||||
},
|
||||
interop_SocketRecv: function(sockFD, dst, length) {
|
||||
var sock = SOCKETS.sockets[sockFD];
|
||||
if (!sock) return SOCKETS.EBADF;
|
||||
|
||||
var sock = SOCKETS.sockets[sockFD];
|
||||
var packet = sock.recv_queue.shift();
|
||||
|
||||
if (!packet) {
|
||||
var ws = sock.socket;
|
||||
|
||||
if (!ws || ws.readyState == ws.CLOSING || ws.readyState == ws.CLOSED) {
|
||||
return SOCKETS.ENOTCONN;
|
||||
return SOCKETS.E_NOT_CONN;
|
||||
} else {
|
||||
// socket is in a valid state but truly has nothing available
|
||||
return SOCKETS.EAGAIN;
|
||||
return SOCKETS.E_WOULD_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -686,10 +672,9 @@ mergeInto(LibraryManager.library, {
|
|||
interop_SocketWritable: function(sockFD, writable) {
|
||||
HEAPU8[writable|0] = 0;
|
||||
var sock = SOCKETS.sockets[sockFD];
|
||||
if (!sock) return SOCKETS.EBADF;
|
||||
|
||||
var ws = sock.socket;
|
||||
if (!ws) return SOCKETS.ENOTCONN;
|
||||
if (!ws) return SOCKETS.E_NOT_CONN;
|
||||
if (ws.readyState === ws.OPEN) HEAPU8[writable|0] = 1;
|
||||
return sock.error || 0;
|
||||
},
|
||||
|
@ -1210,7 +1195,13 @@ mergeInto(LibraryManager.library, {
|
|||
|
||||
|
||||
window.CCFS={
|
||||
streams:[],entries:{},currentPath:"/",ErrnoError:null,
|
||||
streams:[],
|
||||
entries:{},
|
||||
currentPath:"/",
|
||||
ErrnoError:null,
|
||||
E_INVALID_VALUE:-1,E_ENTRY_NOT_FOUND:-2,E_ENTRY_EXISTS:-3,
|
||||
E_FD_CLOSED:-4,E_TOO_MANY_FDS:-5,E_READONLY_FILE:-6,E_WRITEONLY_FILE:-7,
|
||||
|
||||
resolvePath:function(path) {
|
||||
if (path.charAt(0) !== '/') {
|
||||
path = CCFS.currentPath + '/' + path;
|
||||
|
@ -1221,7 +1212,7 @@ mergeInto(LibraryManager.library, {
|
|||
path = CCFS.resolvePath(path);
|
||||
var node = CCFS.entries[path];
|
||||
|
||||
if (!node) throw new CCFS.ErrnoError(2);
|
||||
if (!node) throw new CCFS.ErrnoError(CCFS.E_ENTRY_NOT_FOUND);
|
||||
return { path: path, node: node };
|
||||
},
|
||||
createNode:function(path) {
|
||||
|
@ -1239,7 +1230,7 @@ mergeInto(LibraryManager.library, {
|
|||
{
|
||||
if (!CCFS.streams[fd]) return fd;
|
||||
}
|
||||
throw new CCFS.ErrnoError(24);
|
||||
throw new CCFS.ErrnoError(CCFS.E_TOO_MANY_FDS);
|
||||
},
|
||||
getStream:function(fd) {
|
||||
return CCFS.streams[fd];
|
||||
|
@ -1250,7 +1241,7 @@ mergeInto(LibraryManager.library, {
|
|||
CCFS.streams[fd] = stream;
|
||||
return stream;
|
||||
},
|
||||
readdir:function(path) {
|
||||
getDirEntries:function(path) {
|
||||
path = CCFS.resolvePath(path) + '/';
|
||||
|
||||
// all entries starting with given directory
|
||||
|
@ -1282,7 +1273,7 @@ mergeInto(LibraryManager.library, {
|
|||
if (node) {
|
||||
// if O_CREAT and O_EXCL are set, error out if the node already exists
|
||||
if ((flags & 128)) {
|
||||
throw new CCFS.ErrnoError(17);
|
||||
throw new CCFS.ErrnoError(CCFS.E_ENTRY_EXISTS);
|
||||
}
|
||||
} else {
|
||||
// node doesn't exist, try to create it
|
||||
|
@ -1291,7 +1282,7 @@ mergeInto(LibraryManager.library, {
|
|||
}
|
||||
}
|
||||
if (!node) {
|
||||
throw new CCFS.ErrnoError(2);
|
||||
throw new CCFS.ErrnoError(CCFS.E_ENTRY_NOT_FOUND);
|
||||
}
|
||||
|
||||
// do truncation if necessary
|
||||
|
@ -1314,7 +1305,7 @@ mergeInto(LibraryManager.library, {
|
|||
},
|
||||
close:function(stream) {
|
||||
if (CCFS.isClosed(stream)) {
|
||||
throw new CCFS.ErrnoError(9);
|
||||
throw new CCFS.ErrnoError(CCFS.E_FD_CLOSED);
|
||||
}
|
||||
|
||||
CCFS.streams[stream.fd] = null;
|
||||
|
@ -1325,7 +1316,7 @@ mergeInto(LibraryManager.library, {
|
|||
},
|
||||
llseek:function(stream, offset, whence) {
|
||||
if (CCFS.isClosed(stream)) {
|
||||
throw new CCFS.ErrnoError(9);
|
||||
throw new CCFS.ErrnoError(CCFS.E_FD_CLOSED);
|
||||
}
|
||||
|
||||
var position = offset;
|
||||
|
@ -1338,20 +1329,20 @@ mergeInto(LibraryManager.library, {
|
|||
}
|
||||
|
||||
if (position < 0) {
|
||||
throw new CCFS.ErrnoError(22);
|
||||
throw new CCFS.ErrnoError(CCFS.E_INVALID_VALUE);
|
||||
}
|
||||
stream.position = position;
|
||||
return stream.position;
|
||||
},
|
||||
read:function(stream, buffer, offset, length) {
|
||||
if (length < 0) {
|
||||
throw new CCFS.ErrnoError(22);
|
||||
throw new CCFS.ErrnoError(CCFS.E_INVALID_VALUE);
|
||||
}
|
||||
if (CCFS.isClosed(stream)) {
|
||||
throw new CCFS.ErrnoError(9);
|
||||
throw new CCFS.ErrnoError(CCFS.E_FD_CLOSED);
|
||||
}
|
||||
if ((stream.flags & 2097155) === 1) {
|
||||
throw new CCFS.ErrnoError(9);
|
||||
if ((stream.flags & 2097155) === 1) { // O_WRONLY
|
||||
throw new CCFS.ErrnoError(CCFS.E_WRITEONLY_FILE);
|
||||
}
|
||||
|
||||
var position = stream.position;
|
||||
|
@ -1361,13 +1352,13 @@ mergeInto(LibraryManager.library, {
|
|||
},
|
||||
write:function(stream, buffer, offset, length, canOwn) {
|
||||
if (length < 0) {
|
||||
throw new CCFS.ErrnoError(22);
|
||||
throw new CCFS.ErrnoError(CCFS.E_INVALID_VALUE);
|
||||
}
|
||||
if (CCFS.isClosed(stream)) {
|
||||
throw new CCFS.ErrnoError(9);
|
||||
throw new CCFS.ErrnoError(CCFS.E_FD_CLOSED);
|
||||
}
|
||||
if ((stream.flags & 2097155) === 0) {
|
||||
throw new CCFS.ErrnoError(9);
|
||||
if ((stream.flags & 2097155) === 0) { // O_RDONLY
|
||||
throw new CCFS.ErrnoError(CCFS.E_READONLY_FILE);
|
||||
}
|
||||
if (stream.flags & 1024) {
|
||||
// seek to the end before writing in append mode
|
||||
|
|
Loading…
Reference in a new issue