40
40
*/
41
41
package com .oracle .graal .python .builtins .modules ;
42
42
43
+ import java .io .File ;
43
44
import java .io .IOException ;
44
45
import java .lang .ProcessBuilder .Redirect ;
45
46
import java .nio .ByteBuffer ;
60
61
import com .oracle .graal .python .builtins .objects .list .PList ;
61
62
import com .oracle .graal .python .builtins .objects .module .PythonModule ;
62
63
import com .oracle .graal .python .builtins .objects .str .PString ;
63
- import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
64
+ import com .oracle .graal .python .nodes .expression .CastToBooleanNode ;
65
+ import com .oracle .graal .python .nodes .expression .CastToListNode ;
64
66
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
65
67
import com .oracle .graal .python .nodes .function .PythonBuiltinNode ;
68
+ import com .oracle .graal .python .nodes .util .CastToIndexNode ;
69
+ import com .oracle .graal .python .nodes .util .CastToStringNode ;
66
70
import com .oracle .graal .python .runtime .PosixResources ;
67
71
import com .oracle .graal .python .runtime .PythonContext ;
68
72
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
69
73
import com .oracle .truffle .api .TruffleOptions ;
74
+ import com .oracle .truffle .api .dsl .Cached ;
70
75
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
71
76
import com .oracle .truffle .api .dsl .NodeFactory ;
72
77
import com .oracle .truffle .api .dsl .Specialization ;
@@ -86,25 +91,12 @@ abstract static class ForkExecNode extends PythonBuiltinNode {
86
91
@ Child BytesNodes .ToBytesNode toBytes = BytesNodes .ToBytesNode .create ();
87
92
88
93
@ Specialization
89
- synchronized int forkExecNoEnv (PList args , PTuple executable_list , boolean close_fds ,
90
- PTuple fdsToKeep , PNone cwd , @ SuppressWarnings ("unused" ) PNone env ,
91
- int p2cread , int p2cwrite , int c2pread , int c2pwrite ,
92
- int errread , int errwrite , int errpipe_read , int errpipe_write ,
93
- boolean restore_signals , boolean call_setsid , PNone preexec_fn ) {
94
- return forkExec (args , executable_list , close_fds , fdsToKeep , cwd , factory ().createList (),
95
- p2cread , p2cwrite , c2pread , c2pwrite ,
96
- errread , errwrite , errpipe_read , errpipe_write ,
97
- restore_signals , call_setsid , preexec_fn );
98
- }
99
-
100
- @ SuppressWarnings ("unused" )
101
94
@ TruffleBoundary
102
- @ Specialization
103
- synchronized int forkExec (PList args , PTuple executable_list , boolean close_fds ,
104
- PTuple fdsToKeep , PNone cwd , PList env ,
95
+ synchronized int forkExec (PList args , @ SuppressWarnings ("unused" ) PList execList , @ SuppressWarnings ("unused" ) boolean closeFds ,
96
+ @ SuppressWarnings ("unused" ) PList fdsToKeep , String cwd , PList env ,
105
97
int p2cread , int p2cwrite , int c2pread , int c2pwrite ,
106
- int errread , int errwrite , int errpipe_read , int errpipe_write ,
107
- boolean restore_signals , boolean call_setsid , PNone preexec_fn ) {
98
+ int errread , int errwrite , @ SuppressWarnings ( "unused" ) int errpipe_read , int errpipe_write ,
99
+ @ SuppressWarnings ( "unused" ) boolean restore_signals , @ SuppressWarnings ( "unused" ) boolean call_setsid , @ SuppressWarnings ( "unused" ) PNone preexec_fn ) {
108
100
PythonContext context = getContext ();
109
101
PosixResources resources = context .getResources ();
110
102
if (!context .isExecutableAccessAllowed ()) {
@@ -136,10 +128,6 @@ synchronized int forkExec(PList args, PTuple executable_list, boolean close_fds,
136
128
}
137
129
}
138
130
139
- Channel stdin = null ;
140
- Channel stdout = null ;
141
- Channel stderr = null ;
142
-
143
131
ProcessBuilder pb = new ProcessBuilder (argStrings );
144
132
if (p2cread != -1 && p2cwrite != -1 ) {
145
133
pb .redirectInput (Redirect .PIPE );
@@ -159,6 +147,16 @@ synchronized int forkExec(PList args, PTuple executable_list, boolean close_fds,
159
147
pb .redirectError (Redirect .INHERIT );
160
148
}
161
149
150
+ try {
151
+ if (getContext ().getEnv ().getTruffleFile (cwd ).exists ()) {
152
+ pb .directory (new File (cwd ));
153
+ } else {
154
+ throw raise (PythonBuiltinClassType .OSError , "working directory %s is not accessible" , cwd );
155
+ }
156
+ } catch (SecurityException e ) {
157
+ throw raise (PythonBuiltinClassType .OSError , e .getMessage ());
158
+ }
159
+
162
160
Map <String , String > environment = pb .environment ();
163
161
for (Object keyValue : env .getSequenceStorage ().getInternalArray ()) {
164
162
if (keyValue instanceof PBytes ) {
@@ -204,5 +202,49 @@ synchronized int forkExec(PList args, PTuple executable_list, boolean close_fds,
204
202
return -1 ;
205
203
}
206
204
}
205
+
206
+ @ Specialization (replaces = "forkExec" )
207
+ int forkExecDefault (Object args , Object executable_list , Object close_fds ,
208
+ Object fdsToKeep , Object cwd , Object env ,
209
+ Object p2cread , Object p2cwrite , Object c2pread , Object c2pwrite ,
210
+ Object errread , Object errwrite , Object errpipe_read , Object errpipe_write ,
211
+ Object restore_signals , Object call_setsid , PNone preexec_fn ,
212
+ @ Cached ("create()" ) CastToListNode castArgs ,
213
+ @ Cached ("create()" ) CastToListNode castExecList ,
214
+ @ Cached ("createIfTrueNode()" ) CastToBooleanNode castCloseFds ,
215
+ @ Cached ("create()" ) CastToListNode castFdsToKeep ,
216
+ @ Cached ("create()" ) CastToStringNode castCwd ,
217
+ @ Cached ("create()" ) CastToListNode castEnv ,
218
+ @ Cached ("create()" ) CastToIndexNode castP2cread ,
219
+ @ Cached ("create()" ) CastToIndexNode castP2cwrite ,
220
+ @ Cached ("create()" ) CastToIndexNode castC2pread ,
221
+ @ Cached ("create()" ) CastToIndexNode castC2pwrite ,
222
+ @ Cached ("create()" ) CastToIndexNode castErrread ,
223
+ @ Cached ("create()" ) CastToIndexNode castErrwrite ,
224
+ @ Cached ("create()" ) CastToIndexNode castErrpipeRead ,
225
+ @ Cached ("create()" ) CastToIndexNode castErrpipeWrite ,
226
+ @ Cached ("createIfTrueNode()" ) CastToBooleanNode castRestoreSignals ,
227
+ @ Cached ("createIfTrueNode()" ) CastToBooleanNode castSetsid ) {
228
+
229
+ String actualCwd ;
230
+ if (cwd instanceof PNone ) {
231
+ actualCwd = getContext ().getEnv ().getCurrentWorkingDirectory ().getPath ();
232
+ } else {
233
+ actualCwd = castCwd .execute (cwd );
234
+ }
235
+
236
+ PList actualEnv ;
237
+ if (env instanceof PNone ) {
238
+ actualEnv = factory ().createList ();
239
+ } else {
240
+ actualEnv = castEnv .executeWith (env );
241
+ }
242
+
243
+ return forkExec (castArgs .executeWith (args ), castExecList .executeWith (executable_list ), castCloseFds .executeWith (close_fds ),
244
+ castFdsToKeep .executeWith (fdsToKeep ), actualCwd , actualEnv ,
245
+ castP2cread .execute (p2cread ), castP2cwrite .execute (p2cwrite ), castC2pread .execute (c2pread ), castC2pwrite .execute (c2pwrite ),
246
+ castErrread .execute (errread ), castErrwrite .execute (errwrite ), castErrpipeRead .execute (errpipe_read ), castErrpipeWrite .execute (errpipe_write ),
247
+ castRestoreSignals .executeWith (restore_signals ), castSetsid .executeWith (call_setsid ), preexec_fn );
248
+ }
207
249
}
208
250
}
0 commit comments