save
This commit is contained in:
parent
4b500002f6
commit
db5b7a582d
30
jobs.c
30
jobs.c
|
@ -3,14 +3,13 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "jobs.h"
|
#include "jobs.h"
|
||||||
|
|
||||||
void ajouter(list *l_ptr, int pid, int id, char** seq)
|
void ajouter(list *l_ptr, int pid, int id, char **seq)
|
||||||
{
|
{
|
||||||
|
|
||||||
cell* new_cell = malloc(sizeof(*new_cell));
|
cell *new_cell = malloc(sizeof(*new_cell));
|
||||||
|
|
||||||
|
char *cmd;
|
||||||
char* cmd;
|
cmd = malloc(sizeof(char) * 256);
|
||||||
cmd = malloc(sizeof(char)*256);
|
|
||||||
cmd[0] = '\0';
|
cmd[0] = '\0';
|
||||||
|
|
||||||
while (*seq)
|
while (*seq)
|
||||||
|
@ -35,7 +34,7 @@ void ajouter(list *l_ptr, int pid, int id, char** seq)
|
||||||
|
|
||||||
*l_ptr = new_cell;
|
*l_ptr = new_cell;
|
||||||
|
|
||||||
printf("[%d] %d\n", id, pid);
|
printf("[%d] %d %s\n", id, pid, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void supprimer(list *l_ptr, int pid)
|
void supprimer(list *l_ptr, int pid)
|
||||||
|
@ -47,6 +46,7 @@ void supprimer(list *l_ptr, int pid)
|
||||||
{
|
{
|
||||||
cell *cursor2free = cursor;
|
cell *cursor2free = cursor;
|
||||||
*l_ptr = cursor->next;
|
*l_ptr = cursor->next;
|
||||||
|
printf("[%d] (%d) done: %s\n", cursor->id, cursor->pid, cursor->cmd);
|
||||||
free(cursor2free);
|
free(cursor2free);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -63,6 +63,7 @@ void supprimer(list *l_ptr, int pid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell *cursor_next = cursor->next->next;
|
cell *cursor_next = cursor->next->next;
|
||||||
|
printf("[%d] (%d) done: %s\n", cursor->id, cursor->pid, cursor->cmd);
|
||||||
free(cursor->next);
|
free(cursor->next);
|
||||||
cursor->next = cursor_next;
|
cursor->next = cursor_next;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +99,6 @@ int est_vide(list l_ptr)
|
||||||
|
|
||||||
int contiens(list *l_ptr, int pid)
|
int contiens(list *l_ptr, int pid)
|
||||||
{
|
{
|
||||||
|
|
||||||
cell *cursor = *l_ptr;
|
cell *cursor = *l_ptr;
|
||||||
|
|
||||||
while (cursor != NULL)
|
while (cursor != NULL)
|
||||||
|
@ -112,3 +112,19 @@ int contiens(list *l_ptr, int pid)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cell *trouver(list *l_ptr, int pid)
|
||||||
|
{
|
||||||
|
cell *cursor = *l_ptr;
|
||||||
|
|
||||||
|
while (cursor != NULL)
|
||||||
|
{
|
||||||
|
if (cursor->pid == pid)
|
||||||
|
{
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
cursor = cursor->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL; // erreur
|
||||||
|
}
|
23
jobs.h
23
jobs.h
|
@ -2,21 +2,22 @@
|
||||||
#define __JOBS_H
|
#define __JOBS_H
|
||||||
|
|
||||||
typedef struct cell cell;
|
typedef struct cell cell;
|
||||||
struct cell {
|
struct cell
|
||||||
|
{
|
||||||
int id;
|
int id;
|
||||||
int pid;
|
int pid;
|
||||||
char* cmd;
|
char *cmd;
|
||||||
cell* next;
|
cell *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef cell* list;
|
typedef cell *list;
|
||||||
|
|
||||||
void ajouter(cell** list, int pid, int id, char** cmd);
|
void ajouter(cell **list, int pid, int id, char **cmd);
|
||||||
void supprimer(cell** list, int pid);
|
void supprimer(cell **list, int pid);
|
||||||
void afficher(cell** list);
|
void afficher(cell **list);
|
||||||
void initialiser(list* list);
|
void initialiser(list *list);
|
||||||
void liberer(list* list);
|
void liberer(list *list);
|
||||||
int contiens(list* l_ptr, int pid);
|
int contiens(list *l_ptr, int pid);
|
||||||
cell* trouver(list* l_ptr, int pid);
|
cell *trouver(list *l_ptr, int pid);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -15,6 +15,7 @@ int prompting = 0;
|
||||||
int job_id = 1;
|
int job_id = 1;
|
||||||
list jobs;
|
list jobs;
|
||||||
pid_t pidFils;
|
pid_t pidFils;
|
||||||
|
struct cmdline *cmd;
|
||||||
|
|
||||||
jmp_buf start;
|
jmp_buf start;
|
||||||
|
|
||||||
|
@ -27,8 +28,6 @@ void handler_print(int signal_num, siginfo_t *info)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: trouver id, cmd... à partir pid
|
|
||||||
printf("[%d] --> (%d) %s\n", info->si_pid, signal_num, strsignal(signal_num));
|
|
||||||
supprimer(&jobs, info->si_pid);
|
supprimer(&jobs, info->si_pid);
|
||||||
job_id--;
|
job_id--;
|
||||||
|
|
||||||
|
@ -50,7 +49,7 @@ void handler_stop(int signal_num, siginfo_t *info)
|
||||||
if (!prompting)
|
if (!prompting)
|
||||||
{
|
{
|
||||||
kill(pidFils, SIGTSTP);
|
kill(pidFils, SIGTSTP);
|
||||||
//ajouter(&jobs, pidFils, job_id++, cmd);
|
ajouter(&jobs, pidFils, job_id++, *(cmd->seq));
|
||||||
siglongjmp(start, signal_num);
|
siglongjmp(start, signal_num);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -93,7 +92,7 @@ int main(int argc, char *argv[])
|
||||||
printf("%s >>> ", currentcd);
|
printf("%s >>> ", currentcd);
|
||||||
|
|
||||||
prompting = 1;
|
prompting = 1;
|
||||||
struct cmdline *cmd = readcmd();
|
cmd = readcmd();
|
||||||
prompting = 0;
|
prompting = 0;
|
||||||
|
|
||||||
if (cmd == NULL)
|
if (cmd == NULL)
|
||||||
|
|
127
readcmd.c
127
readcmd.c
|
@ -14,7 +14,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "readcmd.h"
|
#include "readcmd.h"
|
||||||
|
|
||||||
|
|
||||||
static void memory_error(void)
|
static void memory_error(void)
|
||||||
{
|
{
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
|
@ -22,49 +21,52 @@ static void memory_error(void)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *xmalloc(size_t size)
|
static void *xmalloc(size_t size)
|
||||||
{
|
{
|
||||||
void *p = malloc(size);
|
void *p = malloc(size);
|
||||||
if (!p) memory_error();
|
if (!p)
|
||||||
|
memory_error();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *xrealloc(void *ptr, size_t size)
|
static void *xrealloc(void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
void *p = realloc(ptr, size);
|
void *p = realloc(ptr, size);
|
||||||
if (!p) memory_error();
|
if (!p)
|
||||||
|
memory_error();
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Read a line from standard input and put it in a char[] */
|
/* Read a line from standard input and put it in a char[] */
|
||||||
static char *readline(void)
|
static char *readline(void)
|
||||||
{
|
{
|
||||||
size_t buf_len = 16;
|
size_t buf_len = 16;
|
||||||
char *buf = xmalloc(buf_len * sizeof(char));
|
char *buf = xmalloc(buf_len * sizeof(char));
|
||||||
|
|
||||||
if (fgets(buf, buf_len, stdin) == NULL) {
|
if (fgets(buf, buf_len, stdin) == NULL)
|
||||||
|
{
|
||||||
free(buf);
|
free(buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
size_t l = strlen(buf);
|
size_t l = strlen(buf);
|
||||||
if ((l > 0) && (buf[l-1] == '\n')) {
|
if ((l > 0) && (buf[l - 1] == '\n'))
|
||||||
|
{
|
||||||
l--;
|
l--;
|
||||||
buf[l] = 0;
|
buf[l] = 0;
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
if (buf_len >= (INT_MAX / 2)) memory_error();
|
if (buf_len >= (INT_MAX / 2))
|
||||||
|
memory_error();
|
||||||
buf_len *= 2;
|
buf_len *= 2;
|
||||||
buf = xrealloc(buf, buf_len * sizeof(char));
|
buf = xrealloc(buf, buf_len * sizeof(char));
|
||||||
if (fgets(buf + l, buf_len - l, stdin) == NULL) return buf;
|
if (fgets(buf + l, buf_len - l, stdin) == NULL)
|
||||||
|
return buf;
|
||||||
} while (1);
|
} while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Split the string in words, according to the simple shell grammar. */
|
/* Split the string in words, according to the simple shell grammar. */
|
||||||
static char **split_in_words(char *line)
|
static char **split_in_words(char *line)
|
||||||
{
|
{
|
||||||
|
@ -73,10 +75,12 @@ static char **split_in_words(char *line)
|
||||||
size_t l = 0;
|
size_t l = 0;
|
||||||
char c;
|
char c;
|
||||||
|
|
||||||
while ((c = *cur) != 0) {
|
while ((c = *cur) != 0)
|
||||||
|
{
|
||||||
char *w = 0;
|
char *w = 0;
|
||||||
char *start;
|
char *start;
|
||||||
switch (c) {
|
switch (c)
|
||||||
|
{
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\t':
|
case '\t':
|
||||||
/* Ignore any whitespace */
|
/* Ignore any whitespace */
|
||||||
|
@ -101,9 +105,11 @@ static char **split_in_words(char *line)
|
||||||
default:
|
default:
|
||||||
/* Another word */
|
/* Another word */
|
||||||
start = cur;
|
start = cur;
|
||||||
while (c) {
|
while (c)
|
||||||
|
{
|
||||||
c = *++cur;
|
c = *++cur;
|
||||||
switch (c) {
|
switch (c)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\t':
|
case '\t':
|
||||||
|
@ -113,14 +119,15 @@ static char **split_in_words(char *line)
|
||||||
case '&':
|
case '&':
|
||||||
c = 0;
|
c = 0;
|
||||||
break;
|
break;
|
||||||
default: ;
|
default:;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w = xmalloc((cur - start + 1) * sizeof(char));
|
w = xmalloc((cur - start + 1) * sizeof(char));
|
||||||
strncpy(w, start, cur - start);
|
strncpy(w, start, cur - start);
|
||||||
w[cur - start] = 0;
|
w[cur - start] = 0;
|
||||||
}
|
}
|
||||||
if (w) {
|
if (w)
|
||||||
|
{
|
||||||
tab = xrealloc(tab, (l + 1) * sizeof(char *));
|
tab = xrealloc(tab, (l + 1) * sizeof(char *));
|
||||||
tab[l++] = w;
|
tab[l++] = w;
|
||||||
}
|
}
|
||||||
|
@ -130,31 +137,33 @@ static char **split_in_words(char *line)
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void freeseq(char ***seq)
|
static void freeseq(char ***seq)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
for (i=0; seq[i]!=0; i++) {
|
for (i = 0; seq[i] != 0; i++)
|
||||||
|
{
|
||||||
char **cmd = seq[i];
|
char **cmd = seq[i];
|
||||||
|
|
||||||
for (j=0; cmd[j]!=0; j++) free(cmd[j]);
|
for (j = 0; cmd[j] != 0; j++)
|
||||||
|
free(cmd[j]);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
}
|
}
|
||||||
free(seq);
|
free(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Free the fields of the structure but not the structure itself */
|
/* Free the fields of the structure but not the structure itself */
|
||||||
static void freecmd(struct cmdline *s)
|
static void freecmd(struct cmdline *s)
|
||||||
{
|
{
|
||||||
if (s->in) free(s->in);
|
if (s->in)
|
||||||
if (s->out) free(s->out);
|
free(s->in);
|
||||||
// if (s->backgrounded) free(s->backgrounded);
|
if (s->out)
|
||||||
if (s->seq) freeseq(s->seq);
|
free(s->out);
|
||||||
|
// if (s->backgrounded) free(s->backgrounded);
|
||||||
|
if (s->seq)
|
||||||
|
freeseq(s->seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct cmdline *readcmd(void)
|
struct cmdline *readcmd(void)
|
||||||
{
|
{
|
||||||
static struct cmdline *static_cmdline = 0;
|
static struct cmdline *static_cmdline = 0;
|
||||||
|
@ -168,8 +177,10 @@ struct cmdline *readcmd(void)
|
||||||
size_t cmd_len, seq_len;
|
size_t cmd_len, seq_len;
|
||||||
|
|
||||||
line = readline();
|
line = readline();
|
||||||
if (line == NULL) {
|
if (line == NULL)
|
||||||
if (s) {
|
{
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
freecmd(s);
|
freecmd(s);
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
@ -197,22 +208,27 @@ struct cmdline *readcmd(void)
|
||||||
s->seq = 0;
|
s->seq = 0;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while ((w = words[i++]) != 0) {
|
while ((w = words[i++]) != 0)
|
||||||
switch (w[0]) {
|
{
|
||||||
|
switch (w[0])
|
||||||
|
{
|
||||||
case '&':
|
case '&':
|
||||||
if(s->backgrounded){
|
if (s->backgrounded)
|
||||||
s->err = "error on &";
|
{
|
||||||
goto error;
|
s->err = "error on &";
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
s->backgrounded = &w[0];
|
s->backgrounded = &w[0];
|
||||||
break;
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
/* Tricky : the word can only be "<" */
|
/* Tricky : the word can only be "<" */
|
||||||
if (s->in) {
|
if (s->in)
|
||||||
|
{
|
||||||
s->err = "only one input file supported";
|
s->err = "only one input file supported";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (words[i] == 0) {
|
if (words[i] == 0)
|
||||||
|
{
|
||||||
s->err = "filename missing for input redirection";
|
s->err = "filename missing for input redirection";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -220,11 +236,13 @@ struct cmdline *readcmd(void)
|
||||||
break;
|
break;
|
||||||
case '>':
|
case '>':
|
||||||
/* Tricky : the word can only be ">" */
|
/* Tricky : the word can only be ">" */
|
||||||
if (s->out) {
|
if (s->out)
|
||||||
|
{
|
||||||
s->err = "only one output file supported";
|
s->err = "only one output file supported";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (words[i] == 0) {
|
if (words[i] == 0)
|
||||||
|
{
|
||||||
s->err = "filename missing for output redirection";
|
s->err = "filename missing for output redirection";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -232,7 +250,8 @@ struct cmdline *readcmd(void)
|
||||||
break;
|
break;
|
||||||
case '|':
|
case '|':
|
||||||
/* Tricky : the word can only be "|" */
|
/* Tricky : the word can only be "|" */
|
||||||
if (cmd_len == 0) {
|
if (cmd_len == 0)
|
||||||
|
{
|
||||||
s->err = "misplaced pipe";
|
s->err = "misplaced pipe";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -252,22 +271,28 @@ struct cmdline *readcmd(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd_len != 0) {
|
if (cmd_len != 0)
|
||||||
|
{
|
||||||
seq = xrealloc(seq, (seq_len + 2) * sizeof(char **));
|
seq = xrealloc(seq, (seq_len + 2) * sizeof(char **));
|
||||||
seq[seq_len++] = cmd;
|
seq[seq_len++] = cmd;
|
||||||
seq[seq_len] = 0;
|
seq[seq_len] = 0;
|
||||||
} else if (seq_len != 0) {
|
}
|
||||||
|
else if (seq_len != 0)
|
||||||
|
{
|
||||||
s->err = "misplaced pipe";
|
s->err = "misplaced pipe";
|
||||||
i--;
|
i--;
|
||||||
goto error;
|
goto error;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
free(cmd);
|
free(cmd);
|
||||||
free(words);
|
free(words);
|
||||||
s->seq = seq;
|
s->seq = seq;
|
||||||
return s;
|
return s;
|
||||||
error:
|
error:
|
||||||
while ((w = words[i++]) != 0) {
|
while ((w = words[i++]) != 0)
|
||||||
switch (w[0]) {
|
{
|
||||||
|
switch (w[0])
|
||||||
|
{
|
||||||
case '<':
|
case '<':
|
||||||
case '>':
|
case '>':
|
||||||
case '|':
|
case '|':
|
||||||
|
@ -279,18 +304,22 @@ error:
|
||||||
}
|
}
|
||||||
free(words);
|
free(words);
|
||||||
freeseq(seq);
|
freeseq(seq);
|
||||||
for (i=0; cmd[i]!=0; i++) free(cmd[i]);
|
for (i = 0; cmd[i] != 0; i++)
|
||||||
|
free(cmd[i]);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
if (s->in) {
|
if (s->in)
|
||||||
|
{
|
||||||
free(s->in);
|
free(s->in);
|
||||||
s->in = 0;
|
s->in = 0;
|
||||||
}
|
}
|
||||||
if (s->out) {
|
if (s->out)
|
||||||
|
{
|
||||||
free(s->out);
|
free(s->out);
|
||||||
s->out = 0;
|
s->out = 0;
|
||||||
}
|
}
|
||||||
if (s->backgrounded) {
|
if (s->backgrounded)
|
||||||
// free(s->backgrounded);
|
{
|
||||||
|
// free(s->backgrounded);
|
||||||
s->out = 0;
|
s->out = 0;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
|
|
11
readcmd.h
11
readcmd.h
|
@ -14,13 +14,14 @@ struct cmdline *readcmd(void);
|
||||||
* - en cas d'appels successifs,
|
* - en cas d'appels successifs,
|
||||||
* readcmd() réutilise la mémoire allouée à la structure cmdline qu'elle retourne
|
* readcmd() réutilise la mémoire allouée à la structure cmdline qu'elle retourne
|
||||||
*/
|
*/
|
||||||
struct cmdline {
|
struct cmdline
|
||||||
char *err; /* Si non null : message d'erreur à afficher.
|
{
|
||||||
|
char *err; /* Si non null : message d'erreur à afficher.
|
||||||
* Dans ce cas, les autres champs sont nuls. */
|
* Dans ce cas, les autres champs sont nuls. */
|
||||||
char *in; /* Si non null : nom du fichier vers lequel l'entrée doit être redirigée. */
|
char *in; /* Si non null : nom du fichier vers lequel l'entrée doit être redirigée. */
|
||||||
char *out; /* Si non null : nom du fichier vers lequel la sortie doit être redirigée. */
|
char *out; /* Si non null : nom du fichier vers lequel la sortie doit être redirigée. */
|
||||||
char *backgrounded; /* Si non null : commande en tâche de fond */
|
char *backgrounded; /* Si non null : commande en tâche de fond */
|
||||||
char ***seq; /* Une ligne de commande est une suite de commandes liées par des tubes
|
char ***seq; /* Une ligne de commande est une suite de commandes liées par des tubes
|
||||||
* Ainsi,
|
* Ainsi,
|
||||||
* - une commande est un tableau de chaînes de caractères (char **).
|
* - une commande est un tableau de chaînes de caractères (char **).
|
||||||
* Chaque élément de ce tableau est en effet une chaîne (char *)
|
* Chaque élément de ce tableau est en effet une chaîne (char *)
|
||||||
|
|
Loading…
Reference in a new issue