@@ -41,34 +41,35 @@ a file object.
4141 public static object fcntl ( int fd , int cmd , [ NotNone ] Bytes arg ) {
4242 CheckFileDescriptor ( fd ) ;
4343
44- const int maxArgSize = 1024 ;
45- if ( arg . Count > maxArgSize ) {
44+ const int maxArgSize = 1024 ; // 1 KiB
45+ int argSize = arg . Count ;
46+ if ( argSize > maxArgSize ) {
4647 throw PythonOps . ValueError ( "fcntl bytes arg too long" ) ;
4748 }
4849
4950 if ( ! NativeConvert . TryToFcntlCommand ( cmd , out FcntlCommand fcntlCommand ) ) {
5051 throw PythonOps . OSError ( PythonErrno . EINVAL , "unsupported fcntl command" ) ;
5152 }
5253
53- int argSize = arg . Count ;
54- IntPtr ptr = Marshal . AllocHGlobal ( argSize ) ;
55- try {
56- Marshal . Copy ( arg . UnsafeByteArray , 0 , ptr , argSize ) ;
57- int result ;
58- Errno errno ;
59- do {
60- result = Syscall . fcntl ( fd , fcntlCommand , ptr ) ;
61- } while ( UnixMarshal . ShouldRetrySyscall ( result , out errno ) ) ;
62-
63- if ( result == - 1 ) {
64- return LightExceptions . Throw ( PythonNT . GetOsError ( NativeConvert . FromErrno ( errno ) ) ) ;
54+ var buf = new byte [ maxArgSize ] ;
55+ Array . Copy ( arg . UnsafeByteArray , buf , argSize ) ;
56+
57+ int result ;
58+ Errno errno ;
59+ unsafe {
60+ fixed ( byte * ptr = buf ) {
61+ do {
62+ result = Syscall . fcntl ( fd , fcntlCommand , ( IntPtr ) ptr ) ;
63+ } while ( UnixMarshal . ShouldRetrySyscall ( result , out errno ) ) ;
6564 }
66- byte [ ] response = new byte [ argSize ] ;
67- Marshal . Copy ( ptr , response , 0 , argSize ) ;
68- return Bytes . Make ( response ) ;
69- } finally {
70- Marshal . FreeHGlobal ( ptr ) ;
7165 }
66+
67+ if ( result == - 1 ) {
68+ return LightExceptions . Throw ( PythonNT . GetOsError ( NativeConvert . FromErrno ( errno ) ) ) ;
69+ }
70+ byte [ ] response = new byte [ argSize ] ;
71+ Array . Copy ( buf , response , argSize ) ;
72+ return Bytes . Make ( response ) ;
7273 }
7374
7475
0 commit comments