mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-15 15:53:55 +00:00
Linux Update for ioctl and fs.read
This commit is contained in:
@@ -2782,6 +2782,23 @@ duk_ret_t ILibDuktape_Polyfills_isBuffer(duk_context *ctx)
|
||||
duk_push_boolean(ctx, duk_is_buffer_data(ctx, 0));
|
||||
return(1);
|
||||
}
|
||||
#if defined(_POSIX) && !defined(__APPLE__) && !defined(_FREEBSD)
|
||||
duk_ret_t ILibDuktape_ioctl_func(duk_context *ctx)
|
||||
{
|
||||
int fd = (int)duk_require_int(ctx, 0);
|
||||
int code = (int)duk_require_int(ctx, 1);
|
||||
duk_size_t outBufferLen = 0;
|
||||
char *outBuffer = Duktape_GetBuffer(ctx, 2, &outBufferLen);
|
||||
|
||||
duk_push_int(ctx, ioctl(fd, _IOC(_IOC_READ | _IOC_WRITE, 'H', code, outBufferLen), outBuffer) ? errno : 0);
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_ioctl_Push(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_c_function(ctx, ILibDuktape_ioctl_func, DUK_VARARGS);
|
||||
ILibDuktape_WriteID(ctx, "ioctl");
|
||||
}
|
||||
#endif
|
||||
void ILibDuktape_uuidv4_Push(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx);
|
||||
@@ -2819,6 +2836,9 @@ void ILibDuktape_Polyfills_Init(duk_context *ctx)
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "ChainViewer", ILibDuktape_ChainViewer_Push);
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "DescriptorEvents", ILibDuktape_DescriptorEvents_Push);
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "uuid/v4", ILibDuktape_uuidv4_Push);
|
||||
#if defined(_POSIX) && !defined(__APPLE__) && !defined(_FREEBSD)
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "ioctl", ILibDuktape_ioctl_Push);
|
||||
#endif
|
||||
|
||||
|
||||
// Global Polyfills
|
||||
|
||||
@@ -21,6 +21,7 @@ limitations under the License.
|
||||
#include <ws2tcpip.h>
|
||||
#include <direct.h>
|
||||
#include <wchar.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include "microstack/ILibParsers.h"
|
||||
@@ -66,6 +67,9 @@ limitations under the License.
|
||||
#define FS_NOTIFY_DISPATCH_PTR "\xFF_FSWatcher_NotifyDispatchPtr"
|
||||
#define FS_CHAIN_PTR "\xFF_FSWatcher_ChainPtr"
|
||||
#define FS_WATCH_PATH "\xFF_FSWatcher_Path"
|
||||
#define FS_EVENT_R_DESCRIPTORS "\xFF_FSEventReadDescriptors"
|
||||
#define FS_EVENT_W_DESCRIPTORS "\xFF_FSEventWriteDescriptors"
|
||||
#define FS_EVENT_DESCRIPTORS_IO "\xFF_FSEventDescriptors_IO"
|
||||
|
||||
#if defined(_POSIX) && !defined(__APPLE__)
|
||||
typedef struct ILibDuktape_fs_linuxWatcher
|
||||
@@ -197,6 +201,17 @@ FILE* ILibDuktape_fs_getFilePtr(duk_context *ctx, int fd)
|
||||
duk_ret_t ILibDuktape_fs_closeSync(duk_context *ctx)
|
||||
{
|
||||
int fd = duk_require_int(ctx, 0);
|
||||
|
||||
if (fd < 65535)
|
||||
{
|
||||
#ifdef WIN32
|
||||
_close(fd);
|
||||
#else
|
||||
close(fd);
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
FILE *f;
|
||||
char *key = ILibScratchPad;
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%d", fd);
|
||||
@@ -263,21 +278,36 @@ duk_ret_t ILibDuktape_fs_openSync(duk_context *ctx)
|
||||
#else
|
||||
char *path = ILibDuktape_fs_fixLinuxPath((char*)duk_require_string(ctx, 0));
|
||||
#endif
|
||||
char *flags = (char*)duk_require_string(ctx, 1);
|
||||
int retVal = -1;
|
||||
|
||||
if (nargs < 2) { return(ILibDuktape_Error(ctx, "Too few arguments")); }
|
||||
|
||||
retVal = ILibDuktape_fs_openSyncEx(ctx, path, flags, NULL);
|
||||
if (retVal > 0)
|
||||
if (duk_is_string(ctx, 1))
|
||||
{
|
||||
duk_push_int(ctx, retVal);
|
||||
return 1;
|
||||
char *flags = (char*)duk_require_string(ctx, 1);
|
||||
int retVal = -1;
|
||||
|
||||
if (nargs < 2) { return(ILibDuktape_Error(ctx, "Too few arguments")); }
|
||||
|
||||
retVal = ILibDuktape_fs_openSyncEx(ctx, path, flags, NULL);
|
||||
if (retVal > 0)
|
||||
{
|
||||
duk_push_int(ctx, retVal);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "fs.openSync(): Error opening '%s'", path));
|
||||
}
|
||||
}
|
||||
else
|
||||
int flags = (int)duk_require_int(ctx, 1);
|
||||
#ifdef WIN32
|
||||
int fd = -1;
|
||||
if (_wsopen_s(&fd, (wchar_t*)ILibDuktape_String_UTF8ToWide(ctx, path), flags, 0, 0) != 0)
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "fs.openSync(): Error opening '%s'", path));
|
||||
return(ILibDuktape_Error(ctx, "openSync() Error: %d ", errno));
|
||||
}
|
||||
duk_push_int(ctx, fd);
|
||||
#else
|
||||
duk_push_int(ctx, open(path, flags));
|
||||
#endif
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_fs_readSync(duk_context *ctx)
|
||||
{
|
||||
@@ -303,6 +333,146 @@ duk_ret_t ILibDuktape_fs_readSync(duk_context *ctx)
|
||||
|
||||
return(ILibDuktape_Error(ctx, "FS I/O Error"));
|
||||
}
|
||||
duk_ret_t ILibDuktape_fs_read_readsetSink(duk_context *ctx)
|
||||
{
|
||||
int fd = duk_require_int(ctx, 0);
|
||||
duk_push_this(ctx); // [DescriptorEvents]
|
||||
duk_get_prop_string(ctx, -1, FS_EVENT_DESCRIPTORS_IO); // [DescriptorEvents][pending]
|
||||
duk_array_pop(ctx, -1); // [DescriptorEvents][pending][options]
|
||||
|
||||
duk_size_t bufferLen;
|
||||
char *buffer = Duktape_GetBufferProperty(ctx, -1, "buffer");
|
||||
duk_size_t offset = (duk_size_t)Duktape_GetIntPropertyValue(ctx, -1, "offset", 0);
|
||||
duk_size_t length = (duk_size_t)Duktape_GetIntPropertyValue(ctx, -1, "length", (int)bufferLen);
|
||||
int bytesRead = read(fd, buffer + offset, length);
|
||||
int status = bytesRead < 0 ? errno : 0;
|
||||
|
||||
duk_get_prop_string(ctx, -1, "callback"); // [DescriptorEvents][pending][options][callback]
|
||||
duk_get_prop_string(ctx, -1, "call"); duk_swap_top(ctx, -2);// ..............[pending][options][call][this]
|
||||
duk_eval_string(ctx, "require('fs');"); // ..............[pending][options][call][fn/this][this]
|
||||
duk_push_int(ctx, status); // ..............[pending][options][call][fn/this][this][err/status]
|
||||
duk_push_int(ctx, bytesRead); // ..............[pending][options][call][fn/this][this][err/status][bytesRead]
|
||||
duk_get_prop_string(ctx, -6, "buffer"); // ..............[pending][options][call][fn/this][this][err/status][bytesRead][buffer]
|
||||
if (duk_pcall_method(ctx, 4) != 0) // [DescriptorEvents][pending][options][val]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtExceptionEx(ctx, "fs.read() Callback Error: %s ", duk_safe_to_string(ctx, -1));
|
||||
}
|
||||
duk_pop_2(ctx); // [DescriptorEvents][pending]
|
||||
if (duk_get_length(ctx, -1) == 0)
|
||||
{
|
||||
// No more pending I/O operations, so we can cleanup the DescriptorEvents
|
||||
duk_eval_string(ctx, "require('DescriptorEvents');"); // .....[DescriptorEvents]
|
||||
duk_get_prop_string(ctx, -1, "removeDescriptor"); // .....[DescriptorEvents][removeDescriptor]
|
||||
duk_swap_top(ctx, -2); // .....[removeDescriptor][this]
|
||||
duk_push_int(ctx, fd); // .....[removeDescriptor][this][fd]
|
||||
duk_pcall_method(ctx, 1); duk_pop(ctx); // [DescriptorEvents][pending]
|
||||
|
||||
duk_eval_string(ctx, "require('fs');"); // [DescriptorEvents][pending][FS]
|
||||
duk_get_prop_string(ctx, -1,FS_EVENT_R_DESCRIPTORS);// [DescriptorEvents][pending][FS][table]
|
||||
duk_del_prop_index(ctx, -1, fd);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_fs_read(duk_context *ctx)
|
||||
{
|
||||
int top = duk_get_top(ctx);
|
||||
if (top > 2)
|
||||
{
|
||||
// Simplify flow, by converting to an options object
|
||||
duk_push_this(ctx); // [fs]
|
||||
duk_get_prop_string(ctx, -1, "read"); // [fs][read]
|
||||
duk_swap_top(ctx, -2); // [read][this]
|
||||
duk_dup(ctx, 0); // [read][this][fd]
|
||||
duk_push_object(ctx); // [read][this][fd][options]
|
||||
duk_dup(ctx, 1); duk_put_prop_string(ctx, -2, "buffer");
|
||||
duk_dup(ctx, 2); duk_put_prop_string(ctx, -2, "offset");
|
||||
duk_dup(ctx, 3); duk_put_prop_string(ctx, -2, "length");
|
||||
duk_dup(ctx, 4); duk_put_prop_string(ctx, -2, "position");
|
||||
duk_dup(ctx, 5); // [read][this][fd][options][callback]
|
||||
duk_call_method(ctx, 3);
|
||||
return(1);
|
||||
}
|
||||
if (top == 2 && duk_is_function(ctx, 1))
|
||||
{
|
||||
// Simplify flow, by converting to a default options object
|
||||
duk_push_this(ctx); // [fs]
|
||||
duk_get_prop_string(ctx, -1, "read"); // [fs][read]
|
||||
duk_swap_top(ctx, -2); // [read][this]
|
||||
duk_dup(ctx, 0); // [read][this][fd]
|
||||
duk_push_object(ctx); // [read][this][fd][options]
|
||||
duk_push_fixed_buffer(ctx, 16384); // [read][this][fd][options][buffer]
|
||||
duk_push_buffer_object(ctx, -1, 0, 16384, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
duk_remove(ctx, -2); // [read][this][fd][options][buffer]
|
||||
duk_put_prop_string(ctx, -2, "buffer"); // [read][this][fd][options]
|
||||
duk_push_int(ctx, 0); duk_put_prop_string(ctx, -2, "offset");
|
||||
duk_push_int(ctx, 16384); duk_put_prop_string(ctx, -2, "length");
|
||||
duk_push_null(ctx); duk_put_prop_string(ctx, -2, "position");
|
||||
duk_dup(ctx, 1); // [read][this][fd][options][callback]
|
||||
duk_call_method(ctx, 3);
|
||||
return(1);
|
||||
}
|
||||
if (!(duk_is_number(ctx, 0) && duk_is_object(ctx, 1) && duk_is_function(ctx, 2))) { return(ILibDuktape_Error(ctx, "Invalid Parameters")); }
|
||||
int fd = (int)duk_require_int(ctx, 0);
|
||||
|
||||
// First, we'll attempt to read, and see if it completes or is pending
|
||||
duk_size_t bufferLen;
|
||||
char *buffer = Duktape_GetBufferProperty(ctx, 1, "buffer");
|
||||
duk_size_t offset = (duk_size_t)Duktape_GetIntPropertyValue(ctx, 1, "offset", 0);
|
||||
duk_size_t length = (duk_size_t)Duktape_GetIntPropertyValue(ctx, 1, "length", (int)bufferLen);
|
||||
int bytesRead = read(fd, buffer + offset, length);
|
||||
if (bytesRead >= 0 || (errno != E_AGAIN && errno != E_WOULDBLOCK))
|
||||
{
|
||||
// Completed
|
||||
int errStatus = bytesRead >= 0 ? 0 : errno;
|
||||
duk_dup(ctx, 2); // [func]
|
||||
duk_get_prop_string(ctx, -1, "call"); // [func][call]
|
||||
duk_swap_top(ctx, -2); // [call][this]
|
||||
duk_push_this(ctx); // [call][this][this/fs]
|
||||
duk_push_int(ctx, errStatus); // [call][this][this/fs][err/status]
|
||||
duk_push_int(ctx, bytesRead); // [call][this][this/fs][err/status][bytesRead]
|
||||
duk_get_prop_string(ctx, 1, "buffer"); // [call][this][this/fs][err/status][bytesRead][buffer]
|
||||
duk_call_method(ctx, 4);
|
||||
return(0);
|
||||
}
|
||||
|
||||
//
|
||||
// Setup the EventDescriptor listener, because the read did not complete
|
||||
//
|
||||
duk_push_this(ctx); // [fs]
|
||||
duk_get_prop_string(ctx, -1, FS_EVENT_R_DESCRIPTORS); // [fs][table]
|
||||
if (!duk_has_prop_index(ctx, -1, fd))
|
||||
{
|
||||
duk_eval_string(ctx, "require('DescriptorEvents');"); // [fs][table][DE]
|
||||
duk_get_prop_string(ctx, -1, "addDescriptor"); // [fs][table][DE][addDescriptor]
|
||||
duk_swap_top(ctx, -2); // [fs][table][addDescriptor][this]
|
||||
duk_push_int(ctx, fd); // [fs][table][addDescriptor][this][fd]
|
||||
duk_push_object(ctx); // [fs][table][addDescriptor][this][fd][options]
|
||||
duk_push_true(ctx); duk_put_prop_string(ctx, -2, "readset");
|
||||
if (duk_has_prop_string(ctx, 1, "metadata"))
|
||||
{
|
||||
duk_push_string(ctx, "fs.read(), "); // [fs][table][addDescriptor][this][fd][options][str]
|
||||
duk_get_prop_string(ctx, 1, "metadata"); // [fs][table][addDescriptor][this][fd][options][str][str2]
|
||||
duk_string_concat(ctx, -2); duk_remove(ctx, -2); // [fs][table][addDescriptor][this][fd][options][metadata]
|
||||
duk_put_prop_string(ctx, -2, "metadata"); // [fs][table][addDescriptor][this][fd][options]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_string(ctx, "fs.read()"); duk_put_prop_string(ctx, -2, "metadata");
|
||||
}
|
||||
duk_call_method(ctx, 2); // [fs][table][descriptorEvent]
|
||||
ILibDuktape_EventEmitter_SetupOn(ctx, duk_get_heapptr(ctx, -1), "readset"); // ........[on][this][readset]
|
||||
duk_push_c_function(ctx, ILibDuktape_fs_read_readsetSink, DUK_VARARGS); // ........[on][this][readset][func]
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // [fs][table][descriptorEvent]
|
||||
duk_push_array(ctx); duk_put_prop_string(ctx, -1, FS_EVENT_DESCRIPTORS_IO);
|
||||
duk_put_prop_index(ctx, -2, fd); // [fs][table]
|
||||
}
|
||||
duk_get_prop_index(ctx, -1, fd); // [fs][table][desriptorEvent]
|
||||
duk_get_prop_string(ctx, -1, FS_EVENT_DESCRIPTORS_IO); // [fs][table][desriptorEvent][pending]
|
||||
duk_dup(ctx, 1); // [fs][table][desriptorEvent][pending][options]
|
||||
duk_dup(ctx, 2); duk_put_prop_string(ctx, -2, "callback"); // [fs][table][desriptorEvent][pending][options]
|
||||
duk_array_unshift(ctx, -2); // [fs][table][desriptorEvent][pending]
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_fs_writeSync(duk_context *ctx)
|
||||
{
|
||||
int nargs = duk_get_top(ctx);
|
||||
@@ -1644,16 +1814,22 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
|
||||
duk_push_pointer(ctx, chain); // [fs][chain]
|
||||
duk_put_prop_string(ctx, -2, FS_CHAIN_PTR); // [fs]
|
||||
|
||||
duk_push_int(ctx, 0); // [fs][nextFD]
|
||||
duk_push_int(ctx, 65535); // [fs][nextFD]
|
||||
duk_put_prop_string(ctx, -2, FS_NextFD); // [fs]
|
||||
|
||||
duk_push_object(ctx); // [fs][descriptors]
|
||||
duk_put_prop_string(ctx, -2, FS_FDS); // [fs]
|
||||
|
||||
duk_push_object(ctx);
|
||||
duk_put_prop_string(ctx, -2, FS_EVENT_R_DESCRIPTORS);
|
||||
duk_push_object(ctx);
|
||||
duk_put_prop_string(ctx, -2, FS_EVENT_W_DESCRIPTORS);
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "closeSync", ILibDuktape_fs_closeSync, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "openSync", ILibDuktape_fs_openSync, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "readSync", ILibDuktape_fs_readSync, 5);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "writeSync", ILibDuktape_fs_writeSync, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "read", ILibDuktape_fs_read, DUK_VARARGS);
|
||||
#ifdef WIN32
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "_readdirSync", ILibDuktape_fs_readdirSync, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "_statSync", ILibDuktape_fs_statSync, 1);
|
||||
@@ -1701,6 +1877,7 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
|
||||
}\
|
||||
ds.on('close', function onCopyFileDone(){delete this.ss.fs._copyStreams[this.ss.id];});\
|
||||
};\
|
||||
exports.constants = {O_RDONLY: 0, O_WRONLY: 1, O_RDWR: 4, O_NONBLOCK: 2048};\
|
||||
exports.copyFileSync = function copyFileSync(src, dest)\
|
||||
{\
|
||||
var buffer = this.readFileSync(src, {flags: 'rb'});\
|
||||
|
||||
Reference in New Issue
Block a user