diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c613a864..96a48f716 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -166,7 +166,6 @@ add_subdirectory(boot) add_subdirectory(kernel) add_subdirectory(lib) add_subdirectory(userspace) -add_subdirectory(examples) # ============================================================================= # FILESYSTEM @@ -183,7 +182,7 @@ add_custom_target(filesystem COMMAND echo '=============================================================================' COMMAND echo 'Done!' COMMAND echo '=============================================================================' - DEPENDS programs tests examples + DEPENDS programs tests ) # ============================================================================= diff --git a/examples/01_hello.c b/examples/01_hello.c deleted file mode 100644 index 7c225d01d..000000000 --- a/examples/01_hello.c +++ /dev/null @@ -1,17 +0,0 @@ -/// @file 01_hello.c -/// @brief Simplest example: Hello World -/// @details This is the first program to understand MentOS. -/// It demonstrates how to: -/// - Print output -/// - Exit cleanly -/// @copyright (c) 2014-2024 This file is distributed under the MIT License. - -#include -#include - -int main(int argc, char *argv[]) -{ - printf("Hello from MentOS!\n"); - printf("This is the simplest example program.\n"); - return EXIT_SUCCESS; -} diff --git a/examples/02_fork.c b/examples/02_fork.c deleted file mode 100644 index e552aefca..000000000 --- a/examples/02_fork.c +++ /dev/null @@ -1,49 +0,0 @@ -/// @file 02_fork.c -/// @brief Second example: Process creation with fork() -/// @details This program demonstrates: -/// - Creating child processes with fork() -/// - Detecting parent vs child (fork returns different values) -/// - Waiting for child completion with waitpid() -/// - Process IDs (getpid, getppid) -/// @copyright (c) 2014-2024 This file is distributed under the MIT License. - -#include -#include -#include -#include - -int main(int argc, char *argv[]) -{ - printf("Parent: My PID is %d\n", getpid()); - - // Fork creates a new process - pid_t child_pid = fork(); - - if (child_pid < 0) { - // Error in forking - perror("fork"); - return EXIT_FAILURE; - } - - if (child_pid == 0) { - // Child process (fork returns 0 to child) - printf(" Child: My PID is %d, parent is %d\n", getpid(), getppid()); - printf(" Child: Doing some work...\n"); - sleep(1); - printf(" Child: Done! Exiting.\n"); - return EXIT_SUCCESS; - } else { - // Parent process (fork returns child's PID to parent) - printf("Parent: Child process created with PID %d\n", child_pid); - printf("Parent: Waiting for child to finish...\n"); - - int status; - waitpid(child_pid, &status, 0); - - if (WIFEXITED(status)) { - printf("Parent: Child exited with status %d\n", WEXITSTATUS(status)); - } - printf("Parent: All done!\n"); - return EXIT_SUCCESS; - } -} diff --git a/examples/03_pipes.c b/examples/03_pipes.c deleted file mode 100644 index f4390a9b4..000000000 --- a/examples/03_pipes.c +++ /dev/null @@ -1,66 +0,0 @@ -/// @file 03_pipes.c -/// @brief Third example: Inter-process communication with pipes -/// @details This program demonstrates: -/// - Creating pipes for IPC -/// - Parent-child communication through pipes -/// - Read and write operations on pipe file descriptors -/// - Closing unused pipe ends -/// @copyright (c) 2014-2024 This file is distributed under the MIT License. - -#include -#include -#include -#include -#include - -int main(int argc, char *argv[]) -{ - int pipefd[2]; - char buffer[256]; - const char *message = "Hello from parent!"; - - // Create a pipe: pipefd[0] is read end, pipefd[1] is write end - if (pipe(pipefd) == -1) { - perror("pipe"); - return EXIT_FAILURE; - } - - printf("Main: Created pipe\n"); - - pid_t child_pid = fork(); - - if (child_pid < 0) { - perror("fork"); - return EXIT_FAILURE; - } - - if (child_pid == 0) { - // Child process: read from pipe - printf(" Child: Closing write end of pipe\n"); - close(pipefd[1]); // Child doesn't write - - printf(" Child: Waiting to read from pipe...\n"); - ssize_t bytes_read = read(pipefd[0], buffer, sizeof(buffer) - 1); - - if (bytes_read > 0) { - buffer[bytes_read] = '\0'; // Null-terminate - printf(" Child: Received message: %s\n", buffer); - } - - close(pipefd[0]); // Done reading - return EXIT_SUCCESS; - } else { - // Parent process: write to pipe - printf("Main: Closing read end of pipe\n"); - close(pipefd[0]); // Parent doesn't read - - printf("Main: Writing message to pipe\n"); - write(pipefd[1], message, strlen(message)); - close(pipefd[1]); // Done writing - - printf("Main: Waiting for child...\n"); - waitpid(child_pid, NULL, 0); - printf("Main: All done!\n"); - return EXIT_SUCCESS; - } -} diff --git a/examples/04_file_io.c b/examples/04_file_io.c deleted file mode 100644 index 8ac3a555f..000000000 --- a/examples/04_file_io.c +++ /dev/null @@ -1,72 +0,0 @@ -/// @file 04_file_io.c -/// @brief Fourth example: File I/O operations -/// @details This program demonstrates: -/// - Opening files with open() -/// - Reading from files with read() -/// - Writing to files with write() -/// - File descriptors and flags (O_RDONLY, O_WRONLY, O_CREAT) -/// - Proper resource cleanup -/// @copyright (c) 2014-2024 This file is distributed under the MIT License. - -#include -#include -#include -#include -#include -#include - -int main(int argc, char *argv[]) -{ - const char *filename = "/home/user/example_output.txt"; - const char *message = "This file was created by 04_file_io example!\n" - "It demonstrates basic file I/O in MentOS.\n"; - - printf("Creating file: %s\n", filename); - - // Open file for writing, create if doesn't exist, truncate if exists - // Mode 0644 gives owner read/write, group/others read - int fd_write = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); - - if (fd_write < 0) { - perror("open (write)"); - return EXIT_FAILURE; - } - - printf("Writing data to file...\n"); - ssize_t bytes_written = write(fd_write, message, strlen(message)); - - if (bytes_written < 0) { - perror("write"); - close(fd_write); - return EXIT_FAILURE; - } - - printf("Wrote %ld bytes\n", bytes_written); - close(fd_write); - - // Now read the file back - printf("Reading file back...\n"); - int fd_read = open(filename, O_RDONLY, 0); - - if (fd_read < 0) { - perror("open (read)"); - return EXIT_FAILURE; - } - - char buffer[512]; - ssize_t bytes_read = read(fd_read, buffer, sizeof(buffer) - 1); - - if (bytes_read < 0) { - perror("read"); - close(fd_read); - return EXIT_FAILURE; - } - - buffer[bytes_read] = '\0'; // Null-terminate - printf("File contents:\n---\n%s---\n", buffer); - - close(fd_read); - printf("Done!\n"); - - return EXIT_SUCCESS; -} diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt deleted file mode 100644 index 2687eb003..000000000 --- a/examples/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ -# ============================================================================= -# PEDAGOGICAL EXAMPLES -# ============================================================================= -# These are simplified, well-documented examples to help students learn MentOS -# concepts in a natural progression: -# - 01_hello.c: Hello World -# - 02_fork.c: Process creation -# - 03_pipes.c: Inter-process communication -# - 04_file_io.c: File operations - -# List of example programs. -set(EXAMPLE_LIST - 01_hello.c - 02_fork.c - 03_pipes.c - 04_file_io.c -) - -# Set the directory where the compiled binaries will be placed. -set(MENTOS_EXAMPLES_DIR ${CMAKE_SOURCE_DIR}/filesystem/bin/examples) - -foreach(FILE_NAME ${EXAMPLE_LIST}) - # ========================================================================= - # TARGET NAMING - # ========================================================================= - # Prepare the program name. - string(REPLACE ".c" "" EXECUTABLE_NAME ${FILE_NAME}) - # Set the name of the target. - set(TARGET_NAME example_${EXECUTABLE_NAME}) - - # ========================================================================= - # TEXT ADDRESS - # ========================================================================= - # Randomize .text section address so when debugging symbols don't clash. - # The allowed range is from 256MB to 2.75GB - # Minimum allowed address: 0x10000000 - # Max allowed address: 0xB0000000 - string(MD5 RAND_HASH ${FILE_NAME}) - string(SUBSTRING ${RAND_HASH} 1 3 TEXADDR_INFIX) - string(RANDOM LENGTH 1 ALPHABET 0123456789AB RANDOM_SEED ${RAND_HASH} TEXADDR_FIRST) - set(TEXT_ADDR 0x${TEXADDR_FIRST}${TEXADDR_INFIX}0000) - - # ========================================================================= - # EXECUTABLE - # ========================================================================= - # Create the target. - add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/${FILE_NAME}) - # Add the dependency to libc. - add_dependencies(${TARGET_NAME} libc) - # Add the includes. - target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/lib/inc) - # Link the libc library. - target_link_libraries(${TARGET_NAME} libc) - # We need to specify the name of the entry function. - target_compile_options(${TARGET_NAME} PRIVATE -u_start) - # Add the linking properties. - set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "-Wl,-Ttext=${TEXT_ADDR},-e_start,-melf_i386") - # Set the output directory. - set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${MENTOS_EXAMPLES_DIR}") - # Set the output name. - set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME "${EXECUTABLE_NAME}") - - # Append the program name to the list of all the executables. - list(APPEND ALL_EXAMPLES ${TARGET_NAME}) -endforeach() - -# Add the overall target that builds all the examples. -add_custom_target(examples ALL DEPENDS ${ALL_EXAMPLES})