1 When the first argument of process() is a function, it runs in the child 2 process, receives the argument vector and the environment, and returns the 3 argument vector to execute. Changes to the environment apply to the executed 4 program. exit() in the function sets the exit code of the child. An exception 5 or a return value that is not a non-empty array makes the child exit with code 6 255. Buffered output of the parent is written once, and SIGTERM ends the 7 child. 8 9 -- Testcase -- 10 {% 11 import * as uloop from 'uloop'; 12 import * as fs from 'fs'; 13 14 uloop.init(); 15 16 const tmpdir = fs.mkdtemp('/tmp/ucode-uloop-process-XXXXXX'); 17 const outfile = tmpdir + '/out'; 18 19 function run(label, executable, args, env) { 20 let completed = false; 21 let child = uloop.process(executable, args, env, (status) => { 22 completed = true; 23 printf('%s: %d\n', label, status); 24 uloop.end(); 25 }); 26 27 if (!child) 28 die('Unable to start child'); 29 30 uloop.run(); 31 32 if (!completed) 33 die('Missing process callback'); 34 } 35 36 run('argv', (args, env) => { 37 let out = fs.open(outfile, 'w'); 38 fs.dup2(out.fileno(), 1); 39 out.close(); 40 41 env.GREETING = 'changed'; 42 43 return ['/bin/sh', '-c', 'echo "$0 $1 $GREETING"; exit 3', ...args]; 44 }, ['first', 'second'], { GREETING: 'initial' }); 45 46 print(fs.readfile(outfile)); 47 fs.unlink(outfile); 48 fs.rmdir(tmpdir); 49 50 run('exception', () => die('setup failed')); 51 run('null', () => null); 52 run('empty', () => []); 53 run('string', () => '/bin/true'); 54 run('exit', () => exit(3)); 55 56 printf('buffered before fork\n'); 57 run('flush', () => { 58 fs.stdout.flush(); 59 return ['/bin/true']; 60 }); 61 62 uloop.timer(1, () => { 63 let child = uloop.process(() => { 64 sleep(300); 65 return ['/bin/true']; 66 }, null, null, (status) => { 67 printf('TERM: %d\n', status); 68 uloop.end(); 69 }); 70 71 uloop.timer(100, () => system(['kill', '-TERM', `${child.pid()}`])); 72 }); 73 74 uloop.run(); 75 76 printf('invalid: %J\n', uloop.process(123, null, null, () => null)); 77 78 uloop.done(); 79 %} 80 -- End -- 81 82 -- Expect stdout -- 83 argv: 3 84 first second changed 85 exception: 255 86 null: 255 87 empty: 255 88 string: 255 89 exit: 3 90 buffered before fork 91 flush: 0 92 TERM: -15 93 invalid: null 94 -- End -- 95 96 97 Signals received by the child do not reach the signal callbacks of the 98 parent. 99 100 -- Testcase -- 101 {% 102 import * as uloop from 'uloop'; 103 104 if (!uloop.signal) 105 exit(77); 106 107 uloop.init(); 108 109 let usr1_count = 0; 110 let usr1 = uloop.signal('SIGUSR1', () => usr1_count++); 111 112 uloop.timer(1, () => { 113 let child = uloop.process(() => { 114 sleep(300); 115 return ['/bin/true']; 116 }, null, null, (status) => { 117 printf('USR1: %d, parent callbacks: %d\n', status, usr1_count); 118 uloop.end(); 119 }); 120 121 uloop.timer(100, () => system(['kill', '-USR1', `${child.pid()}`])); 122 }); 123 124 uloop.run(); 125 126 usr1.delete(); 127 uloop.done(); 128 %} 129 -- End -- 130 131 -- Expect stdout -- 132 USR1: 0, parent callbacks: 0 133 -- End --
This page was automatically generated by LXR 0.3.1. • OpenWrt