@@ -84,6 +84,52 @@ public function testStartWithCustomPipesWillAssignPipes()
8484 $ this ->assertInstanceOf ('React\Stream\WritableStreamInterface ' , $ process ->pipes [3 ]);
8585 }
8686
87+ /**
88+ * @expectedException RuntimeException
89+ * @expectedExceptionMessage No such file or directory
90+ */
91+ public function testStartWithInvalidFileDescriptorPathWillThrow ()
92+ {
93+ $ fds = array (
94+ 4 => array ('file ' , '/dev/does-not-exist ' , 'r ' )
95+ );
96+
97+ $ process = new Process ('exit 0 ' , null , null , $ fds );
98+ $ process ->start ($ this ->createLoop ());
99+ }
100+
101+ public function testStartWithExcessiveNumberOfFileDescriptorsWillThrow ()
102+ {
103+ $ ulimit = exec ('ulimit -n 2>&1 ' );
104+ if ($ ulimit < 1 ) {
105+ $ this ->markTestSkipped ('Unable to determine limit of open files (ulimit not available?) ' );
106+ }
107+
108+ $ loop = $ this ->createLoop ();
109+
110+ // create 70% (usually ~700) dummy file handles in this parent dummy
111+ $ limit = (int )($ ulimit * 0.7 );
112+ $ fds = array ();
113+ for ($ i = 0 ; $ i < $ limit ; ++$ i ) {
114+ $ fds [$ i ] = fopen ('/dev/null ' , 'r ' );
115+ }
116+
117+ // try to create child process with another ~700 dummy file handles
118+ $ new = array_fill (0 , $ limit , array ('file ' , '/dev/null ' , 'r ' ));
119+ $ process = new Process ('ping example.com ' , null , null , $ new );
120+
121+ try {
122+ $ process ->start ($ loop );
123+
124+ $ this ->fail ('Did not expect to reach this point ' );
125+ } catch (\RuntimeException $ e ) {
126+ // clear dummy files handles to make some room again (avoid fatal errors for autoloader)
127+ $ fds = array ();
128+
129+ $ this ->assertContains ('Too many open files ' , $ e ->getMessage ());
130+ }
131+ }
132+
87133 public function testIsRunning ()
88134 {
89135 if (DIRECTORY_SEPARATOR === '\\' ) {
0 commit comments