@@ -2439,12 +2439,12 @@ public void setBlocking(boolean blocking) {
2439
2439
2440
2440
@ JRubyMethod (name = "fcntl" )
2441
2441
public IRubyObject fcntl (ThreadContext context , IRubyObject cmd ) {
2442
- return ctl (context . runtime , cmd , null );
2442
+ return ctl (context , cmd , null );
2443
2443
}
2444
2444
2445
2445
@ JRubyMethod (name = "fcntl" )
2446
2446
public IRubyObject fcntl (ThreadContext context , IRubyObject cmd , IRubyObject arg ) {
2447
- return ctl (context . runtime , cmd , arg );
2447
+ return ctl (context , cmd , arg );
2448
2448
}
2449
2449
2450
2450
@ JRubyMethod (name = "ioctl" , required = 1 , optional = 1 )
@@ -2458,10 +2458,11 @@ public IRubyObject ioctl(ThreadContext context, IRubyObject[] args) {
2458
2458
arg = context .runtime .getNil ();
2459
2459
}
2460
2460
2461
- return ctl (context . runtime , cmd , arg );
2461
+ return ctl (context , cmd , arg );
2462
2462
}
2463
2463
2464
- private IRubyObject ctl (Ruby runtime , IRubyObject cmd , IRubyObject arg ) {
2464
+ private IRubyObject ctl (ThreadContext context , IRubyObject cmd , IRubyObject arg ) {
2465
+ Ruby runtime = context .runtime ;
2465
2466
long realCmd = cmd .convertToInteger ().getLongValue ();
2466
2467
long nArg = 0 ;
2467
2468
@@ -2494,25 +2495,31 @@ private IRubyObject ctl(Ruby runtime, IRubyObject cmd, IRubyObject arg) {
2494
2495
// for mode changes which should persist across fork() boundaries. Since JVM has no fork
2495
2496
// this is not a problem for us.
2496
2497
if (realCmd == FcntlLibrary .FD_CLOEXEC ) {
2497
- close_on_exec_set (runtime . getCurrentContext () , runtime .getTrue ());
2498
+ close_on_exec_set (context , runtime .getTrue ());
2498
2499
} else if (realCmd == Fcntl .F_SETFD .intValue ()) {
2499
2500
if (arg != null && (nArg & FcntlLibrary .FD_CLOEXEC ) == FcntlLibrary .FD_CLOEXEC ) {
2500
- close_on_exec_set (runtime . getCurrentContext () , arg );
2501
+ close_on_exec_set (context , arg );
2501
2502
} else {
2502
2503
throw runtime .newNotImplementedError ("F_SETFD only supports FD_CLOEXEC" );
2503
2504
}
2504
2505
} else if (realCmd == Fcntl .F_GETFD .intValue ()) {
2505
- return runtime .newFixnum (close_on_exec_p (runtime . getCurrentContext () ).isTrue () ? FD_CLOEXEC : 0 );
2506
+ return runtime .newFixnum (close_on_exec_p (context ).isTrue () ? FD_CLOEXEC : 0 );
2506
2507
} else if (realCmd == Fcntl .F_SETFL .intValue ()) {
2507
2508
if ((nArg & OpenFlags .O_NONBLOCK .intValue ()) != 0 ) {
2508
- boolean block = (nArg & ModeFlags .NONBLOCK ) != ModeFlags .NONBLOCK ;
2509
+ fptr .setBlocking (runtime , true );
2510
+ } else {
2511
+ fptr .setBlocking (runtime , false );
2512
+ }
2509
2513
2510
- fptr .setBlocking (runtime , block );
2514
+ if ((nArg & OpenFlags .O_CLOEXEC .intValue ()) != 0 ) {
2515
+ close_on_exec_set (context , context .tru );
2511
2516
} else {
2512
- throw runtime . newNotImplementedError ( "F_SETFL only supports O_NONBLOCK" );
2517
+ close_on_exec_set ( context , context . fals );
2513
2518
}
2514
2519
} else if (realCmd == Fcntl .F_GETFL .intValue ()) {
2515
- return fptr .isBlocking () ? RubyFixnum .zero (runtime ) : RubyFixnum .newFixnum (runtime , ModeFlags .NONBLOCK );
2520
+ return runtime .newFixnum (
2521
+ (fptr .isBlocking () ? 0 : OpenFlags .O_NONBLOCK .intValue ()) |
2522
+ (close_on_exec_p (context ).isTrue () ? FD_CLOEXEC : 0 ));
2516
2523
} else {
2517
2524
throw runtime .newNotImplementedError ("JRuby only supports F_SETFL and F_GETFL with NONBLOCK for fcntl/ioctl" );
2518
2525
}
0 commit comments