Auto merge of #89518 - a1phyr:unix_file_vectored_at, r=workingjubilee · rust-lang/rust@0fbfc3e (original) (raw)

`@@ -98,7 +98,7 @@ impl FileDesc {

`

98

98

`let ret = cvt(unsafe {

`

99

99

` libc::readv(

`

100

100

`self.as_raw_fd(),

`

101

``

`-

bufs.as_ptr() as *const libc::iovec,

`

``

101

`+

bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,

`

102

102

` cmp::min(bufs.len(), max_iov()) as libc::c_int,

`

103

103

`)

`

104

104

`})?;

`

`@@ -107,7 +107,7 @@ impl FileDesc {

`

107

107

``

108

108

`#[cfg(any(target_os = "espidf", target_os = "horizon"))]

`

109

109

`pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result {

`

110

``

`-

return crate::io::default_read_vectored(|b| self.read(b), bufs);

`

``

110

`+

io::default_read_vectored(|b| self.read(b), bufs)

`

111

111

`}

`

112

112

``

113

113

`#[inline]

`

`@@ -153,6 +153,95 @@ impl FileDesc {

`

153

153

`Ok(())

`

154

154

`}

`

155

155

``

``

156

`+

#[cfg(any(

`

``

157

`+

target_os = "emscripten",

`

``

158

`+

target_os = "freebsd",

`

``

159

`+

target_os = "fuchsia",

`

``

160

`+

target_os = "illumos",

`

``

161

`+

target_os = "linux",

`

``

162

`+

target_os = "netbsd",

`

``

163

`+

))]

`

``

164

`+

pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result {

`

``

165

`+

let ret = cvt(unsafe {

`

``

166

`+

libc::preadv(

`

``

167

`+

self.as_raw_fd(),

`

``

168

`+

bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,

`

``

169

`+

cmp::min(bufs.len(), max_iov()) as libc::c_int,

`

``

170

`+

offset as _,

`

``

171

`+

)

`

``

172

`+

})?;

`

``

173

`+

Ok(ret as usize)

`

``

174

`+

}

`

``

175

+

``

176

`+

#[cfg(not(any(

`

``

177

`+

target_os = "android",

`

``

178

`+

target_os = "emscripten",

`

``

179

`+

target_os = "freebsd",

`

``

180

`+

target_os = "fuchsia",

`

``

181

`+

target_os = "illumos",

`

``

182

`+

target_os = "ios",

`

``

183

`+

target_os = "linux",

`

``

184

`+

target_os = "macos",

`

``

185

`+

target_os = "netbsd",

`

``

186

`+

)))]

`

``

187

`+

pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result {

`

``

188

`+

io::default_read_vectored(|b| self.read_at(b, offset), bufs)

`

``

189

`+

}

`

``

190

+

``

191

`` +

// We support some old Android versions that do not have preadv in libc,

``

``

192

`+

// so we use weak linkage and fallback to a direct syscall if not available.

`

``

193

`+

//

`

``

194

`+

// On 32-bit targets, we don't want to deal with weird ABI issues around

`

``

195

`+

// passing 64-bits parameters to syscalls, so we fallback to the default

`

``

196

`` +

// implementation if preadv is not available.

``

``

197

`+

#[cfg(all(target_os = "android", target_pointer_width = "64"))]

`

``

198

`+

pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result {

`

``

199

`+

super::weak::syscall! {

`

``

200

`+

fn preadv(

`

``

201

`+

fd: libc::c_int,

`

``

202

`+

iovec: *const libc::iovec,

`

``

203

`+

n_iovec: libc::c_int,

`

``

204

`+

offset: off64_t

`

``

205

`+

) -> isize

`

``

206

`+

}

`

``

207

+

``

208

`+

let ret = cvt(unsafe {

`

``

209

`+

preadv(

`

``

210

`+

self.as_raw_fd(),

`

``

211

`+

bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,

`

``

212

`+

cmp::min(bufs.len(), max_iov()) as libc::c_int,

`

``

213

`+

offset as _,

`

``

214

`+

)

`

``

215

`+

})?;

`

``

216

`+

Ok(ret as usize)

`

``

217

`+

}

`

``

218

+

``

219

`` +

// We support old MacOS and iOS versions that do not have preadv. There is

``

``

220

`` +

// no syscall possible in these platform.

``

``

221

`+

#[cfg(any(

`

``

222

`+

all(target_os = "android", target_pointer_width = "32"),

`

``

223

`+

target_os = "ios",

`

``

224

`+

target_os = "macos",

`

``

225

`+

))]

`

``

226

`+

pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result {

`

``

227

`+

super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);

`

``

228

+

``

229

`+

match preadv64.get() {

`

``

230

`+

Some(preadv) => {

`

``

231

`+

let ret = cvt(unsafe {

`

``

232

`+

preadv(

`

``

233

`+

self.as_raw_fd(),

`

``

234

`+

bufs.as_mut_ptr() as *mut libc::iovec as *const libc::iovec,

`

``

235

`+

cmp::min(bufs.len(), max_iov()) as libc::c_int,

`

``

236

`+

offset as _,

`

``

237

`+

)

`

``

238

`+

})?;

`

``

239

`+

Ok(ret as usize)

`

``

240

`+

}

`

``

241

`+

None => io::default_read_vectored(|b| self.read_at(b, offset), bufs),

`

