#include <stdio.h> #include <stdlib.h> #include <console.h> #include <string.h> #include <sys/module.h> #include <sys/exec.h> #define INFO_PRINT(fmt, args...) printf("[COM32] " fmt, ##args) #define MAX_COMMAND_SIZE 80 // Maximum size of the cmd line #define COMMAND_DELIM " \t\n" // Whitespace delimiters #define MAX_COMMAND_ARGS (MAX_COMMAND_SIZE/2) // Maximum argument count for // program execution /** * print_help - Display usage instructions on the screen. */ static void print_help(void) { printf("List of available commands:\n"); printf("exit - exits the program\n"); printf("help - shows this message\n"); printf("load <library>... - loads the libraries into the environment\n"); printf("spawn <executable> <args> - launches an executable module\n"); printf ("unload <library>... - unloads the libraries from the environment\n"); printf("list - prints the currently loaded modules\n"); } /** * print_prompt - Display the command prompt. */ static void print_prompt(void) { printf("\nelflink> "); } /** * read_command - Read a new command from the standard input. * @cmd: the buffer to store the command * @size: the maximum size of the string that can be stored in the buffer * * If the command is larger than the specified size, it is truncated. */ static void read_command(char *cmd, int size) { char *nl = NULL; fgets(cmd, size, stdin); // Strip the newline nl = strchr(cmd, '\n'); if (nl != NULL) *nl = '\0'; } /** * process_spawn - Handles the execution of a 'spawn' command. * * The command line is in the internal buffer of strtok. */ static void process_spawn(void) { // Compose the command line char **cmd_line = malloc((MAX_COMMAND_ARGS + 1) * sizeof(char *)); int argc = 0, result; char *crt_arg; do { crt_arg = strtok(NULL, COMMAND_DELIM); if (crt_arg != NULL && strlen(crt_arg) > 0) { cmd_line[argc] = crt_arg; argc++; } else { break; } } while (argc < MAX_COMMAND_ARGS); cmd_line[argc] = NULL; if (cmd_line[0] == NULL) { printf("You must specify an executable module.\n"); } else { result = spawnv(cmd_line[0], cmd_line); printf("Spawn returned %d\n", result); } free(cmd_line); } /** * process_library - Handles the execution of the 'load' and 'unload' commands. * @load: contains 1 if the libraries are to be loaded, 0 for unloading. * * The command line is in the internal buffer of strtok. */ static void process_library(int load) { char *crt_lib; int result; while ((crt_lib = strtok(NULL, COMMAND_DELIM)) != NULL) { if (strlen(crt_lib) > 0) { if (load) result = load_library(crt_lib); else result = unload_library(crt_lib); if (result == 0) { printf("Library '%s' %sloaded successfully.\n", crt_lib, load ? "" : "un"); } else { printf("Could not %sload library '%s': error %d\n", load ? "" : "un", crt_lib, result); } } } } /** * process_list - Handles the execution of the 'list' command. * */ static void process_list(void) { struct elf_module *module; struct module_dep *crt_dep; for_each_module(module) { printf("%s (%dK, %s, %s) : ", module->name, module->module_size >> 10, module->shallow ? "shallow" : "regular", module->main_func == NULL ? "library" : "program"); list_for_each_entry(crt_dep, &module->required, list) { printf("%s ", crt_dep->module->name); } printf("\n"); } } /** * process_command - Recognizes the requested command and executes it. * @cmd: the command to be executed. * * Returns 1 if the command was 'exit', 0 otherwise. */ static int process_command(char *cmd) { char *cmd_name; cmd_name = strtok(cmd, COMMAND_DELIM); if (strcmp(cmd_name, "exit") == 0) { printf("Goodbye!\n"); return 1; } else if (strcmp(cmd_name, "help") == 0) { print_help(); } else if (strcmp(cmd_name, "load") == 0) { process_library(1); } else if (strcmp(cmd_name, "spawn") == 0) { process_spawn(); } else if (strcmp(cmd_name, "unload") == 0) { process_library(0); } else if (strcmp(cmd_name, "list") == 0) { process_list(); } else { printf("Unknown command. Type 'help' for a list of valid commands.\n"); } return 0; } /** * The entry point of 'test_com32' COM module. */ int main(int argc, char **argv) { int done = 0; int res; char command[MAX_COMMAND_SIZE] = { 0 }; // Open a standard r/w console openconsole(&dev_stdcon_r, &dev_stdcon_w); res = exec_init(); if (res != 0) { printf("Failed to initialize the execution environment.\n"); return res; } else { printf("Execution environment initialized successfully.\n"); } printf("\nFor a list of available commands, type 'help'.\n"); do { print_prompt(); read_command(command, MAX_COMMAND_SIZE); done = process_command(command); } while (!done); exec_term(); return 0; }