@@ -19,13 +19,13 @@ use nix::pty::openpty;
1919use nix:: unistd:: { self , Gid , Pid , Uid , Whence } ;
2020use num_traits:: cast:: ToPrimitive ;
2121
22- use crate :: function:: { IntoPyNativeFunc , PyFuncArgs } ;
22+ use crate :: function:: { IntoPyNativeFunc , OptionalArg , PyFuncArgs } ;
2323use crate :: obj:: objbytes:: PyBytesRef ;
2424use crate :: obj:: objdict:: PyDictRef ;
25- use crate :: obj:: objint:: { self , PyInt , PyIntRef } ;
25+ use crate :: obj:: objint:: { self , PyIntRef } ;
2626use crate :: obj:: objiter;
2727use crate :: obj:: objset:: PySet ;
28- use crate :: obj:: objstr:: { self , PyString , PyStringRef } ;
28+ use crate :: obj:: objstr:: { self , PyStringRef } ;
2929use crate :: obj:: objtype:: { self , PyClassRef } ;
3030use crate :: pyobject:: {
3131 Either , ItemProtocol , PyClassImpl , PyObjectRef , PyRef , PyResult , PyValue , TryIntoRef ,
@@ -95,59 +95,58 @@ pub fn os_close(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
9595 Ok ( vm. get_none ( ) )
9696}
9797
98- #[ cfg( any( unix, windows) ) ]
99- pub fn os_open ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
100- arg_check ! (
101- vm,
102- args,
103- required = [
104- ( name, Some ( vm. ctx. str_type( ) ) ) ,
105- ( flags, Some ( vm. ctx. int_type( ) ) )
106- ] ,
107- optional = [
108- ( _mode, Some ( vm. ctx. int_type( ) ) ) ,
109- ( dir_fd, Some ( vm. ctx. int_type( ) ) )
110- ]
111- ) ;
98+ #[ cfg( unix) ]
99+ type OpenFlags = i32 ;
100+ #[ cfg( windows) ]
101+ type OpenFlags = u32 ;
112102
113- let name = name. clone ( ) . downcast :: < PyString > ( ) . unwrap ( ) ;
114- let dir_fd = if let Some ( obj) = dir_fd {
115- DirFd {
116- dir_fd : Some ( obj. clone ( ) . downcast :: < PyInt > ( ) . unwrap ( ) ) ,
117- }
118- } else {
119- DirFd :: default ( )
103+ #[ cfg( any( unix, windows) ) ]
104+ pub fn os_open (
105+ name : PyStringRef ,
106+ flags : OpenFlags ,
107+ _mode : OptionalArg < PyIntRef > ,
108+ dir_fd : OptionalArg < PyIntRef > ,
109+ vm : & VirtualMachine ,
110+ ) -> PyResult < i64 > {
111+ let dir_fd = DirFd {
112+ dir_fd : dir_fd. into_option ( ) ,
120113 } ;
121- let fname = & make_path ( vm, name, & dir_fd) . value ;
114+ let fname = make_path ( vm, name, & dir_fd) ;
122115
123- let options = _set_file_model ( & flags) ;
124- let handle = options
125- . open ( & fname)
126- . map_err ( |err| convert_io_error ( vm, err) ) ?;
116+ let mut options = OpenOptions :: new ( ) ;
127117
128- Ok ( vm. ctx . new_int ( raw_file_number ( handle) ) )
129- }
118+ macro_rules! bit_contains {
119+ ( $c: expr) => {
120+ flags & $c as OpenFlags == $c as OpenFlags
121+ } ;
122+ }
130123
131- #[ cfg( unix) ]
132- fn _set_file_model ( flags : & PyObjectRef ) -> OpenOptions {
133- let flags = objint:: get_value ( flags) . to_i32 ( ) . unwrap ( ) ;
134- let mut options = OpenOptions :: new ( ) ;
135- options. read ( flags == libc:: O_RDONLY ) ;
136- options. write ( flags & libc:: O_WRONLY != 0 ) ;
137- options. append ( flags & libc:: O_APPEND != 0 ) ;
138- options. custom_flags ( flags) ;
139- options
140- }
124+ if bit_contains ! ( libc:: O_RDWR ) {
125+ options. read ( true ) . write ( true ) ;
126+ } else if bit_contains ! ( libc:: O_WRONLY ) {
127+ options. write ( true ) ;
128+ } else if bit_contains ! ( libc:: O_RDONLY ) {
129+ options. read ( true ) ;
130+ }
131+
132+ if bit_contains ! ( libc:: O_APPEND ) {
133+ options. append ( true ) ;
134+ }
135+
136+ if bit_contains ! ( libc:: O_CREAT ) {
137+ if bit_contains ! ( libc:: O_EXCL ) {
138+ options. create_new ( true ) ;
139+ } else {
140+ options. create ( true ) ;
141+ }
142+ }
141143
142- #[ cfg( windows) ]
143- fn _set_file_model ( flags : & PyObjectRef ) -> OpenOptions {
144- let flags = objint:: get_value ( flags) . to_u32 ( ) . unwrap ( ) ;
145- let mut options = OpenOptions :: new ( ) ;
146- options. read ( ( flags as i32 ) == libc:: O_RDONLY ) ;
147- options. write ( ( flags as i32 ) & libc:: O_WRONLY != 0 ) ;
148- options. append ( ( flags as i32 ) & libc:: O_APPEND != 0 ) ;
149144 options. custom_flags ( flags) ;
150- options
145+ let handle = options
146+ . open ( fname. as_str ( ) )
147+ . map_err ( |err| convert_io_error ( vm, err) ) ?;
148+
149+ Ok ( raw_file_number ( handle) )
151150}
152151
153152#[ cfg( all( not( unix) , not( windows) ) ) ]
0 commit comments