From e19354a9eeb62ea2815e52d3805be5a35d0a2cfe Mon Sep 17 00:00:00 2001 From: Enrico Fraccaroli Date: Thu, 27 Apr 2023 10:10:34 +0200 Subject: [PATCH] Implement ipcs mechanisms. --- libc/inc/ipc/sem.h | 8 -- libc/inc/system/syscall_types.h | 3 +- libc/src/ipc/ipc.c | 15 --- mentos/src/ipc/msg.c | 26 ++++- mentos/src/ipc/sem.c | 25 ++--- mentos/src/ipc/shm.c | 26 ++++- mentos/src/system/syscall.c | 1 - programs/ipcs.c | 185 +++++++++++++------------------- 8 files changed, 130 insertions(+), 159 deletions(-) diff --git a/libc/inc/ipc/sem.h b/libc/inc/ipc/sem.h index 7ebea94..9024358 100644 --- a/libc/inc/ipc/sem.h +++ b/libc/inc/ipc/sem.h @@ -106,10 +106,6 @@ long sys_semop(int semid, struct sembuf *sops, unsigned nsops); /// @return 0 on success, -1 on failure and errno is set to indicate the error. long sys_semctl(int semid, int semnum, int cmd, union semun *arg); -/// @brief Prints System V semaphores Informations -/// @return 0 on success, -1 on failure and errno is set to indicate the error. -long sys_semipcs(); - #else /// @brief Get a System V semaphore set identifier. @@ -136,8 +132,4 @@ long semop(int semid, struct sembuf *sops, unsigned nsops); /// @return 0 on success, -1 on failure and errno is set to indicate the error. long semctl(int semid, int semnum, int cmd, union semun *arg); -/// @brief Prints System V semaphores Informations -/// @return 0 on success, -1 on failure and errno is set to indicate the error. -long semipcs(); - #endif diff --git a/libc/inc/system/syscall_types.h b/libc/inc/system/syscall_types.h index 770ce47..6c29f8c 100644 --- a/libc/inc/system/syscall_types.h +++ b/libc/inc/system/syscall_types.h @@ -193,8 +193,7 @@ #define __NR_shmctl 197 ///< System-call number for `shmctl` #define __NR_shmdt 198 ///< System-call number for `shmdt` #define __NR_shmget 199 ///< System-call number for `shmget` -#define __NR_semipcs 200 ///< System-call number for `ipcs` -#define SYSCALL_NUMBER 201 ///< The total number of system-calls. +#define SYSCALL_NUMBER 200 ///< The total number of system-calls. /// @brief Handle the value returned from a system call. /// @param type Specifies the type of the returned value. diff --git a/libc/src/ipc/ipc.c b/libc/src/ipc/ipc.c index 5c1c12e..9b6aef0 100644 --- a/libc/src/ipc/ipc.c +++ b/libc/src/ipc/ipc.c @@ -41,21 +41,6 @@ _syscall5(long, msgrcv, int, msqid, struct msgbuf *, msgp, size_t, msgsz, long, _syscall3(long, msgctl, int, msqid, int, cmd, struct msqid_ds *, buf) -_syscall0(long, semipcs) - - - -long ipcs(int argc, char** argv) -{ - /*Right now we only call the semipcs function because shared memories and message queues - do not exist. When they will be implemented you will be able to just call their printing function - down here. - */ - long __res; - __inline_syscall0(__res, semipcs); - __syscall_return(long, __res); -} - long semop(int semid, struct sembuf *sops, unsigned nsops) { diff --git a/mentos/src/ipc/msg.c b/mentos/src/ipc/msg.c index 02a3a33..f133ffe 100644 --- a/mentos/src/ipc/msg.c +++ b/mentos/src/ipc/msg.c @@ -16,6 +16,7 @@ #include "system/panic.h" #include "process/process.h" #include "sys/errno.h" +#include "string.h" #include "assert.h" #include "stdio.h" @@ -49,8 +50,29 @@ ssize_t procipc_msg_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte pr_err("Received a NULL file.\n"); return -ENOENT; } - pr_alert("Return MSG stat.\n"); - return 0; + size_t buffer_len = 0, read_pos = 0, write_count = 0, ret = 0; + struct semid_ds *entry = NULL; + char buffer[BUFSIZ]; + + // Prepare a buffer. + memset(buffer, 0, BUFSIZ); + // Prepare the header. + ret = sprintf(buffer, "key msqid ...\n"); + + // Implementation goes here... + sprintf(buffer + ret, "\n"); + + // 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; + } + } + return write_count; } ///! @endcond diff --git a/mentos/src/ipc/sem.c b/mentos/src/ipc/sem.c index 2b2417d..116eaab 100644 --- a/mentos/src/ipc/sem.c +++ b/mentos/src/ipc/sem.c @@ -152,14 +152,12 @@ static inline struct semid_ds *__find_semaphore(int semid) long sys_semget(key_t key, int nsems, int semflg) { struct semid_ds *semaphores = NULL; - //check if nsems is a valid value if (nsems <= 0 && semflg != 0) { //pr_err("Errore NSEMS\n"); //debuggin purposes errno = EINVAL; return -1; } - // Need to find a unique key. if (key == IPC_PRIVATE) { int flag = 1; @@ -196,7 +194,7 @@ 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 - semaphores = (struct semid_ds *)kmalloc(sizeof(struct semid_ds)); + semaphores = __semid_alloc(); __semid_init(semaphores, key, nsems); list_insert_front(&semaphores_list, semaphores); return semaphores->semid; @@ -370,26 +368,18 @@ long sys_semctl(int semid, int semnum, int cmd, union semun *arg) return 0; } -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"); + size_t buffer_len = 0, read_pos = 0, write_count = 0, ret = 0; + struct semid_ds *entry = NULL; + char buffer[BUFSIZ]; // 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"); @@ -398,10 +388,11 @@ ssize_t procipc_sem_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte 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); + ret += 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); } } + sprintf(buffer + ret, "\n"); // Perform read. buffer_len = strlen(buffer); @@ -413,8 +404,6 @@ ssize_t procipc_sem_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte ++read_pos, ++write_count; } } - pr_debug("Write count: %d\n", write_count); - pr_debug("Buffer:\n\"\n%s\"\n", buffer); return write_count; } diff --git a/mentos/src/ipc/shm.c b/mentos/src/ipc/shm.c index 0c3be32..e5577f6 100644 --- a/mentos/src/ipc/shm.c +++ b/mentos/src/ipc/shm.c @@ -16,6 +16,7 @@ #include "system/panic.h" #include "process/process.h" #include "sys/errno.h" +#include "string.h" #include "assert.h" #include "stdio.h" @@ -410,8 +411,29 @@ ssize_t procipc_shm_read(vfs_file_t *file, char *buf, off_t offset, size_t nbyte pr_err("Received a NULL file.\n"); return -ENOENT; } - pr_alert("Return SHM stat.\n"); - return 0; + size_t buffer_len = 0, read_pos = 0, write_count = 0, ret = 0; + struct semid_ds *entry = NULL; + char buffer[BUFSIZ]; + + // Prepare a buffer. + memset(buffer, 0, BUFSIZ); + // Prepare the header. + ret = sprintf(buffer, "key shmid ...\n"); + + // Implementation goes here... + sprintf(buffer + ret, "\n"); + + // 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; + } + } + return write_count; } ///! @endcond diff --git a/mentos/src/system/syscall.c b/mentos/src/system/syscall.c index 6f357be..a6d1ff8 100644 --- a/mentos/src/system/syscall.c +++ b/mentos/src/system/syscall.c @@ -237,7 +237,6 @@ void syscall_init() sys_call_table[__NR_shmctl] = (SystemCall)sys_shmctl; sys_call_table[__NR_shmdt] = (SystemCall)sys_shmdt; sys_call_table[__NR_shmget] = (SystemCall)sys_shmget; - sys_call_table[__NR_semipcs] = (SystemCall)sys_semipcs; isr_install_handler(SYSTEM_CALL, &syscall_handler, "syscall_handler"); } diff --git a/programs/ipcs.c b/programs/ipcs.c index 036fd95..633a7e3 100644 --- a/programs/ipcs.c +++ b/programs/ipcs.c @@ -3,134 +3,97 @@ /// @copyright (c) 2014-2023 This file is distributed under the MIT License. /// See LICENSE.md for details. +#include #include #include #include #include #include +#include - -#if 0 -static inline void print_sem_stat() +static inline void __print_file_content(const char *path) { - printf("Semaphores: \n"); - printf("%-10s %-10s %-10s %-10s %-10s %-10s \n", "T", "ID", "KEY", "MODE", "OWNER", "GROUP"); - printf("%-20s %-10s %-20s \n\n", "", "Semaphores not implemented", ""); + // Prepare the buffer for reading. + char buffer[BUFSIZ]; + // Clean the buffer. + memset(buffer, 0, BUFSIZ); + // Open the file. + int fd = open(path, O_RDONLY, 42); + if (fd >= 0) { + // Put on the standard output the characters. + while (read(fd, buffer, BUFSIZ) > 0) + puts(buffer); + // Close the file descriptor. + close(fd); + } } -static inline void print_msg_stat() -{ - printf("Message Queues: \n"); - printf("%-10s %-10s %-10s %-10s %-10s %-10s \n", "T", "ID", "KEY", "MODE", "OWNER", "GROUP"); - printf("%-20s %-10s %-20s \n\n", "", "Message Queues not implemented", ""); -} - -static inline void print_shm_stat() -{ - printf("Shared Memory: \n"); - printf("%-10s %-10s %-10s %-10s %-10s %-10s \n", "T", "ID", "KEY", "MODE", "OWNER", "GROUP"); - printf("%-20s %-10s %-20s \n\n", "", "Shared Memory not implemented", ""); -} -#endif - int main(int argc, char **argv) { - - if (argc>4) + if (argc > 4) return -1; - if (argc == 1){ /*Default operation, prints all ipcs informations*/ - long __res; - __res = ipcs(); - return __res; + // Default operation, prints all ipcs informations. + if (argc == 1) { + printf("------ Message Queues --------\n"); + __print_file_content("/proc/ipc/msg"); + printf("------ Semaphore Arrays --------\n"); + __print_file_content("/proc/ipc/sem"); + printf("------ Shared Memory Segments --------\n"); + __print_file_content("/proc/ipc/shm"); + return 0; } - - if (argc == 2){ - // all semaphores - if (!strcmp(argv[1], "-s")){ - long __res; - __res = semipcs(); - return __res; - } - - // all shared memories - if (!strcmp(argv[1], "-m")) { - printf("Not Implemented!\n"); - return 0; - } - - // all message queues - if (!strcmp(argv[1], "-q")){ - printf("Not Implemented!\n"); - return 0; - } - - return -1; - } - else{ - // semaphore by id - if(!strcmp(argv[1], "-i" ) && !strcmp(argv[3],"-s")){ - union semun temp; - temp.buf = (struct semid_ds *)malloc(sizeof(struct semid_ds)); - long __res; - __res = semctl(atoi(argv[2]), 0, GETNSEMS, NULL); - temp.buf -> sems = (struct sem *)malloc(sizeof(struct sem) * __res); - __res = semctl(atoi(argv[2]), 0, IPC_STAT, &temp); - printf("------ Matrici semafori --------\n"); - printf("chiave semid proprietario nsems\n"); - printf("%d %d %d %d\n", temp.buf->key, temp.buf->semid, temp.buf->owner, temp.buf->sem_nsems); - if(__res == -1) - return -1; - return __res; - } - - // shared memory by id - if(!strcmp(argv[1], "-i" ) && !strcmp(argv[3],"-m")){ - printf("Not Implemented!\n"); - return 0; - } - - // message queue by id - if(!strcmp(argv[1], "-i" ) && !strcmp(argv[3],"-q")){ - printf("Not Implemented!\n"); - return 0; - } - return -1; - } - - - return 0; - - - -#if 0 - if (argc > 2) { - printf("Too much arguments.\n"); - - return; - } - - char datehour[100] = ""; - strdatehour(datehour); - - printf("IPC status from " OS_NAME " as of %s\n", datehour); - if (argc == 2) { - if (strcmp(argv[1], "-s") == 0) { - print_sem_stat(); - } else if (strcmp(argv[1], "-m") == 0) { - print_shm_stat(); - } else if (strcmp(argv[1], "-q") == 0) { - print_msg_stat(); + if (!strcmp(argv[1], "-q")) { // Show message queues information. + printf("------ Message Queues --------\n"); + __print_file_content("/proc/ipc/msg"); + } else if (!strcmp(argv[1], "-s")) { // Show semaphores information. + printf("------ Semaphore Arrays --------\n"); + __print_file_content("/proc/ipc/sem"); + } else if (!strcmp(argv[1], "-m")) { // Show shared memories information. + printf("------ Shared Memory Segments --------\n"); + __print_file_content("/proc/ipc/shm"); } else { - printf("Option not recognize.\n"); + printf("%s: Command not found.", argv[0]); + return 1; } - } else { - print_sem_stat(); - print_shm_stat(); - print_msg_stat(); + return 0; } + if (!strcmp(argv[1], "-i")) { + // Show details about a specific semaphore. + if (!strcmp(argv[3], "-s")) { + struct semid_ds sem; + union semun temp; + long ret; + // Prepare the data structure. + temp.buf = &sem; + // Retrive the statistics. + ret = semctl(atoi(argv[2]), 0, IPC_STAT, &temp); + // Check if we succeded. + if (!ret) { + //ret = semctl(atoi(argv[2]), 0, GETNSEMS, NULL); + //temp.buf->sems = (struct sem *)malloc(sizeof(struct sem) * ret); + printf("key semid owner perms nsems\n"); + printf("%10d %10d %10d %10d %d\n", sem.key, sem.semid, sem.owner, 0, sem.sem_nsems); + return 0; + } + return 1; + } - return; -#endif + // Show details about a specific shared memory. + if (!strcmp(argv[3], "-m")) { + printf("Not Implemented!\n"); + return 0; + } + + // Show details about a specific message queue. + if (!strcmp(argv[3], "-q")) { + printf("Not Implemented!\n"); + return 0; + } + printf("%s: Wrong combination, with `-i` you should provide either `-s`, `-m`, or `-q`.", argv[0]); + return 1; + } + printf("%s: Command not found.", argv[0]); + return 1; }