|
@@ -4,6 +4,7 @@
|
|
|
*
|
|
|
* Created on 9 novembre 2018
|
|
|
*/
|
|
|
+#define _POSIX_C_SOURCE 200112L
|
|
|
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
@@ -11,19 +12,30 @@
|
|
|
#include "error.h"
|
|
|
#include "str.h"
|
|
|
#include "parser.h"
|
|
|
-#include "mysh.h"
|
|
|
#include "execute.h"
|
|
|
+#include "ipc.h"
|
|
|
+#include "variable.h"
|
|
|
#include "command.h"
|
|
|
+#include "mysh.h"
|
|
|
|
|
|
/* --- Extern --- */
|
|
|
extern Error error;
|
|
|
extern pid_t last;
|
|
|
extern int status_cmd;
|
|
|
extern int result_cmd;
|
|
|
+extern char base_path[];
|
|
|
+extern pid_list pidlist;
|
|
|
char* cmdlist[] = {
|
|
|
"cd",
|
|
|
"exit",
|
|
|
"status",
|
|
|
+ "setenv",
|
|
|
+ "unsetenv",
|
|
|
+ "set",
|
|
|
+ "unset",
|
|
|
+ "myls",
|
|
|
+ "myps",
|
|
|
+ "myjobs",
|
|
|
NULL
|
|
|
};
|
|
|
boolean exitsh = false;
|
|
@@ -34,10 +46,18 @@ void ini_pid_list(pid_list* pl) {
|
|
|
pl->last = NULL;
|
|
|
}
|
|
|
|
|
|
-pid_node* add_pid(pid_list* pl, pid_t pid, int job) {
|
|
|
+pid_node* add_pid(pid_list* pl, pid_t pid, int job, char* cmd) {
|
|
|
+ int length;
|
|
|
+ //Creation noeud
|
|
|
pid_node* pn = malloc(sizeof (pid_node));
|
|
|
pn->pid = pid;
|
|
|
pn->job = job;
|
|
|
+ //Copie nom commande
|
|
|
+ length = strlen(cmd) + 1;
|
|
|
+ pn->cmd = malloc(sizeof(char) * length);
|
|
|
+ memset(pn->cmd, 0, length);
|
|
|
+ strncpy(pn->cmd, cmd, length - 1);
|
|
|
+ //Setup chainement
|
|
|
pn->next = NULL;
|
|
|
if (pl->first == NULL) {
|
|
|
pn->prev = NULL;
|
|
@@ -63,21 +83,22 @@ pid_node* search_pid(pid_list* pl, pid_t pid) {
|
|
|
}
|
|
|
|
|
|
void remove_pid(pid_list* pl, pid_node* pn) {
|
|
|
+ free(pn->cmd);
|
|
|
//Si 1er et seul
|
|
|
if (pn->prev == NULL && pn->next == NULL) {
|
|
|
pl->first = NULL;
|
|
|
pl->last = NULL;
|
|
|
- }
|
|
|
+ }
|
|
|
//Si 1er et non seul
|
|
|
else if (pn->prev == NULL && pn->next != NULL) {
|
|
|
pn->next->prev = NULL;
|
|
|
pl->first = pn->next;
|
|
|
- }
|
|
|
+ }
|
|
|
//Si dernier
|
|
|
else if (pn->next == NULL) {
|
|
|
pn->prev->next = NULL;
|
|
|
pl->last = pn->prev;
|
|
|
- }
|
|
|
+ }
|
|
|
//Sinon si il est au milieu
|
|
|
else {
|
|
|
pn->prev->next = pn->next;
|
|
@@ -91,6 +112,7 @@ void clean_pid(pid_list* pl) {
|
|
|
pid_node* tmp, * pn = pl->first;
|
|
|
while (pn != NULL) {
|
|
|
tmp = pn->next;
|
|
|
+ free(pn->cmd);
|
|
|
free(pn);
|
|
|
pn = tmp;
|
|
|
}
|
|
@@ -114,17 +136,52 @@ int launch_internal_command(Command* cmd) {
|
|
|
if (strncmp(cmd->name, cmdlist[0], length) == 0) {
|
|
|
result = cd(cmd->argc, cmd->argv);
|
|
|
return result;
|
|
|
- }
|
|
|
+ }
|
|
|
//exit
|
|
|
else if (strncmp(cmd->name, cmdlist[1], length) == 0) {
|
|
|
result = exit_sh(cmd->argc, cmd->argv);
|
|
|
return result;
|
|
|
- }
|
|
|
+ }
|
|
|
//status
|
|
|
else if (strncmp(cmd->name, cmdlist[2], length) == 0) {
|
|
|
result = status(cmd->argc, cmd->argv);
|
|
|
return result;
|
|
|
+ }
|
|
|
+ //setenv
|
|
|
+ else if (strncmp(cmd->name, cmdlist[3], length) == 0) {
|
|
|
+ result = set_env(cmd->argc, cmd->argv);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ //unsetenv
|
|
|
+ else if (strncmp(cmd->name, cmdlist[4], length) == 0) {
|
|
|
+ result = unset_env(cmd->argc, cmd->argv);
|
|
|
+ return result;
|
|
|
}
|
|
|
+ //set
|
|
|
+ else if (strncmp(cmd->name, cmdlist[5], length) == 0) {
|
|
|
+ result = set_local(cmd->argc, cmd->argv);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ //unset
|
|
|
+ else if (strncmp(cmd->name, cmdlist[6], length) == 0) {
|
|
|
+ result = unset_local(cmd->argc, cmd->argv);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ //myls
|
|
|
+ else if (strncmp(cmd->name, cmdlist[7], length) == 0) {
|
|
|
+ result = myls(cmd->argc, cmd->argv);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ //myps
|
|
|
+ else if (strncmp(cmd->name, cmdlist[8], length) == 0) {
|
|
|
+ result = myps(cmd->argc, cmd->argv);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ //myjobs
|
|
|
+ else if (strncmp(cmd->name, cmdlist[9], length) == 0) {
|
|
|
+ result = myjobs(cmd->argc, cmd->argv);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
//Aucune commande
|
|
|
else {
|
|
|
return SHELL_FAIL;
|
|
@@ -144,7 +201,7 @@ int cd(int argc, char** argv) {
|
|
|
addperror("Erreur chdir()");
|
|
|
return EXIT_FAILURE;
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
//Sinon on va dans le dossier indiqué par l'utilisateur
|
|
|
else {
|
|
|
if (chdir(argv[1]) == ERR) {
|
|
@@ -157,21 +214,188 @@ int cd(int argc, char** argv) {
|
|
|
//show_current_dir("current working directory is: ", "\n");
|
|
|
}
|
|
|
|
|
|
-int exit_sh(int argc, char** argv){
|
|
|
+int exit_sh(int argc, char** argv) {
|
|
|
exitsh = true;
|
|
|
return EXIT_SUCCESS;
|
|
|
}
|
|
|
|
|
|
-int status(int argc, char** argv){
|
|
|
- if(!(last != -1 && status_cmd != -1)){
|
|
|
+int status(int argc, char** argv) {
|
|
|
+ if (!(last != -1 && status_cmd != -1)) {
|
|
|
error.print("Aucune commande executée\n");
|
|
|
return EXIT_FAILURE;
|
|
|
}
|
|
|
//En fonction du status
|
|
|
- if(result_cmd == SHELL_FAIL){
|
|
|
+ if (result_cmd == SHELL_FAIL) {
|
|
|
printf("%d terminé anormalement\n", last);
|
|
|
} else {
|
|
|
printf("%d terminé avec comme code de retour %d\n", last, status_cmd);
|
|
|
}
|
|
|
return EXIT_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+int set_env(int argc, char** argv) {
|
|
|
+ char* str, * key, * val;
|
|
|
+ int length, pos = 0;
|
|
|
+ //Verif les arguments
|
|
|
+ if (argc < 2) {
|
|
|
+ show_shm_data();
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+ }
|
|
|
+ if (argc > 2) {
|
|
|
+ error.print("too many arguments : 1 required, %d given\n", argc - 1);
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ str = argv[1];
|
|
|
+ length = strlen(str);
|
|
|
+ //Verif que chaine est correcte
|
|
|
+ for (int i = 0; i < length; i++) {
|
|
|
+ if (str[i] == '=') {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pos++;
|
|
|
+ }
|
|
|
+ if (pos >= length - 1) {
|
|
|
+ error.print("Argument invalide : clef=valeur attendu, %s donnée\n", str);
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ //Decoupe la chaine
|
|
|
+ key = malloc(sizeof (char) * (pos + 1));
|
|
|
+ memset(key, 0, pos + 1);
|
|
|
+ strncpy(key, str, pos);
|
|
|
+ val = str + pos + 1;
|
|
|
+ //Ajoute la chaine en shm
|
|
|
+ if (!add_shm_data(str)) {
|
|
|
+ error.print("Erreur interne impossible d'ajouter la variable\n");
|
|
|
+ free(key);
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ //Ajoute sur le système
|
|
|
+ if (setenv(key, val, true) == ERR) {
|
|
|
+ addperror("Impossible d'ajouter la variable d'environnement");
|
|
|
+ error.print("Erreur interne impossible d'ajouter la variable\n");
|
|
|
+ free(key);
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ free(key);
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+int unset_env(int argc, char** argv) {
|
|
|
+ //Verif les arguments
|
|
|
+ if (argc < 2) {
|
|
|
+ error.print("too few arguments : 1 required, 0 given\n");
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ if (argc > 2) {
|
|
|
+ error.print("too many arguments : 1 required, %d given\n", argc - 1);
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ //Supprime de la shm
|
|
|
+ if (!remove_shm_data(argv[1])) {
|
|
|
+ error.print("Erreur interne impossible de supprimer la variable\n");
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ //Supprime du systeme
|
|
|
+ if (unsetenv(argv[1]) == ERR) {
|
|
|
+ addperror("Impossible de supprimer la variable d'environnement");
|
|
|
+ error.print("Erreur interne impossible de supprimer la variable\n");
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+int set_local(int argc, char** argv){
|
|
|
+ char* str;
|
|
|
+ int length, pos = 0;
|
|
|
+ //Verif les arguments
|
|
|
+ if (argc < 2) {
|
|
|
+ show_local_data();
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+ }
|
|
|
+ if (argc > 2) {
|
|
|
+ error.print("too many arguments : 1 required, %d given\n", argc - 1);
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ str = argv[1];
|
|
|
+ length = strlen(str);
|
|
|
+ //Verif que chaine est correcte
|
|
|
+ for (int i = 0; i < length; i++) {
|
|
|
+ if (str[i] == '=') {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pos++;
|
|
|
+ }
|
|
|
+ if (pos >= length - 1) {
|
|
|
+ error.print("Argument invalide : clef=valeur attendu, %s donnée\n", str);
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ //Ajoute la chaine en shm
|
|
|
+ if (!add_local_data(str)) {
|
|
|
+ error.print("Erreur interne impossible d'ajouter la variable\n");
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+int unset_local(int argc, char** argv){
|
|
|
+ //Verif les arguments
|
|
|
+ if (argc < 2) {
|
|
|
+ error.print("too few arguments : 1 required, 0 given\n");
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ if (argc > 2) {
|
|
|
+ error.print("too many arguments : 1 required, %d given\n", argc - 1);
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ //Supprime de la shm
|
|
|
+ if (!remove_local_data(argv[1])) {
|
|
|
+ error.print("Erreur interne impossible de supprimer la variable\n");
|
|
|
+ return EXIT_FAILURE;
|
|
|
+ }
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+int myls(int argc, char** argv){
|
|
|
+ //Preparation nom cmd
|
|
|
+ int length = strlen(base_path);
|
|
|
+ char* path = malloc(sizeof(char) * (length + 4 + 1));
|
|
|
+ memset(path, 0, length + 4 + 1);
|
|
|
+ strncpy(path, base_path, length);
|
|
|
+ path[length] = '/';
|
|
|
+ path[length + 1] = 'm';
|
|
|
+ path[length + 2] = 'y';
|
|
|
+ path[length + 3] = 'l';
|
|
|
+ path[length + 4] = 's';
|
|
|
+ //Execution
|
|
|
+ //return exec_file(path, argv);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int myps(int argc, char** argv){
|
|
|
+ //Preparation nom cmd
|
|
|
+ int length = strlen(base_path);
|
|
|
+ char* path = malloc(sizeof(char) * (length + 4 + 1));
|
|
|
+ memset(path, 0, length + 4 + 1);
|
|
|
+ strncpy(path, base_path, length);
|
|
|
+ path[length] = '/';
|
|
|
+ path[length + 1] = 'm';
|
|
|
+ path[length + 2] = 'y';
|
|
|
+ path[length + 3] = 'p';
|
|
|
+ path[length + 4] = 's';
|
|
|
+ //Execution
|
|
|
+ //return exec_file(path, argv);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int myjobs(int argc, char** argv){
|
|
|
+ pid_node* pn = pidlist.first;
|
|
|
+ if(pn == NULL){
|
|
|
+ printf("Aucun job\n");
|
|
|
+ return EXIT_SUCCESS;
|
|
|
+ }
|
|
|
+ while(pn != NULL){
|
|
|
+ printf("[%d] %d En cours %s\n", pn->job, pn->pid, pn->cmd);
|
|
|
+ pn = pn->next;
|
|
|
+ }
|
|
|
+ return EXIT_SUCCESS;
|
|
|
}
|