aboutsummaryrefslogtreecommitdiff
path: root/elymas/lib/sys.ey
blob: c8d0cf147a6c95a7b014fa4cccb760fb944bc2fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# abstract system layer

<
  sys .linux "+" via

  { # ==directory
    "\0" cat 511 +mkdir 0 neq { ??io.dir.mk } rep
  } /mkdir sys .deff

  { # ==directory
    "\0" cat +ORDONLY +ODIRECTORY bor 0 +open ==fd
    fd 0 lt { ??io.dir.ls.open } {
      [ [ { fd +getdents64 _ 0 lt { ??io.dir.ls.getdents } rep } { _ len dearray } loop ] { .dname } each ]
      fd +close 0 lt { ??io.dir.ls.close } rep
    } ? *
  } /readdir sys .deff

  { # ==directory
    sys .readdir { 0 -01 * 0 "." * neq } grep
  } /ls sys .deff

  { _ ==pattern
    "^(.*)/([^/]*)$" regex {
      ==dir =pattern
    }" {
      "." ==dir
    }" ? *
    [ pattern { ==c
      [
        # FIXME: [, ] escapes in regexes
        { c 0 "." * eq } { "\\." { } each }
        { c 0 "*" * eq } { ".*" { } each }
        { c 0 "?" * eq } { "." { } each }
        { 1 } { c }
      ] conds
    } each ] str .fromArray ==rx
    dir sys .readdir { rx regex } grep
  } /glob sys .deff

  {
    "\0" cat -01 "\0" cat -01 +rename 0 neq { ??io.rename } rep
  } /rename sys .deff

  # 0 -> an array of strings determining argv
  # 1 -> path to executable
  {
    -01 "\0" cat -01 [ ] +execve ??proc.exec
  } /exec sys .deff

  # 0 -> a shell command
  { ==cmd
    "/bin/sh" [ "sh" "-c" cmd ] "\0" |cat '*00.0 [ ] +execve ??proc.exec
  } /shell sys .deff

  # 0 -> function to execute in the child
  # 0 <- scope describing child, available members:
  #      .pid
  #      .wait (will return some status code) # TODO decompose this according to man 2 waitpid
  #      <SIG> .kill
  #      .in - child stdin
  #      .out - child stdout
  #      .err - child stderr (maybe inject some polling on this one per default)
  #
  # Example:
  # { "wget 'http://drahflow.name/' -O -" sys .shell } sys .spawn _ |dump -01 .out .eachLine .wait --
  { =*f
    +pipe 0 neq { ??proc.spawn.pipe } rep ==readA ==writeA
    +pipe 0 neq { ??proc.spawn.pipe } rep ==readB ==writeB
    +pipe 0 neq { ??proc.spawn.pipe } rep ==readC ==writeC
    +fork _ ==child not {
      [ writeA readB readC 0 1 2 ] { +close } '*0.0 --
      [ readA writeB writeC ] [ 0 1 2 ] { +dup2 } '*00.0 --
      f 0 sys .exit
    } rep
    child 1 neg eq { ??proc.spawn.fork } {
      readA +close { ??proc.spawn.close } rep
      writeB +close { ??proc.spawn.close } rep
      writeC +close { ??proc.spawn.close } rep
      child < ==pid
        { pid 0 +waitpid -- } =*wait
        { pid -01 +kill -- } =*kill
        writeA _ ==inFd sys .fdToFile _ .writeonly ==in
        readB _ ==outFd sys .fdToFile _ .readonly ==out
        readC _ ==errFd sys .fdToFile _ .readonly ==err
      >
    } ? *
  } /spawn sys .deff
> --

# vim: syn=elymas