Keine Beschreibung
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

main.rs 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. use std::env::args;
  2. use std::process;
  3. extern crate nix;
  4. use nix::unistd::{fork, pipe, read, write};
  5. use nix::sys::wait::wait;
  6. use std::str;
  7. use nix::sys::wait::WaitStatus;
  8. use nix::unistd::ForkResult::{Child, Parent};
  9. use std::os::unix::io::RawFd;
  10. const BUFFER_SIZE : usize = 256;
  11. fn main() {
  12. let arguments: Vec<String> = args().collect();
  13. if arguments.len() > 2 {
  14. if let Ok((reader, writer)) = pipe(){
  15. let numbers = arguments[1..].to_vec();
  16. let pid = fork();
  17. match pid {
  18. Ok(Child) => {
  19. match read_from_pipe(reader) {
  20. Ok(msg_received) => {
  21. let vec = split_into_strings(&msg_received);
  22. let pid = fork();
  23. match pid {
  24. Ok(Child) => {
  25. match sum_strings(vec) {
  26. Ok(res) => println!("Sum = {}", res),
  27. Err(e) => println!("{}", e),
  28. }
  29. },
  30. Ok(Parent{..}) => {
  31. if let Ok(ws) = wait() {
  32. if let WaitStatus::Exited(_,_) = ws {
  33. match mul_strings(vec) {
  34. Ok(res) => println!("Mul = {}", res),
  35. Err(e) => println!("{}", e),
  36. }
  37. }
  38. }
  39. },
  40. Err(_) => println!("Fatal error: Fork failed"),
  41. }
  42. },
  43. Err(_) => {},
  44. }
  45. }
  46. Ok(Parent{..}) => {
  47. let mut args = String::new();
  48. for s in numbers {
  49. args = concatenate_strings(&args, &concatenate_strings(&s , " "));
  50. }
  51. println!("sending to children: {}", args);
  52. if let Err(_) = write(writer, args.as_bytes()) { println!("Broken pipe") }
  53. if let Err(_) = wait() {
  54. println!("Waiting on children failed")
  55. }
  56. }
  57. Err(_) => {}
  58. }
  59. }
  60. } else {
  61. println!("Correct usage: number number <number> ...");
  62. process::exit(1)
  63. }
  64. }
  65. fn read_from_pipe(reader:RawFd) -> Result<String, String>{
  66. let mut read_buf = [0u8; BUFFER_SIZE];
  67. match read(reader, &mut read_buf){
  68. Ok(bytes_read) => {
  69. match str::from_utf8(&read_buf[0 .. bytes_read]) {
  70. Ok(msg_received) => Ok(msg_received.to_string()),
  71. Err(_) => Err("Couldn't read".to_string()),
  72. }
  73. },
  74. Err(_) => Err("Couldn't read".to_string()),
  75. }
  76. }
  77. /// Concats the two given String *references* and returns them as a String.
  78. fn concatenate_strings<'a>(s1: &'a str, s2: &'a str) -> String {
  79. s1.to_string() + s2
  80. }
  81. /// Splits the given String reference and returns it as Vector.
  82. fn split_into_strings<'a>(s1: &'a str) -> Vec<String> {
  83. s1.to_string()
  84. .split_whitespace()
  85. .map(|s| s.to_string())
  86. .collect()
  87. }
  88. /// Calculates the sum of the given Strings and returns them as a Result.
  89. fn sum_strings(v: Vec<String>) -> Result<i32, String> {
  90. let mut sum = 0;
  91. for x in v {
  92. match x.parse::<i32>() {
  93. Ok(val) => {
  94. match i32::checked_add(sum, val) {
  95. Some(y) => {
  96. sum = y;
  97. }
  98. None => return Err("Overflow would happen in sum_strings()".to_string()),
  99. }
  100. }
  101. Err(_) => return Err("Given String is not a int".to_string()),
  102. }
  103. }
  104. Ok(sum)
  105. }
  106. /// Calculates the product of the given Strings and returns them as a Result.
  107. fn mul_strings(v: Vec<String>) -> Result<i32, String> {
  108. let mut prod = 1;
  109. for x in v {
  110. match x.parse::<i32>() {
  111. Ok(val) => {
  112. match i32::checked_mul(prod, val) {
  113. Some(y) => {
  114. prod = y;
  115. }
  116. None => return Err("Overflow would happen in mul_strings()".to_string()),
  117. }
  118. }
  119. Err(_) => return Err("Given String is not a int".to_string()),
  120. }
  121. }
  122. Ok(prod)
  123. }