I took a quick look at the 2!:2 code and it's mostly ok in that the file descriptors returned in the array are usable. Unfortunately using it causes spurious errors crashes:
$ jconsole a=: (2!:2) '/bin/ls -l' a 28836 94660922311904 94660922312464 b =: mema 1024 |ill-formed number ...other J commands... Program received signal SIGSEGV, Segmentation fault. Note that "ill-formed number" error is incorrect. The parser has gotten mixed up. I tracked this down to the fdopen usage in 'jthostio'. If I move that to after the fork call then the J system doesn't become unstable. This patch basically: ------------------------------8<------------------------- diff --git a/jsrc/xh.c b/jsrc/xh.c index 912738b..93213e5 100644 --- a/jsrc/xh.c +++ b/jsrc/xh.c @@ -151,8 +151,6 @@ F1(jthostio){C*s;A z;F*pz;int fi[2],fo[2],r;int fii[2],foi[2]; RZ(w=vs(w)); s=CAV(w); GAT(z,INT,3,1,0); pz=(F*)AV(z); if((r=pipe(fii))==-1||pipe(foi)==-1){if(r!=-1)CL(fi); ASSERT(0,EVFACE);} - if(!((pz[1]=fdopen(fi[0],"r"))&&(pz[2]=fdopen(fo[1],"w")))){ - if(pz[1])fclose(pz[1]); CL(fi);CL(fo);} if(!add2(pz[1],pz[2],s)){fclose(pz[1]);fclose(pz[2]); CL(fi);CL(fo);} switch(r=fork()){ @@ -165,6 +163,8 @@ F1(jthostio){C*s;A z;F*pz;int fi[2],fo[2],r;int fii[2],foi[2]; #endif }close(fo[0]);close(fi[1]); add2(NULL,NULL,NULL); pz[0]=(F)(intptr_t)r; + if(!((pz[1]=fdopen(fi[0],"r"))&&(pz[2]=fdopen(fo[1],"w")))){ + if(pz[1])fclose(pz[1]); CL(fi);CL(fo);} R z; } ------------------------------8<------------------------- Can anyone else duplicate this system instability? 1!:1 and 1!:11 still can't be used to read from these descriptors as they attempt to seek the file. This fails as the file descriptors are not seekable files, they're ends of a pipe. The return values of the seek call aren't checked so no error is raised, the system gets confused, and eventually a segfault occurs. The seek occurs in 'jtrd', during the 'fsize' call: https://github.com/jsoftware/jsource/blob/master/jsrc/xf.c#L83 'jtrd' gets called as part of the 1!:1 conjunction (the 'jtfjread' function): https://github.com/jsoftware/jsource/blob/master/jsrc/xf.c#L124 Note there that it checks for the constant value 3 to indicate a read from the non-seekable 'stdin' and that calls 'jtrdns' which doesn't do an fsize or seek. Possible the code could detect for a non-seekable descriptor and call 'jtrdns' but that's still not too useful for a stream where you are reading and writing (eg. interacting with a shell) since it would try to read the entire contents and block. Maybe 1!:11 could be changed to detect and not seek (it calls fsize too): https://github.com/jsoftware/jsource/blob/master/jsrc/xf.c#L188 it's possible though to use the FFI to use the descriptors: a=: (2!:2) '/bin/ls -l' a 28836 94660922311904 94660922312464 b=: mema 1024 b 94660922313024 '/lib/x86_64-linux-gnu/libc.so.6 fread > i *c i i x' cd (<b);1;10;94660922311904 10 memr 94660922313024 0 8 2 total 16 -- http://bluishcoder.co.nz ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm