Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f886792a2b | ||
|
|
de896eb2ba |
No files matched your search
@@ -1,8 +1,9 @@
|
||||
|
||||
#define ARG_DEBUG "d" /* avec lw */
|
||||
#define ARG_TRACE "t" /* avec lw */
|
||||
#define ARG_BACKGROUND "b" /* avec lw (process deja lance en background) */
|
||||
#define ARG_DISASM "u" /* avec lwa */
|
||||
#define ARG_COMPRESS "c" /* avec lwa */
|
||||
#define ARG_COMPRESS "c" /* avec lwa (compression du wp genere, assemblage) */
|
||||
#define ARG_SOURCE "s" /* avec lwc */
|
||||
|
||||
void GetArgs(env * e, int argc, char * argv[], Dynamic * arg)
|
||||
@@ -18,6 +19,8 @@ void GetArgs(env * e, int argc, char * argv[], Dynamic * arg)
|
||||
dynStoreSz(e, arg, 1, ++nbOpt, ARG_DEBUG, 1, cFM, cVM);
|
||||
else if(strcmp(argv[a], "-" ARG_TRACE) == 0)
|
||||
dynStoreSz(e, arg, 1, ++nbOpt, ARG_TRACE, 1, cFM, cVM);
|
||||
else if(strcmp(argv[a], "-" ARG_BACKGROUND) == 0)
|
||||
dynStoreSz(e, arg, 1, ++nbOpt, ARG_BACKGROUND, 1, cFM, cVM);
|
||||
else if(strcmp(argv[a], "-" ARG_DISASM) == 0)
|
||||
dynStoreSz(e, arg, 1, ++nbOpt, ARG_DISASM, 1, cFM, cVM);
|
||||
else if(strcmp(argv[a], "-" ARG_COMPRESS) == 0)
|
||||
|
||||
@@ -72,8 +72,8 @@ enum {
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
WAPIDECL void Init(env * e, modCtxFcgi * ctx);
|
||||
WAPIDECL void End(env * e, modCtxFcgi * ctx);
|
||||
WAPIDECL void InitFcgi(env * e, modCtxFcgi * ctx);
|
||||
WAPIDECL void FreeFcgi(env * e, modCtxFcgi * ctx);
|
||||
|
||||
WAPIDECL long ExtractMessage(env * e, modCtxFcgi * ctx, Dynamic * data);
|
||||
|
||||
|
||||
@@ -27,25 +27,35 @@
|
||||
|
||||
#include "langage.h"
|
||||
#include "dynamic.h"
|
||||
#include "var.h"
|
||||
|
||||
#include "fcgi.h"
|
||||
|
||||
/* ============================================================================================= */
|
||||
typedef struct {
|
||||
int error; // dernier code erreur specifique au module
|
||||
//*** a completer selon le besoin du module
|
||||
modCtxFcgi ctxFcgi;
|
||||
} modEtat;
|
||||
|
||||
#define MOD_VERSION 1
|
||||
|
||||
/* mettre ici les codes d'erreurs specifiques au module */
|
||||
/* codes a passer a la fonction setError */
|
||||
#define EXMOD_xxx 1
|
||||
enum {
|
||||
EXMOD_FCGI_REQUEST_ERROR = 1,
|
||||
EXMOD_FCGI_RESPONSE_ERROR = 2,
|
||||
EXMOD_NB = 2
|
||||
};
|
||||
/* libelles des codes d'erreur, qui doivent aller de 1 a EXMOD_NB */
|
||||
char * descModErr[] = {
|
||||
"No error", // 0
|
||||
"Error in FCGI request",
|
||||
"Error making FCGI response"
|
||||
};
|
||||
/* ============================================================================================= */
|
||||
|
||||
static int setError(modEtat * p, int err)
|
||||
{
|
||||
if(p != NULL)
|
||||
p->error = err;
|
||||
return err == OK ? OK : EX_MODERR;
|
||||
}
|
||||
#include "mod.c"
|
||||
|
||||
#ifdef WINLIB
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
@@ -56,100 +66,169 @@ long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
modEtat * p_etat;
|
||||
long exc = OK;
|
||||
// init/end/vers/error sont obligatoires pour tout module
|
||||
// - - - - - - - - - - - - - - - - - - - -
|
||||
/* init/end/vers/error sont obligatoires pour tout module */
|
||||
if(etat == NULL)
|
||||
return EX_MODPARAM;
|
||||
else
|
||||
p_etat = (modEtat *)(*etat); /* evite de la faire a chaque fonction */
|
||||
//
|
||||
if(param1 != NULL)
|
||||
if(param1->type == VAR_PARAM)
|
||||
param1 = (var *)param1->ptr; /* evite de le faire a chaque fonction */
|
||||
if(param2 != NULL)
|
||||
if(param2->type == VAR_PARAM)
|
||||
param2 = (var *)param2->ptr; /* evite de le faire a chaque fonction */
|
||||
if(param3 != NULL)
|
||||
if(param3->type == VAR_PARAM)
|
||||
param3 = (var *)param3->ptr; /* evite de le faire a chaque fonction */
|
||||
//
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
if(modFnIs(e, "init", 4))
|
||||
{
|
||||
// alloc ptr sur zone memoire pour memoriser l'etat du module
|
||||
*etat = memalloc(e, sizeof(modEtat));
|
||||
if(*etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
else
|
||||
if(p_etat == NULL)
|
||||
{
|
||||
p_etat = (modEtat *)(*etat);
|
||||
p_etat->error = 0;
|
||||
//*** code specifique ici
|
||||
Init(e, &p_etat->ctxFcgi);
|
||||
//
|
||||
// alloc ptr sur zone memoire pour memoriser l'etat du module
|
||||
*etat = memalloc(e, sizeof(modEtat));
|
||||
if(*etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
else
|
||||
{
|
||||
p_etat = (modEtat *)(*etat);
|
||||
setError(p_etat, OK); // evite un warning de compil
|
||||
//*** code specifique ici
|
||||
InitFcgi(e, &p_etat->ctxFcgi);
|
||||
/* ============ here ============ */
|
||||
}
|
||||
}
|
||||
/* ne rien faire si deja un etat (rappels d'init ne font rien) */
|
||||
}
|
||||
else if(modFnIs(e, "end", 3))
|
||||
{
|
||||
//*** code specifique ici
|
||||
End(e, &p_etat->ctxFcgi);
|
||||
//
|
||||
// liberation specifique au module avant arret process
|
||||
if(p_etat != NULL)
|
||||
{
|
||||
//*** code specifique ici
|
||||
FreeFcgi(e, &p_etat->ctxFcgi);
|
||||
/* ============ here ============ */
|
||||
// liberation du module avant arret process
|
||||
memfree(e, p_etat);
|
||||
}
|
||||
}
|
||||
else if(p_etat == NULL)
|
||||
{
|
||||
exc = EX_MODETAT;
|
||||
}
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
if(param1 == NULL)
|
||||
var * paramVersion = getParam(e, "version", 7);
|
||||
if(paramVersion == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
// renvoie la version du module/plugins
|
||||
if(param1->type == VAR_DYNAMIC)
|
||||
dynLet(e, param1, "1", 1); //*** version en alpha
|
||||
else if(param1->type == VAR_NUMBER)
|
||||
param1->num = NUM_UN; //*** version en numerique
|
||||
// renvoie la version du module
|
||||
if(paramVersion->type == VAR_DYNAMIC)
|
||||
dynLet(e, paramVersion, Int32ToSz(MOD_VERSION, FALSE, 0), DYN_LGNONE);
|
||||
else if(paramVersion->type == VAR_NUMBER)
|
||||
paramVersion->num = (ent64)(MOD_VERSION * NUM_FACTEUR);
|
||||
else
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
{
|
||||
var_let(e, paramVersion, &e->int_number, FALSE, FALSE);
|
||||
paramVersion->num = (ent64)(MOD_VERSION * NUM_FACTEUR);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(modFnIs(e, "error", 5))
|
||||
{
|
||||
// renvoie la derniere erreur specifique au module
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
else if(param1 == NULL)
|
||||
/* renvoie la derniere erreur specifique au module*/
|
||||
var * paramModError = getParam(e, "modError", 8);
|
||||
var * paramModErrorDescription = getParam(e, "modErrorDescription", 19); /* facultatif */
|
||||
if(paramModError == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
if(param1->type == VAR_NUMBER)
|
||||
param1->num = (ent64)(NUM_FACTEUR * p_etat->error);
|
||||
// renvoie le dernier code erreur specifique du module
|
||||
if(paramModError->type == VAR_DYNAMIC)
|
||||
dynLet(e, paramModError, Int32ToSz(p_etat->error, FALSE, 0), DYN_LGNONE);
|
||||
else if(paramModError->type == VAR_NUMBER)
|
||||
paramModError->num = (ent64)(NUM_FACTEUR * p_etat->error);
|
||||
else
|
||||
exc = EX_MODPARAM; // bad type of parameter
|
||||
{
|
||||
var_let(e, paramModError, &e->int_number, FALSE, FALSE);
|
||||
paramModError->num = (ent64)(NUM_FACTEUR * p_etat->error);
|
||||
}
|
||||
if(paramModErrorDescription != NULL)
|
||||
{
|
||||
if(paramModErrorDescription->type != VAR_DYNAMIC)
|
||||
var_let(e, paramModErrorDescription, &e->int_dynamic, FALSE, FALSE);
|
||||
dynSetLen(e, paramModErrorDescription, 0);
|
||||
if(p_etat->error >= 0 && p_etat->error <= EXMOD_NB)
|
||||
dynLet(e, paramModErrorDescription, descModErr[p_etat->error], DYN_LGNONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(modFnIs(e, "get", 3))
|
||||
else if(modFnIs(e, "getRequest", 10))
|
||||
{
|
||||
if(param1 == NULL || param2 == NULL || param3 == NULL)
|
||||
/* get param in the right order */
|
||||
var * paramInput = getParam(e, "inputData", 9); // format FCGI
|
||||
var * paramContent = getParam(e, "content", 7); // message "clair"
|
||||
var * paramReturn = getParam(e, "returnCode", 10);
|
||||
if(paramInput == NULL || paramContent == NULL || paramReturn == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
if(param1->type != VAR_DYNAMIC || param3->type != VAR_DYNAMIC || param2->type != VAR_NUMBER)
|
||||
else if(paramInput->type != VAR_DYNAMIC || paramContent->type != VAR_DYNAMIC)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
long cr = ExtractMessage(e, &p_etat->ctxFcgi, param1);
|
||||
param2->num = cr * NUM_FACTEUR;
|
||||
if(paramReturn->type != VAR_NUMBER)
|
||||
var_let(e, paramReturn, &e->int_number, FALSE, FALSE);
|
||||
/* */
|
||||
long cr = ExtractMessage(e, &p_etat->ctxFcgi, paramInput);
|
||||
/* */
|
||||
p_etat->error = OK;
|
||||
if(cr == FCGI_REQUEST_AVAILABLE)
|
||||
dynSetAs(e, param3, &p_etat->ctxFcgi.dataIn);
|
||||
dynSetAs(e, paramContent, &p_etat->ctxFcgi.dataIn);
|
||||
else if(cr == FCGI_REQUEST_ERROR)
|
||||
p_etat->error = EXMOD_FCGI_REQUEST_ERROR; /* A REVOIR !! */
|
||||
/* */
|
||||
paramReturn->num = cr * NUM_FACTEUR;
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
else if(modFnIs(e, "setResponse", 11))
|
||||
{
|
||||
/* get param in the right order */
|
||||
var * paramOutput = getParam(e, "outputData", 9); // format FCGI
|
||||
var * paramContent = getParam(e, "content", 7); // reponse "clair"
|
||||
var * paramReturn = getParam(e, "returnCode", 10);
|
||||
if(paramOutput == NULL || paramContent == NULL || paramReturn == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
else if(paramOutput->type != VAR_DYNAMIC || paramContent->type != VAR_DYNAMIC)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
number retCode;
|
||||
if( ! var_conv_num(e, paramReturn, &retCode))
|
||||
exc = setError(p_etat, EX_MODPARAM);
|
||||
else
|
||||
{
|
||||
p_etat->error = OK;
|
||||
long cr = MakeResponse(e, &p_etat->ctxFcgi, retCode / NUM_FACTEUR, paramContent);
|
||||
/* */
|
||||
if(cr == OK)
|
||||
dynSetAs(e, paramOutput, &p_etat->ctxFcgi.dataOut);
|
||||
else
|
||||
p_etat->error = EXMOD_FCGI_RESPONSE_ERROR; /* A REVOIR !! */
|
||||
}
|
||||
}
|
||||
}
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
else if(modFnIs(e, "getHeader", 9))
|
||||
{
|
||||
/* get param in the right order */
|
||||
var * paramHeader = getParam(e, "headerList", 10);
|
||||
if(paramHeader == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
if(paramHeader->type != VAR_DYNAMIC)
|
||||
var_let(e, paramHeader, &e->int_dynamic, FALSE, FALSE);
|
||||
/* verifier si keepalive est dedans, sinon l'ajouter */
|
||||
dynSetAs(e, paramHeader, &p_etat->ctxFcgi.param);
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else
|
||||
{
|
||||
setError(p_etat, 0); // evite un warning de compil
|
||||
exc = EX_MODFUNC; // fonction non prise en charge
|
||||
exc = EX_MODFUNC; /* unsupported function */
|
||||
}
|
||||
//
|
||||
return exc;
|
||||
}
|
||||
+2
-4
@@ -137,7 +137,7 @@ static long EcrireCorps(env * e, modCtxFcgi * ctx, octet type, long crApplicatif
|
||||
}
|
||||
|
||||
/* ***** PUBLIC *************** */
|
||||
WAPIDECL void Init(env * e, modCtxFcgi * ctx)
|
||||
WAPIDECL void InitFcgi(env * e, modCtxFcgi * ctx)
|
||||
{
|
||||
ctx->keepAlive = 0;
|
||||
ctx->resteALireEntete = -1;
|
||||
@@ -153,7 +153,7 @@ WAPIDECL void Init(env * e, modCtxFcgi * ctx)
|
||||
dynInit(e, &ctx->dataOut, DYN_LGMIN);
|
||||
}
|
||||
|
||||
WAPIDECL void End(env * e, modCtxFcgi * ctx)
|
||||
WAPIDECL void FreeFcgi(env * e, modCtxFcgi * ctx)
|
||||
{
|
||||
dynFree(e, &ctx->param);
|
||||
dynFree(e, &ctx->dataIn);
|
||||
@@ -295,8 +295,6 @@ WAPIDECL long MakeResponse(env * e, modCtxFcgi * ctx, long cr, Dynamic * reponse
|
||||
if(EcrireCorps(e, ctx, FCGI_END_REQUEST, cr, FCGI_REQUEST_COMPLETE) != OK)
|
||||
return DYN_ERR;
|
||||
//
|
||||
// reponse mis a jour au format fcgi
|
||||
dynSetAs(e, reponse, &ctx->dataOut);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -3731,8 +3731,8 @@ void instr_056(env * e)
|
||||
/*
|
||||
@varnull,@varnumber,@varsubroutine,@varparam,@vardynamic,@varhashtable,@varobject,@varbuffer,@false,@true
|
||||
1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,10 ,11
|
||||
@level,@kill,@oid,@prog,@exceptstr,@exceptline,@except,@part,@line,@os,@vers,@verw,@demon,@endian,@file,@arg,@pi
|
||||
12 ,13 ,14 ,15 ,18 ,19 ,20 ,21 ,22 ,23 ,24 ,25 ,26 ,27 ,28 ,29 ,30
|
||||
@level,@kill,@oid,@prog,@pid,@exceptstr,@exceptline,@except,@part,@line,@os,@vers,@verw,@demon,@endian,@file,@arg,@pi
|
||||
12 ,13 ,14 ,15 ,16 ,18 ,19 ,20 ,21 ,22 ,23 ,24 ,25 ,26 ,27 ,28 ,29 ,30
|
||||
@fm,@vm,@svm,@tm,@currfm,@currvm,@cr,@lf,@tab,@number,@dynamic,@empty,@trim,@left,@right,@center,@surround,@asc,@desc
|
||||
31 ,32 ,33 ,34 ,35 ,36 ,37 ,38, ,39, ,40 ,41 ,42 ,50 ,51 ,52 ,53 ,54 ,55 ,56
|
||||
*/
|
||||
@@ -3780,7 +3780,7 @@ void instr_056(env * e)
|
||||
npushc(e, NUM_UN); /* true */
|
||||
break;
|
||||
case 14:
|
||||
npushc(e, e->oid_cpt * NUM_FACTEUR); /* oid */
|
||||
npushc(e, e->oid_cpt * NUM_FACTEUR); /* oid dernier objet instancie */
|
||||
break;
|
||||
case 15:
|
||||
{
|
||||
@@ -3792,6 +3792,9 @@ void instr_056(env * e)
|
||||
npushs(e, e->tmp_dynamic.mPtr);
|
||||
break;
|
||||
}
|
||||
case 16:
|
||||
npushc(e, getpid() * NUM_FACTEUR);
|
||||
break;
|
||||
case 18:
|
||||
if(e->except_ex > 0 && e->except_ex <= EXNB)
|
||||
dynLet(e, &e->tmp_dynamic, strerr[e->except_ex - 1], DYN_LGNONE);
|
||||
@@ -6236,8 +6239,8 @@ void instr_250(env * e)
|
||||
return;
|
||||
}
|
||||
#ifdef WINLIB
|
||||
if(e->use_signal)
|
||||
if(SetConsoleCtrlHandler(trtEvent, TRUE) == 0) // ajoute un handler d'events, cas d'usage : process lancé en direct et utilisateur agit sur le process en cours : ctrl-c ou ctrl-break (debug)
|
||||
if(e->use_signal && ! e->demon)
|
||||
if(SetConsoleCtrlHandler(trtEvent, TRUE) == 0) // ajoute un handler d'events, cas d'usage : process lancé en direct (pas en tache de fond) et utilisateur agit sur le process en cours : ctrl-c ou ctrl-break (debug)
|
||||
e->except_ex = EX_END; // TODO creer une exception
|
||||
#endif
|
||||
}
|
||||
@@ -6254,7 +6257,7 @@ void instr_251(env * e)
|
||||
void instr_252(env * e)
|
||||
{
|
||||
/* ENDL */
|
||||
/* idem ENDS + "decharger" la lib + maj _libaddr sauf si appel recursif + si kill ENDP en cours, attention pour la liberation (et si recursif) */
|
||||
/* idem ENDS (ne PAS "decharger" la lib) + maj _libaddr sauf si appel recursif + si kill ENDP en cours, attention pour la liberation (et si recursif) */
|
||||
var * v;
|
||||
if(e->local == NULL)
|
||||
{
|
||||
@@ -6387,7 +6390,8 @@ void instr_253(env * e)
|
||||
/* verifier que premiere instruction */
|
||||
if(e->si != e->debut + 1)
|
||||
e->except_ex = EX_END; /* forcer la sortie : pas la premiere instruction */
|
||||
else
|
||||
else if( ! e->demon) // si deja lance en demon avant, ne pas refaire le fork() !
|
||||
{
|
||||
if((pid = fork()) > 0)
|
||||
{
|
||||
printf("Lancement en tache de fond du process, pid %ld\n", pid);
|
||||
@@ -6404,6 +6408,7 @@ void instr_253(env * e)
|
||||
e->trace = 0;
|
||||
e->demon = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* */
|
||||
@@ -6748,13 +6753,13 @@ static void decode(env * e)
|
||||
{
|
||||
if(e->si < e->debut || e->si > e->fin || e->except_ex == EX_END)
|
||||
{
|
||||
e->instr = IN_ENDP; /* hors code : forcer END + exception (ok avec cas pas de EDS/END dans e->fin) */
|
||||
e->instr = IN_ENDP; /* hors code : forcer END + exception */
|
||||
e->exception = EX_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
e->instr = *(octet *)(e->si++) | ctx_env_kill;
|
||||
e->exception = OK; // raz exception a chaque instruction
|
||||
e->exception = OK; /* raz exception a chaque instruction */
|
||||
}
|
||||
/* */
|
||||
instr_trace(e);
|
||||
@@ -7112,7 +7117,7 @@ int CreateContext(env ** ctx, int useSignal, int argc, char *argv[])
|
||||
/* */
|
||||
e->trace = (dynLocateSz(e, &e->tmp_dynamic, ARG_TRACE, cVM, 1, cFM) > 0);
|
||||
e->debug = (dynLocateSz(e, &e->tmp_dynamic, ARG_DEBUG, cVM, 1, cFM) > 0);
|
||||
// -c compress ; -k compress with key
|
||||
//
|
||||
if(dynExtractPos(e, &e->tmp_dynamic, 2, 1, cFM, cVM) <= 0)
|
||||
return (e->except_ex = EX_CMDLINE_ARG); // pas de prog wp ici
|
||||
// wbin
|
||||
@@ -7154,6 +7159,12 @@ int CreateContext(env ** ctx, int useSignal, int argc, char *argv[])
|
||||
e->demon = 1;
|
||||
}
|
||||
#endif
|
||||
if(dynLocateSz(e, &e->tmp_dynamic, ARG_BACKGROUND, cVM, 1, cFM) > 0)
|
||||
{
|
||||
// process deja lance en mode background
|
||||
e->trace = 0;
|
||||
e->demon = 1;
|
||||
}
|
||||
/* lire les commandes lex pour le mode debug */
|
||||
//#ifdef WINLIB
|
||||
//if(lire_regles_lex(e, &e->debugreglelex, "C:\\Users\\Poupougne42\\source\\repos\\win_w_src\\lex\\debuglex") == DYN_OK) // a parametrer/lire du source
|
||||
@@ -7261,10 +7272,10 @@ void Execute(env * ctx, pointeur * addr)
|
||||
ctx->debut = *addr;
|
||||
ctx->fin = *(addr + 1);
|
||||
/* */
|
||||
if(ctx->fin - ctx->debut + 1 < 8)
|
||||
ctx->except_ex = EX_PCODE; /* 8 est la longueur mini possible d'un prog */
|
||||
if(ctx->fin - ctx->debut + 1 <= 8)
|
||||
ctx->except_ex = EX_PCODE; /* 9 est la longueur mini possible d'un prog */
|
||||
else if(*ctx->debut != IN_PROG && *ctx->debut != IN_BACK)
|
||||
ctx->except_ex = EX_PCODE; /* le pcode doit commencer par PROG ou BACK ! */
|
||||
ctx->except_ex = EX_PCODE; /* le pcode "directement executable" doit commencer par PROG ou BACK ! */
|
||||
/* */
|
||||
if(ctx->except_ex == 0)
|
||||
{
|
||||
@@ -7276,7 +7287,7 @@ void Execute(env * ctx, pointeur * addr)
|
||||
if(clock_gettime_monotonic(&ts) != -1)
|
||||
lap = ts.tv_sec * 1000000 + (ts.tv_nsec / 1000);
|
||||
/* */
|
||||
decode(ctx); // c_prog(ctx); si compile genere, mais a appeler avec dlfcn (dynamique)
|
||||
decode(ctx);
|
||||
/* */
|
||||
if(clock_gettime_monotonic(&ts) != -1)
|
||||
lap = ts.tv_sec * 1000000 + (ts.tv_nsec / 1000) - lap;
|
||||
@@ -7345,7 +7356,7 @@ int ReadProg(env * ctx, char * fichier, pointeur * prg, int * lg)
|
||||
}
|
||||
*prg = (pointeur)prog.mPtr;
|
||||
*lg = (int)prog.mLg;
|
||||
/* pas de dynFree(&prog) ici : le memfree de mPtr sera fait ailleurs (comme dans l'ancienne methode) */
|
||||
/* pas de dynFree(&prog) ici : le memfree de mPtr sera fait ailleurs */
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -7364,11 +7375,6 @@ void Load(env * ctx, char * fichier, pointeur ** binaddr)
|
||||
{
|
||||
/* fichier non trouve : a charger */
|
||||
var * var_bin = ctx->ad_var;
|
||||
//if(dynCtrl(ctx, var_bin, var_bin->lg + strlen(fichier) + 1, TRUE) != DYN_OK)
|
||||
//{
|
||||
// ctx->except_ex = EX_MEM;
|
||||
// return;
|
||||
//}
|
||||
hashtable_do(ctx, HASH_READ, &ctx->g, copy_nom(ctx, GUV_ENV), &ctx->ad_var);
|
||||
if(ctx->ad_var == NULL)
|
||||
{
|
||||
@@ -7415,16 +7421,12 @@ void Load(env * ctx, char * fichier, pointeur ** binaddr)
|
||||
ctx->ad_var->lg += sizeof(pointeur) * 3;
|
||||
pos_binaddr = ctx->ad_var->lg / (sizeof(pointeur) * 3);
|
||||
ctx->binaddr = ctx->ad_var->ptr;
|
||||
//dynLet(ctx, &ctx->int_dynamic, Int32ToSz(pos_binaddr, DYN_NONE, DYN_NONE), DYN_LGNONE);
|
||||
//pos_bin = dynDcount(ctx, var_bin, cVM, 1, cFM) + 1;
|
||||
pos_bin = pos_binaddr;
|
||||
dynInsSz(ctx, var_bin, 1, pos_bin, fichier, DYN_LGNONE, cFM, cVM);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* lecture position de _binaddr puis +1 sur son compteur */
|
||||
//dynField(ctx, ctx->ad_var, &ctx->int_dynamic, 2, pos_bin, cFM, cVM, 1);
|
||||
//pos_binaddr = dynToNum(ctx, &ctx->int_dynamic, DYN_NONE, DYN_NONE);
|
||||
pos_binaddr = pos_bin;
|
||||
/* lecture _binaddr */
|
||||
hashtable_do(ctx, HASH_READ, &ctx->g, copy_nom(ctx, GUV_BINADDR), &ctx->ad_var);
|
||||
@@ -7435,11 +7437,6 @@ void Load(env * ctx, char * fichier, pointeur ** binaddr)
|
||||
}
|
||||
*(((pointeur *)(ctx->ad_var->ptr + (pos_binaddr - 1) * 3 * sizeof(pointeur))) + 2) += 1;
|
||||
}
|
||||
/* maj _bin dans tous les cas a la fin, avec pos_binaddr */
|
||||
//pos_bin = dynDcount(ctx, var_bin, cVM, 1, cFM) + 1;
|
||||
//dynInsSz(ctx, var_bin, 1, pos_bin, fichier, DYN_LGNONE, cFM, cVM);
|
||||
//dynInsSz(ctx, var_bin, 2, pos_bin, ctx->int_dynamic.mPtr, DYN_LGNONE, cFM, cVM);
|
||||
/* */
|
||||
*binaddr = (pointeur *)(ctx->ad_var->ptr + ((pos_binaddr - 1) * 3 * sizeof(pointeur)));
|
||||
ctx->bin_indice = pos_bin;
|
||||
return;
|
||||
@@ -7464,7 +7461,6 @@ void SetBinIndex(env * ctx)
|
||||
{
|
||||
/* chercher dans _binaddr l'indice du source en cours */
|
||||
hashtable_do(ctx, HASH_READ, &ctx->g, copy_nom(ctx, GUV_BINADDR), &ctx->ad_var);
|
||||
//if(ctx->exception != OK) return;
|
||||
if(ctx->ad_var == NULL)
|
||||
{
|
||||
ctx->exception = EX_BINADDRVAR_KO;
|
||||
@@ -7493,7 +7489,7 @@ int main(int argc, char *argv[])
|
||||
if(argc < 2)
|
||||
{
|
||||
/* incorrect command line */
|
||||
printf("Usage: lw [-d] [-c|-k] [-t] [-WBIN:<chemin>] [-WLIB:<chemin>] [-WSRC:<chemin>] <prog> [parms...]\n");
|
||||
printf("Usage: lw [-d] [-t] [-WBIN:<chemin>] [-WLIB:<chemin>] [-WSRC:<chemin>] <prog> [parms...]\n");
|
||||
#ifdef BUILD
|
||||
#ifdef WINLIB
|
||||
printf("Build %lld\n", BUILD);
|
||||
@@ -7512,14 +7508,10 @@ int main(int argc, char *argv[])
|
||||
Load(ctx_env, ctx_env->tmp_dynamic.mPtr, &addr);
|
||||
if(ctx_env->except_ex == OK)
|
||||
Execute(ctx_env, addr);
|
||||
/* TODO : avant de liberer, supprimer toutes les fonctions des modules dans les vars : ?? */
|
||||
/* supprimer tous les progs de _binaddr */
|
||||
/* TODO : avant de liberer, supprimer toutes les fonctions des modules dans les vars ? (ce qui est fait dans ENDP : est-il toujours appele ?) */
|
||||
/* liberer tous les progs presents dans _binaddr */
|
||||
Unload(ctx_env);
|
||||
/* TODO : utilisation de w comme langage de plugins : prevoir un prog de base + instruction HOLD
|
||||
qui rend la main et attend un Execlibr = CALL, exception apres HOLD est traitee en specifique
|
||||
pour sortir propre. Prog, pas d'I/O console (EOFF = echo off ?) ou io console redirigee dans var
|
||||
A l'init, choix du nom de la CALL externe, 1 seul param, hashtable (!?). Definir le pseudo PROG...
|
||||
*/
|
||||
/* */
|
||||
cr = ctx_env->except_ex;
|
||||
demon = ctx_env->demon;
|
||||
}
|
||||
|
||||
@@ -399,7 +399,7 @@ enum {
|
||||
#define GOV_THIS "this"
|
||||
#define GOV_PARENT "parent"
|
||||
|
||||
#define VARSYS "@varnull,@varnumber,@varsubroutine,@varparam,@vardynamic,@varhashtable,@varobject,@varbuffer,@false,@true,@level,@kill,@oid,@prog,@exceptstr,@exceptline,@except,@part,@line,@os,@vers,@verw,@demon,@endian,@file,@arg,@pi,@fm,@vm,@svm,@tm,@currfm,@currvm,@cr,@lf,@tab,@number,@dynamic,@empty,@trim,@left,@right,@center,@surround,@asc,@desc;1,2,3,4,5,6,7,8,10,11,12,13,14,15,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,50,51,52,53,54,55,56"
|
||||
#define VARSYS "@varnull,@varnumber,@varsubroutine,@varparam,@vardynamic,@varhashtable,@varobject,@varbuffer,@false,@true,@level,@kill,@oid,@prog,@pid,@exceptstr,@exceptline,@except,@part,@line,@os,@vers,@verw,@demon,@endian,@file,@arg,@pi,@fm,@vm,@svm,@tm,@currfm,@currvm,@cr,@lf,@tab,@number,@dynamic,@empty,@trim,@left,@right,@center,@surround,@asc,@desc;1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,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,50,51,52,53,54,55,56"
|
||||
|
||||
#include "global.h"
|
||||
|
||||
|
||||
@@ -71,7 +71,8 @@ enum {
|
||||
EXMOD_SOCK_NOTNUM = 10,
|
||||
EXMOD_SOCK_GETHOST = 11,
|
||||
EXMOD_SOCK_GETNAME = 12,
|
||||
EXMOD_NB = 12
|
||||
EXMOD_SOCK_WAIT_TIMEOUT = 13,
|
||||
EXMOD_NB = 13
|
||||
};
|
||||
/* libelles des codes d'erreur, qui doivent aller de 1 a EXMOD_NB */
|
||||
char * descModErr[] = {
|
||||
@@ -196,24 +197,40 @@ long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
/* get param in the right order */
|
||||
var * paramPortNumber = getParam(e, "portNumber", 10);
|
||||
/* TODO socket unix locale (pas en mode secure) */
|
||||
if(paramPortNumber == NULL)
|
||||
var * paramLocalSocket = getParam(e, "localSocket", 11);
|
||||
/* */
|
||||
if((paramPortNumber == NULL && paramLocalSocket == NULL) ||
|
||||
(paramPortNumber != NULL && paramLocalSocket != NULL) )
|
||||
exc = EX_MODPARAM;
|
||||
else if(paramPortNumber->type != VAR_NUMBER && paramPortNumber->type != VAR_DYNAMIC)
|
||||
else if((paramPortNumber != NULL && paramPortNumber->type != VAR_NUMBER && paramPortNumber->type != VAR_DYNAMIC) ||
|
||||
(paramLocalSocket != NULL && paramLocalSocket->type != VAR_NUMBER && paramLocalSocket->type != VAR_DYNAMIC) )
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
/* cree un point d'entree serveur */
|
||||
number port;
|
||||
if( ! var_conv_num(e, paramPortNumber, &port))
|
||||
exc = setError(p_etat, EXMOD_SOCK_SERVER_PORT_NUM);
|
||||
else if(port < 1024 * NUM_FACTEUR || port > 65535 * NUM_FACTEUR)
|
||||
exc = setError(p_etat, EXMOD_SOCK_SERVER_PORT_INVALID); /* en dessous de 1024, necessite des autorisations speciales, non gere ici */
|
||||
number port = 0;
|
||||
var * local = NULL;
|
||||
if(paramLocalSocket != NULL)
|
||||
{
|
||||
GetTempDirectory(e, &e->tmp_dynamic);
|
||||
if(paramLocalSocket->type == VAR_NUMBER)
|
||||
dynConcatNumber(e, &e->tmp_dynamic, paramLocalSocket->num / NUM_FACTEUR);
|
||||
else
|
||||
dynConcat(e, &e->tmp_dynamic, paramLocalSocket);
|
||||
local = &e->tmp_dynamic;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(NewSocket(e, &p_etat->ctxSock, FALSE) == WSOCKET_OK)
|
||||
if( ! var_conv_num(e, paramPortNumber, &port))
|
||||
exc = setError(p_etat, EXMOD_SOCK_SERVER_PORT_NUM);
|
||||
else if(port < 1024 * NUM_FACTEUR || port > 65535 * NUM_FACTEUR)
|
||||
exc = setError(p_etat, EXMOD_SOCK_SERVER_PORT_INVALID); /* en dessous de 1024, necessite des autorisations speciales, non gere ici */
|
||||
}
|
||||
if(exc == OK)
|
||||
{
|
||||
if(NewSocket(e, &p_etat->ctxSock, (local != NULL)) == WSOCKET_OK)
|
||||
{
|
||||
if(SocketSetServer(e, &p_etat->ctxSock, p_etat->ctxSock.sock, (int)(port / NUM_FACTEUR), NULL) != WSOCKET_OK)
|
||||
if(SocketSetServer(e, &p_etat->ctxSock, p_etat->ctxSock.sock, (int)(port / NUM_FACTEUR), local) != WSOCKET_OK)
|
||||
exc = setError(p_etat, EXMOD_SOCK_SETSERVER);
|
||||
}
|
||||
else
|
||||
@@ -228,22 +245,38 @@ long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
var * paramHost = getParam(e, "host", 4);
|
||||
var * paramPortNumber = getParam(e, "portNumber", 10);
|
||||
var * paramSocket = getParam(e, "socket", 6);
|
||||
/* socket unix locale (pas en mode secure) */
|
||||
if(paramHost == NULL || paramPortNumber == NULL || paramSocket == NULL)
|
||||
var * paramLocalSocket = getParam(e, "localSocket", 11);
|
||||
/* */
|
||||
if(paramHost == NULL || paramSocket == NULL || (paramPortNumber == NULL && paramLocalSocket == NULL) ||
|
||||
(paramPortNumber != NULL && paramLocalSocket != NULL) )
|
||||
exc = EX_MODPARAM;
|
||||
else if(paramHost->type != VAR_DYNAMIC || (paramPortNumber->type != VAR_NUMBER && paramPortNumber->type != VAR_DYNAMIC))
|
||||
else if(paramHost->type != VAR_DYNAMIC || (paramPortNumber != NULL && paramPortNumber->type != VAR_NUMBER && paramPortNumber->type != VAR_DYNAMIC) ||
|
||||
(paramLocalSocket != NULL && paramLocalSocket->type != VAR_NUMBER && paramLocalSocket->type != VAR_DYNAMIC) )
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
/* connexion a un serveur */
|
||||
number port;
|
||||
if( ! var_conv_num(e, paramPortNumber, &port))
|
||||
exc = setError(p_etat, EXMOD_SOCK_SERVER_PORT_NUM);
|
||||
number port = 0;
|
||||
var * local = NULL;
|
||||
if(paramLocalSocket != NULL)
|
||||
{
|
||||
GetTempDirectory(e, &e->tmp_dynamic);
|
||||
if(paramLocalSocket->type == VAR_NUMBER)
|
||||
dynConcatNumber(e, &e->tmp_dynamic, paramLocalSocket->num / NUM_FACTEUR);
|
||||
else
|
||||
dynConcat(e, &e->tmp_dynamic, paramLocalSocket);
|
||||
local = &e->tmp_dynamic;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(NewSocket(e, &p_etat->ctxSock, FALSE) == WSOCKET_OK)
|
||||
if( ! var_conv_num(e, paramPortNumber, &port))
|
||||
exc = setError(p_etat, EXMOD_SOCK_SERVER_PORT_NUM);
|
||||
}
|
||||
if(exc == OK)
|
||||
{
|
||||
if(NewSocket(e, &p_etat->ctxSock, (local != NULL)) == WSOCKET_OK)
|
||||
{
|
||||
if(SocketConnectToServer(e, &p_etat->ctxSock, p_etat->ctxSock.sock, (int)(port / NUM_FACTEUR), NULL, paramHost) == WSOCKET_OK)
|
||||
if(SocketConnectToServer(e, &p_etat->ctxSock, p_etat->ctxSock.sock, (int)(port / NUM_FACTEUR), local, paramHost) == WSOCKET_OK)
|
||||
{
|
||||
if(paramSocket->type != VAR_NUMBER)
|
||||
var_let(e, paramSocket, &e->int_number, FALSE, FALSE);
|
||||
@@ -451,45 +484,52 @@ long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
/* get param in the right order */
|
||||
var * paramSocket = getParam(e, "socket", 6);
|
||||
var * paramPid = getParam(e, "pid", 3);
|
||||
var * paramClose = getParam(e, "closeOnSend", 11);
|
||||
/* envoi d'une socket a un autre process via son pid, par socket unix locale (non secu) */
|
||||
if(paramSocket == NULL || paramPid == NULL)
|
||||
if(paramSocket == NULL || paramPid == NULL || paramClose == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
else if((paramSocket->type != VAR_NUMBER && paramSocket->type != VAR_DYNAMIC) || (paramPid->type != VAR_NUMBER && paramPid->type != VAR_DYNAMIC))
|
||||
else if((paramSocket->type != VAR_NUMBER && paramSocket->type != VAR_DYNAMIC) || (paramPid->type != VAR_NUMBER && paramPid->type != VAR_DYNAMIC) ||
|
||||
(paramClose->type != VAR_NUMBER && paramClose->type != VAR_DYNAMIC) )
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
number socket, pid;
|
||||
if( ! var_conv_num(e, paramSocket, &socket) || ! var_conv_num(e, paramPid, &pid))
|
||||
exc = setError(p_etat, EXMOD_SOCK_SERVER_PORT_NUM); // TODO
|
||||
number socket, pid, closeOnSend;
|
||||
if( ! var_conv_num(e, paramSocket, &socket) || ! var_conv_num(e, paramPid, &pid) || ! var_conv_num(e, paramClose, &closeOnSend))
|
||||
exc = setError(p_etat, EX_MODPARAM);
|
||||
else
|
||||
{
|
||||
if(NewSocket(e, &p_etat->ctxSock, TRUE) == WSOCKET_OK)
|
||||
{
|
||||
GetTempDirectory(e, &e->tmp_dynamic);
|
||||
dynConcatSz(e, &e->tmp_dynamic, "wsocket_", 8);
|
||||
dynConcatNumber(e, &e->tmp_dynamic, pid);
|
||||
dynConcatNumber(e, &e->tmp_dynamic, pid / NUM_FACTEUR);
|
||||
if(SocketConnectToServer(e, &p_etat->ctxSock, p_etat->ctxSock.sock, 0, &e->tmp_dynamic, NULL) == WSOCKET_OK)
|
||||
{
|
||||
if(SendSocket(e, &p_etat->ctxSock, p_etat->ctxSock.sock, socket, pid) == OK)
|
||||
/* si socket donnee = 0, envoyer la socket serveur */
|
||||
if(SendSocket(e, &p_etat->ctxSock, p_etat->ctxSock.sock, socket == 0 ? p_etat->ctxSock.servSock : socket, pid / NUM_FACTEUR) == OK)
|
||||
{
|
||||
dynSetLen(e, &e->tmp_dynamic, 0);
|
||||
if(ReadSocket(e, &p_etat->ctxSock, p_etat->ctxSock.sock, &e->tmp_dynamic, 1000) == WSOCKET_OK) /* delai 1 sec. */
|
||||
{
|
||||
/* verifier si les donnes lues sont egales a "OK" */
|
||||
/* socket bien recue par l'autre process : fermer celle ici */
|
||||
FreeSocket(e, &p_etat->ctxSock, socket);
|
||||
if(dynCompare(e, &e->tmp_dynamic, CMP_NE, "OK", 2))
|
||||
exc = setError(p_etat, EXMOD_SOCK_READ);
|
||||
/* socket bien recue par l'autre process : fermer celle ici si besoin */
|
||||
else if(closeOnSend)
|
||||
FreeSocket(e, &p_etat->ctxSock, socket == 0 ? p_etat->ctxSock.servSock : socket);
|
||||
}
|
||||
else
|
||||
exc = setError(p_etat, EXMOD_SOCK_READ); // TODO
|
||||
exc = setError(p_etat, EXMOD_SOCK_READ);
|
||||
}
|
||||
else
|
||||
exc = setError(p_etat, EXMOD_SOCK_READ); // TODO
|
||||
exc = setError(p_etat, EXMOD_SOCK_WRITE);
|
||||
FreeSocket(e, &p_etat->ctxSock, p_etat->ctxSock.sock);
|
||||
}
|
||||
else
|
||||
exc = setError(p_etat, EXMOD_SOCK_CONNECT); // TODO
|
||||
exc = setError(p_etat, EXMOD_SOCK_CONNECT);
|
||||
}
|
||||
else
|
||||
exc = setError(p_etat, EXMOD_SOCK_NEW); // TODO
|
||||
exc = setError(p_etat, EXMOD_SOCK_NEW);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -520,7 +560,7 @@ long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
if(cr < 0)
|
||||
exc = setError(p_etat, EXMOD_SOCK_WAIT);
|
||||
else if(cr == 0)
|
||||
; /* => timeout, RAS */
|
||||
exc = setError(p_etat, EXMOD_SOCK_WAIT_TIMEOUT);
|
||||
else
|
||||
{
|
||||
/* nouvelle connexion entrante */
|
||||
@@ -536,10 +576,14 @@ long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
paramSocket->num = socket;
|
||||
}
|
||||
else
|
||||
exc = setError(p_etat, EXMOD_SOCK_WRITE); // TODO
|
||||
{
|
||||
/* ecriture cr KO, mais socket recue => dans le doute, fermer la socket quand meme */
|
||||
FreeSocket(e, &p_etat->ctxSock, socket);
|
||||
exc = setError(p_etat, EXMOD_SOCK_WRITE);
|
||||
}
|
||||
}
|
||||
else
|
||||
exc = setError(p_etat, EXMOD_SOCK_READ); // TODO
|
||||
exc = setError(p_etat, EXMOD_SOCK_READ);
|
||||
FreeSocket(e, &p_etat->ctxSock, p_etat->ctxSock.sock);
|
||||
}
|
||||
else
|
||||
|
||||
+29
-20
@@ -359,14 +359,11 @@ WAPIDECL long SocketConnectToServer(env * e, modContextSocket * ctx, Socket sock
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
addr.sun_family = AF_UNIX;
|
||||
dynSetAs(e, &ctx->localSocket, localPath);
|
||||
/* localPath doit contenir le chemin complet d'un "fichier" unique pour la socket locale (exemple: /tmp/wsock_1234.sock et C:\\Temp\\wsock_1234.sock) */
|
||||
if(ctx->localSocket.mLg >= sizeof(addr.sun_path))
|
||||
{
|
||||
dynSetLen(e, &ctx->localSocket, 0);
|
||||
if(localPath->mLg >= sizeof(addr.sun_path))
|
||||
return WSOCKET_ERROR;
|
||||
}
|
||||
strcpy(addr.sun_path, ctx->localSocket.mPtr); /* la gestion du fichier socket local est laisse a la gestion du socket serveur en ecoute */
|
||||
/* */
|
||||
strcpy(addr.sun_path, localPath->mPtr); /* la gestion du fichier socket local est laisse a la gestion du socket serveur en ecoute */
|
||||
sa = (struct sockaddr *)&addr;
|
||||
sofsa = sizeof(addr);
|
||||
}
|
||||
@@ -462,16 +459,20 @@ WAPIDECL long SendSocket(env * e, modContextSocket * ctx, Socket sock, Socket so
|
||||
/* send socket using AF_UNIX local socket */
|
||||
#ifndef WINLIB
|
||||
struct msghdr msg = {0};
|
||||
char buffer[CMSG_SPACE(sizeof(int))];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
union {
|
||||
char buffer[CMSG_SPACE(sizeof(int))];
|
||||
struct cmsghdr align;
|
||||
} u;
|
||||
memset(u.buffer, 0, sizeof(u.buffer));
|
||||
char buf_data = 'X';
|
||||
struct iovec io = {
|
||||
.iov_base = (void *)"X", /* peu importe... */
|
||||
.iov_base = &buf_data,
|
||||
.iov_len = 1
|
||||
};
|
||||
msg.msg_iov = &io;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = buffer;
|
||||
msg.msg_controllen = sizeof(buffer);
|
||||
msg.msg_control = u.buffer;
|
||||
msg.msg_controllen = sizeof(u.buffer);
|
||||
struct cmsghdr * cmsg = CMSG_FIRSTHDR(&msg);
|
||||
if(cmsg == NULL)
|
||||
return -1;
|
||||
@@ -505,16 +506,20 @@ WAPIDECL long ReceiveSocket(env * e, modContextSocket * ctx, Socket sock, Socket
|
||||
/* receive socket from AF_UNIX local socket */
|
||||
#ifndef WINLIB
|
||||
struct msghdr msg = {0};
|
||||
char buffer[CMSG_SPACE(sizeof(int))];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
union {
|
||||
char buffer[CMSG_SPACE(sizeof(int))];
|
||||
struct cmsghdr align;
|
||||
} u;
|
||||
memset(u.buffer, 0, sizeof(u.buffer));
|
||||
char buf_data;
|
||||
struct iovec io = {
|
||||
.iov_base = (void *)"X", /* peu importe... */
|
||||
.iov_len = sizeof(1)
|
||||
.iov_base = &buf_data,
|
||||
.iov_len = 1
|
||||
};
|
||||
msg.msg_iov = &io;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = buffer;
|
||||
msg.msg_controllen = sizeof(buffer);
|
||||
msg.msg_control = u.buffer;
|
||||
msg.msg_controllen = sizeof(u.buffer);
|
||||
if(recvmsg(sock, &msg, 0) <= 0)
|
||||
return -1;
|
||||
if(msg.msg_flags & MSG_CTRUNC)
|
||||
@@ -523,7 +528,6 @@ WAPIDECL long ReceiveSocket(env * e, modContextSocket * ctx, Socket sock, Socket
|
||||
if(cmsg == NULL || cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS || cmsg->cmsg_len < CMSG_LEN(sizeof(int)))
|
||||
return -1; /* pas de socket valide recue */
|
||||
memcpy(socketReceived, CMSG_DATA(cmsg), sizeof(*socketReceived));
|
||||
return OK;
|
||||
/* */
|
||||
#else
|
||||
var * v = &e->tmp_dynamic;
|
||||
@@ -537,9 +541,14 @@ WAPIDECL long ReceiveSocket(env * e, modContextSocket * ctx, Socket sock, Socket
|
||||
*socketReceived = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &info, 0, 0);
|
||||
if(*socketReceived == INVALID_SOCKET)
|
||||
return -1;
|
||||
else
|
||||
return OK;
|
||||
#endif
|
||||
/* socket recu = socket serveur forcement */
|
||||
if(AddSocket(e, ctx, *socketReceived) == WSOCKET_OK)
|
||||
{
|
||||
FreeSocket(e, ctx, ctx->servSock); /* securite : libere l'ancien socket server */
|
||||
ctx->servSock = *socketReceived;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
WAPIDECL long AddSocket(env * e, modContextSocket * ctx, Socket sock)
|
||||
|
||||
+16
-16
@@ -463,27 +463,27 @@ long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
var_let(e, paramPid, &e->int_number, FALSE, FALSE);
|
||||
paramPid->num = 0; /* erreur par defaut */
|
||||
/* lire GUV_ENV et GUV_WARGV{1} pour reconstituer la ligne de commande windows/unix */
|
||||
var * va = &e->int_dynamic;
|
||||
var * va = NULL, * ve = NULL;
|
||||
hashtable_do(e, HASH_READ, &e->g, copy_nom(e, GUV_WARGV), &va); // garder {1,1} = executeur W
|
||||
var * ve = &e->tmp_dynamic;
|
||||
hashtable_do(e, HASH_READ, &e->g, copy_nom(e, GUV_ENV), &ve); // wbin wsrc wlib {1,1-3}
|
||||
if(va && ve)
|
||||
{
|
||||
dynStore(e, va, 2, DYN_NONE, ve, cVM, DYN_NONE);
|
||||
dynField(e, va, ve, 1, DYN_NONE, cVM, DYN_NONE, 4); /* ve = execw wbin wsrc wlib en VM */
|
||||
dynReplace(e, ve, cVM, cFM);
|
||||
dynConcatSz(e, ve, sFM, 1);
|
||||
dynConcat(e, ve, paramArgs); /* ve = execw wbin wsrc wlib progw argw1 etc. en FM */
|
||||
dynInsSz(e, ve, 2, 1, "-WBIN", 5, cFM, ':');
|
||||
dynInsSz(e, ve, 3, 1, "-WSRC", 5, cFM, ':');
|
||||
dynInsSz(e, ve, 4, 1, "-WLIB", 5, cFM, ':');
|
||||
/* ve (tmp_dynamic) contient la ligne de commande complete */
|
||||
dynField(e, va, &e->tmp_dynamic, 1, DYN_NONE, cVM, DYN_NONE, 1);
|
||||
dynStore(e, &e->tmp_dynamic, 2, DYN_NONE, ve, cVM, DYN_NONE); /* tmp_dynamic = execw wbin wsrc wlib en VM */
|
||||
dynReplace(e, &e->tmp_dynamic, cVM, cFM);
|
||||
dynConcatSz(e, &e->tmp_dynamic, sFM, 1);
|
||||
dynConcat(e, &e->tmp_dynamic, paramArgs); /* tmp_dynamic = execw wbin wsrc wlib progw argw1 etc. en FM */
|
||||
dynInsSz(e, &e->tmp_dynamic, 2, 1, "-WBIN", 5, cFM, ':');
|
||||
dynInsSz(e, &e->tmp_dynamic, 3, 1, "-WSRC", 5, cFM, ':');
|
||||
dynInsSz(e, &e->tmp_dynamic, 4, 1, "-WLIB", 5, cFM, ':');
|
||||
dynInsSz(e, &e->tmp_dynamic, 5, DYN_NONE, "-b", 2, cFM, DYN_NONE); /* indique aux fils que deja lance en background */
|
||||
/* tmp_dynamic contient la ligne de commande complete */
|
||||
#ifdef WINLIB
|
||||
dynReplace(e, ve, cFM, ' '); /* recree une ligne de commande */
|
||||
dynReplace(e, &e->tmp_dynamic, cFM, ' '); /* recree une ligne de commande */
|
||||
STARTUPINFO si = {0};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
si.cb = sizeof(si);
|
||||
if(CreateProcess(NULL, ve->mPtr, NULL, NULL, FALSE, e->demon ? CREATE_NO_WINDOW : CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) // ou DETACHED_PROCESS comme avec BACK !?
|
||||
if(CreateProcess(NULL, e->tmp_dynamic.mPtr, NULL, NULL, FALSE, e->demon ? CREATE_NO_WINDOW : DETACHED_PROCESS, NULL, NULL, &si, &pi)) // ou DETACHED_PROCESS comme avec BACK !? (CREATE_NEW_CONSOLE lance une console !)
|
||||
{
|
||||
paramPid->num = pi.dwProcessId * NUM_FACTEUR; /* ok, code retour = pid du process cree */
|
||||
CloseHandle(pi.hThread);
|
||||
@@ -499,9 +499,9 @@ long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
else if(pid == 0)
|
||||
{
|
||||
/* dans le fils : execvp et sortie */
|
||||
dynField(e, ve, va, 1, DYN_NONE, cFM, DYN_NONE, 1);
|
||||
char ** argv = dynToTabPtr(e, ve, cFM);
|
||||
execvp(va->mPtr, argv); /* attention : si programme interactif en front lance (cas exec 'calc') avec acces entree standard => generera une exception car ce n'est pas possible sous Unix (ok windows) */
|
||||
dynField(e, &e->tmp_dynamic, &e->int_dynamic, 1, DYN_NONE, cFM, DYN_NONE, 1);
|
||||
char ** argv = dynToTabPtr(e, &e->tmp_dynamic, cFM);
|
||||
execvp(e->int_dynamic.mPtr, argv); /* attention : si programme interactif en front lance (cas exec 'calc') avec acces entree standard => generera une exception car ce n'est pas possible sous Unix (ok windows) */
|
||||
/* ici, erreur de execvp */
|
||||
_exit(127); /* mieux que exit(0) !? */
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user