1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

preloading improvement

This commit is contained in:
dokaptur 2014-12-14 01:20:49 +01:00
parent 32259aadda
commit 563c9ab34e
3 changed files with 42 additions and 12 deletions

View file

@ -1,16 +1,23 @@
#![crate_type = "dylib"]
#![crate_name = "libstdbuf"]
#![crate_type = "staticlib"]
#![feature(macro_rules)]
extern crate libc;
use libc::{c_int, size_t, c_char, FILE, _IOFBF, _IONBF, _IOLBF, setvbuf};
use std::ptr;
use std::os;
#[path = "../common/util.rs"]
mod util;
extern {
static stdin: *mut FILE;
static stdout: *mut FILE;
static stderr: *mut FILE;
}
static NAME: &'static str = "libstdbuf";
fn set_buffer(stream: *mut FILE, value: &str) {
let (mode, size): (c_int, size_t) = match value {
"0" => (_IONBF, 0 as size_t),
@ -18,7 +25,7 @@ fn set_buffer(stream: *mut FILE, value: &str) {
input => {
let buff_size: uint = match from_str(input) {
Some(num) => num,
None => panic!("incorrect size of buffer!")
None => crash!(1, "incorrect size of buffer!")
};
(_IOFBF, buff_size as size_t)
}
@ -30,7 +37,7 @@ fn set_buffer(stream: *mut FILE, value: &str) {
res = libc::setvbuf(stream, buffer, mode, size);
}
if res != 0 {
panic!("error while calling setvbuf!");
crash!(res, "error while calling setvbuf!");
}
}

View file

@ -2,8 +2,8 @@
cd $(dirname $0)
rustc libstdbuf.rs
gcc -c -Wall -Werror -fpic libstdbuf.c -L. -llibstdbuf.so
gcc -shared -o libstdbuf.so libstdbuf.o
gcc -c -Wall -Werror -fpic libstdbuf.c -L. -llibstdbuf.a
gcc -shared -o libstdbuf.so -Wl,--whole-archive liblibstdbuf.a -Wl,--no-whole-archive libstdbuf.o -lpthread
mv *.so ../../build/
rm *.o
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH":"$PWD"/../../build
rm *.a

View file

@ -16,22 +16,21 @@ use getopts::{optopt, optflag, getopts, usage, Matches, OptGroup};
use std::io::process::{Command, StdioContainer};
use std::iter::range_inclusive;
use std::num::Int;
use std::os;
#[path = "../common/util.rs"]
mod util;
static NAME: &'static str = "stdbuf";
static VERSION: &'static str = "1.0.0";
static LIBSTDBUF_PATH: &'static str = "liblibstdbuf.so libstdbuf.so";
static LIBSTDBUF: &'static str = "libstdbuf.so";
#[deriving(Show)]
enum BufferType {
Default,
Line,
Size(u64)
}
#[deriving(Show)]
struct ProgramOptions {
stdin: BufferType,
stdout: BufferType,
@ -49,6 +48,22 @@ enum OkMsg {
Version
}
#[cfg(target_os = "linux")]
fn preload_env() -> &'static str {
"LD_PRELOAD"
}
#[cfg(target_os = "macos")]
fn preload_env() -> &'static str {
"DYLD_INSERT_LIBRARIES"
}
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
fn preload_env() -> &'static str {
crash!(1, "Command not supported for this operating system!")
}
fn print_version() {
println!("{} version {}", NAME, VERSION);
}
@ -181,7 +196,7 @@ pub fn uumain(args: Vec<String>) -> int {
for i in range_inclusive(1, args.len()) {
match parse_options(args.slice(1, i), &mut options, &optgrps) {
Ok(OkMsg::Buffering) => {
command_idx = i-1;
command_idx = i - 1;
break;
},
Ok(OkMsg::Help) => {
@ -201,7 +216,16 @@ pub fn uumain(args: Vec<String>) -> int {
}
let ref command_name = args[command_idx];
let mut command = Command::new(command_name);
command.args(args.slice_from(command_idx+1)).env("LD_PRELOAD", LIBSTDBUF_PATH);
let mut path = match os::self_exe_path() {
Some(exe_path) => exe_path,
None => crash!(1, "Impossible to fetch the path of this executable.")
};
path.push(LIBSTDBUF);
let libstdbuf = match path.as_str() {
Some(s) => s,
None => crash!(1, "Error while converting path.")
};
command.args(args.slice_from(command_idx+1)).env(preload_env(), libstdbuf);
command.stdin(StdioContainer::InheritFd(0)).stdout(StdioContainer::InheritFd(1)).stderr(StdioContainer::InheritFd(2));
set_command_env(&mut command, "_STDBUF_I", options.stdin);
set_command_env(&mut command, "_STDBUF_O", options.stdout);
@ -212,4 +236,3 @@ pub fn uumain(args: Vec<String>) -> int {
};
0
}