•SH
This commit is contained in:
parent
5c829a7fd7
commit
10d0cdc2fe
@ -1,8 +1,15 @@
|
|||||||
|
#include <spawn.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include "../core.h"
|
#include "../core.h"
|
||||||
#include "../utils/hash.h"
|
#include "../utils/hash.h"
|
||||||
#include "../utils/file.h"
|
#include "../utils/file.h"
|
||||||
#include "../utils/wyhash.h"
|
#include "../utils/wyhash.h"
|
||||||
#include "../utils/builtins.h"
|
#include "../utils/builtins.h"
|
||||||
|
#include "../utils/mut.h"
|
||||||
#include "../ns.h"
|
#include "../ns.h"
|
||||||
#include "../nfns.h"
|
#include "../nfns.h"
|
||||||
|
|
||||||
@ -489,6 +496,61 @@ B fromUtf8_c1(B t, B x) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern char** environ;
|
||||||
|
|
||||||
|
B sh_c1(B t, B x) {
|
||||||
|
if (isAtm(x) || rnk(x)>1) thrM("•SH: 𝕩 must be a vector of strings");
|
||||||
|
usz xia = a(x)->ia;
|
||||||
|
if (xia==0) thrM("•SH: 𝕩 must have at least one item");
|
||||||
|
TALLOC(char*, argv, xia+1);
|
||||||
|
BS2B xgetU = TI(x,getU);
|
||||||
|
for (u64 i = 0; i < xia; i++) {
|
||||||
|
B c = xgetU(x, i);
|
||||||
|
if (isAtm(c) || rnk(c)!=1) thrM("•SH: 𝕩 must be a vector of strings");
|
||||||
|
u64 len = utf8lenB(c);
|
||||||
|
TALLOC(char, cstr, len+1);
|
||||||
|
toUTF8(c, cstr);
|
||||||
|
cstr[len] = 0;
|
||||||
|
argv[i] = cstr;
|
||||||
|
}
|
||||||
|
argv[xia] = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
int p_out[2];
|
||||||
|
int p_err[2];
|
||||||
|
if (pipe(p_out) || pipe(p_err)) thrM("•SH: Failed to create process: Couldn't create pipes");
|
||||||
|
|
||||||
|
posix_spawn_file_actions_t a; posix_spawn_file_actions_init(&a);
|
||||||
|
posix_spawn_file_actions_addclose(&a, p_out[0]); posix_spawn_file_actions_adddup2(&a, p_out[1], 1); posix_spawn_file_actions_addclose(&a, p_out[1]);
|
||||||
|
posix_spawn_file_actions_addclose(&a, p_err[0]); posix_spawn_file_actions_adddup2(&a, p_err[1], 2); posix_spawn_file_actions_addclose(&a, p_err[1]);
|
||||||
|
|
||||||
|
pid_t pid;
|
||||||
|
if(posix_spawnp(&pid, argv[0], &a, NULL, argv, environ) != 0) thrF("•SH: Failed to create process: %S", strerror(errno));
|
||||||
|
|
||||||
|
for (u64 i = 0; i < xia; i++) TFREE(argv[i]);
|
||||||
|
TFREE(argv);
|
||||||
|
close(p_out[1]); B s_out = emptyCVec();
|
||||||
|
close(p_err[1]); B s_err = emptyCVec();
|
||||||
|
|
||||||
|
const u64 bufsz = 1024;
|
||||||
|
TALLOC(char, buf, bufsz);
|
||||||
|
struct pollfd ps[] = {{.fd=p_out[0], .events=POLLIN}, {.fd=p_err[0], .events=POLLIN}};
|
||||||
|
while (poll(&ps[0], 2, -1) > 0) {
|
||||||
|
if (ps[0].revents & POLLIN) s_out = vec_join(s_out, fromUTF8(buf, read(p_out[0], &buf[0], bufsz)));
|
||||||
|
else if (ps[1].revents & POLLIN) s_err = vec_join(s_err, fromUTF8(buf, read(p_err[0], &buf[0], bufsz)));
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
TFREE(buf);
|
||||||
|
|
||||||
|
int status;
|
||||||
|
waitpid(pid, &status, 0);
|
||||||
|
|
||||||
|
posix_spawn_file_actions_destroy(&a);
|
||||||
|
dec(x);
|
||||||
|
return m_v3(m_i32(WEXITSTATUS(status)), s_out, s_err);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
B getInternalNS(void);
|
B getInternalNS(void);
|
||||||
B getMathNS(void);
|
B getMathNS(void);
|
||||||
|
|
||||||
@ -517,6 +579,7 @@ B sys_c1(B t, B x) {
|
|||||||
else if (eqStr(c, U"internal")) r.a[i] = getInternalNS();
|
else if (eqStr(c, U"internal")) r.a[i] = getInternalNS();
|
||||||
else if (eqStr(c, U"math")) r.a[i] = getMathNS();
|
else if (eqStr(c, U"math")) r.a[i] = getMathNS();
|
||||||
else if (eqStr(c, U"type")) r.a[i] = inc(bi_type);
|
else if (eqStr(c, U"type")) r.a[i] = inc(bi_type);
|
||||||
|
else if (eqStr(c, U"sh")) r.a[i] = inc(bi_sh);
|
||||||
else if (eqStr(c, U"decompose")) r.a[i] = inc(bi_decp);
|
else if (eqStr(c, U"decompose")) r.a[i] = inc(bi_decp);
|
||||||
else if (eqStr(c, U"primind")) r.a[i] = inc(bi_primInd);
|
else if (eqStr(c, U"primind")) r.a[i] = inc(bi_primInd);
|
||||||
else if (eqStr(c, U"bqn")) r.a[i] = inc(bi_bqn);
|
else if (eqStr(c, U"bqn")) r.a[i] = inc(bi_bqn);
|
||||||
|
|||||||
@ -95,8 +95,6 @@ static B m_v1(B a ); // consumes all
|
|||||||
static B m_v2(B a, B b ); // consumes all
|
static B m_v2(B a, B b ); // consumes all
|
||||||
static B m_v3(B a, B b, B c ); // consumes all
|
static B m_v3(B a, B b, B c ); // consumes all
|
||||||
static B m_v4(B a, B b, B c, B d); // consumes all
|
static B m_v4(B a, B b, B c, B d); // consumes all
|
||||||
static B vec_join(B w, B x);
|
|
||||||
static B vec_add(B w, B x);
|
|
||||||
static bool isNumEl(u8 elt) { return elt==el_i32 | elt==el_f64; }
|
static bool isNumEl(u8 elt) { return elt==el_i32 | elt==el_f64; }
|
||||||
|
|
||||||
// string stuff
|
// string stuff
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
/* sort.c*/A(gradeUp,"⍋") A(gradeDown,"⍒") \
|
/* sort.c*/A(gradeUp,"⍋") A(gradeDown,"⍒") \
|
||||||
/* everything before the definition of •Type is defined to be pure, and everything after is not */ \
|
/* everything before the definition of •Type is defined to be pure, and everything after is not */ \
|
||||||
/* sysfn.c*/M(type,"•Type") M(decp,"•Decompose") M(primInd,"•PrimInd") M(glyph,"•Glyph") A(fill,"•FillFn") M(sys,"•getsys") A(grLen,"•GroupLen") D(grOrd,"•groupOrd") \
|
/* sysfn.c*/M(type,"•Type") M(decp,"•Decompose") M(primInd,"•PrimInd") M(glyph,"•Glyph") A(fill,"•FillFn") M(sys,"•getsys") A(grLen,"•GroupLen") D(grOrd,"•groupOrd") \
|
||||||
/* sysfn.c*/M(repr,"•Repr") A(asrt,"!") A(casrt,"!") M(out,"•Out") M(show,"•Show") M(bqn,"•BQN") M(fromUtf8,"•FromUTF8") \
|
/* sysfn.c*/M(repr,"•Repr") A(asrt,"!") A(casrt,"!") M(out,"•Out") M(show,"•Show") M(bqn,"•BQN") M(sh,"•SH") M(fromUtf8,"•FromUTF8") \
|
||||||
/* sysfn.c*/D(cmp,"•Cmp") A(hash,"•Hash") M(delay,"•Delay") M(makeRand,"•MakeRand") M(exit,"•Exit") M(getLine,"•GetLine") \
|
/* sysfn.c*/D(cmp,"•Cmp") A(hash,"•Hash") M(delay,"•Delay") M(makeRand,"•MakeRand") M(exit,"•Exit") M(getLine,"•GetLine") \
|
||||||
/*internal.c*/M(itype,"•internal.Type") M(refc,"•internal.Refc") M(squeeze,"•internal.Squeeze") M(isPure,"•internal.IsPure") A(info,"•internal.Info") \
|
/*internal.c*/M(itype,"•internal.Type") M(refc,"•internal.Refc") M(squeeze,"•internal.Squeeze") M(isPure,"•internal.IsPure") A(info,"•internal.Info") \
|
||||||
/*internal.c*/D(variation,"•internal.Variation") A(listVariations,"•internal.ListVariations") M(clearRefs,"•internal.ClearRefs") M(unshare,"•internal.Unshare")
|
/*internal.c*/D(variation,"•internal.Variation") A(listVariations,"•internal.ListVariations") M(clearRefs,"•internal.ClearRefs") M(unshare,"•internal.Unshare")
|
||||||
|
|||||||
@ -62,7 +62,7 @@ u64 utf8lenB(B x) { // doesn't consume; may error as it verifies whether is all
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
void toUTF8(B x, char* p) { // doesn't consume; doesn't verify anything; p must have utf8lenB(x) bytes (calculating which should verify that this call is ok)
|
void toUTF8(B x, char* p) {
|
||||||
BS2B xgetU = TI(x,getU);
|
BS2B xgetU = TI(x,getU);
|
||||||
usz ia = a(x)->ia;
|
usz ia = a(x)->ia;
|
||||||
for (usz i = 0; i < ia; i++) {
|
for (usz i = 0; i < ia; i++) {
|
||||||
|
|||||||
@ -6,4 +6,4 @@ B fromUTF8l(char* s);
|
|||||||
void printUTF8(u32 c);
|
void printUTF8(u32 c);
|
||||||
|
|
||||||
u64 utf8lenB(B x); // doesn't consume; may error as it verifies whether is all chars
|
u64 utf8lenB(B x); // doesn't consume; may error as it verifies whether is all chars
|
||||||
void toUTF8(B x, char* p); // doesn't consume; doesn't verify anything; p must have utf8lenB(x) bytes (calculating which should verify that this call is ok)
|
void toUTF8(B x, char* p); // doesn't consume; doesn't verify anything; p must have utf8lenB(x) bytes (calculating which should verify that this call is ok), add trailing null yourself
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user