From 3f478d3b96a10340be0954992825b1e51b52063d Mon Sep 17 00:00:00 2001 From: stickynotememo Date: Fri, 19 Dec 2025 18:13:45 +1100 Subject: [PATCH] Added python Also updated Makefile for ease of use. --- 2q | 25 ------------------------- Makefile | 18 +++++++++++------- README.md | 15 +++++++++++++++ src/3_rust.rs | 16 +++++++++++++--- src/4_python.py | 21 +++++++++++++++++++++ 5 files changed, 60 insertions(+), 35 deletions(-) delete mode 100644 2q create mode 100644 src/4_python.py diff --git a/2q b/2q deleted file mode 100644 index f57f6f7..0000000 --- a/2q +++ /dev/null @@ -1,25 +0,0 @@ -use std::ffi::CStr; -use std::ffi::c_char; - -#[cfg(target_family = "unix")] -extern "C" { - fn _2_c_func() -> *const c_char; -} - -fn main() -> Result<(), String> { - let raw_string_pointer: *const c_char = unsafe { _2_c_func() }; - if raw_string_pointer.is_null() { - return Err(String::from("pointer is null")); - }; - let c_string = unsafe { CStr::from_ptr(raw_string_pointer) }; // SAFETY: we are assuming the - // string is null terminated since we created it ourselves in a previous program. However, if - // it is not, it is UB. - - let Some(string) = c_string.to_str() else { - return Err(String::from("string should be null terminated")) - }; - - println!("{}", string); - Ok(()) -} - diff --git a/Makefile b/Makefile index a9d9314..c81910a 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,18 @@ -3_rust: 2_c - rustc -Clink-arg=target/1_assembly.o -Clink-arg=target/2_c.o src/3_rust.rs -o target/3_rust --verbose - # rustc src/3_rust.rs -o target/3_rust --verbose - # -L target -l 2_c +target/4_python.py: target/3_rust src/4_python.py + cp src/4_python.py target/4_python.py -2_c: 1_assembly +target/3_rust: target/2_c.o src/3_rust.rs + rustc -Clink-arg=target/1_assembly.o -Clink-arg=target/2_c.o src/3_rust.rs -o target/3_rust + +target/2_c.o: target/1_assembly.o src/2_c.c gcc -Wall -Wpedantic -Werror src/2_c.c -c -fPIC -o target/2_c.o - # ar rcs target/lib2_c.a target/2_c.o -1_assembly: +target/1_assembly.o: src/1_assembly.S nasm -f elf64 src/1_assembly.S -o target/1_assembly.o +.PHONY: clean run clean: rm target/* + +run: src/4_python.py + python target/4_python.py diff --git a/README.md b/README.md index 9c384fd..d6a4252 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,17 @@ # Chinese Whispers A project to pass a string between as many languages as I know. + +Has no practical purpose, but it's interesting to see how far I can push the idea. It's also teaching me a lot about IPC. + +If you know any languages not on the list, please add them! Each file should be named n_[programming language], where n is the number of the program. It should take in a string, and append "Hello from [programming language].\n". It is your resonsibility to add appropriate output IPC to the previous file, so that it can interface with your program. + +Chain of messages: + +1. NASM x86_64 Assembly +2. C +3. Rust +4. Python + +## Requirements +- Linux x86_64 +- Python interpreter diff --git a/src/3_rust.rs b/src/3_rust.rs index 2bca2e7..561c402 100644 --- a/src/3_rust.rs +++ b/src/3_rust.rs @@ -1,5 +1,8 @@ use std::ffi::CStr; use std::ffi::c_char; +use std::path::Path; +use std::fs::*; +use std::io::Write; #[cfg(target_family = "unix")] extern "C" { @@ -7,9 +10,9 @@ extern "C" { } fn main() -> Result<(), String> { + // Get input string let raw_string_pointer: *const c_char = unsafe { _2_c_func() }; - if raw_string_pointer.is_null() { - return Err(String::from("pointer is null")); + if raw_string_pointer.is_null() { return Err(String::from("pointer is null")); }; let c_string = unsafe { CStr::from_ptr(raw_string_pointer) }; // SAFETY: we are assuming the // string is null terminated since we created it ourselves in a previous program. However, if @@ -20,8 +23,15 @@ fn main() -> Result<(), String> { }; let mut string = String::from(string); + + ////////////////////////////////////// string.push_str("Hello from Rust."); - println!("{}", string); + + ////////////////////////////////////// + + let pipe_path = &Path::new("chinese_whispers_pipe"); + let mut file = File::create(pipe_path).expect("Couldn't open pipe!"); + file.write(string.as_bytes()).expect("Couldn't write to pipe!"); Ok(()) } diff --git a/src/4_python.py b/src/4_python.py new file mode 100644 index 0000000..9d119ad --- /dev/null +++ b/src/4_python.py @@ -0,0 +1,21 @@ +# adapted from https://stackoverflow.com/a +# Retrieved 2025-12-19, License - CC BY-SA 3.0 + +import os +import errno + +try: + os.mkfifo('chinese_whispers_pipe') +except OSError as oe: + if oe.errno != errno.EEXIST: + raise + +os.system("./target/3_rust &"); # Run 3_rust in background to start writing to pipe + +with open('chinese_whispers_pipe') as fifo: + data = fifo.read() + +print(data + "\nHello from Python.") + + +