``

242

`+

}

`

``

243

`+

}

`

``

244

+

156

245

`pub fn write(&self, buf: &[u8]) -> io::Result {

`

157

246

`let ret = cvt(unsafe {

`

158

247

` libc::write(

`

`@@ -178,7 +267,7 @@ impl FileDesc {

`

178

267

``

179

268

`#[cfg(any(target_os = "espidf", target_os = "horizon"))]

`

180

269

`pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result {

`

181

``

`-

return crate::io::default_write_vectored(|b| self.write(b), bufs);

`

``

270

`+

io::default_write_vectored(|b| self.write(b), bufs)

`

182

271

`}

`

183

272

``

184

273

`#[inline]

`

`@@ -203,6 +292,95 @@ impl FileDesc {

`

203

292

`}

`

204

293

`}

`

205

294

``

``

295

`+

#[cfg(any(

`

``

296

`+

target_os = "emscripten",

`

``

297

`+

target_os = "freebsd",

`

``

298

`+

target_os = "fuchsia",

`

``

299

`+

target_os = "illumos",

`

``

300

`+

target_os = "linux",

`

``

301

`+

target_os = "netbsd",

`

``

302

`+

))]

`

``

303

`+

pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result {

`

``

304

`+

let ret = cvt(unsafe {

`

``

305

`+

libc::pwritev(

`

``

306

`+

self.as_raw_fd(),

`

``

307

`+

bufs.as_ptr() as *const libc::iovec,

`

``

308

`+

cmp::min(bufs.len(), max_iov()) as libc::c_int,

`

``

309

`+

offset as _,

`

``

310

`+

)

`

``

311

`+

})?;

`

``

312

`+

Ok(ret as usize)

`

``

313

`+

}

`

``

314

+

``

315

`+

#[cfg(not(any(

`

``

316

`+

target_os = "android",

`

``

317

`+

target_os = "emscripten",

`

``

318

`+

target_os = "freebsd",

`

``

319

`+

target_os = "fuchsia",

`

``

320

`+

target_os = "illumos",

`

``

321

`+

target_os = "ios",

`

``

322

`+

target_os = "linux",

`

``

323

`+

target_os = "macos",

`

``

324

`+

target_os = "netbsd",

`

``

325

`+

)))]

`

``

326

`+

pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result {

`

``

327

`+

io::default_write_vectored(|b| self.write_at(b, offset), bufs)

`

``

328

`+

}

`

``

329

+

``

330

`` +

// We support some old Android versions that do not have pwritev in libc,

``

``

331

`+

// so we use weak linkage and fallback to a direct syscall if not available.

`

``

332

`+

//

`

``

333

`+

// On 32-bit targets, we don't want to deal with weird ABI issues around

`

``

334

`+

// passing 64-bits parameters to syscalls, so we fallback to the default

`

``

335

`` +

// implementation if pwritev is not available.

``

``

336

`+

#[cfg(all(target_os = "android", target_pointer_width = "64"))]

`

``

337

`+

pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result {

`

``

338

`+

super::weak::syscall! {

`

``

339

`+

fn pwritev(

`

``

340

`+

fd: libc::c_int,

`

``

341

`+

iovec: *const libc::iovec,

`

``

342

`+

n_iovec: libc::c_int,

`

``

343

`+

offset: off64_t

`

``

344

`+

) -> isize

`

``

345

`+

}

`

``

346

+

``

347

`+

let ret = cvt(unsafe {

`

``

348

`+

pwritev(

`

``

349

`+

self.as_raw_fd(),

`

``

350

`+

bufs.as_ptr() as *const libc::iovec,

`

``

351

`+

cmp::min(bufs.len(), max_iov()) as libc::c_int,

`

``

352

`+

offset as _,

`

``

353

`+

)

`

``

354

`+

})?;

`

``

355

`+

Ok(ret as usize)

`

``

356

`+

}

`

``

357

+

``

358

`` +

// We support old MacOS and iOS versions that do not have pwritev. There is

``

``

359

`` +

// no syscall possible in these platform.

``

``

360

`+

#[cfg(any(

`

``

361

`+

all(target_os = "android", target_pointer_width = "32"),

`

``

362

`+

target_os = "ios",

`

``

363

`+

target_os = "macos",

`

``

364

`+

))]

`

``

365

`+

pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result {

`

``

366

`+

super::weak::weak!(fn pwritev64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize);

`

``

367

+

``

368

`+

match pwritev64.get() {

`

``

369

`+

Some(pwritev) => {

`

``

370

`+

let ret = cvt(unsafe {

`

``

371

`+

pwritev(

`

``

372

`+

self.as_raw_fd(),

`

``

373

`+

bufs.as_ptr() as *const libc::iovec,

`

``

374

`+

cmp::min(bufs.len(), max_iov()) as libc::c_int,

`

``

375

`+

offset as _,

`

``

376

`+

)

`

``

377

`+

})?;

`

``

378

`+

Ok(ret as usize)

`

``

379

`+

}

`

``

380

`+

None => io::default_write_vectored(|b| self.write_at(b, offset), bufs),

`

``

381

`+

}

`

``

382

`+

}

`

``

383

+

206

384

`#[cfg(not(any(

`

207

385

` target_env = "newlib",

`

208

386

` target_os = "solaris",

`