From 86705308b1c0c5f51f9e53acf96b7a48cf2ea19c Mon Sep 17 00:00:00 2001 From: Santiago Lo Coco Date: Sun, 31 Oct 2021 19:45:18 -0300 Subject: [PATCH] Fix bugs and add more features Co-authored-by: Ezequiel Bellver Co-authored-by: Juan Barmasch --- Kernel/include/pipe.h | 4 +- Kernel/include/pipeLib.h | 1 + Kernel/include/scheduler.h | 1 + Kernel/include/semLib.h | 1 + Kernel/interruptions/systemCallsDispatcher.c | 2 + Kernel/tests/test_prio.c | 107 ++++++++++++++++++ Kernel/tests/test_processes.c | 101 +++++++++++++++++ Kernel/tests/test_sync.c | 84 ++++++++++++++ Kernel/utils/pipe.c | 62 ++++++++++ Kernel/utils/scheduler.c | 77 ++++++++++--- Kernel/utils/sem.c | 25 ++-- Userland/SampleCodeModule/asm/libasm.asm | 17 ++- Userland/SampleCodeModule/bottler/bottler.c | 2 +- Userland/SampleCodeModule/sampleCodeModule.c | 3 +- .../SampleCodeModule/shell/commands/block.c | 5 +- .../SampleCodeModule/shell/commands/clear.c | 3 +- .../SampleCodeModule/shell/commands/filter.c | 13 +++ .../SampleCodeModule/shell/commands/kill.c | 5 +- .../SampleCodeModule/shell/commands/loop.c | 15 ++- .../SampleCodeModule/shell/commands/pipes.c | 10 ++ .../SampleCodeModule/shell/include/pipes.h | 6 + Userland/SampleCodeModule/shell/shell.c | 79 ++++++++----- 22 files changed, 554 insertions(+), 69 deletions(-) create mode 100644 Kernel/tests/test_prio.c create mode 100644 Kernel/tests/test_processes.c create mode 100644 Kernel/tests/test_sync.c create mode 100644 Userland/SampleCodeModule/shell/commands/pipes.c create mode 100644 Userland/SampleCodeModule/shell/include/pipes.h diff --git a/Kernel/include/pipe.h b/Kernel/include/pipe.h index ffb756d..e63dea5 100644 --- a/Kernel/include/pipe.h +++ b/Kernel/include/pipe.h @@ -9,8 +9,10 @@ #include "memManager.h" #include "pipeLib.h" -#define MAX_SEM 100 +#define MAX_PIPES 100 #define SEM_NAME "Pipes" +#define PIPE_DATA_MAX_SIZE 100 +#define MAX_PIDS_SIZE 50 int exists(pipe_t * pipe); node_t * searchPipe(node_t ** previous, int fd); diff --git a/Kernel/include/pipeLib.h b/Kernel/include/pipeLib.h index a175031..1e215d6 100644 --- a/Kernel/include/pipeLib.h +++ b/Kernel/include/pipeLib.h @@ -23,5 +23,6 @@ typedef struct node_t { char openPipe(int * fds, char * name); void writePipe(int fd, char c); char readPipe(int fd); +char * pipes(); #endif \ No newline at end of file diff --git a/Kernel/include/scheduler.h b/Kernel/include/scheduler.h index e032841..83e19f1 100644 --- a/Kernel/include/scheduler.h +++ b/Kernel/include/scheduler.h @@ -26,5 +26,6 @@ void newProcess(processADT process, char * name, char priority, char foreground, uint64_t nextProcess(); char updateRSP(uint64_t newRsp); char getProcessData(char * out, processADT proc); +processADT searchProcess(processADT * previous, int pid, processADT first); #endif \ No newline at end of file diff --git a/Kernel/include/semLib.h b/Kernel/include/semLib.h index 237d9c2..e8105f0 100644 --- a/Kernel/include/semLib.h +++ b/Kernel/include/semLib.h @@ -21,5 +21,6 @@ char semClose(sem_t * sem); void semWait(sem_t * sem); void semPost(sem_t * sem); char * getSems(); +char * getEntering(sem_t * sem); #endif \ No newline at end of file diff --git a/Kernel/interruptions/systemCallsDispatcher.c b/Kernel/interruptions/systemCallsDispatcher.c index 49a7619..a452adc 100644 --- a/Kernel/interruptions/systemCallsDispatcher.c +++ b/Kernel/interruptions/systemCallsDispatcher.c @@ -63,6 +63,8 @@ uint64_t systemCallsDispatcher(uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_ return unblock(rsi); case 21: return wait(); + case 22: + return pipes(); default: return -1; } diff --git a/Kernel/tests/test_prio.c b/Kernel/tests/test_prio.c new file mode 100644 index 0000000..e660008 --- /dev/null +++ b/Kernel/tests/test_prio.c @@ -0,0 +1,107 @@ +// #include +// #include + +// #define MINOR_WAIT 1000000 // TODO: To prevent a process from flooding the screen +// #define WAIT 10000000 // TODO: Long enough to see theese processes beeing run at least twice + +// uint64_t my_getpid(){ +// return 0; +// } + +// uint64_t my_create_process(char * name){ +// return 0; +// } + +// uint64_t my_nice(uint64_t pid, uint64_t newPrio){ +// return 0; +// } + +// uint64_t my_kill(uint64_t pid){ +// return 0; +// } + +// uint64_t my_block(uint64_t pid){ +// return 0; +// } + +// uint64_t my_unblock(uint64_t pid){ +// return 0; +// } + +// void bussy_wait(uint64_t n){ +// uint64_t i; +// for (i = 0; i < n; i++); +// } + +// void endless_loop(){ +// uint64_t pid = my_getpid(); + +// while(1){ +// printf("%d ",pid); +// bussy_wait(MINOR_WAIT); +// } +// } + +// #define TOTAL_PROCESSES 3 + +// void test_prio(){ +// uint64_t pids[TOTAL_PROCESSES]; +// uint64_t i; + +// for(i = 0; i < TOTAL_PROCESSES; i++) +// pids[i] = my_create_process("endless_loop"); + +// bussy_wait(WAIT); +// printf("\nCHANGING PRIORITIES...\n"); + +// for(i = 0; i < TOTAL_PROCESSES; i++){ +// switch (i % 3){ +// case 0: +// my_nice(pids[i], 0); //lowest priority +// break; +// case 1: +// my_nice(pids[i], 1); //medium priority +// break; +// case 2: +// my_nice(pids[i], 2); //highest priority +// break; +// } +// } + +// bussy_wait(WAIT); +// printf("\nBLOCKING...\n"); + +// for(i = 0; i < TOTAL_PROCESSES; i++) +// my_block(pids[i]); + +// printf("CHANGING PRIORITIES WHILE BLOCKED...\n"); +// for(i = 0; i < TOTAL_PROCESSES; i++){ +// switch (i % 3){ +// case 0: +// my_nice(pids[i], 1); //medium priority +// break; +// case 1: +// my_nice(pids[i], 1); //medium priority +// break; +// case 2: +// my_nice(pids[i], 1); //medium priority +// break; +// } +// } + +// printf("UNBLOCKING...\n"); + +// for(i = 0; i < TOTAL_PROCESSES; i++) +// my_unblock(pids[i]); + +// bussy_wait(WAIT); +// printf("\nKILLING...\n"); + +// for(i = 0; i < TOTAL_PROCESSES; i++) +// my_kill(pids[i]); +// } + +// int main(){ +// test_prio(); +// return 0; +// } diff --git a/Kernel/tests/test_processes.c b/Kernel/tests/test_processes.c new file mode 100644 index 0000000..e89b577 --- /dev/null +++ b/Kernel/tests/test_processes.c @@ -0,0 +1,101 @@ +// #include +// #include "test_util.h" + +// //TO BE INCLUDED +// void endless_loop(){ +// while(1); +// } + +// uint32_t my_create_process(char * name){ +// return 0; +// } + +// uint32_t my_kill(uint32_t pid){ +// return 0; +// } + +// uint32_t my_block(uint32_t pid){ +// return 0; +// } + +// uint32_t my_unblock(uint32_t pid){ +// return 0; +// } + +// #define MAX_PROCESSES 10 //Should be around 80% of the the processes handled by the kernel + +// enum State {ERROR, RUNNING, BLOCKED, KILLED}; + +// typedef struct P_rq{ +// uint32_t pid; +// enum State state; +// }p_rq; + +// void test_processes(){ +// p_rq p_rqs[MAX_PROCESSES]; +// uint8_t rq; +// uint8_t alive = 0; +// uint8_t action; + +// while (1){ + +// // Create MAX_PROCESSES processes +// for(rq = 0; rq < MAX_PROCESSES; rq++){ +// p_rqs[rq].pid = my_create_process("endless_loop"); // TODO: Port this call as required + +// if (p_rqs[rq].pid == -1){ // TODO: Port this as required +// printf("Error creating process\n"); // TODO: Port this as required +// return; +// }else{ +// p_rqs[rq].state = RUNNING; +// alive++; +// } +// } + +// // Randomly kills, blocks or unblocks processes until every one has been killed +// while (alive > 0){ + +// for(rq = 0; rq < MAX_PROCESSES; rq++){ +// action = GetUniform(2) % 2; + +// switch(action){ +// case 0: +// if (p_rqs[rq].state == RUNNING || p_rqs[rq].state == BLOCKED){ +// if (my_kill(p_rqs[rq].pid) == -1){ // TODO: Port this as required +// printf("Error killing process\n"); // TODO: Port this as required +// return; +// } +// p_rqs[rq].state = KILLED; +// alive--; +// } +// break; + +// case 1: +// if (p_rqs[rq].state == RUNNING){ +// if(my_block(p_rqs[rq].pid) == -1){ // TODO: Port this as required +// printf("Error blocking process\n"); // TODO: Port this as required +// return; +// } +// p_rqs[rq].state = BLOCKED; +// } +// break; +// } +// } + +// // Randomly unblocks processes +// for(rq = 0; rq < MAX_PROCESSES; rq++) +// if (p_rqs[rq].state == BLOCKED && GetUniform(2) % 2){ +// if(my_unblock(p_rqs[rq].pid) == -1){ // TODO: Port this as required +// printf("Error unblocking process\n"); // TODO: Port this as required +// return; +// } +// p_rqs[rq].state = RUNNING; +// } +// } +// } +// } + +// int main(){ +// test_processes(); +// return 0; +// } diff --git a/Kernel/tests/test_sync.c b/Kernel/tests/test_sync.c new file mode 100644 index 0000000..d174e44 --- /dev/null +++ b/Kernel/tests/test_sync.c @@ -0,0 +1,84 @@ +// #include +// #include + +// uint64_t my_create_process(char * name){ +// return 0; +// } + +// uint64_t my_sem_open(char *sem_id, uint64_t initialValue){ +// return 0; +// } + +// uint64_t my_sem_wait(char *sem_id){ +// return 0; +// } + +// uint64_t my_sem_post(char *sem_id){ +// return 0; +// } + +// uint64_t my_sem_close(char *sem_id){ +// return 0; +// } + +// #define TOTAL_PAIR_PROCESSES 2 +// #define SEM_ID "sem" + +// int64_t global; //shared memory + +// void slowInc(int64_t *p, int64_t inc){ +// int64_t aux = *p; +// aux += inc; +// yield(); +// *p = aux; +// } + +// void inc(uint64_t sem, int64_t value, uint64_t N){ +// uint64_t i; + +// if (sem && !my_sem_open(SEM_ID, 1)){ +// printf("ERROR OPENING SEM\n"); +// return; +// } + +// for (i = 0; i < N; i++){ +// if (sem) my_sem_wait(SEM_ID); +// slowInc(&global, value); +// if (sem) my_sem_post(SEM_ID); +// } + +// if (sem) my_sem_close(SEM_ID); + +// printf("Final value: %d\n", global); +// } + +// void test_sync(){ +// uint64_t i; + +// global = 0; + +// printf("CREATING PROCESSES...(WITH SEM)\n"); + +// for(i = 0; i < TOTAL_PAIR_PROCESSES; i++){ +// my_create_process("inc", 1, 1, 1000000); +// my_create_process("inc", 1, -1, 1000000); +// } +// } + +// void test_no_sync(){ +// uint64_t i; + +// global = 0; + +// printf("CREATING PROCESSES...(WITHOUT SEM)\n"); + +// for(i = 0; i < TOTAL_PAIR_PROCESSES; i++){ +// my_create_process("inc", 0, 1, 1000000); +// my_create_process("inc", 0, -1, 1000000); +// } +// } + +// int main(){ +// test_sync(); +// return 0; +// } diff --git a/Kernel/utils/pipe.c b/Kernel/utils/pipe.c index c3b74cc..d6fecfb 100644 --- a/Kernel/utils/pipe.c +++ b/Kernel/utils/pipe.c @@ -120,4 +120,66 @@ void closePipe(int fd) { vPortFree(del->pipe->buffer); vPortFree(del->pipe); vPortFree(del); +} + +void getGenPipeData(char ** out, char * written, char toAdd, char * in, char isLast) { + char copied = strcpy(*out, in); + *out += copied; + *out += addSpaces(*out, toAdd - copied); + *written += toAdd; + if (!isLast) { + *out += addSpaces(*out, 2); + *written += 2; + } +} + +char getPipeData(char * out, node_t * node) { + if (node == NULL) + return EXIT_FAILURE; + + char written = 0; + + char flag = 0; + for (int j = 0; j < MAX_NAME_SIZE; j++) { + if (!flag && node->pipe->name[j] == 0) + flag = 1; + else if (flag) + out += addSpaces(out, 1); + else + *out++ = node->pipe->name[j]; + } + written += MAX_NAME_SIZE; + + out += addSpaces(out, 2); + written += 2; + + char buffer[10]; + getGenPipeData(&out, &written, MAX_ATTR_SIZE, itoa(node->pipe->fd[0], buffer, 10, 2), 0); + getGenPipeData(&out, &written, MAX_ATTR_SIZE, itoa(node->pipe->fd[1], buffer, 16, 10), 0); + char * aux = getEntering(node->pipe->sem); + getGenPipeData(&out, &written, MAX_PIDS_SIZE, aux, 1); + vPortFree(aux); + + return written; +} + +char * pipes(){ + char * ans = pvPortMalloc((fdIndex / 2) * PIPE_DATA_MAX_SIZE); + char * ret = ans; + + char * info = "name fdIn fdOut pids\n"; + ans += strcpy(ans, info); + + node_t * aux = firstPipe; + while (aux != NULL) { + char writtenChars = getPipeData(ans, aux); + if (writtenChars == EXIT_FAILURE) + return NULL; + ans += writtenChars - 1; + *ans++ = '\n'; + aux = aux->next; + } + *--ans = 0; + + return ret; } \ No newline at end of file diff --git a/Kernel/utils/scheduler.c b/Kernel/utils/scheduler.c index 7385f8a..7f02e47 100644 --- a/Kernel/utils/scheduler.c +++ b/Kernel/utils/scheduler.c @@ -41,7 +41,23 @@ static int pids = IDLE_PID; static char update = 1; static char idleFlag = 2; -void removeProcess(processCDT * del, processCDT * prev, processCDT ** first, processCDT ** last) { +// void removeProcessIzElOrishinal(processCDT * del, processCDT * prev, processCDT ** first, processCDT ** last) { +// if (prev == NULL) { +// *first = del->next; +// if (*last == del) +// *last = NULL; +// } +// else { +// prev->next = del->next; +// if (*last == del) +// *last = prev; +// } +// } + +void removeProcess(processCDT * del, processCDT ** first, processCDT ** last) { + processCDT * prev = NULL; + del = searchProcess(&prev, del->pid, *first); + if (prev == NULL) { *first = del->next; if (*last == del) @@ -54,6 +70,10 @@ void removeProcess(processCDT * del, processCDT * prev, processCDT ** first, pro } } +void debug1() { + return; +} + uint64_t nextProcess(uint64_t currentRSP) { if (currentProcess != NULL /*&& currentProcess->state != BLOCKED*/) currentProcess->rsp = currentRSP; @@ -63,21 +83,25 @@ uint64_t nextProcess(uint64_t currentRSP) { if (currentProcess != NULL && currentProcess->state == READY && currentProcess->executions == MAX_PRIORITY - currentProcess->priority + 1) { currentProcess->executions = 0; currentProcess = currentProcess->next; + // firstBlockedIteration = NULL; + // currentProcess->executions++; + // return currentProcess->rsp; } while (currentProcess == NULL || currentProcess->state == BLOCKED || currentProcess->state == DEAD || currentProcess->state == WAITING) { if (currentProcess == NULL) { currentProcess = firstProcess; } else if (currentProcess == firstBlockedIteration) { - idleFlag = 2; + idleFlag = 1; unblock(IDLE_PID); prev = currentProcess; currentProcess = currentProcess->next; } else if (currentProcess->state == DEAD) { + debug1(); processCDT * del = currentProcess; currentProcess = currentProcess->next; - removeProcess(del, prev, &firstProcess, &lastProcess); + removeProcess(del, &firstProcess, &lastProcess); vPortFree((void *) del); } else if (currentProcess->state == BLOCKED || currentProcess->state == WAITING) { @@ -86,10 +110,17 @@ uint64_t nextProcess(uint64_t currentRSP) { prev = currentProcess; currentProcess = currentProcess->next; } + // else if (currentProcess != NULL && currentProcess->state == READY && currentProcess->executions == MAX_PRIORITY - currentProcess->priority + 1) { + // currentProcess->executions = 0; + // currentProcess = currentProcess->next; + // } } - if (currentProcess->pid != IDLE_PID) { + if (currentProcess->pid != IDLE_PID && idleFlag) { + idleFlag = 0; block(IDLE_PID); } + // if (currentProcess->pid >= 5) + // debug1(); firstBlockedIteration = NULL; currentProcess->executions++; return currentProcess->rsp; @@ -117,7 +148,8 @@ int enqueueProcess(void (*fn) (int, char **), char foreground, int argc, char *a block(IDLE_PID); if (currentProcess != NULL) { - currentProcess->children++; + if (foreground) + currentProcess->children++; if (currentProcess->foreground && foreground) { currentProcess->foreground = 0; currentProcess->backWait = 1; @@ -229,6 +261,13 @@ char block(int pid) { del->state = BLOCKED; } + processADT parent = searchProcess(&prev, del->ppid, firstProcess); + if (del->foreground) + if (parent->backWait) { + parent->backWait = 0; + parent->foreground = 1; + } + if (pid == currentProcess->pid) { forceTimer(); } @@ -245,16 +284,19 @@ char unblock(int pid) { else { del->state = READY; } - if (idleFlag && !(--idleFlag)) - block(IDLE_PID); + + processADT parent = searchProcess(&prev, del->ppid, firstProcess); + if (del->foreground) + if (parent->foreground) { + parent->backWait = 1; + parent->foreground = 0; + } + // if (idleFlag && !(--idleFlag)) + // block(IDLE_PID); return EXIT_SUCCESS; } -void debug() { - return; -} - char kill(int pid) { processADT prev = NULL; processADT del = searchProcess(&prev, pid, firstProcess); @@ -262,16 +304,17 @@ char kill(int pid) { return EXIT_FAILURE; } processADT parent = searchProcess(&prev, del->ppid, firstProcess); - parent->children--; - if (!parent->children && parent->state == WAITING) { - debug(); - parent->state = READY; - } - if (del->foreground) + + if (parent != NULL && del->foreground) { + parent->children--; + if (!parent->children && parent->state == WAITING) { + parent->state = READY; + } if (parent->backWait) { parent->backWait = 0; parent->foreground = 1; } + } vPortFree(del->fd); vPortFree((void *) del->rbp - STACK_SIZE); diff --git a/Kernel/utils/sem.c b/Kernel/utils/sem.c index 918f455..96cf11d 100644 --- a/Kernel/utils/sem.c +++ b/Kernel/utils/sem.c @@ -75,13 +75,6 @@ char semClose(sem_t * sem) { return EXIT_SUCCESS; } -void debug2() { - return; -} -void debug3() { - return; -} - void semWait(sem_t * sem) { enter_region(&semLock); @@ -90,7 +83,6 @@ void semWait(sem_t * sem) { } else { leave_region(&semLock); - debug2(); pid_t * curr = pvPortMalloc(sizeof(pid_t)); curr->pid = getPid(); @@ -115,7 +107,6 @@ void semPost(sem_t * sem) { sem->value++; if (sem->entering != NULL) { - debug3(); pid_t * aux = sem->entering; sem->entering = sem->entering->next; if (sem->entering == NULL) @@ -167,6 +158,22 @@ char getSemaphoresData(char * out, node_t * node) { return written; } +#define MAX_PID 4 + +char * getEntering(sem_t * sem){ + char * ans = pvPortMalloc(sizeof(pid_t *)); + pid_t * aux = sem->entering; + char buffer[MAX_PID]; + while(aux != NULL){ + + strcpy(ans, itoa(aux->pid, buffer, 10, 3)); + aux = aux->next; + if (aux != NULL) + strcpy(ans, ' '); + } + return ans; +} + char * getSems() { char * ans = pvPortMalloc(counter * SEM_DATA_MAX_SIZE); char * ret = ans; diff --git a/Userland/SampleCodeModule/asm/libasm.asm b/Userland/SampleCodeModule/asm/libasm.asm index 46cdcda..5826f43 100644 --- a/Userland/SampleCodeModule/asm/libasm.asm +++ b/Userland/SampleCodeModule/asm/libasm.asm @@ -5,7 +5,7 @@ GLOBAL _getRegs, sys_switchContext GLOBAL cpu_id, cpu_id_support GLOBAL sys_exit, sys_ps, sys_free, sys_malloc, sys_sem, sys_openPipe, sys_semClose GLOBAL sys_nice, sys_semWait, sys_semPost, sys_semOpen, sys_sleep, sys_kill, sys_getPid, -GLOBAL sys_block, sys_unblock, sys_wait +GLOBAL sys_block, sys_unblock, sys_wait, sys_pipes section .text @@ -197,6 +197,21 @@ sys_sem: pop rbp ret +sys_pipes: + push rbp + mov rbp, rsp + + push rdi + + mov rdi, 22 + int 80h + + pop rdi + + mov rsp, rbp + pop rbp + ret + sys_getPid: push rbp mov rbp, rsp diff --git a/Userland/SampleCodeModule/bottler/bottler.c b/Userland/SampleCodeModule/bottler/bottler.c index d807b1e..c636651 100644 --- a/Userland/SampleCodeModule/bottler/bottler.c +++ b/Userland/SampleCodeModule/bottler/bottler.c @@ -34,7 +34,7 @@ void bottler(int argc, char ** argv) { printStringLen( " %%%%%%%%%%%%% ", 80); new_line(); printStringLen( " %%%%%%% ", 80); new_line(); printStringLen( " ", 80); new_line(); - // sys_sleep(3); + sys_sleep(3); winClear(); sys_exit(); diff --git a/Userland/SampleCodeModule/sampleCodeModule.c b/Userland/SampleCodeModule/sampleCodeModule.c index ad88b9f..75b0877 100644 --- a/Userland/SampleCodeModule/sampleCodeModule.c +++ b/Userland/SampleCodeModule/sampleCodeModule.c @@ -13,7 +13,8 @@ int main(int argc, char *argv[]) { char * argv1[] = {"bottler"}; sys_loadProcess(bottler, 1, 1, argv1, NULL); - // sys_sleep(4); + sys_wait(); + // sys_sleep(3); // winClear(); char * argv2[] = {"shell"}; diff --git a/Userland/SampleCodeModule/shell/commands/block.c b/Userland/SampleCodeModule/shell/commands/block.c index d989602..e0b640f 100644 --- a/Userland/SampleCodeModule/shell/commands/block.c +++ b/Userland/SampleCodeModule/shell/commands/block.c @@ -3,10 +3,11 @@ void block(int argc, char ** argv) { if (argc != 2) { printStringLen("block receives a pid\n", 21); - sys_exit(); + // sys_exit(); + return; } int pid = atoi(argv[1], MAX_LEN); sys_block(pid); - sys_exit(); + // sys_exit(); } \ No newline at end of file diff --git a/Userland/SampleCodeModule/shell/commands/clear.c b/Userland/SampleCodeModule/shell/commands/clear.c index 97d81b8..6cf6a4f 100644 --- a/Userland/SampleCodeModule/shell/commands/clear.c +++ b/Userland/SampleCodeModule/shell/commands/clear.c @@ -4,5 +4,6 @@ void clear(int argc, char *argv[]) { winClear(); - sys_exit(); + // sys_exit(); + return; } \ No newline at end of file diff --git a/Userland/SampleCodeModule/shell/commands/filter.c b/Userland/SampleCodeModule/shell/commands/filter.c index fc505b0..4bcfda0 100644 --- a/Userland/SampleCodeModule/shell/commands/filter.c +++ b/Userland/SampleCodeModule/shell/commands/filter.c @@ -6,11 +6,23 @@ int isVocal(char c) { return c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' || c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'; } +void debug8() +{ + return; +} + +void debug9() +{ + return; +} + void filter(int argc, char ** argv) { char c; int i = 0; char buffer[SIZE] = {0}; + debug9(); while ((c = getChar()) != 0 && c != -1) { + debug8(); if (i >= SIZE) break; if (isVocal(c)) @@ -18,5 +30,6 @@ void filter(int argc, char ** argv) { } printStringLen(buffer, i); + new_line(); sys_exit(); } \ No newline at end of file diff --git a/Userland/SampleCodeModule/shell/commands/kill.c b/Userland/SampleCodeModule/shell/commands/kill.c index ddecaee..e3d436b 100644 --- a/Userland/SampleCodeModule/shell/commands/kill.c +++ b/Userland/SampleCodeModule/shell/commands/kill.c @@ -3,10 +3,11 @@ void kill(int argc, char ** argv) { if (argc != 2) { printStringLen("kill receives a pid\n", 21); - sys_exit(); + // sys_exit(); + return; } int pid = atoi(argv[1], MAX_LEN); sys_kill(pid); - sys_exit(); + // sys_exit(); } \ No newline at end of file diff --git a/Userland/SampleCodeModule/shell/commands/loop.c b/Userland/SampleCodeModule/shell/commands/loop.c index e71ad6c..384e574 100644 --- a/Userland/SampleCodeModule/shell/commands/loop.c +++ b/Userland/SampleCodeModule/shell/commands/loop.c @@ -2,12 +2,19 @@ #define PUAN -1 void loop(int argc, char *argv[]) { + if (argc != 3) { + printStringLen("loop receives an amount of seconds and a text\n", 47); + sys_exit(); + } int pid = sys_getPid(), secs = atoi(argv[1], PUAN); - char * str = "Hola, soy el proceso "; - char buffer[MAX_PID_LEN]; - str = strcat(str, itoa(pid, buffer, 10)); + char * str = argv[2]; + char * buffer = sys_malloc(MAX_PID_LEN); + buffer = strcat(strcat(itoa(pid, buffer, 10), " "), str); while (1) { - printString(str); + printString(buffer); + putChar('\n'); sys_sleep(secs); } + sys_free(buffer); + sys_exit(); } \ No newline at end of file diff --git a/Userland/SampleCodeModule/shell/commands/pipes.c b/Userland/SampleCodeModule/shell/commands/pipes.c new file mode 100644 index 0000000..baca9fb --- /dev/null +++ b/Userland/SampleCodeModule/shell/commands/pipes.c @@ -0,0 +1,10 @@ +#include "libc.h" +#include "shell.h" + +void pipes(int argc, char *argv[]) { + char * output = sys_pipes(); + printString(output); + new_line(); + sys_free(output); + sys_exit(); +} \ No newline at end of file diff --git a/Userland/SampleCodeModule/shell/include/pipes.h b/Userland/SampleCodeModule/shell/include/pipes.h new file mode 100644 index 0000000..1dc2723 --- /dev/null +++ b/Userland/SampleCodeModule/shell/include/pipes.h @@ -0,0 +1,6 @@ +#ifndef PIPES_LIB +#define PIPES_LIB + +void pipes(int argc, char *argv[]); + +#endif \ No newline at end of file diff --git a/Userland/SampleCodeModule/shell/shell.c b/Userland/SampleCodeModule/shell/shell.c index 9295d2c..e868537 100644 --- a/Userland/SampleCodeModule/shell/shell.c +++ b/Userland/SampleCodeModule/shell/shell.c @@ -10,6 +10,7 @@ #include "quadratic.h" #include "cpu_id.h" #include "ps.h" +#include "pipes.h" #include "wc.h" #include "filter.h" #include "cat.h" @@ -34,30 +35,33 @@ typedef struct cmd_t { char * name; void (*func) (int argc, char * argv[]); char isBuiltIn; + char isForeground; } cmd_t; cmd_t commands[] = { - { "help", help, 1 }, - { "cat", cat, 0 }, - { "time", time, 1 }, - { "block", block, 0 }, - { "unblock", unblock, 0 }, - { "inforeg", inforeg, 1 }, - { "excdiv", excdiv, 1 }, - { "excop", excop, 1 }, - { "filter", filter, 0 }, - { "clear", clear, 1 }, - { "cpufeatures", cpufeatures, 1 }, - { "nice", nice, 0 }, - { "ps", ps, 1 }, - { "kill", kill, 1 }, - { "sem", sem, 1 }, - { "quadratic", quadratic, 0 }, - { "printmem", printmem, 0 }, - { "phylo", phylo, 0 }, - { "wc", wc, 0 }, - { "loop", loop, 0 }, - { NULL, NULL, 0} + { "help", help, 0, 1}, + { "cat", cat, 0, 1}, + { "time", time, 0, 1}, + { "block", block, 1, 1}, + { "unblock", unblock, 1, 1}, + { "inforeg", inforeg, 0, 1}, + { "excdiv", excdiv, 1, 1}, + { "excop", excop, 1, 1}, + { "filter", filter, 0, 1}, + { "clear", clear, 1, 1}, + { "cpufeatures", cpufeatures, 0, 1}, + { "nice", nice, 0, 1}, + { "ps", ps, 0, 1}, + { "pipes", pipes, 0, 1}, + { "kill", kill, 1, 1}, + { "sem", sem, 0, 1}, + { "quadratic", quadratic, 0, 1}, + { "printmem", printmem, 0, 1}, + { "phylo", phylo, 0, 1}, + { "wc", wc, 0, 1}, + { "loop", loop, 0, 0}, + { "loopcaca", loop, 0, 1}, + { NULL, NULL, 0, 0} }; int scanfNoPrint(char * buffer) { @@ -80,7 +84,7 @@ int scanfNoPrint(char * buffer) { } void processInput(char * input) { - int comm_flag0 = 0, comm_flag1 = 0, pipe = -1, end = -1; + int comm_flag0 = 0, comm_flag1 = 0, pipe = -1, end = -1, ampersand = -1; char* tokens[SIZE] = {0}; tokens[0] = strstrip(input, ' '); for (int i = 1; i < MAX_ARGS; i++) { @@ -90,6 +94,10 @@ void processInput(char * input) { pipe = i - 1; } if (tokens[i][0] == 0) { + if (i > 1 && !strcmp(tokens[i-1], "&")) { + ampersand = end = i - 1; + break; + } end = i; break; } @@ -148,11 +156,22 @@ void processInput(char * input) { if (comm_flag0 && (comm_flag1 || pipe == -1)) { if (pipe != -1) { - sys_loadProcess(commands[comm0].func, 1, pipe, argv0, fd1); - sys_loadProcess(commands[comm1].func, 1, end - pipe - 1, argv1, fd2); + sys_loadProcess(commands[comm0].func, commands[comm0].isForeground, pipe, argv0, fd1); + sys_loadProcess(commands[comm1].func, commands[comm0].isForeground, end - pipe - 1, argv1, fd2); } - else sys_loadProcess(commands[comm0].func, 1, end, argv0, fd1); - sys_wait(); + else { + if (commands[comm0].isBuiltIn) + commands[comm0].func(end, argv0); + // sys_loadProcess(commands[comm0].func, 1, end, argv0, fd1); + else { + if (ampersand >= 0) + commands[comm0].isForeground = 0; + sys_loadProcess(commands[comm0].func, commands[comm0].isForeground, end, argv0, fd1); + } + } + + if (commands[comm0].isForeground) + sys_wait(); } if (!comm_flag0) { @@ -165,10 +184,10 @@ void processInput(char * input) { } } -void loader(void (*fn) (int, char **), int argc, char * argv[]) { - fn(argc, argv); - sys_exit(); -} +// void loader(void (*fn) (int, char **), int argc, char * argv[]) { +// fn(argc, argv); +// sys_exit(); +// } void shell(int argc, char *argv[]) { printStringLen("$> ", 3);