Skip to content

add functions <signal.h> , getenv/system (node.js)<stdlib> #3948

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 15 commits into from
Closed
15 changes: 8 additions & 7 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -448,16 +448,17 @@ LibraryManager.library = {
}
return ret; // Previous break location.
},

system__deps: ['__setErrNo', '$ERRNO_CODES'],
system: function(command) {
// int system(const char *command);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/system.html
// Can't call external programs.
___setErrNo(ERRNO_CODES.EAGAIN);
return -1;
if (ENVIRONMENT_IS_NODE) {
var cmd = Pointer_stringify(command);
var sys = require('util');
var exec = require('child_process').exec;
function out(error, stdout, stderr) {console.log(stdout)}
exec( cmd , out);
}
return 0;
},

// ==========================================================================
// stdlib.h
// ==========================================================================
Expand Down
127 changes: 65 additions & 62 deletions src/library_signals.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,33 @@
// 'use strict'
var funs = {
_sigalrm_handler: 0,
var funs =
{
signal__deps: ['_sig_handler_'],

signal__deps: ['_sigalrm_handler'],
signal: function(sig, func) {
if (sig == 14 /*SIGALRM*/) {
__sigalrm_handler = func;
} else {
#if ASSERTIONS
Module.printErr('Calling stub instead of signal()');
#endif
}
return 0;
signal: function(sig, func) {
if ( typeof signal__deps === 'undefined' ) signal__deps = [] ;
if ( typeof signal__deps['_sig_handler_'] === 'undefined' ) signal__deps['_sig_handler_'] = [] ;
signal__deps['_sig_handler_'][sig] = func ;

return sig;
},
sigemptyset: function(set) {
{{{ makeSetValue('set', '0', '0', 'i32') }}};
return 0;
sigemptyset: function(set) {
{{{ makeSetValue('set', '0', '0', 'i32') }}};
return 0;
},
sigfillset: function(set) {
{{{ makeSetValue('set', '0', '-1>>>0', 'i32') }}};
return 0;
sigfillset: function(set) {
{{{ makeSetValue('set', '0', '-1>>>0', 'i32') }}};
return 0;
},
sigaddset: function(set, signum) {
{{{ makeSetValue('set', '0', makeGetValue('set', '0', 'i32') + '| (1 << (signum-1))', 'i32') }}};
return 0;
{{{ makeSetValue('set', '0', makeGetValue('set', '0', 'i32') + '| (1 << (signum-1))', 'i32') }}};
return 0;
},
sigdelset: function(set, signum) {
{{{ makeSetValue('set', '0', makeGetValue('set', '0', 'i32') + '& (~(1 << (signum-1)))', 'i32') }}};
return 0;
},
sigismember: function(set, signum) {
return {{{ makeGetValue('set', '0', 'i32') }}} & (1 << (signum-1));
return {{{ makeGetValue('set', '0', 'i32') }}} & (1 << (signum-1));
},
sigaction: function(signum, act, oldact) {
//int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
Expand All @@ -39,23 +36,29 @@ var funs = {
#endif
return 0;
},
sigprocmask: function() {
#if ASSERTIONS
Module.printErr('Calling stub instead of sigprocmask()');
#endif
return 0;
},
__libc_current_sigrtmin: function() {
#if ASSERTIONS
Module.printErr('Calling stub instead of __libc_current_sigrtmin');
#endif
return 0;
},
__libc_current_sigrtmax: function() {
#if ASSERTIONS
Module.printErr('Calling stub instead of __libc_current_sigrtmax');
#endif
return 0;
sigprocmask: function( how , set , old ) {
var SIG_BLOCK = 1;
var EINVAL = 22 ;
if ( how - SIG_BLOCK >2 ) return EINVAL ;
//ret = -__syscall(SYS_rt_sigprocmask, how, set, old, _NSIG/8);
ret = 0 ;
if (!ret && old) {
{{{ makeSetValue('old', '0', '~0x80000000', 'i32') }}};
{{{ makeSetValue('old', '1', '~0x00000003', 'i32') }}};
}
return ret;
},
__libc_current_sigrtmin: function() {
// POSIX timers use __SIGRTMIN + 0.
// libbacktrace uses __SIGRTMIN + 1.
// libcore uses __SIGRTMIN + 2.
var __SIGRTMIN = 34
return __SIGRTMIN+3;
},
__libc_current_sigrtmax: function()
{
var __SIGRTMAX = 64;
return __SIGRTMAX;
},
kill__deps: ['$ERRNO_CODES', '__setErrNo'],
kill: function(pid, sig) {
Expand All @@ -68,7 +71,6 @@ var funs = {
___setErrNo(ERRNO_CODES.EPERM);
return -1;
},

killpg__deps: ['$ERRNO_CODES', '__setErrNo'],
killpg: function() {
#if ASSERTIONS
Expand All @@ -83,19 +85,27 @@ var funs = {
#endif
return 0;
},
raise: function(sig) {
if ( typeof signal__deps === 'undefined' )
return -1 ;
if ( typeof signal__deps['_sig_handler_'] === 'undefined' ) {
Module.printErr ( 'undefined signal handler : ' + sig);
return -1 ;
}
if ( typeof signal__deps['_sig_handler_'][sig] === 'undefined' ){
Module.printErr ( 'undefined signal handler :' + sig );
return -1;
}
var ff = signal__deps['_sig_handler_'][sig] ;

raise__deps: ['$ERRNO_CODES', '__setErrNo'],
raise: function(sig) {
#if ASSERTIONS
Module.printErr('Calling stub instead of raise()');
#endif
___setErrNo(ERRNO_CODES.ENOSYS);
#if ASSERTIONS
Runtime.warnOnce('raise() returning an error as we do not support it');
#endif
return -1;
if ( ff == 0 ) {
Module.printErr ( 'undefined signal handler :' + sig );
return -1;
}
Runtime.dynCall('vi', ff, [0]);
___setErrNo(ERRNO_CODES.ENOSYS);
return sig;
},

// http://pubs.opengroup.org/onlinepubs/000095399/functions/alarm.html
alarm__deps: ['_sigalrm_handler'],
alarm: function(seconds) {
Expand All @@ -112,21 +122,14 @@ var funs = {
getitimer: function() {
throw 'getitimer() is not implemented yet';
},

pause__deps: ['__setErrNo', '$ERRNO_CODES'],
pause: function() {
// int pause(void);
// http://pubs.opengroup.org/onlinepubs/000095399/functions/pause.html
// We don't support signals, so we return immediately.
#if ASSERTIONS
Module.printErr('Calling stub instead of pause()');
#endif
___setErrNo(ERRNO_CODES.EINTR);
return -1;
// implemened as #define in emscripten.h
// #define pause( t )
},
sigpending: function(set) {
{{{ makeSetValue('set', 0, 0, 'i32') }}};
return 0;
sigpending: function(set) {
{{{ makeSetValue('set', 0, 0, 'i32') }}};
return 0;
}
//signalfd
//ppoll
Expand Down
6 changes: 5 additions & 1 deletion system/include/emscripten/emscripten.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,11 @@ emscripten_coroutine emscripten_coroutine_create(em_arg_callback_func func, void
int emscripten_coroutine_next(emscripten_coroutine);
void emscripten_yield(void);


// library_signal.js : pause
#define pause( t ) raise(SIGSTOP);emscripten_sleep(t);raise(SIGCONT);
#define __SIGRTMIN 34
#define __SIGRTMAX 64

#ifdef __cplusplus
}
#endif
Expand Down
20 changes: 20 additions & 0 deletions tests/node001-getenv.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <stdio.h>
#include <emscripten.h>

int main ()
{
char *s = getenv ( process.env.APPDATA );
printf ( "\n NODE.JS <%s> " ,s ) ;
printf ( "\n NODE.JS <%s> " , getenv ( process.env.HOMEDRIVE ) ) ;
printf ( "\n NODE.JS <%s> " , getenv ( process.env ) ) ;

return 0;
}

/* OUTPUT

NODE.JS <"C:\\Users\\claudio\\AppData\\Roaming">
NODE.JS <"C:">
...

*/
53 changes: 53 additions & 0 deletions tests/node002-system.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
#include <emscripten.h>

int main ()
{
system ( "dir" ) ;
system ( "node -v" ) ;
system ( "dir c:\\windows" );
system ( "em++ node001-getenv.cpp -o main.js" );

return 0;
}

/* OUTPUT

v4.1.1

Il volume nell'unita C ROOT
Numero di serie del volume: 06E6-D93D

Directory di c:\windows

24/10/2015 13.08 <DIR> .
24/10/2015 13.08 <DIR> ..
10/07/2015 12.04 <DIR> addins
30/10/2015 10.59 <DIR> appcompat
24/11/2015 03.15 <DIR> AppPatch
02/12/2015 15.29 <DIR> AppReadiness
...
10/07/2015 12.00 11.264 write.exe
23 File 721.754.485 byte
70 Directory 170.484.563.968 byte disponibili

Il volume nell'unita C ROOT
Numero di serie del volume: 06E6-D93D

Directory di C:\wamp\www\em\

02/12/2015 15.44 <DIR> .
02/12/2015 15.44 <DIR> ..
18/11/2015 21.59 137 index.html
02/12/2015 15.44 370.407 main.js
...
02/12/2015 15.22 2.006 signal003-sigprocmask.cpp
02/12/2015 15.44 0 txt.txt
23/11/2015 14.58 946 type.signal.CPP
10 File 376.049 byte
2 Directory 170.484.563.968 byte disponibili

*/


28 changes: 28 additions & 0 deletions tests/signa001-signa-raise.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <stdio.h>
#include <signal.h>

void mySTUB1 (int param)
{
puts ( "ONE!");
}
void mySTUB2 (int param)
{
puts ( "TWO!");
}

int main ()
{
// ........................ signal handler
signal (SIGINT , NULL );
signal (SIGABRT, mySTUB2 );
// ........................ raise risgnal
raise(SIGINT);
raise(SIGABRT);
// ........................ raise undef handler
printf ( "%d" ,raise(SIGSTOP) ) ;
// ........................ raise undef signal
printf ( "%d" ,raise(-2) ) ;


return 0;
}
31 changes: 31 additions & 0 deletions tests/signal002-pause.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <signal.h>
#include <emscripten.h>

// compile with :
//
// em++ signal002-pause.cpp -o main.js -s ASYNCIFY=1
//


void mystop (int param)
{
puts ( "stop!");
}
void mycont (int param)
{
puts ( "cont!");
}
int main (int argc, char *argv[])
{
// ........................ signal handler
signal (SIGSTOP, mystop );
signal (SIGCONT, mycont );

pause ( 1000 ) ;

return 0;
}
39 changes: 39 additions & 0 deletions tests/signal003-sigprocmask.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#include <stdlib.h>
#include <emscripten.h>

int main()
{
sigset_t old_set,new_set;

sigemptyset(&old_set);
sigemptyset(&new_set);

if(sigaddset(&old_set,SIGSEGV)==0)
{
printf("sigaddset successfully added for SIGSEGV\n");
}
sigprocmask(SIG_BLOCK,&old_set,NULL); // SIGSEGV signal is masked
//kill(0,SIGSEGV);


//*****************************************************************

if(sigaddset(&new_set,SIGRTMIN)==0)
{
printf("sigaddset successfully added for SIGRTMIN\n");
}
sigprocmask(SIG_BLOCK,&new_set,&old_set); // SIGRTMIN signal is masked
//kill(0,SIGSEGV);

//****************** Unblock one signal at a time ******************

sigprocmask(SIG_UNBLOCK,&new_set,&old_set); // SIGRTMIN signal is unmasked
sigprocmask(SIG_UNBLOCK,&new_set,&old_set); // SIGSEGV signal is unmasked
}