Skip to content

Commit e3da874

Browse files
author
lind
committed
first commit
1 parent 7dca0f6 commit e3da874

File tree

1 file changed

+50
-7
lines changed

1 file changed

+50
-7
lines changed

src/safeposix/syscalls/fs_calls.rs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4979,27 +4979,63 @@ impl Cage {
49794979
None
49804980
}
49814981

4982-
//------------------SHMGET SYSCALL------------------
4983-
4984-
pub fn shmget_syscall(&self, key: i32, size: usize, shmflg: i32) -> i32 {
4982+
/// ### Description
4983+
///
4984+
/// `shmget_syscall` returns the shared memory segment identifier associated with a particular `key`
4985+
/// If a key doesn't exist or equals `IPC_PRIVATE`, shmget creates a new
4986+
/// memory segment and attaches it to the key, however we only create a new memory segment if the key
4987+
/// doesn't exist, and return an error if key equals `IPC_PRIVATE`
4988+
///
4989+
/// ### Returns
4990+
///
4991+
/// An 32 bit integer which represens the identifier of the memory segment associated with the key
4992+
///
4993+
/// ### Arguments
4994+
///
4995+
/// `key` : An i32 value that references a memory segment
4996+
/// `size` : Size of the memory segment to be created if key doesn't exist
4997+
/// `shmflag` : mode flags which indicate whether to create a new key or not
4998+
///
4999+
/// ### Errors
5000+
///
5001+
/// * ENOENT : the key equals the `IPC_PRIVATE` constant
5002+
/// * EEXIST : key exists and yet either `IPC_CREAT` or `IPC_EXCL` are passed as flags
5003+
/// * ENOENT : key did not exist and the `IPC_CREAT` flag was not passed
5004+
/// * EINVAL : the size passed was less than the minimum size of segment or greater than the maximum possible size
5005+
///
5006+
/// ### Panics
5007+
///
5008+
/// There are no cases where the function directly panics
5009+
///
5010+
pub fn shmget_syscall(&self, key: i32, size: usize, shmflg: i32) -> i32 {
5011+
//Check if the key passed equals the IPC_PRIVATE flag
49855012
if key == IPC_PRIVATE {
5013+
// Return error since this is not suppported currently
49865014
return syscall_error(Errno::ENOENT, "shmget", "IPC_PRIVATE not implemented");
49875015
}
5016+
// Variable to store shmid
49885017
let shmid: i32;
5018+
// data of the shm table
49895019
let metadata = &SHM_METADATA;
49905020

5021+
// Check if there exists a memory segment associated with the key passed as argument
49915022
match metadata.shmkeyidtable.entry(key) {
5023+
// If there exists a memory segment at that key
49925024
interface::RustHashEntry::Occupied(occupied) => {
5025+
// Produce an error if invalid flags are used with a valid key
49935026
if (IPC_CREAT | IPC_EXCL) == (shmflg & (IPC_CREAT | IPC_EXCL)) {
49945027
return syscall_error(
49955028
Errno::EEXIST,
49965029
"shmget",
49975030
"key already exists and IPC_CREAT and IPC_EXCL were used",
49985031
);
49995032
}
5033+
// Get the id of the occupied memory segment
50005034
shmid = *occupied.get();
50015035
}
5036+
// If the memory segment doesn't exist
50025037
interface::RustHashEntry::Vacant(vacant) => {
5038+
// Return an error if IPC_CREAT was not specified
50035039
if 0 == (shmflg & IPC_CREAT) {
50045040
return syscall_error(
50055041
Errno::ENOENT,
@@ -5008,6 +5044,9 @@ impl Cage {
50085044
);
50095045
}
50105046

5047+
// If memory segment doesn't exist and IPC_CREAT was specified - we create a new memory segment
5048+
5049+
// Check if the size passed is a valid value
50115050
if (size as u32) < SHMMIN || (size as u32) > SHMMAX {
50125051
return syscall_error(
50135052
Errno::EINVAL,
@@ -5016,11 +5055,13 @@ impl Cage {
50165055
);
50175056
}
50185057

5058+
// Generate a new id for the new memory segment
50195059
shmid = metadata.new_keyid();
5060+
// Insert new id in the hash table entry pointed by the key
50205061
vacant.insert(shmid);
5021-
let mode = (shmflg & 0x1FF) as u16; // mode is 9 least signficant bits of shmflag, even if we dont really do
5022-
// anything with them
5023-
5062+
// Mode of the new segment is the 9 least significant bits of the shmflag
5063+
let mode = (shmflg & 0x1FF) as u16;
5064+
// Create a new segment with the key, size, cageid of the calling process
50245065
let segment = new_shm_segment(
50255066
key,
50265067
size,
@@ -5029,10 +5070,12 @@ impl Cage {
50295070
DEFAULT_GID,
50305071
mode,
50315072
);
5073+
// Insert the newly created segment in the SHM table with its key
50325074
metadata.shmtable.insert(shmid, segment);
50335075
}
50345076
};
5035-
shmid // return the shmid
5077+
// Return the shmid
5078+
shmid
50365079
}
50375080

50385081
//------------------SHMAT SYSCALL------------------

0 commit comments

Comments
 (0)