From f74cebc12da6cdfa5576252933ad592e261c99ca Mon Sep 17 00:00:00 2001 From: iDunnoDev Date: Fri, 13 Jan 2023 17:37:43 +0000 Subject: [PATCH] Added comments and help commands to user apps --- Makefile | 4 +- console.c | 168 ++++++++++++++++++++++++++++++++++++++++-------------- count.c | 11 ++++ exec.c | 1 + hello.c | 11 ++++ maze.c | 23 ++++++-- proc.c | 5 ++ proc.h | 4 +- screen.c | 8 ++- sysproc.c | 14 ++++- user.h | 3 + 11 files changed, 197 insertions(+), 55 deletions(-) diff --git a/Makefile b/Makefile index 82ac32c..da185f0 100644 --- a/Makefile +++ b/Makefile @@ -225,8 +225,8 @@ QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \ then echo "-gdb tcp::$(GDBPORT)"; \ else echo "-s -p $(GDBPORT)"; fi) ifndef CPUS -#CPUS := 2 -CPUS := 1 # For debugging +CPUS := 2 +#CPUS := 1 # For debugging endif QEMUOPTS = -drive file=fs.img,index=1,media=disk,format=raw -drive file=xv6.img,index=0,media=disk,format=raw -smp $(CPUS) -m 512 $(QEMUEXTRA) diff --git a/console.c b/console.c index 3fc65a4..e6daad4 100644 --- a/console.c +++ b/console.c @@ -20,7 +20,7 @@ #define MENUWIDTH 27 // Number of max consoles + 1 for bottom border and another 2 for a space between top and bottom #define MENUHEIGHT (MAXVCONSOLES + 3); - +// Vars to hold the current menu item and menu active bool static int currentmenuitem = 0; static int menuactive = 0; @@ -36,6 +36,7 @@ struct kbdbuffer inputBuffer; struct kbdbuffer *input = 0; +// Struct to hold the variables needed for a virtual console struct vconsole { uint consoleindex; @@ -46,9 +47,11 @@ struct vconsole int pos; int active; int inuse; + // Variables for the title bar, this can be manual set and locked, if not the current process is used uint titlebgcol; char proctitle[20]; int titlelocked; + // Status for possible future use with the title bar to allow a proccess to set messages to print char status[30]; }; @@ -80,6 +83,7 @@ static struct int locking; } vcons; +// Static function for getting the current count of active consoles static int getcurrentactiveconsolecount(void) { int resultcount = 0; @@ -94,6 +98,7 @@ static int getcurrentactiveconsolecount(void) return resultcount; } +// Function to get the menu index of an active console because they might be offset static int getconsolemenuindex(struct vconsole* consolein) { int resultcount = 0; @@ -112,6 +117,7 @@ static int getconsolemenuindex(struct vconsole* consolein) return resultcount; } +// Function for getting the console at the given menu index static int getmenuindexconsole(int menuindex) { int resultcount = 0; @@ -135,6 +141,7 @@ static int getmenuindexconsole(int menuindex) return resultconsoleindex; } +// Function for getting a consoles index int getconsoleindex(struct vconsole* consolein) { return consolein->consoleindex; @@ -173,6 +180,7 @@ static int itoa(int xx, int base, int sign, char* buf) return i; } +// Function for printing an integer as a string to the screen static void printint(int xx, int base, int sign) { int i = 0; @@ -256,6 +264,8 @@ void cprintf(char *fmt, ...) } } +// Function to provide the same string manipulation as cprint but saving to the given buffer so it can be used without printing to the screen +// sprintf is the c function that normally does this so i used the same name here void sprintf(char* strbuffer, char *fmt, ...) { int i, c, si; @@ -401,28 +411,40 @@ struct vconsole* getvalidprocessconsoleptr(void) static ushort *crt = (ushort *)P2V(0xb8000); // CGA memory +// Function for drawing the menu onto the screen static void drawmenu(void) { struct vconsole* inconsoleptr = getvalidprocessconsoleptr(); + // Rows = the number of active consoles + 1 for the padding at the top, 1 for the padding at the bottom and 1 for the border int rows = getcurrentactiveconsolecount() + 3; int pos = TITLEOFF; uint c = 0; + // Small buffer to hold the menu memory char menulines[MAXVCONSOLES][24]; + // Setup our menu item line strings + int menuindex = 0; for (int i = 0; i < MAXVCONSOLES; i++) { if (consoles[i].active) { - memset(menulines[i], 0, sizeof(menulines[i][0]) * sizeof(menulines[i])); - sprintf(menulines[i], "%d: %s", consoles[i].consoleindex, consoles[i].proctitle); + memset(menulines[menuindex], 0, sizeof(menulines[i][0]) * sizeof(menulines[i])); + sprintf(menulines[menuindex], "%d: %s", consoles[i].consoleindex, consoles[i].proctitle); + if (consoles[i].inuse) + { + currentmenuitem = menuindex; + } + menuindex++; } } + // Draw the rows for the menu for (int y = 0; y < rows; y++) { pos = TITLEOFF + (y * SCRWIDTH); for (int x = 0; x < MENUWIDTH; x++) { + // Top line and the 2nd to last line are padding, we just draw spaces and the first and last x are the border character if (y == 0 || y == (rows - 2)) { if (x == 0 || x == (MENUWIDTH - 1)) @@ -434,10 +456,12 @@ static void drawmenu(void) c = 0x0720; } } + // The last row is the bottom border, so we can just fill it with the border character else if (y == (rows - 1)) { c = 0xB2 | inconsoleptr->titlebgcol; } + // Otherwise we draw the border chars and padding space with the console menu item string between else { if (x == 0 || x == (MENUWIDTH - 1)) @@ -471,6 +495,7 @@ static void drawmenu(void) menuactive = 1; } +// Function that handles the moving of the highlight bar for the menu static void navigatemenu(int dir) { int pos = 0; @@ -486,14 +511,18 @@ static void navigatemenu(int dir) newindex = totalactiveconsoles - 1; } + // make sure the new index isnt just the same as the current selected menu item, we then change the background bits around + // which saves us from redrawing the menu every time the selected item changes if (newindex != currentmenuitem) { + // change the background bits of the last selected item to black pos = TITLEOFF + ((currentmenuitem + 1) * SCRWIDTH); for (int x = 2; x < MENUWIDTH - 2; x++) { crt[pos + x] = (crt[pos + x] & 0x00FF) | 0x0700; } + // change the background bits of the new selected item to the highlight color pos = TITLEOFF + ((newindex + 1) * SCRWIDTH); for (int x = 2; x < MENUWIDTH - 2; x++) { @@ -504,6 +533,7 @@ static void navigatemenu(int dir) } } +// Function that closes the menu and reloads the buffer into screen memory static void closemenu(void) { loadscreenbuffer(currentconsole->screenbuffer); @@ -517,42 +547,51 @@ static void closemenu(void) menuactive = 0; } +// Function for drawing the title bar of the current console static void drawtitle(void) { struct vconsole* inconsoleptr = getvalidprocessconsoleptr(); int pos = 0; char c = ' '; + // Setup the title bar strings to print char menutext[] = "(M)enu"; char consoletitletext[10]; // + (inconsoleptr->consoleindex + 1); sprintf(consoletitletext, "Console %d", inconsoleptr->consoleindex); + // Loop through the top row and write the current character to the screen buffer for (pos = 0; pos < SCRWIDTH; pos++) { int offset = 0; + // Print the menu text if (pos < 6) { c = menutext[pos - offset]; } + // Print the console title else if (pos >= 10 && pos < 20) { offset = 10; c = consoletitletext[pos - offset]; } + // Print the process/title name else if (pos >= 25 && pos < 45) { offset = 25; c = inconsoleptr->proctitle[pos - offset]; } + // Print the status (not current in use) else if (pos >= 50 && pos < 80) { offset = 50; c = inconsoleptr->status[pos - offset]; } + // Otherwise print a space character so we still get the background else { c = ' '; } + // Print the actual character with the given bg and fg color settings if (inconsoleptr->inuse) { crt[pos] = (c & 0xff) | inconsoleptr->titlebgcol; @@ -561,6 +600,7 @@ static void drawtitle(void) } } +// Function for printing a character to the screen and/or the current console buffer static void cgaputc(int c) { int pos; @@ -568,6 +608,7 @@ static void cgaputc(int c) ushort *currentbuffer = inconsoleptr->screenbuffer; + // if the console is inuse we get the hardware cursor position so we can use it if (inconsoleptr->inuse) { // Cursor position: col + 80*row. @@ -576,6 +617,7 @@ static void cgaputc(int c) outb(CRTPORT, 15); pos |= inb(CRTPORT + 1); } + // If the console is not in use we use the position saved to the console struct else { pos = inconsoleptr->pos; @@ -587,6 +629,7 @@ static void cgaputc(int c) } else if (c == BACKSPACE) { + // Check that the pos is not in the title offset so they cant remove it if (pos > (TITLEOFF)) { currentbuffer[pos] = 0; // Clear the character from the buffer @@ -595,19 +638,22 @@ static void cgaputc(int c) } else { - // int posp = pos; + // If the console is inuse print the character to the screen if (inconsoleptr->inuse) { crt[pos] = (c & 0xff) | 0x0700; // black on white } + // Save the current character to the console buffer currentbuffer[pos] = (c & 0xff) | 0x0700; // black on white pos++; } + // Check that the pos is not in the title area or greater than the screen size if (pos < TITLEOFF || pos > SCRHEIGHT * SCRWIDTH) { panic("pos under/overflow"); } + // Handle the overflow scrolling for the screen and buffer if ((pos / 80) >= 24) { // Scroll up. memmove(currentbuffer + TITLEOFF, currentbuffer + (SCRWIDTH + TITLEOFF), sizeof(crt[0]) * (SCRHEIGHT - 1) * SCRWIDTH); @@ -615,6 +661,7 @@ static void cgaputc(int c) memset(currentbuffer + pos, 0, sizeof(crt[0]) * (SCRHEIGHT * SCRWIDTH - pos)); if (inconsoleptr->inuse) { + // Check if the menu is active, if so we want to offset the scrolling start pos so we dont overwrite the menu in screen memory int menuoffset = 0; if (menuactive) { @@ -629,6 +676,8 @@ static void cgaputc(int c) memset(crt + pos, 0, sizeof(crt[0]) * (SCRHEIGHT * SCRWIDTH - pos)); } } + + // Set the consoles pos to the new pos, if the console was in use also save the hardware cursor pos inconsoleptr->pos = pos; if (inconsoleptr->inuse) @@ -692,20 +741,24 @@ void consoleintr(int (*getc)(void)) int doconsoleswitch = 0; int switchto = -1; int doconsolehome = 0; - //struct vconsole* inconsoleptr = getvalidprocessconsoleptr(); + + struct vconsole* inconsoleptr = getvalidprocessconsoleptr(); struct kbdbuffer* consolekbdbuffer = ¤tconsole->keybuffer; - acquire(&cons.lock); + acquire(&cons.lock); while ((c = getc()) >= 0) { switch (c) - { + { + // Hotkeys for dealing with the menu + // Close the menu case 27: if (menuactive) { closemenu(); } break; + // Menu nav to the previous item // Up arrow (found in kbd.h) case 0xE2: if (menuactive) @@ -713,6 +766,7 @@ void consoleintr(int (*getc)(void)) navigatemenu(-1); } break; + // Menu nav to the next item // Down arrow (found in kbd.h) case 0xE3: if (menuactive) @@ -740,12 +794,15 @@ void consoleintr(int (*getc)(void)) consputc(BACKSPACE); } break; + // Hotkey to switch to the next console case C('T'): doconsoleswitch = 1; break; + // Hotkey to switch to the home console case C('K'): doconsolehome = 1; break; + // Hotkey open the menu case C('M'): if (!menuactive) { @@ -766,31 +823,35 @@ void consoleintr(int (*getc)(void)) // The menu has been sorted we can break from the switch break; } - // if the menu was not active we want the enter to be handled in the default case + // if the menu was not active we want the enter to be handled in the default case default: if (!menuactive) { - if (c != 0 && consolekbdbuffer->e - consolekbdbuffer->r < INPUT_BUF) + if (inconsoleptr->inuse) { - c = (c == '\r') ? '\n' : c; - consolekbdbuffer->buf[consolekbdbuffer->e++ % INPUT_BUF] = c; - consputc(c); - if (c == '\n' || c == C('D') || consolekbdbuffer->e == consolekbdbuffer->r + INPUT_BUF) + if (c != 0 && consolekbdbuffer->e - consolekbdbuffer->r < INPUT_BUF) { - consolekbdbuffer->w = consolekbdbuffer->e; - wakeup(&(consolekbdbuffer->r)); + c = (c == '\r') ? '\n' : c; + consolekbdbuffer->buf[consolekbdbuffer->e++ % INPUT_BUF] = c; + consputc(c); + if (c == '\n' || c == C('D') || consolekbdbuffer->e == consolekbdbuffer->r + INPUT_BUF) + { + consolekbdbuffer->w = consolekbdbuffer->e; + wakeup(&(consolekbdbuffer->r)); + } } } } break; } } - release(&cons.lock); + release(&cons.lock); if (doprocdump && !menuactive) { procdump(); // now call procdump() wo. cons.lock held } + // Handle the home console hotkey if (doconsolehome) { if (currentconsole->consoleindex != 0) @@ -798,9 +859,11 @@ void consoleintr(int (*getc)(void)) switchtoconsole(getbaseconsoleptr()); } } + // Handle the console switch hotkey if (doconsoleswitch) { struct vconsole* toconsole = 0; + acquire(&vcons.lock); acquire(&cons.lock); if (switchto == -1) { @@ -822,6 +885,7 @@ void consoleintr(int (*getc)(void)) toconsole = &consoles[getmenuindexconsole(switchto)]; } release(&cons.lock); + release(&vcons.lock); if (!toconsole->inuse) { switchtoconsole(toconsole); @@ -837,8 +901,7 @@ int consoleread(struct inode *ip, char *dst, int n) struct kbdbuffer* consolekbdbuffer = &inconsoleptr->keybuffer; iunlock(ip); - target = n; - //acquire(&cons.lock); + target = n; acquire(&inconsoleptr->lock); while (n > 0) { @@ -869,8 +932,7 @@ int consoleread(struct inode *ip, char *dst, int n) { break; } - } - //release(&cons.lock); + } release(&inconsoleptr->lock); ilock(ip); @@ -882,14 +944,12 @@ int consolewrite(struct inode *ip, char *buf, int n) int i; struct vconsole* inconsoleptr = getvalidprocessconsoleptr(); - iunlock(ip); - //acquire(&cons.lock); + iunlock(ip); acquire(&inconsoleptr->lock); - for (i = 0; i < n; i++) - { - consputc(buf[i] & 0xff); - } - //release(&cons.lock); + for (i = 0; i < n; i++) + { + consputc(buf[i] & 0xff); + } release(&inconsoleptr->lock); ilock(ip); @@ -916,29 +976,34 @@ void testfillbuffer(ushort *bufferin) } } +// Function to get a pointer to the base console struct vconsole* getbaseconsoleptr(void) { return &consoles[0]; } +// Function to clear a given buffer using its pointer/address void clearconsole(ushort *bufferin) { // Flood the screen buffer with blank spaces memset(bufferin, 0, sizeof(bufferin[0]) * SCRHEIGHT * SCRWIDTH); } +// Function for loading an entire buffer into the screen memory using its pointer/address void loadscreenbuffer(ushort *bufferin) { // Copy the memory from the console buffer to the crt buffer memmove(crt, bufferin, sizeof(bufferin[0]) * SCRHEIGHT * SCRWIDTH); } +// Function for saving the current screen memory into a given buffer void savescreenbuffer(ushort *bufferin) { // Copy the memory from the console buffer to the crt buffer memmove(bufferin, crt, sizeof(crt[0]) * SCRHEIGHT * SCRWIDTH); } +// Function for clearing the current screen/buffer void clearscreen(int prelocked) { // Check if a process has actually been created otherwise use the base console @@ -952,6 +1017,7 @@ void clearscreen(int prelocked) clearconsole(inconsoleptr->screenbuffer); inconsoleptr->pos = pos; + // If the console is in use load the blank buffer into screen memory and set the cursor position if (inconsoleptr->inuse) { loadscreenbuffer(inconsoleptr->screenbuffer); @@ -961,6 +1027,8 @@ void clearscreen(int prelocked) outb(CRTPORT, 15); outb(CRTPORT + 1, pos); } + + // Draw the title bar onto the console drawtitle(); if (!prelocked) { @@ -973,6 +1041,7 @@ void consoleinit(void) initlock(&cons.lock, "console"); initlock(&vcons.lock, "vconglobal"); + // Init all of the virtual console buffers for (int i = 0; i < MAXVCONSOLES; i++) { consoles[i].consoleindex = i; @@ -997,12 +1066,15 @@ void consoleinit(void) devsw[CONSOLE].read = consoleread; cons.locking = 1; + // Clear the screen and print the welcome message clearscreen(0); cprintf("Welcome! you are currently in the base console\n"); ioapicenable(IRQ_KBD, 0); } +// Function for "creating" a new console, in reality it sets the first non active console to active and setups the struct +// if none are free it returns a nullptr/zero for the calling function to handle struct vconsole* newconsole(char* title, int bgpreset) { struct vconsole* result = 0; @@ -1034,6 +1106,7 @@ struct vconsole* newconsole(char* title, int bgpreset) return result; } +// Function to "release" all consoles from inuse, this is to stop the chance of one not clearing and causing an issue with 2 being inuse void releaseallconsoles(void) { for (int i = 0; i < MAXVCONSOLES; i++) @@ -1042,20 +1115,22 @@ void releaseallconsoles(void) } } +// Function for switching to another console using the given pointer int switchtoconsole(struct vconsole* consoleptr) { int pos; - acquire(&vcons.lock); + acquire(&vcons.lock); + // Release all consoles before setting the new one to inuse releaseallconsoles(); currentconsole = consoleptr; currentconsole->inuse = 1; - //input = ¤tconsole->keybuffer; - // ioapicenable(IRQ_KBD, 0); - + acquire(&cons.lock); + // Load the next console into screen memory loadscreenbuffer(currentconsole->screenbuffer); + // Checks if the console was active, if not its most likely the first switch to this so we clear and print the welcome message if (!currentconsole->active) { clearscreen(1); @@ -1064,6 +1139,7 @@ int switchtoconsole(struct vconsole* consoleptr) } else { + // If it was already active we just set the cursor position to the one saved in the console struct pos = currentconsole->pos; outb(CRTPORT, 14); @@ -1072,7 +1148,7 @@ int switchtoconsole(struct vconsole* consoleptr) outb(CRTPORT + 1, pos); } - //drawtitle(); + // Remove the menu if it was active and set the console as the current menu item menuactive = 0; currentmenuitem = getconsolemenuindex(currentconsole); release(&cons.lock); @@ -1080,17 +1156,19 @@ int switchtoconsole(struct vconsole* consoleptr) return 0; } +// Function for closing the current console int closeconsole(void) { struct vconsole* consoleptr = myproc()->consoleptr; - - //cprintf("Console Owner PID: %d\n", consoleptr->processowner->pid); + acquire(&vcons.lock); + // Check if the process exiting is the consoles parent process we clear the buffer and set the active to 0 if (myproc() == consoleptr->processowner) { clearconsole(consoleptr->screenbuffer); consoleptr->active = 0; + // If the console was in use to switch back to the base console if (consoleptr->inuse) { consoleptr->inuse = 0; @@ -1103,6 +1181,7 @@ int closeconsole(void) return 0; } +// Function for getting the console index of the current inuse console int getcurrentconsoleindex(void) { acquire(&vcons.lock); @@ -1118,19 +1197,20 @@ int getcurrentconsoleindex(void) return -1; } +// Function for setting the title of a console for the title bar and menu void setconsoleproctitle(struct vconsole* consoleptr, char* newtitle) { if (!consoleptr->titlelocked) { - acquire(&consoleptr->lock); - //Clear the current buffer - memset(consoleptr->proctitle, 0, sizeof(consoleptr->proctitle[0]) * sizeof(consoleptr->proctitle)); - //Copy the new title into the console title buffer - safestrcpy(consoleptr->proctitle, newtitle, sizeof(consoleptr->proctitle)); - - //Redraw the title since its been updated now - drawtitle(); - - release(&consoleptr->lock); + acquire(&vcons.lock); + //Clear the current buffer + memset(consoleptr->proctitle, 0, sizeof(consoleptr->proctitle[0]) * sizeof(consoleptr->proctitle)); + //Copy the new title into the console title buffer + safestrcpy(consoleptr->proctitle, newtitle, sizeof(consoleptr->proctitle)); + + //Redraw the title since its been updated now + drawtitle(); + + release(&vcons.lock); } } \ No newline at end of file diff --git a/count.c b/count.c index 05fd448..370828a 100644 --- a/count.c +++ b/count.c @@ -1,6 +1,8 @@ #include "types.h" #include "user.h" +// Simple user app to do a count from 0 to the given number (1000 by defaulf) +// for testing concurrency int main(int argc, char *argv[]) { int countto = 1000; @@ -8,6 +10,15 @@ int main(int argc, char *argv[]) { if (strcmp(argv[i], "-c") == 0) { countto = atoi(argv[i + 1]); } + else if (strcmp(argv[i], "-help") == 0) + { + printf(1, "Counts from 0 to the given number.\n"); + printf(1, "Default: 1000\n"); + printf(1, "Options:\n"); + printf(1, "-c [Number] : Sets the value to count upto.\n"); + exit(); + return 0; + } } cls(); diff --git a/exec.c b/exec.c index 9524288..8c777cc 100644 --- a/exec.c +++ b/exec.c @@ -130,6 +130,7 @@ int exec(char *path, char **argv) { } safestrcpy(curproc->name, last, sizeof(curproc->name)); + // If the process is tied to a console update the title to the new process name if (curproc->consoleptr != 0) { setconsoleproctitle(curproc->consoleptr, curproc->name); diff --git a/hello.c b/hello.c index c1dde4d..773412b 100644 --- a/hello.c +++ b/hello.c @@ -1,7 +1,18 @@ #include "types.h" #include "user.h" +// User app that was from one of the tutorial but i have since changed it to provide useful information about the current process and console int main(int argc, char *argv[]) { + + for (int i = 1; i < argc; i++) { + if (strcmp(argv[i], "-help") == 0) + { + printf(1, "Does a system call that returns the current process and console information, used for debugging.\n"); + exit(); + return 0; + } + } + greeting(); exit(); } \ No newline at end of file diff --git a/maze.c b/maze.c index 8250db2..651583c 100644 --- a/maze.c +++ b/maze.c @@ -1,9 +1,11 @@ #include "types.h" #include "user.h" +// User app for generating a simple maze similar to the c64 version using the border ascii characters +// This doesnt seem to work on the azure server but left in since i did the work on it... uint rngnumber(void) { - // Take from http://stackoverflow.com/questions/1167253/implementation-of-rand + // Taken from http://stackoverflow.com/questions/1167253/implementation-of-rand static unsigned int z1 = 12345, z2 = 12345, z3 = 12345, z4 = 12345; unsigned int b; b = ((z1 << 6) ^ z1) >> 13; @@ -44,12 +46,24 @@ int main(int argc, char *argv[]) { { seed = atoi(argv[i + 1]); } + else if (strcmp(argv[i], "-help") == 0) + { + printf(1, "Generates X lines of random maze.\n"); + printf(1, "Options:\n"); + printf(1, "-l [Number] : Sets number of lines to generate for the maze.\n"); + printf(1, "-s [Number] : Sets the current seed for the random function.\n"); + exit(); + return 0; + } } cls(); - greeting(); - printf(1, "Start Maze\n"); - + + printf(1, "Start Maze (DISABLED)\n"); + printf(1, "This does not work on the azure servers, but it would generate a random x lines of characters to look like a maze, similar to the old c64 basic program.\n"); + printf(1, "I could have used the slashes but they look aweful in this font so use the count app instead.\n\n"); + exit(); + char mazeline[80]; for (int y = 0; y < lines; y++) { @@ -83,5 +97,6 @@ int main(int argc, char *argv[]) { sleep(10); } printf(1, "Maze Ended\n"); + exit(); } \ No newline at end of file diff --git a/proc.c b/proc.c index 3656987..d409ad6 100644 --- a/proc.c +++ b/proc.c @@ -142,6 +142,7 @@ void userinit(void) { safestrcpy(p->name, "initcode", sizeof(p->name)); p->cwd = namei("/"); + // Set the user init console to the base console p->consoleptr = getbaseconsoleptr(); safestrcpy(p->title, "Shell (Root)", sizeof(p->title)); @@ -219,6 +220,7 @@ int fork(void) { acquire(&ptable.lock); np->state = RUNNABLE; + // Copy the console pointer to the child np->consoleptr = curproc->consoleptr; release(&ptable.lock); @@ -267,11 +269,14 @@ void exit(void) { } } + // Check if the assigned console is not the base console if (curproc->consoleptr != getbaseconsoleptr()) { + // If so try to close the console, this will only happen if this process is the owner for the console closeconsole(); } + // Update the current process title for its assigned console if (curproc->consoleptr != 0) { setconsoleproctitle(curproc->consoleptr, curproc->parent->name); diff --git a/proc.h b/proc.h index 10b5ce0..fcf5760 100644 --- a/proc.h +++ b/proc.h @@ -48,8 +48,8 @@ struct proc { struct file *ofile[NOFILE]; // Open files struct inode *cwd; // Current directory char name[16]; // Process name (debugging) - struct vconsole* consoleptr; - char title[20]; + struct vconsole* consoleptr; // Pointer to the processes assigned console + char title[20]; // the title for the process }; // Process memory is laid out contiguously, low addresses first: diff --git a/screen.c b/screen.c index ec79caf..f08c309 100644 --- a/screen.c +++ b/screen.c @@ -23,10 +23,12 @@ int main(int argc, char *argv[]) { { printf(1, "Creates a new virtual console.\n"); printf(1, "Options:\n"); - printf(1, "-bg [0 - 9] : Sets a background preset for the title bar."); + printf(1, "-bg [0 - 9] : Sets a background preset for the title bar.\n"); + printf(1, "-t [String] : Sets a custom title for the console.\n"); exit(); return 0; } + // Setup the title, it adds the space seperated strings to the title else { if (accepttitle) @@ -50,6 +52,7 @@ int main(int argc, char *argv[]) { } } + // Set the variable to the selected bg/fg preset option switch(selopt) { case 1: @@ -81,6 +84,7 @@ int main(int argc, char *argv[]) { break; } + // Fork into a new process and create the screen pid = fork(); if (pid < 0) { printf(1, "screen: fork failed\n"); @@ -93,7 +97,7 @@ int main(int argc, char *argv[]) { } else { - printf(1, "screen: failed to create a new console\n"); + } } exit(); diff --git a/sysproc.c b/sysproc.c index 79373e9..0768c02 100644 --- a/sysproc.c +++ b/sysproc.c @@ -92,9 +92,10 @@ int sys_uptime(void) return xticks; } +// System call i used to debug and test the consoles, it returns useful information in relation to the current console/process int sys_greeting(void) { - cprintf("Hello again\n"); + cprintf("Hello! here is the info you requested...\n"); cprintf("Using Console: %d\n", getcurrentconsoleindex()); cprintf("Current PID: %d\n", myproc()->pid); cprintf("Current Parent PID: %d\n", myproc()->parent->pid); @@ -102,6 +103,7 @@ int sys_greeting(void) return 0; } +// System call to shutdown or restart the OS int sys_shutdown(void) { int restart; @@ -125,6 +127,7 @@ int sys_shutdown(void) return 0; } +// System call for handling the new screen user app int sys_screen(void) { struct proc *curproc = myproc(); @@ -133,25 +136,34 @@ int sys_screen(void) int bgcol; char *title; + // Get the background color value if (argint(1, &bgcol) < 0) { return -1; } + // Get the title arg value if (argstr(0, &title) < 0) { return -1; } + // Try to setup an unused console from the pool if ((consoleptr = newconsole(title, bgcol)) != 0) { + // New console was successful, set the pointer and switch to it curproc->consoleptr = consoleptr; switchtoconsole(consoleptr); result = 1; } + else + { + cprintf("screen: failed to create a new console\n"); + } return result; } +// System call to clear the screen int sys_cls(void) { clearscreen(0); diff --git a/user.h b/user.h index 21ca1ab..a30c565 100644 --- a/user.h +++ b/user.h @@ -25,8 +25,11 @@ int sleep(int); int uptime(void); int getch(void); int greeting(void); +// function to shutdown int shutdown(int restart); +// function to create a new screen int screen(const char*, int); +// function to clear the current screen int cls(void); // ulib.c