diff --git a/.gitignore b/.gitignore index 3d8789c..2cafb9a 100644 --- a/.gitignore +++ b/.gitignore @@ -56,4 +56,3 @@ dkms.conf # Nix related things .direnv/ -result*/ diff --git a/README.md b/README.md deleted file mode 100644 index ba72f97..0000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# CS 3502 Operating Systems Assignments - -This repository contains my work for CS 3502: Operating Systems. diff --git a/assignment1/default.nix b/assignment1/default.nix deleted file mode 100644 index 293fb6b..0000000 --- a/assignment1/default.nix +++ /dev/null @@ -1,22 +0,0 @@ -let - basic-c = name: { stdenv }: - stdenv.mkDerivation { - inherit name; - src = ./.; - buildPhase = '' - runHook preBuild - gcc part2/${name}.c -o ${name} - runHook postBuild - ''; - installPhase = '' - runHook preInstall - mkdir -p $out/bin - install ${name} $out/bin/ - runHook postInstall - ''; - }; -in { - a1-hello = basic-c "hello"; - a1-employee = basic-c "employee"; - a1-logwriter = basic-c "logwriter"; -} diff --git a/assignment1/part1/neofetch.png b/assignment1/part1/neofetch.png deleted file mode 100644 index a2bd8bc..0000000 Binary files a/assignment1/part1/neofetch.png and /dev/null differ diff --git a/assignment1/part1/nix_gcc.png b/assignment1/part1/nix_gcc.png deleted file mode 100644 index ecb0860..0000000 Binary files a/assignment1/part1/nix_gcc.png and /dev/null differ diff --git a/assignment1/part2/employee.c b/assignment1/part2/employee.c deleted file mode 100644 index 70c3465..0000000 --- a/assignment1/part2/employee.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include - -int main() { - // Character array to store name - // In C, strings are arrays of characters ending with '\0' - char name[50]; - int employee_id; - float hours_worked; - - printf("OwlTech Employee Registration\n"); - printf("=============================\n"); - - printf("Enter your name: "); - // fgets reads a line including spaces - // stdin means "standard input" (keyboard) - fgets(name, sizeof(name), stdin); - - // Remove newline that fgets includes - name[strcspn(name, "\n")] = '\0'; - - printf("Enter your employee ID: "); - // & means "address of" - scanf needs to know where to store the value - scanf("%d", &employee_id); - printf("Hours worked this week: "); - scanf("%f", &hours_worked); - - printf("\nEmployee Summary:\n"); - printf("Name: %s\n", name); // %s for string - printf("ID: %d\n", employee_id); // %d for integer - printf("Hours: %.2f\n", hours_worked); // %.2f for float with 2 decimals - - return 0; -} diff --git a/assignment1/part2/employee.png b/assignment1/part2/employee.png deleted file mode 100644 index df1ef0e..0000000 Binary files a/assignment1/part2/employee.png and /dev/null differ diff --git a/assignment1/part2/hello.c b/assignment1/part2/hello.c deleted file mode 100644 index a936748..0000000 --- a/assignment1/part2/hello.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int main() { - printf("Welcome to OwlTech Industries!\n"); - printf("Systems Programming Division\n"); - - return 0; -} diff --git a/assignment1/part2/hello.png b/assignment1/part2/hello.png deleted file mode 100644 index 4778b67..0000000 Binary files a/assignment1/part2/hello.png and /dev/null differ diff --git a/assignment1/part2/log.png b/assignment1/part2/log.png deleted file mode 100644 index b415757..0000000 Binary files a/assignment1/part2/log.png and /dev/null differ diff --git a/assignment1/part2/logwriter.c b/assignment1/part2/logwriter.c deleted file mode 100644 index d5e8087..0000000 --- a/assignment1/part2/logwriter.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include - -int main() { - FILE *logfile; // Pointer to file structure - char message[100]; - time_t current_time; - - // Open file for appending ("a" mode) - // "w" would overwrite, "r" would read - logfile = fopen("owltech.log", "a"); - - // Always check if file opened successfully - if (logfile == NULL) { - printf("Error: Could not open log file\n"); - return 1; // Return non-zero to indicate error - } - - printf("Enter log message: "); - fgets(message, sizeof(message), stdin); - - // Get current time - time(¤t_time); - - // Write to file with timestamp - // fprintf works like printf but writes to a file - fprintf(logfile, "[%s] %s", ctime(¤t_time), message); - - // Always close files when done - fclose(logfile); - printf("Log entry saved successfully!\n"); - - // Display the log file contents - printf("\n--- Current Log Contents ---\n"); - system("cat owltech.log"); - - return 0; -} diff --git a/assignment1/part2/logwriter.png b/assignment1/part2/logwriter.png deleted file mode 100644 index 0d07bb4..0000000 Binary files a/assignment1/part2/logwriter.png and /dev/null differ diff --git a/assignment1/part3/gitconfig.png b/assignment1/part3/gitconfig.png deleted file mode 100644 index 8e7f91d..0000000 Binary files a/assignment1/part3/gitconfig.png and /dev/null differ diff --git a/assignment1/test.nix b/assignment1/test.nix deleted file mode 100644 index 0967ef4..0000000 --- a/assignment1/test.nix +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/assignment2/default.nix b/assignment2/default.nix deleted file mode 100644 index 7f9f5b6..0000000 --- a/assignment2/default.nix +++ /dev/null @@ -1,26 +0,0 @@ -let - basic-c = subdir: name: { stdenv }: - stdenv.mkDerivation { - inherit name; - src = ./.; - buildPhase = '' - runHook preBuild - gcc ${subdir}/${name}.c -o ${name} - runHook postBuild - ''; - installPhase = '' - runHook preInstall - mkdir -p $out/bin - install ${name} $out/bin/ - runHook postInstall - ''; - }; -in { - a2-p1-producer = basic-c "part1" "producer"; - a2-p1-consumer = basic-c "part1" "consumer"; - - a2-p2-bidirectional = basic-c "part2" "bidirectional"; - - a2-p3-producer = basic-c "part3" "producer"; - a2-p3-consumer = basic-c "part3" "consumer"; -} diff --git a/assignment2/part1/consumer.c b/assignment2/part1/consumer.c deleted file mode 100644 index 8f0bc4b..0000000 --- a/assignment2/part1/consumer.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include -#include -#include -#include -#include - -int main(int argc, char *argv[]) { - int max_lines = -1; // -1 means unlimited - int verbose = 0; - - // Parse arguments (-n max_lines, -v verbose) - char opt; - while ((opt = getopt(argc, argv, "n:v")) != -1) { - switch (opt) { - case 'n': - max_lines = atoi(optarg); break; - case 'v': - verbose = 1; break; - default: - printf("Usage: %s [-n max_lines] [-v]\n", argv[0]); - return 1; - } - } - - // Read from stdin line by line - // Count lines and characters - // If verbose, echo lines to stdout - char buffer[256]; - int lines = 0; - int chars = 0; - while (fgets(buffer, sizeof(buffer), stdin) != NULL) { - int size = strlen(buffer); - if (verbose) - fwrite(buffer, sizeof(char), size, stdout); - chars += size; - if (size > 0 && buffer[size - 1] == '\n') - lines++; - if (lines == max_lines) - break; - } - - // Print statistics to stderr - fprintf(stderr, "Lines: %d\n", lines); - - return 0; -} diff --git a/assignment2/part1/producer.c b/assignment2/part1/producer.c deleted file mode 100644 index 291e39c..0000000 --- a/assignment2/part1/producer.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include -#include - -int main(int argc, char *argv[]) { - FILE *input = stdin; - int buffer_size = 4096; - - // Parse command line arguments - // -f filename (optional) - // b buffer_size (optional) - char opt; - while ((opt = getopt(argc, argv, "f:b:")) != -1) { - switch (opt) { - case 'f': - input = fopen(optarg, "r"); - if (input == NULL) { - fprintf(stderr, "Error: Could not open input file\n"); - return EXIT_FAILURE; - } - break; - case 'b': - buffer_size = atoi(optarg); break; - default: - printf("Usage: %s [-f filename] [-b buffer_size]\n", argv[0]); - return 1; - } - } - - // Allocate buffer - char *buffer = malloc(buffer_size); - - // Read from input and write to stdout - while (fgets(buffer, buffer_size, input) != NULL) { - fwrite(buffer, sizeof(char), strlen(buffer), stdout); - } - - // Cleanup - free(buffer); - - return 0; -} diff --git a/assignment2/part1/test b/assignment2/part1/test deleted file mode 100755 index 4ed3156..0000000 --- a/assignment2/part1/test +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash - -echo "Building executables..." - -cd "${FLAKE:-$(dirname $0)}" -if command -v nix; then - producer="$(nix build --no-link --print-out-paths .#a2-p1-producer)/bin/producer" - consumer="$(nix build --no-link --print-out-paths .#a2-p1-consumer)/bin/consumer" -else - gcc producer.c -o producer - gcc consumer.c -o consumer - producer="./producer" - consumer="./consumer" -fi - -echo -e "\nTEST - Sanity Check" - -out="$(seq -s " " 1 10 | "$producer" | "$consumer" -v)" -if test "$out" = "$(seq -s " " 1 10)"; then - echo "SUCCESS" -fi - -echo -e "\nTEST - Smaller Buffer Size" - -out="$(seq -s " " 1 10 | "$producer" -b 16 | "$consumer" -v)" -if test "$out" = "$(seq -s " " 1 10)"; then - echo "SUCCESS" -fi - -echo -e "\nTEST - Large External File" - -head -c 10000 random.txt -out="$("$producer" -f random.txt | "$consumer" -v)" -if test "$out" = "$(cat random.txt)"; then - echo "SUCCESS" -fi -rm random.txt - - -echo -e "\nTEST - Maximum Lines (5)" - -head -c 1000 random.txt -out="$("$producer" -f random.txt | "$consumer" -v -n 5)" -if test "$out" = "$(cat random.txt | head -n 5)"; then - echo "SUCCESS" -fi -rm random.txt diff --git a/assignment2/part2/bidirectional.c b/assignment2/part2/bidirectional.c deleted file mode 100644 index c123f51..0000000 --- a/assignment2/part2/bidirectional.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include -#include - -int main () { - int pipe1[2]; // Parent to child - int pipe2[2]; // Child to parent - - // Create both pipes - if (pipe(pipe1) == -1 || pipe(pipe2) == -1) { - fprintf(stderr, "Could not open pipes"); - return 1; - } - - // Fork process - pid_t pid = fork(); - - if (pid == 0) { - // Child process - - // Close unused pipe ends - close(pipe1[1]) ; // Close write end of pipe1 - close(pipe2[0]) ; // Close read end of pipe2 - - // Read message, send response - char *message = malloc(100); - read(pipe1[0], message, 100); - printf("%s", message); - free(message); - - char response[] = "Response from child to parent\n"; - write(pipe2[1], response, sizeof(response)); - } else { - // Parent process - - // Close unused pipe ends - close(pipe1[0]) ; // Close read end of pipe1 - close(pipe2[1]) ; // Close write end of pipe2 - - // Send message, read response - char message[] = "Sending message from parent to child\n"; - write(pipe1[1], message, sizeof(message)); - - char *response = malloc(100); - read(pipe2[0], response, 100); - printf("%s", response); - free(response); - - // Wait for child process to terminate - waitpid(pid, NULL, 0); - } - - return 0; -} diff --git a/assignment2/part2/test b/assignment2/part2/test deleted file mode 100755 index f036c53..0000000 --- a/assignment2/part2/test +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -echo "Building executable..." - -cd "${FLAKE:-$(dirname $0)}" -if command -v nix; then - bidirectional="$(nix build --no-link --print-out-paths .#a2-p2-bidirectional)/bin/bidirectional" -else - gcc bidirectional.c -o bidirectional - bidirectional="./bidirectional" -fi - -out="$("$bidirectional")" -read -r -d '' expected < -#include -#include -#include -#include -#include -#include - -volatile sig_atomic_t shutdown_flag = 0; -volatile sig_atomic_t stats_flag = 0; - -void handle_sigint(int sig) { - shutdown_flag = 1; -} - -void handle_sigusr1(int sig) { - stats_flag = 1; -} - -int main(int argc, char *argv[]) { - struct sigaction sa_sigint; - sa_sigint.sa_handler = handle_sigint; - sigemptyset(&sa_sigint.sa_mask); - sa_sigint.sa_flags = 0; - sigaction(SIGINT, &sa_sigint, NULL); - - struct sigaction sa_sigusr1; - sa_sigusr1.sa_handler = handle_sigusr1; - sigemptyset(&sa_sigusr1.sa_mask); - sa_sigusr1.sa_flags = 0; - sigaction(SIGUSR1, &sa_sigusr1, NULL); - - int max_lines = -1; // -1 means unlimited - int verbose = 0; - - // Parse arguments (-n max_lines, -v verbose) - char opt; - while ((opt = getopt(argc, argv, "n:v")) != -1) { - switch (opt) { - case 'n': - max_lines = atoi(optarg); break; - case 'v': - verbose = 1; break; - default: - printf("Usage: %s [-n max_lines] [-v]\n", argv[0]); - return 1; - } - } - - clock_t start = clock(); - - // Read from stdin line by line - // Count lines and characters - // If verbose, echo lines to stdout - char buffer[256]; - int lines = 0; - int chars = 0; - while (fgets(buffer, sizeof(buffer), stdin) != NULL) { - int size = strlen(buffer); - if (verbose) - fwrite(buffer, sizeof(char), size, stdout); - chars += size; - if (size > 0 && buffer[size - 1] == '\n') - lines++; - if (lines == max_lines) - break; - - // Handle shutdown - if (shutdown_flag) { - fprintf(stderr, "Cancelled\n"); - return 1; - } - } - - // Print statistics to stderr (handle SIGUSR1) - if (stats_flag) { - clock_t end = clock(); - double time = ((double)(end - start)) / CLOCKS_PER_SEC; - double throughput = (double)chars / 1024.0 / 1024.0 / time; - printf("Stats:\n"); - printf("File Size: %d bytes\n", chars); - printf("Total Time: %.3f secs\n", time); - printf("Throughput: %.3f MB/s\n", throughput); - } - fprintf(stderr, "Lines: %d\n", lines); - - return 0; -} diff --git a/assignment2/part3/producer.c b/assignment2/part3/producer.c deleted file mode 100644 index fb634fc..0000000 --- a/assignment2/part3/producer.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -#include -#include -#include -#include - -volatile sig_atomic_t shutdown_flag = 0; - -void handle_sigint(int sig) { - shutdown_flag = 1; -} - -int main(int argc, char *argv[]) { - struct sigaction sa; - sa.sa_handler = handle_sigint; - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sigaction(SIGINT, &sa, NULL); - - FILE *input = stdin; - int buffer_size = 4096; - - // Parse command line arguments - // -f filename (optional) - // b buffer_size (optional) - char opt; - while ((opt = getopt(argc, argv, "f:b:")) != -1) { - switch (opt) { - case 'f': - input = fopen(optarg, "r"); - if (input == NULL) { - fprintf(stderr, "Error: Could not open input file\n"); - return EXIT_FAILURE; - } - break; - case 'b': - buffer_size = atoi(optarg); break; - default: - printf("Usage: %s [-f filename] [-b buffer_size]\n", argv[0]); - return 1; - } - } - - // Allocate buffer - char *buffer = malloc(buffer_size); - - // Read from input and write to stdout - while (fgets(buffer, buffer_size, input) != NULL) { - fwrite(buffer, sizeof(char), strlen(buffer), stdout); - - // Handle shutdown - if (shutdown_flag) { - fprintf(stderr, "Cancelled\n"); - return 1; - } - } - - // Cleanup - free(buffer); - - return 0; -} diff --git a/assignment2/part3/test b/assignment2/part3/test deleted file mode 100755 index d81d0a7..0000000 --- a/assignment2/part3/test +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash - -echo "Building executables..." - -cd "${FLAKE:-$(dirname $0)}" -if command -v nix; then - producer="$(nix build --no-link --print-out-paths .#a2-p3-producer)/bin/producer" - consumer="$(nix build --no-link --print-out-paths .#a2-p3-consumer)/bin/consumer" -else - gcc producer.c -o producer - gcc consumer.c -o consumer - producer="./producer" - consumer="./consumer" -fi - -seq 1 10000000 >large.txt - -echo -e "\nTEST - Buffer size 1024" -"$producer" -b 1024 -f large.txt | "$consumer" & -kill -USR1 "$(pidof consumer)" -wait "$(jobs -rp)" - -echo -e "\nTEST - Buffer size 4096" -"$producer" -b 4096 -f large.txt | "$consumer" & -kill -USR1 "$(pidof consumer)" -wait "$(jobs -rp)" - -echo -e "\nTEST - Buffer size 16384" -"$producer" -b 16384 -f large.txt | "$consumer" & -kill -USR1 "$(pidof consumer)" -wait "$(jobs -rp)" - -rm large.txt diff --git a/assignment2/test.nix b/assignment2/test.nix deleted file mode 100644 index f04cf34..0000000 --- a/assignment2/test.nix +++ /dev/null @@ -1,12 +0,0 @@ -let - bash-test = subdir: { runCommandLocal }: - runCommandLocal "${subdir}-test" { FLAKE = ../.; } - '' - mkdir -p $out/bin - install ${subdir}/test $out/bin/ - ''; -in { - a2-p1 = bash-test "part1"; - a2-p2 = bash-test "part2"; - a2-p3 = bash-test "part3"; -} diff --git a/flake.nix b/flake.nix index 03d2962..bccf8ee 100644 --- a/flake.nix +++ b/flake.nix @@ -7,25 +7,11 @@ }; outputs = { self, nixpkgs, systems, ... }: - let - subdirs = [ - "assignment1" - "assignment2" - ]; - - eachSystem = nixpkgs.lib.genAttrs (import systems); - - importFromSubdirs = file: eachSystem (system: - let pkgs = nixpkgs.legacyPackages.${system}; - in pkgs.lib.mergeAttrsList - (builtins.map (d: - builtins.mapAttrs - (_: v: pkgs.callPackage v {}) - (import ./${d}/${file})) - subdirs)); + let eachSystem = nixpkgs.lib.genAttrs (import systems); in { - packages = importFromSubdirs "default.nix"; - checks = importFromSubdirs "test.nix"; + packages = eachSystem (system: + let pkgs = nixpkgs.legacyPackages.${system}; + in {}); devShells = eachSystem (system: let pkgs = nixpkgs.legacyPackages.${system}; diff --git a/shell.nix b/shell.nix index cc840a0..e155fa2 100644 --- a/shell.nix +++ b/shell.nix @@ -1,4 +1,2 @@ -{ mkShell }: - -# GCC is provided by default -mkShell {} +{ pkgs }: +pkgs.mkShell {}