Skip to content

Commit 01edb24

Browse files
committed
feat(std): emulate flock for solaris via fcntl
Upstream Solaris flock emulation to libstd from cargo. This is borrowed from https://github.com/rust-lang/cargo/blob/3b379fcc541b39321a7758552d37e5e0cc4277b9/src/cargo/util/flock.rs#L502-L536 which was implemented by an Oracle employee. The code has been in cargo since 2022-12. Python's `fcntl.flock` emulates like this as well: https://github.com/python/cpython/blob/c919d02edecfe9d75fe374756fb8aa1db8d95f55/Modules/fcntlmodule.c#L337-L400 We did the same thing in https://github.com/rust-lang/rust/blob/0d0f4eac8b98133e5da6d3604d86a8f3b5a67844/compiler/rustc_data_structures/src/flock/unix.rs#L13-L39
1 parent 0d0f4ea commit 01edb24

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-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: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,13 +1293,23 @@ impl File {
12931293
return Ok(());
12941294
}
12951295

1296+
#[cfg(target_os = "solaris")]
1297+
pub fn lock(&self) -> io::Result<()> {
1298+
let mut flock: libc::flock = unsafe { mem::zeroed() };
1299+
flock.l_type = libc::F_WRLCK as libc::c_short;
1300+
flock.l_whence = libc::SEEK_SET as libc::c_short;
1301+
cvt(unsafe { libc::fcntl(self.as_raw_fd(), libc::F_SETLKW, &flock) })?;
1302+
Ok(())
1303+
}
1304+
12961305
#[cfg(not(any(
12971306
target_os = "freebsd",
12981307
target_os = "fuchsia",
12991308
target_os = "linux",
13001309
target_os = "netbsd",
13011310
target_os = "openbsd",
13021311
target_os = "cygwin",
1312+
target_os = "solaris",
13031313
target_vendor = "apple",
13041314
)))]
13051315
pub fn lock(&self) -> io::Result<()> {
@@ -1320,13 +1330,23 @@ impl File {
13201330
return Ok(());
13211331
}
13221332

1333+
#[cfg(target_os = "solaris")]
1334+
pub fn lock_shared(&self) -> io::Result<()> {
1335+
let mut flock: libc::flock = unsafe { mem::zeroed() };
1336+
flock.l_type = libc::F_RDLCK as libc::c_short;
1337+
flock.l_whence = libc::SEEK_SET as libc::c_short;
1338+
cvt(unsafe { libc::fcntl(self.as_raw_fd(), libc::F_SETLKW, &flock) })?;
1339+
Ok(())
1340+
}
1341+
13231342
#[cfg(not(any(
13241343
target_os = "freebsd",
13251344
target_os = "fuchsia",
13261345
target_os = "linux",
13271346
target_os = "netbsd",
13281347
target_os = "openbsd",
13291348
target_os = "cygwin",
1349+
target_os = "solaris",
13301350
target_vendor = "apple",
13311351
)))]
13321352
pub fn lock_shared(&self) -> io::Result<()> {
@@ -1355,13 +1375,31 @@ impl File {
13551375
}
13561376
}
13571377

1378+
#[cfg(target_os = "solaris")]
1379+
pub fn try_lock(&self) -> Result<(), TryLockError> {
1380+
let mut flock: libc::flock = unsafe { mem::zeroed() };
1381+
flock.l_type = libc::F_WRLCK as libc::c_short;
1382+
flock.l_whence = libc::SEEK_SET as libc::c_short;
1383+
let result = cvt(unsafe { libc::fcntl(self.as_raw_fd(), libc::F_SETLK, &flock) });
1384+
if let Err(err) = result {
1385+
if err.kind() == io::ErrorKind::WouldBlock {
1386+
Err(TryLockError::WouldBlock)
1387+
} else {
1388+
Err(TryLockError::Error(err))
1389+
}
1390+
} else {
1391+
Ok(())
1392+
}
1393+
}
1394+
13581395
#[cfg(not(any(
13591396
target_os = "freebsd",
13601397
target_os = "fuchsia",
13611398
target_os = "linux",
13621399
target_os = "netbsd",
13631400
target_os = "openbsd",
13641401
target_os = "cygwin",
1402+
target_os = "solaris",
13651403
target_vendor = "apple",
13661404
)))]
13671405
pub fn try_lock(&self) -> Result<(), TryLockError> {
@@ -1393,13 +1431,31 @@ impl File {
13931431
}
13941432
}
13951433

1434+
#[cfg(target_os = "solaris")]
1435+
pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
1436+
let mut flock: libc::flock = unsafe { mem::zeroed() };
1437+
flock.l_type = libc::F_RDLCK as libc::c_short;
1438+
flock.l_whence = libc::SEEK_SET as libc::c_short;
1439+
let result = cvt(unsafe { libc::fcntl(self.as_raw_fd(), libc::F_SETLK, &flock) });
1440+
if let Err(err) = result {
1441+
if err.kind() == io::ErrorKind::WouldBlock {
1442+
Err(TryLockError::WouldBlock)
1443+
} else {
1444+
Err(TryLockError::Error(err))
1445+
}
1446+
} else {
1447+
Ok(())
1448+
}
1449+
}
1450+
13961451
#[cfg(not(any(
13971452
target_os = "freebsd",
13981453
target_os = "fuchsia",
13991454
target_os = "linux",
14001455
target_os = "netbsd",
14011456
target_os = "openbsd",
14021457
target_os = "cygwin",
1458+
target_os = "solaris",
14031459
target_vendor = "apple",
14041460
)))]
14051461
pub fn try_lock_shared(&self) -> Result<(), TryLockError> {
@@ -1423,13 +1479,23 @@ impl File {
14231479
return Ok(());
14241480
}
14251481

1482+
#[cfg(target_os = "solaris")]
1483+
pub fn unlock(&self) -> io::Result<()> {
1484+
let mut flock: libc::flock = unsafe { mem::zeroed() };
1485+
flock.l_type = libc::F_UNLCK as libc::c_short;
1486+
flock.l_whence = libc::SEEK_SET as libc::c_short;
1487+
cvt(unsafe { libc::fcntl(self.as_raw_fd(), libc::F_SETLKW, &flock) })?;
1488+
Ok(())
1489+
}
1490+
14261491
#[cfg(not(any(
14271492
target_os = "freebsd",
14281493
target_os = "fuchsia",
14291494
target_os = "linux",
14301495
target_os = "netbsd",
14311496
target_os = "openbsd",
14321497
target_os = "cygwin",
1498+
target_os = "solaris",
14331499
target_vendor = "apple",
14341500
)))]
14351501
pub fn unlock(&self) -> io::Result<()> {

0 commit comments

Comments
 (0)