mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-30 20:47:46 +00:00
preloading improvement
This commit is contained in:
parent
32259aadda
commit
563c9ab34e
3 changed files with 42 additions and 12 deletions
|
@ -1,16 +1,23 @@
|
||||||
#![crate_type = "dylib"]
|
#![crate_name = "libstdbuf"]
|
||||||
|
#![crate_type = "staticlib"]
|
||||||
|
#![feature(macro_rules)]
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
use libc::{c_int, size_t, c_char, FILE, _IOFBF, _IONBF, _IOLBF, setvbuf};
|
use libc::{c_int, size_t, c_char, FILE, _IOFBF, _IONBF, _IOLBF, setvbuf};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::os;
|
use std::os;
|
||||||
|
|
||||||
|
#[path = "../common/util.rs"]
|
||||||
|
mod util;
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
static stdin: *mut FILE;
|
static stdin: *mut FILE;
|
||||||
static stdout: *mut FILE;
|
static stdout: *mut FILE;
|
||||||
static stderr: *mut FILE;
|
static stderr: *mut FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NAME: &'static str = "libstdbuf";
|
||||||
|
|
||||||
fn set_buffer(stream: *mut FILE, value: &str) {
|
fn set_buffer(stream: *mut FILE, value: &str) {
|
||||||
let (mode, size): (c_int, size_t) = match value {
|
let (mode, size): (c_int, size_t) = match value {
|
||||||
"0" => (_IONBF, 0 as size_t),
|
"0" => (_IONBF, 0 as size_t),
|
||||||
|
@ -18,7 +25,7 @@ fn set_buffer(stream: *mut FILE, value: &str) {
|
||||||
input => {
|
input => {
|
||||||
let buff_size: uint = match from_str(input) {
|
let buff_size: uint = match from_str(input) {
|
||||||
Some(num) => num,
|
Some(num) => num,
|
||||||
None => panic!("incorrect size of buffer!")
|
None => crash!(1, "incorrect size of buffer!")
|
||||||
};
|
};
|
||||||
(_IOFBF, buff_size as size_t)
|
(_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);
|
res = libc::setvbuf(stream, buffer, mode, size);
|
||||||
}
|
}
|
||||||
if res != 0 {
|
if res != 0 {
|
||||||
panic!("error while calling setvbuf!");
|
crash!(res, "error while calling setvbuf!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
cd $(dirname $0)
|
cd $(dirname $0)
|
||||||
rustc libstdbuf.rs
|
rustc libstdbuf.rs
|
||||||
gcc -c -Wall -Werror -fpic libstdbuf.c -L. -llibstdbuf.so
|
gcc -c -Wall -Werror -fpic libstdbuf.c -L. -llibstdbuf.a
|
||||||
gcc -shared -o libstdbuf.so libstdbuf.o
|
gcc -shared -o libstdbuf.so -Wl,--whole-archive liblibstdbuf.a -Wl,--no-whole-archive libstdbuf.o -lpthread
|
||||||
mv *.so ../../build/
|
mv *.so ../../build/
|
||||||
rm *.o
|
rm *.o
|
||||||
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH":"$PWD"/../../build
|
rm *.a
|
||||||
|
|
|
@ -16,22 +16,21 @@ use getopts::{optopt, optflag, getopts, usage, Matches, OptGroup};
|
||||||
use std::io::process::{Command, StdioContainer};
|
use std::io::process::{Command, StdioContainer};
|
||||||
use std::iter::range_inclusive;
|
use std::iter::range_inclusive;
|
||||||
use std::num::Int;
|
use std::num::Int;
|
||||||
|
use std::os;
|
||||||
|
|
||||||
#[path = "../common/util.rs"]
|
#[path = "../common/util.rs"]
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
static NAME: &'static str = "stdbuf";
|
static NAME: &'static str = "stdbuf";
|
||||||
static VERSION: &'static str = "1.0.0";
|
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 {
|
enum BufferType {
|
||||||
Default,
|
Default,
|
||||||
Line,
|
Line,
|
||||||
Size(u64)
|
Size(u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Show)]
|
|
||||||
struct ProgramOptions {
|
struct ProgramOptions {
|
||||||
stdin: BufferType,
|
stdin: BufferType,
|
||||||
stdout: BufferType,
|
stdout: BufferType,
|
||||||
|
@ -49,6 +48,22 @@ enum OkMsg {
|
||||||
Version
|
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() {
|
fn print_version() {
|
||||||
println!("{} version {}", NAME, VERSION);
|
println!("{} version {}", NAME, VERSION);
|
||||||
}
|
}
|
||||||
|
@ -181,7 +196,7 @@ pub fn uumain(args: Vec<String>) -> int {
|
||||||
for i in range_inclusive(1, args.len()) {
|
for i in range_inclusive(1, args.len()) {
|
||||||
match parse_options(args.slice(1, i), &mut options, &optgrps) {
|
match parse_options(args.slice(1, i), &mut options, &optgrps) {
|
||||||
Ok(OkMsg::Buffering) => {
|
Ok(OkMsg::Buffering) => {
|
||||||
command_idx = i-1;
|
command_idx = i - 1;
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
Ok(OkMsg::Help) => {
|
Ok(OkMsg::Help) => {
|
||||||
|
@ -201,7 +216,16 @@ pub fn uumain(args: Vec<String>) -> int {
|
||||||
}
|
}
|
||||||
let ref command_name = args[command_idx];
|
let ref command_name = args[command_idx];
|
||||||
let mut command = Command::new(command_name);
|
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));
|
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_I", options.stdin);
|
||||||
set_command_env(&mut command, "_STDBUF_O", options.stdout);
|
set_command_env(&mut command, "_STDBUF_O", options.stdout);
|
||||||
|
@ -212,4 +236,3 @@ pub fn uumain(args: Vec<String>) -> int {
|
||||||
};
|
};
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue