Skip to content

Commit b89997f

Browse files
Auto merge of #146269 - weihanglo:solaris-flock, r=<try>
feat(std): emulate flock for solaris via fcntl try-job: `*-solaris`
2 parents 6d5caf3 + 95e73a2 commit b89997f

File tree

2 files changed

+61
-0
lines changed

2 files changed

+61
-0
lines changed

library/std/src/fs/tests.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ fn file_test_io_seek_and_write() {
226226
target_os = "freebsd",
227227
target_os = "linux",
228228
target_os = "netbsd",
229+
target_os = "solaris",
229230
target_vendor = "apple",
230231
))]
231232
fn file_lock_multiple_shared() {
@@ -249,6 +250,7 @@ fn file_lock_multiple_shared() {
249250
target_os = "freebsd",
250251
target_os = "linux",
251252
target_os = "netbsd",
253+
target_os = "solaris",
252254
target_vendor = "apple",
253255
))]
254256
fn file_lock_blocking() {
@@ -273,6 +275,7 @@ fn file_lock_blocking() {
273275
target_os = "freebsd",
274276
target_os = "linux",
275277
target_os = "netbsd",
278+
target_os = "solaris",
276279
target_vendor = "apple",
277280
))]
278281
fn file_lock_drop() {
@@ -294,6 +297,7 @@ fn file_lock_drop() {
294297
target_os = "freebsd",
295298
target_os = "linux",
296299
target_os = "netbsd",
300+
target_os = "solaris",
297301
target_vendor = "apple",
298302
))]
299303
fn file_lock_dup() {

library/std/src/sys/fs/unix.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,13 +1293,19 @@ impl File {
12931293
return Ok(());
12941294
}
12951295

1296+
#[cfg(any(target_os = "solaris",))]
1297+
pub fn lock(&self) -> io::Result<()> {
1298+
self.emulate_flock(libc::F_WRLCK, libc::F_SETLK);
1299+
}
1300+
12961301
#[cfg(not(any(
12971302
target_os = "freebsd",
12981303
target_os = "fuchsia",
12991304
target_os = "linux",
13001305
target_os = "netbsd",
13011306
target_os = "openbsd",
13021307
target_os = "cygwin",
1308+
target_os = "solaris",
13031309
target_vendor = "apple",
13041310
)))]
13051311
pub fn lock(&self) -> io::Result<()> {
@@ -1320,13 +1326,19 @@ impl File {
13201326
return Ok(());
13211327
}
13221328

1329+
#[cfg(target_os = "solaris")]
1330+
pub fn lock_shared(&self) -> io::Result<()> {
1331+
self.emulate_flock(libc::F_RDLCK, libc::F_SETLK);
1332+
}
1333+
13231334
#[cfg(not(any(
13241335
target_os = "freebsd",
13251336
target_os = "fuchsia",
13261337
target_os = "linux",
13271338
target_os = "netbsd",
13281339
target_os = "openbsd",
13291340
target_os = "cygwin",
1341+
target_os = "solaris",
13301342
target_vendor = "apple",
13311343
)))]
13321344
pub fn lock_shared(&self) -> io::Result<()> {
@@ -1355,13 +1367,28 @@ impl File {
13551367
}
13561368
}
13571369

1370+
#[cfg(target_os = "solaris")]
1371+
pub fn try_lock(&self) -> io::Result<()> {
1372+
let result = self.emulate_flock(libc::F_WRLCK, libc::F_SETLKW);
1373+
if let Err(err) = result {
1374+
if err.kind() == io::ErrorKind::WouldBlock {
1375+
Err(TryLockError::WouldBlock)
1376+
} else {
1377+
Err(TryLockError::Error(err))
1378+
}
1379+
} else {
1380+
Ok(())
1381+
}
1382+
}
1383+
13581384
#[cfg(not(any(
13591385
target_os = "freebsd",
13601386
target_os = "fuchsia",
13611387
target_os = "linux",
13621388
target_os = "netbsd",
13631389
target_os = "openbsd",
13641390
target_os = "cygwin",
1391+
target_os = "solaris",
13651392
target_vendor = "apple",
13661393
)))]
13671394
pub fn try_lock(&self) -> Result<(), TryLockError> {
@@ -1393,13 +1420,28 @@ impl File {
13931420
}
13941421
}
13951422

1423+
#[cfg(target_os = "solaris")]
1424+
pub fn try_lock_shared(&self) -> io::Result<()> {
1425+
let result = self.emulate_flock(libc::F_RDLCK, libc::F_SETLKW);
1426+
if let Err(err) = result {
1427+
if err.kind() == io::ErrorKind::WouldBlock {
1428+
Err(TryLockError::WouldBlock)
1429+
} else {
1430+
Err(TryLockError::Error(err))
1431+
}
1432+
} else {
1433+
Ok(())
1434+
}
1435+
}
1436+
13961437
#[cfg(not(any(
13971438
target_os = "freebsd",
13981439
target_os = "fuchsia",
13991440
target_os = "linux",
14001441
target_os = "netbsd",
14011442
target_os = "openbsd",
14021443
target_os = "cygwin",
1444+
target_os = "solaris",
14031445
target_vendor = "apple",
14041446
)))]
14051447
pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
@@ -1423,19 +1465,34 @@ impl File {
14231465
return Ok(());
14241466
}
14251467

1468+
#[cfg(target_os = "solaris")]
1469+
pub fn unlock(&self) -> io::Result<()> {
1470+
self.emulate_flock(libc::F_UNLCK, libc::F_SETLK)
1471+
}
1472+
14261473
#[cfg(not(any(
14271474
target_os = "freebsd",
14281475
target_os = "fuchsia",
14291476
target_os = "linux",
14301477
target_os = "netbsd",
14311478
target_os = "openbsd",
14321479
target_os = "cygwin",
1480+
target_os = "solaris",
14331481
target_vendor = "apple",
14341482
)))]
14351483
pub fn unlock(&self) -> io::Result<()> {
14361484
Err(io::const_error!(io::ErrorKind::Unsupported, "unlock() not supported"))
14371485
}
14381486

1487+
/// Emulates flock by `fcntl`.
1488+
#[cfg(any(target_os = "solaris",))]
1489+
fn emulate_flock(&self, lock_type: libc::c_int, cmd: libc::c_int) -> Result<()> {
1490+
let mut flock: libc::flock = unsafe { mem::zeroed() };
1491+
flock.l_whence = libc::SEEK_SET;
1492+
flock.l_type = lock_type;
1493+
cvt(unsafe { libc::fcntl(file.as_raw_fd(), cmd, &flock) })
1494+
}
1495+
14391496
pub fn truncate(&self, size: u64) -> io::Result<()> {
14401497
let size: off64_t =
14411498
size.try_into().map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?;

0 commit comments

Comments
 (0)