u/Fair_Temperature_420

Quest to see rust project in game of trees

Had a rust project and wanted to see game of trees working.

I made backup copy of my rust project before starting this to be safe.

I have no ideal how .git folder ended up in my rust project unless its used internally ?

Remove the .git folder in rust project if its there. This is very important because the g.o.t. don't like .git in your work tree. You can leave .gitignore.

~/ is your home directory /home/someone

// -p make all directories
mkdir -p ~/got-repos/bin
// -b stands for branch
gotadmin init -b main ~/got-repos/bin/project.git

open a text editor and save got.conf file into ~/got-repos/bin/project.git containing

author "your name <someone@somewhere.com>"

space between your name and email is important.

// -m stands for message
// -r repository directory
// . means all
got import -m "Setup" -r ~/got-repos/bin/project.git ~/rust_project/.
// -E file already exist
got checkout -E ~/got-repos/bin/project.git

Now you should see a new directory in ~/got-repos/bin/project folder next to your project.git folder containing your Cargo.toml and src/main.rs.

While inside this project folder run ls -a you should see .got directory

got commands should be run in this directory: ex. got add src/another.rs

got status .got show list of information am still learning.

New to git and g.o.t. this was neat seeing it track changes in the code and showing the format changes.

reddit.com
u/Fair_Temperature_420 — 2 days ago

The man 2 sysctl is interesting function for communicating with a the system kernel.

The two part process of getting size of data and storing it in a buffer.

My take on getting a Process Arguments in Rust on OpenBSD.

// used for C types
use std::ffi::c_void;
// used for ptr::null_mut();
use std::ptr;

// size_t in C
type SizeT = usize;


unsafe extern "C"{
  fn sysctl(
    name:*const i32,
    namelen:u32,
    oldp:*mut c_void,
    oldlenp:*mut SizeT,
    newp:*mut c_void,
    newlen:SizeT
  )->i32;
}

fn main()
{  
  // can be found in /usr/include/sys/sysctl.h
  // const CTL_KERN:i32 = ; 
  // const KERN_PROC_ARGS:i32 = ;  
  // const KERN_PROC_ARGV:i32 = ;
 
  // run man 2 sysctl &
  // [0] 1551   
  // let pid:i32 = 1551;
  
  let mib:[i32;4] = [CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_ARGV ];
  
  let mut size:SizeT = 0;
  
  // Lets get the size  
  if unsafe{
     sysctl(
       mib.as_ptr(),
       mib.len() as u32,// keyword as is for type casting like (int)
       ptr::null_mut(), 
       // need the size of data
       &mut size as *mut SizeT, 
       ptr::null_mut(), 
       0) 
      } == -1 {
      eprintln!("Getting Data Size Failed");
      return;
  }
  // lets get the data
  let mut args:Vec<u8> = vec![0u8;size];
  if unsafe{
    sysctl(
      mib.as_ptr(),
      mib.len() as u32,
      // pass the buffer 
      args.as_mut_ptr() as *mut c_void, 
      &mut size as *mut SizeT, 
      ptr::null_mut(), 
      0) } == -1 {
      eprintln!("Getting Data Failed");
      return;
  }
  // This is really neat the kernel took my buffer and made a pointer 
  // table in it.
  // In C this is easy 
  // Zero-copy "parsing" char **argv = (char **)args; 
  // Now argv[0] works instantly return done!
  
  // I don't need it. Could I use it? Have to do more
  // research on this vec from raw parts?. What if rust wanted to
  // return a raw Vec<String> what would this look like as a raw [u8]? 
  
  // print 0-31 bytes making sure pointer address match to human eye
  // println!("\n----Buffer---");
  // args[0..32].iter().for_each(|byte|print!("{:x} ",*byte));
  // println!();

  // Pointers are type usize in rust
  let mut ptr_table:Vec<usize> = Vec::new();

  // Store 8 bytes of them for a pointer
  // I should use const size_of::<usize>();
  let mut ptr:[u8;8] = [0;8];

  // Where the strings starts
  let mut string_start:usize = 0; 
 
  // Lets create a 8 byte iterator on args
  let mut chunk = args.chunks_exact(8);
  
  // This is if you want to keep the pointers  
  // Lets process the pointers until null pointer 8 * 0x00
  while let Some(part8) = chunk.next() {
    
    for (i,byte) in part8.iter().enumerate() {
      ptr[i] = *byte;
    }
    // Array -> native endian -> usize
    let hold = usize::from_ne_bytes(ptr);
    
    // Pointer or null add 8
    string_start += 8;

    // Null pointer reached?
    if hold == 0 { break; } else { ptr_table.push(hold); } 

 }
  // Now we only care about the data from string_start to 'size'
  let relevant_data = &args[string_start..size];

  // Check memory address of 1st string with pointers
  // print a pointer {:p}
  println!("1st string_start_char:{:p} = 0x{:x}",
      &relevant_data[0],
      ptr_table[0]
  );

  let command: Vec<String> = relevant_data
  // split the slice at every null byte
    .split(|&b| b == 0)             
  // ignore empty chunks (double nulls)
    .filter(|s| !s.is_empty())      
  // convert to string
    .map(|s| String::from_utf8_lossy(s).into_owned()) 
  // put it all into a vec
    .collect();                     

  // This is a debug print "{:?}" so is dbg!(command);
  println!("{:?}",command);
}

This is all I have save it and run rustc on it. If you don't want to look up the constants in sysctl.h then its 1, 55, 1.

reddit.com
u/Fair_Temperature_420 — 20 days ago