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