@@ -123,16 +123,25 @@ pub(crate) fn open(path: &CStr, oflags: OFlags, mode: Mode) -> io::Result<OwnedF
123
123
if oflags. contains ( OFlags :: TMPFILE ) && crate :: backend:: if_glibc_is_less_than_2_25 ( ) {
124
124
return open_via_syscall ( path, oflags, mode) ;
125
125
}
126
- unsafe {
127
- // Pass `mode` as a `c_ulong` even if `mode_t` is narrower, since
128
- // `c::open` is declared as a variadic function and narrower
129
- // arguments are promoted.
130
- ret_owned_fd ( c:: open (
131
- c_str ( path) ,
132
- bitflags_bits ! ( oflags) ,
133
- mode. bits ( ) as c:: c_ulong ,
134
- ) )
135
- }
126
+
127
+ // On these platforms, `mode_t` is `u16` and can't be passed directly to
128
+ // a variadic function.
129
+ #[ cfg( any(
130
+ apple,
131
+ freebsdlike,
132
+ all( target_os = "android" , target_pointer_width = "32" )
133
+ ) ) ]
134
+ let mode: c:: c_uint = mode. bits ( ) . into ( ) ;
135
+
136
+ // Otherwise, cast to `mode_t` as that's what `open` is documented to take.
137
+ #[ cfg( not( any(
138
+ apple,
139
+ freebsdlike,
140
+ all( target_os = "android" , target_pointer_width = "32" )
141
+ ) ) ) ]
142
+ let mode: c:: mode_t = mode. bits ( ) as _ ;
143
+
144
+ unsafe { ret_owned_fd ( c:: open ( c_str ( path) , bitflags_bits ! ( oflags) , mode) ) }
136
145
}
137
146
138
147
/// Use a direct syscall (via libc) for `openat`.
@@ -177,15 +186,30 @@ pub(crate) fn openat(
177
186
if oflags. contains ( OFlags :: TMPFILE ) && crate :: backend:: if_glibc_is_less_than_2_25 ( ) {
178
187
return openat_via_syscall ( dirfd, path, oflags, mode) ;
179
188
}
189
+
190
+ // On these platforms, `mode_t` is `u16` and can't be passed directly to
191
+ // a variadic function.
192
+ #[ cfg( any(
193
+ apple,
194
+ freebsdlike,
195
+ all( target_os = "android" , target_pointer_width = "32" )
196
+ ) ) ]
197
+ let mode: c:: c_uint = mode. bits ( ) . into ( ) ;
198
+
199
+ // Otherwise, cast to `mode_t` as that's what `open` is documented to take.
200
+ #[ cfg( not( any(
201
+ apple,
202
+ freebsdlike,
203
+ all( target_os = "android" , target_pointer_width = "32" )
204
+ ) ) ) ]
205
+ let mode: c:: mode_t = mode. bits ( ) as _ ;
206
+
180
207
unsafe {
181
- // Pass `mode` as a `c_ulong` even if `mode_t` is narrower, since
182
- // `c::openat` is declared as a variadic function and narrower
183
- // arguments are promoted.
184
208
ret_owned_fd ( c:: openat (
185
209
borrowed_fd ( dirfd) ,
186
210
c_str ( path) ,
187
211
bitflags_bits ! ( oflags) ,
188
- mode. bits ( ) as c :: c_ulong ,
212
+ mode,
189
213
) )
190
214
}
191
215
}
@@ -924,9 +948,6 @@ pub(crate) fn chmodat(
924
948
return Err ( io:: Errno :: INVAL ) ;
925
949
}
926
950
unsafe {
927
- // Pass `mode` as a `c_ulong` even if `mode_t` is narrower, since
928
- // `c::syscall` is declared as a variadic function and narrower
929
- // arguments are promoted.
930
951
ret ( fchmodat (
931
952
borrowed_fd ( dirfd) ,
932
953
c_str ( path) ,
0 commit comments