@@ -200,7 +200,7 @@ protected void removeFile(int fd) {
200
200
filePaths .set (fd , null );
201
201
}
202
202
203
- private static int nextFreeFd () {
203
+ protected static int nextFreeFd () {
204
204
for (int i = 0 ; i < filePaths .size (); i ++) {
205
205
String openPath = filePaths .get (i );
206
206
if (openPath == null ) {
@@ -1024,15 +1024,6 @@ private int getLength(PTuple times) {
1024
1024
}
1025
1025
}
1026
1026
1027
- @ Builtin (name = "waitpid" , fixedNumOfPositionalArgs = 2 )
1028
- @ GenerateNodeFactory
1029
- abstract static class WaitpidNode extends PythonBinaryBuiltinNode {
1030
- @ SuppressWarnings ("unused" )
1031
- @ Specialization
1032
- PTuple waitpid (int pid , int options ) {
1033
- throw raise (NotImplementedError , "waitpid" );
1034
- }
1035
- }
1036
1027
1037
1028
// FIXME: this is not nearly ready, just good enough for now
1038
1029
@ Builtin (name = "system" , fixedNumOfPositionalArgs = 1 )
@@ -1200,4 +1191,264 @@ PBytes urandom(int size) {
1200
1191
return factory ().createBytes (range );
1201
1192
}
1202
1193
}
1194
+
1195
+
1196
+
1197
+ @ Builtin (name ="WIFSIGNALED" , fixedNumOfPositionalArgs = 1 )
1198
+ @ GenerateNodeFactory
1199
+ abstract static class WifsignaledNode extends PythonBuiltinNode {
1200
+
1201
+ /**
1202
+ * Note: Implementation taken from glibc
1203
+ * @param status
1204
+ * @return
1205
+ */
1206
+ @ Specialization
1207
+ @ TruffleBoundary
1208
+ boolean wifsignaled (int status ){
1209
+ return ((char ) (((status )&0x7f )+1 )>>1 ) >1 ;
1210
+ }
1211
+ }
1212
+
1213
+ @ Builtin (name ="WTERMSIG" , fixedNumOfPositionalArgs = 1 )
1214
+ @ GenerateNodeFactory
1215
+ abstract static class WtermsigNode extends PythonBuiltinNode {
1216
+
1217
+ /**
1218
+ * Note: Implementation taken from glibc
1219
+ * @param status
1220
+ * @return
1221
+ */
1222
+ @ Specialization
1223
+ @ TruffleBoundary
1224
+ boolean wtermsig (int status ){
1225
+ return (status & 0x7f ) != 0 ;
1226
+ }
1227
+ }
1228
+
1229
+ @ Builtin (name ="WIFEXITED" , fixedNumOfPositionalArgs = 1 )
1230
+ @ GenerateNodeFactory
1231
+ abstract static class WifexitedNode extends PythonBuiltinNode {
1232
+ /**
1233
+ * Note: Implementation taken from glibc
1234
+ * @param status
1235
+ * @return
1236
+ */
1237
+ @ Specialization
1238
+ @ TruffleBoundary
1239
+ boolean wifexited (int status ){
1240
+ return ((status ) & 0x7f ) == 0 ;
1241
+ }
1242
+ }
1243
+
1244
+
1245
+ @ Builtin (name ="WEXITSTATUS" , fixedNumOfPositionalArgs = 1 )
1246
+ @ GenerateNodeFactory
1247
+ abstract static class WexitstatusNode extends PythonBuiltinNode {
1248
+
1249
+ /**
1250
+ * Note: Implementation taken from glibc
1251
+ * @param status
1252
+ * @return
1253
+ */
1254
+ @ Specialization
1255
+ @ TruffleBoundary
1256
+ boolean wexitstatus (int status ){
1257
+ return ((status & 0xFF00 ) >> 8 ) != 0 ;
1258
+ }
1259
+ }
1260
+
1261
+
1262
+
1263
+ @ Builtin (name ="WIFSTOPPED" , fixedNumOfPositionalArgs = 1 )
1264
+ @ GenerateNodeFactory
1265
+ abstract static class WifstoppedNode extends PythonBuiltinNode {
1266
+ /**
1267
+ * Note: Implementation taken from glibc
1268
+ * @param status
1269
+ * @return
1270
+ */
1271
+ @ Specialization
1272
+ @ TruffleBoundary
1273
+ boolean wifstopped (int status ){
1274
+ return (status & 0xff )== 0x7f ;
1275
+ }
1276
+ }
1277
+
1278
+ @ Builtin (name ="WSTOPSIG" , fixedNumOfPositionalArgs = 1 )
1279
+ @ GenerateNodeFactory
1280
+ abstract static class WstopsigNode extends PythonBuiltinNode {
1281
+ /**
1282
+ * Note: Implementation taken from glibc
1283
+ * @param status
1284
+ * @return
1285
+ */
1286
+ @ Specialization
1287
+ @ TruffleBoundary
1288
+ boolean wstopsig (int status ){
1289
+ return ((status & 0xFF00 ) >> 8 ) != 0 ;
1290
+ }
1291
+ }
1292
+
1293
+ @ Builtin (name ="waitpid" , fixedNumOfPositionalArgs = 2 )
1294
+ @ GenerateNodeFactory
1295
+ abstract static class WaitpidNode extends PythonBuiltinNode {
1296
+ @ Specialization
1297
+ @ TruffleBoundary
1298
+ PTuple waitpid (long pid , int options ){
1299
+
1300
+ //TODO check what is really needed
1301
+ if (pid < -1 ){
1302
+ //wait for any chlid process whose process group id is equal to the value of pid
1303
+ throw raise (PythonErrorType .NotImplementedError , "Not implemented for pid <= 1" );
1304
+ }else if (pid == -1 ){
1305
+ //wait for any child process
1306
+ throw raise (PythonErrorType .NotImplementedError , "Not implemented for pid == -1" );
1307
+ }else if (pid == 0 ){
1308
+ //wait for any child process whose process group id is equal to the value of the calling process
1309
+ throw raise (PythonErrorType .NotImplementedError , "Not implemented for pid == 0" );
1310
+ }else {
1311
+ //pid > 0 wait for the child process with this pid
1312
+
1313
+ //TODO consider possible options: WNOHANG, WUNTRACED and WCONTINUED
1314
+ // seems like only WNOHANG is needed?
1315
+
1316
+ Process p = PosixSubprocessModuleBuiltins .getProcessByPid (pid );
1317
+ int status = -1 ;
1318
+ try {
1319
+ status = p .waitFor ();
1320
+
1321
+ //TODO: Make sure that here is the right place
1322
+ PosixSubprocessModuleBuiltins .removeProcessByPid (pid );
1323
+
1324
+ } catch (InterruptedException e ) {
1325
+ //TODO: Error handling
1326
+ e .printStackTrace ();
1327
+ throw raise (PythonErrorType .NotImplementedError , "Error handling for waitFor not implemented" );
1328
+ }
1329
+
1330
+
1331
+
1332
+ //TODO encode status return the right way
1333
+ return factory ().createTuple (new Object []{
1334
+ PosixSubprocessModuleBuiltins .getPidOfProcess (p ), status });
1335
+ }
1336
+ }
1337
+ }
1338
+
1339
+ /**
1340
+ * taken from glibc:
1341
+ *
1342
+ *
1343
+ * Bits in the third argument to 'waitpid'
1344
+ * WNOHANG: Dont block waiting
1345
+ */
1346
+ @ Builtin (name ="WNOHANG" , fixedNumOfPositionalArgs = 1 )
1347
+ @ GenerateNodeFactory
1348
+ abstract static class WnohangNode extends PythonBuiltinNode {
1349
+ @ Specialization
1350
+ @ TruffleBoundary
1351
+ int wnohang (){
1352
+ return 1 ;
1353
+ }
1354
+ }
1355
+
1356
+ @ SuppressWarnings ("MagicConstant" )
1357
+ @ Builtin (name ="pipe" , fixedNumOfPositionalArgs = 0 )
1358
+ @ GenerateNodeFactory
1359
+ abstract static class PipeNode extends PythonFileNode {
1360
+
1361
+ /*TODO find good (already existing?) implementation
1362
+ Looks like there is no good implementation in java
1363
+ for in-memory files that implement SeekableByteChannel?
1364
+ */
1365
+ private class SeekableByteBuffer implements SeekableByteChannel {
1366
+
1367
+ ByteBuffer buffer ;
1368
+
1369
+ private long position ;
1370
+ private boolean open ;
1371
+ public SeekableByteBuffer (ByteBuffer buffer ){
1372
+ this .buffer = buffer ;
1373
+ open = true ;
1374
+ }
1375
+
1376
+ @ Override
1377
+ public int read (ByteBuffer dst ) throws IOException {
1378
+ if (!isOpen ()){
1379
+ return -1 ;
1380
+ }
1381
+
1382
+ int i = 0 ;
1383
+ dst .reset ();
1384
+
1385
+ while (dst .remaining () > 0 && buffer .remaining () > 0 ){
1386
+ byte b = buffer .get ();
1387
+ dst .put (b );
1388
+ i ++;
1389
+ }
1390
+
1391
+ return i ;
1392
+ }
1393
+
1394
+ @ Override
1395
+ public int write (ByteBuffer src ) throws IOException {
1396
+
1397
+ int before = buffer .position ();
1398
+ buffer .put (src );
1399
+ return buffer .position ()-before ;
1400
+ }
1401
+
1402
+ @ Override
1403
+ public long position () throws IOException {
1404
+ return buffer .position ();
1405
+ }
1406
+
1407
+ @ Override
1408
+ public SeekableByteChannel position (long newPosition ) throws IOException {
1409
+ //seeking not allowed in pipes...
1410
+ throw new UnsupportedOperationException ();
1411
+ }
1412
+
1413
+ @ Override
1414
+ public long size () throws IOException {
1415
+ return buffer .position ();
1416
+ }
1417
+
1418
+ @ Override
1419
+ public SeekableByteChannel truncate (long size ) throws IOException {
1420
+ throw new UnsupportedOperationException ();
1421
+ }
1422
+
1423
+ @ Override
1424
+ public boolean isOpen () {
1425
+ return open ;
1426
+ }
1427
+
1428
+ @ Override
1429
+ public void close () throws IOException {
1430
+ open = false ;
1431
+ }
1432
+ }
1433
+
1434
+ @ Specialization
1435
+ @ TruffleBoundary
1436
+ Object pipe (){
1437
+
1438
+ ByteBuffer buffer = ByteBuffer .allocate (1024 );
1439
+ SeekableByteBuffer p = new SeekableByteBuffer (buffer );
1440
+
1441
+ int a = nextFreeFd ();
1442
+ files .set (a ,p );
1443
+ filePaths .set (a ,"pipe" );
1444
+
1445
+ int b = nextFreeFd ();
1446
+ files .set (b ,p );
1447
+ filePaths .set (b ,"pipe" );
1448
+
1449
+ return factory ().createTuple (new Object []{a ,b });
1450
+ }
1451
+
1452
+ }
1453
+
1203
1454
}
0 commit comments