Unable to override temporary file with `tempfile` - rust

Getting an error when creating a tempfile for socket use.:
Error: Custom { kind: AlreadyExists, error: PathError { path: "/tmp", err: Custom { kind: AlreadyExists, error: "too many temporary files exist" } } }
use tempfile::{tempfile, Builder, NamedTempFile};
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let file = Builder::new().prefix("testsock").rand_bytes(0).tempfile()?;
Ok(())
}
Is there any way I can override the file?

The two many files exist error occurs if the file it is trying to create already exists. You can solve this error by deleting the files in your temp dir. In your case this is probably in /tmp/testsock/, you may also need to remove the folder testsock if just deleting the files does not work.
The default temp file will be used if .tempfile()
However you can specify the tempfile if you use the following.
let tmp = Builder::new()
.prefix("example")
.rand_bytes(0)
.tempfile_in("./")?;
The documentation for the tempfile builder can be found:
https://docs.rs/tempfile/latest/tempfile/struct.Builder.html

Related

Is it possible to access current file name?

Is it possible to access current file name in Rust by
// main.rs
fn main() {
println!("filename: {}", FILE_NAME);
}
?
(This program should print filename: main.rs)
You can use the std::file macro to get the current source filename at the compile time.
let this_file = file!();
If you want to remove the path from the returned filename, you can construct a Path with it and call the file_name method.
let filename_only = Path::new(this_file).file_name().and_then(|s| s.to_str()).unwrap();
Playground

Compressing and decompressing a tar.gz file

I'm trying to compress a directory into a tar.gz file and decompressing it after using Rust.
I'm using the crates tar = "0.4.35" and flate2 = "1.0.20". I'm on Windows.
My code is almost identical to the examples here.
let tar = File::create("a.tar.gz").unwrap();
let enc = GzEncoder::new(tar, Compression::default());
let mut a = tar::Builder::new(enc);
a.append_dir_all("", "in").unwrap();
let tar = File::open("a.tar.gz").unwrap();
let dec = GzDecoder::new(tar);
let mut a = Archive::new(dec);
a.unpack("out").unwrap();
I'm always getting an error when decompressing:
thread 'main' panicked at 'called Result::unwrap() on an Errvalue: Custom { kind: InvalidInput, error: TarError { desc: "failed to iterate over archive", io: Custom { kind: InvalidInput, error: "invalid gzip header" } } }', src\main.rs:21:26
I can open the generated tar.gz in 7-Zip without a problem.
What am I doing wrong or is it an issue with the crates?
I found the issue!
Apparently there are reading and writing encoders and decoders in flate2. They both have the same name so you can't distinguish them easily when importing. You have to be careful importing the right ones or you'll get strange errors.
In my example I have to import:
use flate2::write::{GzEncoder};
use flate2::read::{GzDecoder};

How to create a folder outside the poject directory in rust

I using rust to create a folder in ~, however when my code runs the directory is created inside my project's folder instead in ~.
My code:
use std::fs::create_dir_all;
use std::path::Path;
fn main() {
let path = Path::new("~/.hidden_folder");
match create_dir_all(path) {
Ok(f) => {
println!("created folder")
},
Err(err) => {
println!("{:?}", err);
}
};
}
Any idea how to create the folder in the correct directory ?
If you want your home directory, I recommend using this crate or specifying the absolute path. If you want to save it in any other directories, just use relative or absolute paths, but don't use ~ because Rust doesn't know the context of ~.

Inconsistent behavior of `mktemp` crate in Rust

If I call .to_path_buf() immediately after expect, the temporary directory will not be created. Is this a bug or a Rust feature?
extern crate mktemp;
use std::path::Path;
fn main() {
let temp_dir = mktemp::Temp::new_dir().expect("Failed to create a temp directory");
let temp_dir_path = temp_dir.to_path_buf();
println!("tmp path exists: {}", Path::exists(&temp_dir_path));
let temp_dir_path = mktemp::Temp::new_dir().expect("Failed to create a temp directory").to_path_buf();
println!("tmp path exists: {}", Path::exists(&temp_dir_path));
}
Which outputs:
tmp path exists: true
tmp path exists: false
I don't know, but I wonder if there's something in the mktemp documentation about this...
Once the variable goes out of scope, the underlying file system resource is removed.
You're not storing the Temp in a variable, so it goes out of scope immediately. It's creating the directory and then immediately destroying it.

Unable to use std::process::Command - No such file or directory

I am trying to use the following Rust code to connect to EC2 instances.
#[test]
fn client_ssh_timeout2() {
match Command::new("/usr/bin/ssh -i /tmp/.ssh/25.pem ubuntu#ip").spawn() {
Ok(_) => println!("Able to ssh"),
Err(e) => println!("{:?}", e),
};
}
But I am getting the following error
Error { repr: Os { code: 2, message: "No such file or directory" } }
Has anyone been able to use std::process::Command or any other Rust library to connect to EC2 instances using PEM files? I tried using ssh2-rs(libssh2) but couldn't connect to EC2 instances.
This appears to be a misunderstanding of how to use std::process:Command. Command::new takes just the program:
fn new<S: AsRef<OsStr>>(program: S) -> Command
Command::arg or Command::args are used to provide the arguments.
You will want something like
Command::new("/usr/bin/ssh")
.args(&["-i", "/tmp/.ssh/25.pem", "ubuntu#ip"])
.spawn()

Resources