Write procfs function for IPC semaphores. Clean up the semaphores code.
This commit is contained in:
@@ -1,36 +0,0 @@
|
||||
/// @file ipc.h
|
||||
/// @brief
|
||||
/// @copyright (c) 2014-2023 This file is distributed under the MIT License.
|
||||
/// See LICENSE.md for details.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stddef.h"
|
||||
|
||||
#define IPC_CREAT 01000 ///< Create key if key does not exist.
|
||||
|
||||
#define IPC_EXCL 02000 ///< Fail if key exists.
|
||||
#define IPC_NOWAIT 04000 ///< Return error on wait.
|
||||
#define IPC_RMID 0 ///< Remove identifier.
|
||||
#define IPC_SET 1 ///< Set `ipc_perm' options.
|
||||
#define IPC_STAT 2 ///< Get `ipc_perm' options.
|
||||
#define IPC_INFO 3 ///< See ipcs.
|
||||
#define IPC_PRIVATE 4 ///< assures getting a new ipc_key.
|
||||
|
||||
/// @brief Holds details about IPCs.
|
||||
typedef struct ipc_perm_t {
|
||||
/// Creator user id.
|
||||
uid_t cuid;
|
||||
/// Creator group id.
|
||||
gid_t cgid;
|
||||
/// User id.
|
||||
uid_t uid;
|
||||
/// Group id.
|
||||
gid_t gid;
|
||||
/// r/w permission.
|
||||
ushort mode;
|
||||
/// Sequence # (to generate unique msg/sem/shm id).
|
||||
ushort seq;
|
||||
/// User specified msg/sem/shm key.
|
||||
key_t key;
|
||||
} ipc_perm_t;
|
||||
+45
-23
@@ -9,23 +9,15 @@
|
||||
#include "io/debug.h"
|
||||
#include "string.h"
|
||||
|
||||
static ssize_t procipc_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte)
|
||||
{
|
||||
if (!file) {
|
||||
pr_err("Received a NULL file.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
if (!strcmp(file->name, "/proc/ipc/msg")) {
|
||||
pr_alert("Return MSG stat.\n");
|
||||
}
|
||||
if (!strcmp(file->name, "/proc/ipc/sem")) {
|
||||
pr_alert("Return SEM stat.\n");
|
||||
}
|
||||
if (!strcmp(file->name, "/proc/ipc/shm")) {
|
||||
pr_alert("Return SHM stat.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#include "ipc/msg.h"
|
||||
#include "ipc/sem.h"
|
||||
#include "ipc/shm.h"
|
||||
|
||||
extern ssize_t procipc_msg_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte);
|
||||
|
||||
extern ssize_t procipc_sem_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte);
|
||||
|
||||
extern ssize_t procipc_shm_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte);
|
||||
|
||||
/// Filesystem general operations.
|
||||
static vfs_sys_operations_t procipc_sys_operations = {
|
||||
@@ -34,12 +26,38 @@ static vfs_sys_operations_t procipc_sys_operations = {
|
||||
.stat_f = NULL
|
||||
};
|
||||
|
||||
/// Filesystem file operations.
|
||||
static vfs_file_operations_t procipc_fs_operations = {
|
||||
/// Filesystem file operations for message queues.
|
||||
static vfs_file_operations_t procipc_msg_fs_operations = {
|
||||
.open_f = NULL,
|
||||
.unlink_f = NULL,
|
||||
.close_f = NULL,
|
||||
.read_f = procipc_read,
|
||||
.read_f = procipc_msg_read,
|
||||
.write_f = NULL,
|
||||
.lseek_f = NULL,
|
||||
.stat_f = NULL,
|
||||
.ioctl_f = NULL,
|
||||
.getdents_f = NULL
|
||||
};
|
||||
|
||||
/// Filesystem file operations for semaphores.
|
||||
static vfs_file_operations_t procipc_sem_fs_operations = {
|
||||
.open_f = NULL,
|
||||
.unlink_f = NULL,
|
||||
.close_f = NULL,
|
||||
.read_f = procipc_sem_read,
|
||||
.write_f = NULL,
|
||||
.lseek_f = NULL,
|
||||
.stat_f = NULL,
|
||||
.ioctl_f = NULL,
|
||||
.getdents_f = NULL
|
||||
};
|
||||
|
||||
/// Filesystem file operations for shared memry.
|
||||
static vfs_file_operations_t procipc_shm_fs_operations = {
|
||||
.open_f = NULL,
|
||||
.unlink_f = NULL,
|
||||
.close_f = NULL,
|
||||
.read_f = procipc_shm_read,
|
||||
.write_f = NULL,
|
||||
.lseek_f = NULL,
|
||||
.stat_f = NULL,
|
||||
@@ -50,11 +68,13 @@ static vfs_file_operations_t procipc_fs_operations = {
|
||||
int procipc_module_init()
|
||||
{
|
||||
proc_dir_entry_t *folder = NULL, *entry = NULL;
|
||||
|
||||
// First, we need to create the `/proc/ipc` folder.
|
||||
if ((folder = proc_mkdir("ipc", NULL)) == NULL) {
|
||||
pr_err("Cannot create the `/proc/ipc` directory.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create the `/proc/ipc/msg` entry.
|
||||
if ((entry = proc_create_entry("msg", folder)) == NULL) {
|
||||
pr_err("Cannot create the `/proc/ipc/msg` file.\n");
|
||||
@@ -62,7 +82,8 @@ int procipc_module_init()
|
||||
}
|
||||
// Set the specific operations.
|
||||
entry->sys_operations = &procipc_sys_operations;
|
||||
entry->fs_operations = &procipc_fs_operations;
|
||||
entry->fs_operations = &procipc_msg_fs_operations;
|
||||
|
||||
// Create the `/proc/ipc/sem` entry.
|
||||
if ((entry = proc_create_entry("sem", folder)) == NULL) {
|
||||
pr_err("Cannot create the `/proc/ipc/sem` file.\n");
|
||||
@@ -70,7 +91,8 @@ int procipc_module_init()
|
||||
}
|
||||
// Set the specific operations.
|
||||
entry->sys_operations = &procipc_sys_operations;
|
||||
entry->fs_operations = &procipc_fs_operations;
|
||||
entry->fs_operations = &procipc_sem_fs_operations;
|
||||
|
||||
// Create the `/proc/ipc/shm` entry.
|
||||
if ((entry = proc_create_entry("shm", folder)) == NULL) {
|
||||
pr_err("Cannot create the `/proc/ipc/shm` file.\n");
|
||||
@@ -78,6 +100,6 @@ int procipc_module_init()
|
||||
}
|
||||
// Set the specific operations.
|
||||
entry->sys_operations = &procipc_sys_operations;
|
||||
entry->fs_operations = &procipc_fs_operations;
|
||||
entry->fs_operations = &procipc_shm_fs_operations;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4,14 +4,20 @@
|
||||
/// See LICENSE.md for details.
|
||||
///! @cond Doxygen_Suppress
|
||||
|
||||
// ============================================================================
|
||||
// Setup the logging for this file (do this before any other include).
|
||||
#include "sys/kernel_levels.h" // Include kernel log levels.
|
||||
#define __DEBUG_HEADER__ "[IPCmsg]" ///< Change header.
|
||||
#define __DEBUG_LEVEL__ LOGLEVEL_NOTICE ///< Set log level.
|
||||
#include "io/debug.h" // Include debugging functions.
|
||||
// ============================================================================
|
||||
|
||||
#include "ipc/msg.h"
|
||||
#include "system/panic.h"
|
||||
#include "process/process.h"
|
||||
#include "sys/errno.h"
|
||||
#include "assert.h"
|
||||
#include "stdio.h"
|
||||
|
||||
long sys_msgget(key_t key, int msgflg)
|
||||
{
|
||||
@@ -37,4 +43,14 @@ long sys_msgctl(int msqid, int cmd, struct msqid_ds *buf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t procipc_msg_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte)
|
||||
{
|
||||
if (!file) {
|
||||
pr_err("Received a NULL file.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
pr_alert("Return MSG stat.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
///! @endcond
|
||||
|
||||
+142
-97
@@ -42,44 +42,92 @@
|
||||
#include "klib/list.h"
|
||||
#include "process/process.h"
|
||||
#include "sys/errno.h"
|
||||
#include "string.h"
|
||||
#include "assert.h"
|
||||
#include "stdio.h"
|
||||
|
||||
///@brief A value to compute the semid value.
|
||||
int semid_assign = 0;
|
||||
|
||||
/// @brief list of all current active semaphores
|
||||
list_t *current_semaphores;
|
||||
/// @brief List of all current active semaphores.
|
||||
list_t semaphores_list = {
|
||||
.head = NULL,
|
||||
.tail = NULL,
|
||||
.size = 0
|
||||
};
|
||||
|
||||
/// @brief [temporary] To implement the IPC_PRIVATE mechanism.
|
||||
int count_ipc_private = 2;
|
||||
|
||||
/// @brief Initializes a single semaphore.
|
||||
/// @param temp the pointer to the struct of the semaphore.
|
||||
static inline void __sem_init(struct sem *temp)
|
||||
/// @brief Allocates the memory for an array of semaphores.
|
||||
/// @param nsems number of semaphores in the array.
|
||||
/// @return a pointer to the allocated array of semaphores.
|
||||
static inline struct sem *__sem_alloc(int nsems)
|
||||
{
|
||||
temp->sem_val = 0;
|
||||
temp->sem_pid = sys_getpid();
|
||||
temp->sem_zcnt = 0;
|
||||
// Allocate the memory.
|
||||
struct sem *ptr = (struct sem *)kmalloc(sizeof(struct sem) * nsems);
|
||||
// Check the allocated memory.
|
||||
assert(ptr && "Failed to allocate memory for the array of semaphores.");
|
||||
// Clean the memory.
|
||||
memset(ptr, 0, sizeof(struct sem));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/// @brief Initializes a semid struct (set of semaphores).
|
||||
/// @param temp the pointer to the semid struct.
|
||||
/// @brief Frees the memory of an array of semaphores.
|
||||
/// @param ptr the pointer to the array of semaphores.
|
||||
static inline void __sem_dealloc(struct sem *ptr)
|
||||
{
|
||||
assert(ptr && "Received a NULL pointer.");
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
/// @brief Initializes a single semaphore.
|
||||
/// @param ptr the pointer to the single semaphore.
|
||||
static inline void __sem_init(struct sem *ptr)
|
||||
{
|
||||
ptr->sem_val = 0;
|
||||
ptr->sem_pid = sys_getpid();
|
||||
ptr->sem_zcnt = 0;
|
||||
}
|
||||
|
||||
/// @brief Allocates the memory for a semid structure.
|
||||
/// @return a pointer to the allocated semid structure.
|
||||
static inline struct semid_ds *__semid_alloc()
|
||||
{
|
||||
// Allocate the memory.
|
||||
struct semid_ds *ptr = (struct semid_ds *)kmalloc(sizeof(struct semid_ds));
|
||||
// Check the allocated memory.
|
||||
assert(ptr && "Failed to allocate memory for a semid structure.");
|
||||
// Clean the memory.
|
||||
memset(ptr, 0, sizeof(struct semid_ds));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/// @brief Frees the memory of a semid structure.
|
||||
/// @param ptr pointer to the semid structure.
|
||||
static inline void __semid_dealloc(struct semid_ds *ptr)
|
||||
{
|
||||
assert(ptr && "Received a NULL pointer.");
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
/// @brief Initializes a semid struct.
|
||||
/// @param ptr the pointer to the semid struct.
|
||||
/// @param key IPC_KEY associated with the set of semaphores
|
||||
/// @param nsems number of semaphores to initialize
|
||||
/// @todo The way we compute the semid is a temporary solution.
|
||||
static inline void __semid_init(struct semid_ds *temp, key_t key, int nsems)
|
||||
static inline void __semid_init(struct semid_ds *ptr, key_t key, int nsems)
|
||||
{
|
||||
assert(temp && "Received NULL semid data structure.");
|
||||
temp->owner = sys_getpid();
|
||||
temp->key = key;
|
||||
temp->semid = ++semid_assign;
|
||||
temp->sem_otime = 0;
|
||||
temp->sem_ctime = 0;
|
||||
temp->sem_nsems = nsems;
|
||||
temp->sems = (struct sem *)kmalloc(sizeof(struct sem) * nsems);
|
||||
assert(ptr && "Received a NULL pointer.");
|
||||
ptr->owner = sys_getpid();
|
||||
ptr->key = key;
|
||||
ptr->semid = ++semid_assign;
|
||||
ptr->sem_otime = 0;
|
||||
ptr->sem_ctime = 0;
|
||||
ptr->sem_nsems = nsems;
|
||||
ptr->sems = __sem_alloc(nsems);
|
||||
for (int i = 0; i < nsems; i++) {
|
||||
__sem_init(&(temp->sems[i]));
|
||||
__sem_init(&ptr->sems[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,48 +136,23 @@ static inline void __semid_init(struct semid_ds *temp, key_t key, int nsems)
|
||||
/// @return the semaphore with the given id.
|
||||
static inline struct semid_ds *__find_semaphore(int semid)
|
||||
{
|
||||
struct semid_ds *semaphore, *entry;
|
||||
struct semid_ds *semaphores;
|
||||
// Iterate through the list of semaphores.
|
||||
listnode_foreach(listnode, current_semaphores)
|
||||
listnode_foreach(listnode, &semaphores_list)
|
||||
{
|
||||
// Get the current entry.
|
||||
entry = (struct semid_ds *)listnode->value;
|
||||
// If the entry is valid, check the id.
|
||||
if (entry && (entry->semid == semid))
|
||||
return entry;
|
||||
// Get the current list of semaphores.
|
||||
semaphores = (struct semid_ds *)listnode->value;
|
||||
// If semaphores is valid, check the id.
|
||||
if (semaphores && (semaphores->semid == semid))
|
||||
return semaphores;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// @brief for debugging purposes, print all the stats of the semid_ds
|
||||
/// @param temp the pointer to the semid struct
|
||||
void semid_print(struct semid_ds *temp)
|
||||
{
|
||||
assert(temp && "Received NULL semid data structure.");
|
||||
|
||||
pr_debug("pid, IPC_KEY, Semid, semop, change: %d, %d, %d, %d, %d\n", temp->owner, temp->key, temp->semid, temp->sem_otime, temp->sem_ctime);
|
||||
for (int i = 0; i < (temp->sem_nsems); i++) {
|
||||
pr_debug("%d semaphore:\n", i + 1);
|
||||
pr_debug("value: %d, pid %d, process waiting %d\n", temp->sems[i].sem_val, temp->sems[i].sem_pid, temp->sems[i].sem_zcnt);
|
||||
//pr_debug("pid of last op: %d\n", temp->sems[i].sem_pid);
|
||||
//pr_debug("process waiting: %d\n", temp->sems[i].sem_zcnt);
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief prints informations about the struct pointed by temp
|
||||
/// @param temp the pointer to the semid struct to print
|
||||
void show_ipcs(struct semid_ds *temp){
|
||||
printf("%d %d %d %d\n", temp->key, temp->semid, temp->owner, temp->sem_nsems);
|
||||
|
||||
}
|
||||
|
||||
/// @brief list of all current active semaphores
|
||||
list_t *current_semaphores;
|
||||
|
||||
|
||||
long sys_semget(key_t key, int nsems, int semflg)
|
||||
{
|
||||
struct semid_ds *temp = NULL;
|
||||
struct semid_ds *semaphores = NULL;
|
||||
|
||||
//check if nsems is a valid value
|
||||
if (nsems <= 0 && semflg != 0) {
|
||||
//pr_err("Errore NSEMS\n"); //debuggin purposes
|
||||
@@ -137,25 +160,17 @@ long sys_semget(key_t key, int nsems, int semflg)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*if (count == 0){ //first ever to call semget
|
||||
current_semaphores = list_create(); //init the list
|
||||
temp = (struct semid_ds *)kmalloc(sizeof(struct semid_ds)); //create the first one
|
||||
__semid_init(temp, key, nsems);
|
||||
list_insert_front(current_semaphores, temp);
|
||||
count++;
|
||||
return temp->semid;
|
||||
}*/
|
||||
|
||||
if (current_semaphores == NULL) { //if this is the first time that the function is called
|
||||
current_semaphores = list_create(); //we initialize the list
|
||||
}
|
||||
|
||||
if (key == IPC_PRIVATE) { // need to find a unique key
|
||||
// Need to find a unique key.
|
||||
if (key == IPC_PRIVATE) {
|
||||
int flag = 1;
|
||||
while (1) { //exit when i find a unique key
|
||||
listnode_foreach(listnode, current_semaphores)
|
||||
// Exit when i find a unique key.
|
||||
while (1) {
|
||||
listnode_foreach(listnode, &semaphores_list)
|
||||
{
|
||||
if (((struct semid_ds *)listnode->value)->key == count_ipc_private)
|
||||
// Get the current list of semaphores.
|
||||
semaphores = (struct semid_ds *)listnode->value;
|
||||
// If semaphores is valid, check the key.
|
||||
if (semaphores && (semaphores->key == count_ipc_private))
|
||||
flag = 0;
|
||||
}
|
||||
if (flag == 1)
|
||||
@@ -164,14 +179,15 @@ long sys_semget(key_t key, int nsems, int semflg)
|
||||
count_ipc_private *= 3; //multiply to try to find a unique key
|
||||
}
|
||||
//we have the key
|
||||
temp = (struct semid_ds *)kmalloc(sizeof(struct semid_ds));
|
||||
__semid_init(temp, count_ipc_private, nsems);
|
||||
list_insert_front(current_semaphores, temp);
|
||||
return temp->semid;
|
||||
semaphores = __semid_alloc();
|
||||
__semid_init(semaphores, count_ipc_private, nsems);
|
||||
list_insert_front(&semaphores_list, semaphores);
|
||||
return semaphores->semid;
|
||||
}
|
||||
|
||||
int flag = 0;
|
||||
int temp_semid = -1;
|
||||
listnode_foreach(listnode, current_semaphores)
|
||||
listnode_foreach(listnode, &semaphores_list)
|
||||
{ //iterate through the list
|
||||
if (((struct semid_ds *)listnode->value)->key == key) { //if we find a semid with the given key
|
||||
temp_semid = ((struct semid_ds *)listnode->value)->semid; //saving the semid
|
||||
@@ -180,10 +196,10 @@ long sys_semget(key_t key, int nsems, int semflg)
|
||||
}
|
||||
if (flag == 0) { //unique key
|
||||
if (semflg & IPC_CREAT) { //and i want to create a semaphore set with it
|
||||
temp = (struct semid_ds *)kmalloc(sizeof(struct semid_ds));
|
||||
__semid_init(temp, key, nsems);
|
||||
list_insert_front(current_semaphores, temp);
|
||||
return temp->semid;
|
||||
semaphores = (struct semid_ds *)kmalloc(sizeof(struct semid_ds));
|
||||
__semid_init(semaphores, key, nsems);
|
||||
list_insert_front(&semaphores_list, semaphores);
|
||||
return semaphores->semid;
|
||||
}
|
||||
errno = EINVAL; //invalid argument bc it is a unique key but with no IPC_CREAT
|
||||
return -1;
|
||||
@@ -250,7 +266,7 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
|
||||
switch (cmd) {
|
||||
//remove the semaphore set; any processes blocked is awakened (errno set to EIDRM); no argument required.
|
||||
case IPC_RMID:
|
||||
list_remove_node(current_semaphores, list_find(current_semaphores, temp));
|
||||
list_remove_node(&semaphores_list, list_find(&semaphores_list, temp));
|
||||
|
||||
//pr_debug("\ndone\n");
|
||||
/*gonna need to unblock all the processes on the semaphore*/
|
||||
@@ -354,23 +370,52 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long sys_semipcs(){
|
||||
|
||||
//default operation --- no semaphores
|
||||
if (current_semaphores == NULL){
|
||||
printf("------ Matrici semafori --------\n");
|
||||
printf("chiave semid proprietario nsems\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("------ Matrici semafori --------\n");
|
||||
printf("chiave semid proprietario nsems\n");
|
||||
listnode_foreach(listnode, current_semaphores)
|
||||
{ //iterate through the list
|
||||
show_ipcs(((struct semid_ds *)listnode->value));
|
||||
}
|
||||
|
||||
long sys_semipcs()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t procipc_sem_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte)
|
||||
{
|
||||
size_t buffer_len = 0, read_pos = 0, write_count = 0, ret = 0;
|
||||
struct semid_ds *entry = NULL;
|
||||
|
||||
if (!file) {
|
||||
pr_err("Received a NULL file.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
pr_alert("Return SEM stat.\n");
|
||||
|
||||
// Prepare a buffer.
|
||||
char buffer[BUFSIZ];
|
||||
memset(buffer, 0, BUFSIZ);
|
||||
|
||||
// Prepare the header.
|
||||
ret = sprintf(buffer, "key semid perms nsems uid gid cuid cgid otime ctime\n");
|
||||
|
||||
// Iterate through the list.
|
||||
if (semaphores_list.size > 0) {
|
||||
listnode_foreach(listnode, &semaphores_list)
|
||||
{
|
||||
entry = ((struct semid_ds *)listnode->value);
|
||||
sprintf(buffer + ret, "%8d %5d %10d %7d %5d %4d %5d %9d %10d %d\n",
|
||||
entry->key, entry->semid, 0, entry->sem_nsems, entry->owner, 0, 0, 0, entry->sem_otime, entry->sem_ctime);
|
||||
}
|
||||
}
|
||||
|
||||
// Perform read.
|
||||
buffer_len = strlen(buffer);
|
||||
read_pos = offset;
|
||||
if (read_pos < buffer_len) {
|
||||
while ((write_count < nbyte) && (read_pos < buffer_len)) {
|
||||
buf[write_count] = buffer[read_pos];
|
||||
// Move the pointers.
|
||||
++read_pos, ++write_count;
|
||||
}
|
||||
}
|
||||
pr_debug("Write count: %d\n", write_count);
|
||||
pr_debug("Buffer:\n\"\n%s\"\n", buffer);
|
||||
return write_count;
|
||||
}
|
||||
|
||||
///! @endcond
|
||||
|
||||
+17
-1
@@ -4,14 +4,20 @@
|
||||
/// See LICENSE.md for details.
|
||||
///! @cond Doxygen_Suppress
|
||||
|
||||
// ============================================================================
|
||||
// Setup the logging for this file (do this before any other include).
|
||||
#include "sys/kernel_levels.h" // Include kernel log levels.
|
||||
#define __DEBUG_HEADER__ "[IPCshm]" ///< Change header.
|
||||
#define __DEBUG_LEVEL__ LOGLEVEL_NOTICE ///< Set log level.
|
||||
#include "io/debug.h" // Include debugging functions.
|
||||
// ============================================================================
|
||||
|
||||
#include "ipc/shm.h"
|
||||
#include "system/panic.h"
|
||||
#include "process/process.h"
|
||||
#include "sys/errno.h"
|
||||
#include "assert.h"
|
||||
#include "stdio.h"
|
||||
|
||||
#if 0
|
||||
struct shmid_ds *head = NULL;
|
||||
@@ -374,7 +380,7 @@ struct shmid_ds *find_shm_fromvaddr(void *shmvaddr)
|
||||
}
|
||||
#endif
|
||||
|
||||
void * sys_shmat(int shmid, const void *shmaddr, int shmflg)
|
||||
void *sys_shmat(int shmid, const void *shmaddr, int shmflg)
|
||||
{
|
||||
TODO("Not implemented");
|
||||
return 0;
|
||||
@@ -398,4 +404,14 @@ long sys_shmctl(int shmid, int cmd, struct shmid_ds *buf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t procipc_shm_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte)
|
||||
{
|
||||
if (!file) {
|
||||
pr_err("Received a NULL file.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
pr_alert("Return SHM stat.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
///! @endcond
|
||||
|
||||
Reference in New Issue
Block a user