@@ -4979,27 +4979,69 @@ 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, shmget creates a new memory segment and attaches it to the key.
4986+ /// Traditionally if the value of the key equals `IPC_PRIVATE`, we also create a new memory segment which
4987+ /// is not associated with a key during this syscall,
4988+ /// but for our implementaion, we return an error and only create a new memory
4989+ /// segment when the IPC_CREAT flag is specified in the`shmflag` argument.
4990+ ///
4991+ /// ### Returns
4992+ ///
4993+ /// An 32 bit integer which represens the identifier of the memory segment associated with the key
4994+ ///
4995+ /// ### Arguments
4996+ ///
4997+ /// `key` : An i32 value that references a memory segment
4998+ /// `size` : Size of the memory segment to be created if key doesn't exist
4999+ /// `shmflag` : mode flags which indicate whether to create a new key or not
5000+ /// The `shmflag` is composed of the following
5001+ /// * IPC_CREAT - specify that the system call creates a new segment
5002+ /// * IPC_EXCL - this flag is used with IPC_CREAT to cause this function to fail when IPC_CREAT is also used
5003+ /// and the key passed has a memory segment associated with it.
5004+ ///
5005+ /// ### Errors
5006+ ///
5007+ /// * ENOENT : the key equals the `IPC_PRIVATE` constant
5008+ /// * EEXIST : key exists and yet either `IPC_CREAT` or `IPC_EXCL` are passed as flags
5009+ /// * ENOENT : key did not exist and the `IPC_CREAT` flag was not passed
5010+ /// * EINVAL : the size passed was less than the minimum size of segment or greater than the maximum possible size
5011+ ///
5012+ /// ### Panics
5013+ ///
5014+ /// There are no cases where the function directly panics
5015+ ///
5016+ pub fn shmget_syscall ( & self , key : i32 , size : usize , shmflg : i32 ) -> i32 {
5017+ //Check if the key passed equals the IPC_PRIVATE flag
49855018 if key == IPC_PRIVATE {
5019+ // Return error since this is not suppported currently
49865020 return syscall_error ( Errno :: ENOENT , "shmget" , "IPC_PRIVATE not implemented" ) ;
49875021 }
5022+ // Variable to store shmid
49885023 let shmid: i32 ;
5024+ // data of the shm table
49895025 let metadata = & SHM_METADATA ;
49905026
5027+ // Check if there exists a memory segment associated with the key passed as argument
49915028 match metadata. shmkeyidtable . entry ( key) {
5029+ // If there exists a memory segment at that key
49925030 interface:: RustHashEntry :: Occupied ( occupied) => {
5031+ // Produce an error if invalid flags are used with a valid key
49935032 if ( IPC_CREAT | IPC_EXCL ) == ( shmflg & ( IPC_CREAT | IPC_EXCL ) ) {
49945033 return syscall_error (
49955034 Errno :: EEXIST ,
49965035 "shmget" ,
49975036 "key already exists and IPC_CREAT and IPC_EXCL were used" ,
49985037 ) ;
49995038 }
5039+ // Get the id of the occupied memory segment
50005040 shmid = * occupied. get ( ) ;
50015041 }
5042+ // If the memory segment doesn't exist
50025043 interface:: RustHashEntry :: Vacant ( vacant) => {
5044+ // Return an error if IPC_CREAT was not specified
50035045 if 0 == ( shmflg & IPC_CREAT ) {
50045046 return syscall_error (
50055047 Errno :: ENOENT ,
@@ -5008,6 +5050,8 @@ impl Cage {
50085050 ) ;
50095051 }
50105052
5053+ // If memory segment doesn't exist and IPC_CREAT was specified - we create a new memory segment
5054+ // Check if the size passed is a valid value
50115055 if ( size as u32 ) < SHMMIN || ( size as u32 ) > SHMMAX {
50125056 return syscall_error (
50135057 Errno :: EINVAL ,
@@ -5016,11 +5060,13 @@ impl Cage {
50165060 ) ;
50175061 }
50185062
5063+ // Generate a new id for the new memory segment
50195064 shmid = metadata. new_keyid ( ) ;
5065+ // Insert new id in the hash table entry pointed by the key
50205066 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-
5067+ // Mode of the new segment is the 9 least significant bits of the shmflag
5068+ let mode = ( shmflg & 0x1FF ) as u16 ;
5069+ // Create a new segment with the key, size, cageid of the calling process
50245070 let segment = new_shm_segment (
50255071 key,
50265072 size,
@@ -5029,10 +5075,12 @@ impl Cage {
50295075 DEFAULT_GID ,
50305076 mode,
50315077 ) ;
5078+ // Insert the newly created segment in the SHM table with its key
50325079 metadata. shmtable . insert ( shmid, segment) ;
50335080 }
50345081 } ;
5035- shmid // return the shmid
5082+ // Return the shmid
5083+ shmid
50365084 }
50375085
50385086 //------------------SHMAT SYSCALL------------------
0 commit comments