Merge branch 'flock' into 'master'
feat(redox): flocking See merge request redox-os/relibc!1037
This commit is contained in:
Generated
+2
-2
@@ -463,9 +463,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.7.0"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27"
|
||||
checksum = "6d94dd2f7cd932d4dc02cc8b2b50dfd38bd079a4e5d79198b99743d7fcf9a4b4"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
@@ -137,9 +137,7 @@ $(BUILD)/$(PROFILE)/ld_so: $(BUILD)/$(PROFILE)/ld_so.o $(BUILD)/$(PROFILE)/crti.
|
||||
# TODO: merge ld.so with libc.so: --dynamic-list=dynamic-list-file
|
||||
$(LD) --shared -Bsymbolic --no-relax -T ld_so/ld_script/$(TARGET).ld --allow-multiple-definition --gc-sections $^ -o $@
|
||||
|
||||
# Debug targets
|
||||
|
||||
$(BUILD)/debug/libc.a: $(BUILD)/debug/librelibc.a $(BUILD)/openlibm/libopenlibm.a
|
||||
$(BUILD)/$(PROFILE)/libc.a: $(BUILD)/$(PROFILE)/librelibc.a $(BUILD)/openlibm/libopenlibm.a
|
||||
echo "create $@" > "$@.mri"
|
||||
for lib in $^; do\
|
||||
echo "addlib $$lib" >> "$@.mri"; \
|
||||
@@ -148,6 +146,8 @@ $(BUILD)/debug/libc.a: $(BUILD)/debug/librelibc.a $(BUILD)/openlibm/libopenlibm.
|
||||
echo "end" >> "$@.mri"
|
||||
$(AR) -M < "$@.mri"
|
||||
|
||||
# Debug targets
|
||||
|
||||
$(BUILD)/debug/librelibc.a: $(SRC)
|
||||
$(CARGO) rustc $(CARGOFLAGS) -- --emit link=$@ -g -C debug-assertions=no $(RUSTCFLAGS)
|
||||
./renamesyms.sh "$@" "$(BUILD)/debug/deps/"
|
||||
@@ -172,15 +172,6 @@ $(BUILD)/debug/ld_so.o: $(SRC)
|
||||
|
||||
# Release targets
|
||||
|
||||
$(BUILD)/release/libc.a: $(BUILD)/release/librelibc.a $(BUILD)/openlibm/libopenlibm.a
|
||||
echo "create $@" > "$@.mri"
|
||||
for lib in $^; do\
|
||||
echo "addlib $$lib" >> "$@.mri"; \
|
||||
done
|
||||
echo "save" >> "$@.mri"
|
||||
echo "end" >> "$@.mri"
|
||||
$(AR) -M < "$@.mri"
|
||||
|
||||
$(BUILD)/release/librelibc.a: $(SRC)
|
||||
$(CARGO) rustc --release $(CARGOFLAGS) -- --emit link=$@ $(RUSTCFLAGS)
|
||||
@# TODO: Better to only allow a certain whitelisted set of symbols? Perhaps
|
||||
|
||||
+150
-2
@@ -4,13 +4,14 @@ use core::{
|
||||
num::NonZeroU64,
|
||||
ptr, slice, str,
|
||||
};
|
||||
use object::bytes_of_slice_mut;
|
||||
use redox_rt::{
|
||||
RtTcb,
|
||||
protocol::{WaitFlags, wifstopped},
|
||||
sys::{Resugid, WaitpidTarget},
|
||||
};
|
||||
use syscall::{
|
||||
self, EILSEQ, Error, MODE_PERM,
|
||||
self, EILSEQ, ESRCH, Error, MODE_PERM, StdFsCallKind, StdFsCallMeta,
|
||||
data::{Map, TimeSpec as redox_timespec},
|
||||
dirent::{DirentHeader, DirentKind},
|
||||
};
|
||||
@@ -30,7 +31,10 @@ use crate::{
|
||||
EBADF, EBADFD, EBADR, EEXIST, EFAULT, EFBIG, EINTR, EINVAL, EIO, ENAMETOOLONG, ENOENT,
|
||||
ENOMEM, ENOSYS, EOPNOTSUPP, EPERM, ERANGE,
|
||||
},
|
||||
fcntl::{self, AT_EMPTY_PATH, AT_FDCWD, AT_SYMLINK_NOFOLLOW},
|
||||
fcntl::{
|
||||
self, AT_EMPTY_PATH, AT_FDCWD, AT_SYMLINK_NOFOLLOW, F_GETLK, F_OFD_GETLK, F_OFD_SETLK,
|
||||
F_RDLCK, F_SETLK, F_SETLKW, F_UNLCK, F_WRLCK, flock,
|
||||
},
|
||||
limits,
|
||||
pthread::{pthread_cancel, pthread_create},
|
||||
signal::{NSIG, SIGEV_NONE, SIGEV_SIGNAL, SIGEV_THREAD, SIGRTMIN, sigevent},
|
||||
@@ -293,6 +297,116 @@ impl Pal for Sys {
|
||||
}
|
||||
|
||||
fn fcntl(fd: c_int, cmd: c_int, args: c_ulonglong) -> Result<c_int> {
|
||||
match cmd {
|
||||
F_SETLK | F_OFD_SETLK => {
|
||||
let is_ofd = cmd == F_OFD_SETLK;
|
||||
let flock = unsafe { &mut *(args as *mut flock) };
|
||||
|
||||
let (start, len) = Self::relative_to_absolute_foffset(
|
||||
fd as usize,
|
||||
flock.l_whence,
|
||||
flock.l_start,
|
||||
flock.l_len,
|
||||
)?;
|
||||
|
||||
let start = start as u64 | if is_ofd { 1 << 63 } else { 0 };
|
||||
let len = len as u64;
|
||||
|
||||
match flock.l_type as i32 {
|
||||
F_UNLCK => {
|
||||
let meta = StdFsCallMeta::new(StdFsCallKind::Unlock, start, len);
|
||||
syscall::std_fs_call(fd as usize, &mut [], &meta)?;
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
F_RDLCK | F_WRLCK => {
|
||||
let meta = StdFsCallMeta::new(
|
||||
StdFsCallKind::Lock,
|
||||
start,
|
||||
len | if flock.l_type as i32 == F_WRLCK {
|
||||
1 << 63
|
||||
} else {
|
||||
0
|
||||
},
|
||||
);
|
||||
syscall::std_fs_call(fd as usize, &mut [], &meta)?;
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
_ => return Err(Errno(EINVAL)),
|
||||
};
|
||||
}
|
||||
|
||||
F_GETLK | F_OFD_GETLK => {
|
||||
let is_ofd = cmd == F_OFD_GETLK;
|
||||
let flock = unsafe { &mut *(args as *mut flock) };
|
||||
|
||||
if is_ofd && flock.l_pid != 0 {
|
||||
log::warn!("POSIX requires `l_pid` to be 0 on input for `F_OFD_GETLK`");
|
||||
return Err(Errno(EINVAL));
|
||||
}
|
||||
|
||||
let (start, len) = Self::relative_to_absolute_foffset(
|
||||
fd as usize,
|
||||
flock.l_whence,
|
||||
flock.l_start,
|
||||
flock.l_len,
|
||||
)?;
|
||||
|
||||
let mut start = start as u64;
|
||||
if is_ofd {
|
||||
start |= 1 << 63;
|
||||
}
|
||||
|
||||
let mut len = len as u64;
|
||||
if flock.l_type as i32 == F_WRLCK {
|
||||
len |= 1 << 63;
|
||||
}
|
||||
|
||||
let meta = StdFsCallMeta::new(StdFsCallKind::GetLock, 0, 0);
|
||||
let payload = &mut [start, len];
|
||||
// `pid` if traditional POSIX otherwise 0
|
||||
let val =
|
||||
match syscall::std_fs_call(fd as usize, bytes_of_slice_mut(payload), &meta) {
|
||||
// According to POSIX Issue 8:
|
||||
// > If no lock is found that would prevent this lock from being created, then
|
||||
// > the structure shall be left unchanged except for the lock type in `l_type`
|
||||
// > which shall be set to F_UNLCK.
|
||||
Err(err) if err.errno == ESRCH => {
|
||||
flock.l_type = F_UNLCK as i16;
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
Ok(val) => val,
|
||||
Err(err) => return Err(Errno(err.errno)),
|
||||
};
|
||||
|
||||
debug_assert_ne!(payload[0] & (1 << 63), 1 << 63);
|
||||
|
||||
if is_ofd {
|
||||
flock.l_pid = -1;
|
||||
} else {
|
||||
flock.l_pid = val as i32;
|
||||
}
|
||||
|
||||
let len = payload[1] & !(1 << 63);
|
||||
if payload[1] & (1 << 63) == (1 << 63) {
|
||||
flock.l_type = F_WRLCK as i16;
|
||||
} else {
|
||||
flock.l_type = F_RDLCK as i16;
|
||||
}
|
||||
|
||||
flock.l_whence = SEEK_SET as _;
|
||||
flock.l_start = start as i64;
|
||||
flock.l_len = len as i64;
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
F_SETLKW => log::warn!("F_SETLKW: not yet implemented"),
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(syscall::fcntl(fd as usize, cmd as usize, args as usize)? as c_int)
|
||||
}
|
||||
|
||||
@@ -1490,3 +1604,37 @@ impl Pal for Sys {
|
||||
unsafe { redox_rt::thread::exit_this_thread(stack_base, stack_size) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Sys {
|
||||
fn relative_to_absolute_foffset(
|
||||
fd: usize,
|
||||
whence: c_short,
|
||||
start: off_t,
|
||||
len: off_t,
|
||||
) -> Result<(off_t, off_t)> {
|
||||
// let file_off = Self::lseek(fd, 0, SEEK_SET)?;
|
||||
match whence as i32 {
|
||||
SEEK_SET => {
|
||||
let (start, len) = if len < 0 {
|
||||
(start + len, -len)
|
||||
} else {
|
||||
(start, len)
|
||||
};
|
||||
|
||||
if start < 0 {
|
||||
return Err(Errno(EINVAL));
|
||||
}
|
||||
|
||||
assert!(len >= 0);
|
||||
Ok((start, len))
|
||||
}
|
||||
// FIXME: andypython: SEEK_CUR, SEEK_END
|
||||
c => {
|
||||
log::warn!(
|
||||
"Sys::relative_to_absolute_foffset: whence={whence} not yet implemented"
|
||||
);
|
||||
Ok((0, 0))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,6 +303,7 @@ VARIED_NAMES=\
|
||||
pthread/rwlock_randtest \
|
||||
pthread/mutex_recursive \
|
||||
pthread/timeout \
|
||||
pthread/tls \
|
||||
grp/getgrouplist \
|
||||
grp/getgrgid_r \
|
||||
grp/getgrnam_r \
|
||||
|
||||
Reference in New Issue
Block a user