summaryrefslogtreecommitdiff
path: root/Year_2/OS/hw
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2021-09-11 11:46:57 +0200
committerSanto Cariotti <santo@dcariotti.me>2021-09-11 11:46:57 +0200
commit79cd77906c3de2a01af9ceb1cb9689b314a970b3 (patch)
treed28b63dd7073d821477ac59ac2032668de8cc03f /Year_2/OS/hw
parentf0e969bd2e954e31d6750cefb8691659248f7746 (diff)
os: add homework 6
Diffstat (limited to 'Year_2/OS/hw')
-rw-r--r--Year_2/OS/hw/hw6.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/Year_2/OS/hw/hw6.c b/Year_2/OS/hw/hw6.c
new file mode 100644
index 0000000..8c78b09
--- /dev/null
+++ b/Year_2/OS/hw/hw6.c
@@ -0,0 +1,123 @@
+/*
+ Homework n.6
+
+ Scrivere un programma che crei un processo figlio con cui scambiera' dati
+ tramite una coda di messaggi. Tale coda sara' creata dal padre e distrutta,
+ a fine lavori, dal figlio.
+
+ Il processo padre dovra' accettare comandi inseriti da tastiera (per semplicita'
+ senza parametri) e questi dovranno essere inviati al figlio che li eseguira'
+ di volta in volta creando dei processi nipoti: uno per ogni comando.
+
+ Il tutto si dovra' arrestare correttamente all'inserimento del comando
+ 'exit' sul padre.
+
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#define MTYPE 1
+
+struct msgbuf {
+ long mtype;
+ char mtext[1024];
+};
+
+void
+execute(int qid)
+{
+ pid_t pid;
+ struct msgbuf msg;
+ char command[1024];
+ int n;
+ char* p;
+
+ while (1) {
+ if (msgrcv(qid, (void*)&msg, sizeof(msg.mtext), MTYPE, 0) == -1) {
+ perror("msgrcv");
+ exit(1);
+ }
+
+ /* The variable `command` will be the substring of the passed string
+ * until the first space, ignoring all parameters */
+ n = 0;
+ p = msg.mtext;
+ while (*p != '\0') {
+ if (*p == ' ')
+ break;
+ n++;
+ p++;
+ }
+
+ strncpy(command, msg.mtext, n);
+ command[n] = '\0';
+
+ if (strcmp(command, "exit") == 0)
+ break;
+
+ pid = fork();
+ if (pid == -1) {
+ perror("fork");
+ exit(1);
+ }
+
+ if (pid == 0) {
+ execlp(command, "", NULL);
+ fprintf(stderr, "Error executing '%s'\n", command);
+ } else {
+ wait(NULL);
+ }
+ }
+
+ msgctl(qid, IPC_RMID, NULL);
+}
+
+int
+main()
+{
+ pid_t pid;
+ int qid;
+ int n;
+
+ if ((qid = msgget(IPC_PRIVATE, IPC_CREAT | 0644)) == -1) {
+ perror("msgget");
+ exit(1);
+ }
+
+ pid = fork();
+ if (pid == -1) {
+ perror("fork");
+ exit(1);
+ }
+
+ if (pid != 0) {
+ struct msgbuf msg;
+ msg.mtype = MTYPE;
+ do {
+ printf("Insert a command: ");
+ fgets(msg.mtext, 1024, stdin);
+ n = strlen(msg.mtext);
+ msg.mtext[n - 1] = '\0';
+
+ /* Ignore empty string */
+ if (strcmp(msg.mtext, "") == 0)
+ continue;
+
+ if (msgsnd(qid, (void*)&msg, sizeof(msg.mtext), IPC_NOWAIT) == -1) {
+ perror("msgsnd");
+ exit(1);
+ }
+ sleep(1);
+ } while (strcmp(msg.mtext, "exit") != 0);
+ } else {
+ execute(qid);
+ }
+
+ return 0;
+}