mirror of
https://github.com/Llewellynvdm/exa.git
synced 2024-11-26 05:47:32 +00:00
Upgrade to latest Rust nightly
This commit is contained in:
parent
26f8ad08bf
commit
933f98d2c3
@ -19,24 +19,24 @@ pub enum Alignment {
|
|||||||
impl Column {
|
impl Column {
|
||||||
pub fn alignment(&self) -> Alignment {
|
pub fn alignment(&self) -> Alignment {
|
||||||
match *self {
|
match *self {
|
||||||
FileSize(_) => Right,
|
Column::FileSize(_) => Alignment::Right,
|
||||||
HardLinks => Right,
|
Column::HardLinks => Alignment::Right,
|
||||||
Inode => Right,
|
Column::Inode => Alignment::Right,
|
||||||
Blocks => Right,
|
Column::Blocks => Alignment::Right,
|
||||||
_ => Left,
|
_ => Alignment::Left,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn header(&self) -> &'static str {
|
pub fn header(&self) -> &'static str {
|
||||||
match *self {
|
match *self {
|
||||||
Permissions => "Permissions",
|
Column::Permissions => "Permissions",
|
||||||
FileName => "Name",
|
Column::FileName => "Name",
|
||||||
FileSize(_) => "Size",
|
Column::FileSize(_) => "Size",
|
||||||
Blocks => "Blocks",
|
Column::Blocks => "Blocks",
|
||||||
User => "User",
|
Column::User => "User",
|
||||||
Group => "Group",
|
Column::Group => "Group",
|
||||||
HardLinks => "Links",
|
Column::HardLinks => "Links",
|
||||||
Inode => "inode",
|
Column::Inode => "inode",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,8 +49,8 @@ impl Column {
|
|||||||
impl Alignment {
|
impl Alignment {
|
||||||
pub fn pad_string(&self, string: &String, padding: uint) -> String {
|
pub fn pad_string(&self, string: &String, padding: uint) -> String {
|
||||||
match *self {
|
match *self {
|
||||||
Left => string.clone().append(" ".to_string().repeat(padding).as_slice()),
|
Alignment::Left => string.clone() + " ".to_string().repeat(padding).as_slice(),
|
||||||
Right => " ".to_string().repeat(padding).append(string.as_slice()),
|
Alignment::Right => " ".to_string().repeat(padding) + string.as_slice(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
17
src/exa.rs
17
src/exa.rs
@ -1,4 +1,4 @@
|
|||||||
#![feature(phase)]
|
#![feature(phase, globs)]
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
#[phase(plugin)] extern crate regex_macros;
|
#[phase(plugin)] extern crate regex_macros;
|
||||||
extern crate ansi_term;
|
extern crate ansi_term;
|
||||||
@ -8,8 +8,9 @@ use std::os;
|
|||||||
|
|
||||||
use file::File;
|
use file::File;
|
||||||
use dir::Dir;
|
use dir::Dir;
|
||||||
use column::{Column, Left};
|
use column::Column;
|
||||||
use options::{Options, Details, Lines, Grid};
|
use column::Alignment::Left;
|
||||||
|
use options::{Options, View};
|
||||||
use unix::Unix;
|
use unix::Unix;
|
||||||
|
|
||||||
use ansi_term::{Paint, Plain, strip_formatting};
|
use ansi_term::{Paint, Plain, strip_formatting};
|
||||||
@ -25,7 +26,7 @@ pub mod sort;
|
|||||||
pub mod term;
|
pub mod term;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args = os::args();
|
let args: Vec<String> = os::args();
|
||||||
|
|
||||||
match Options::getopts(args) {
|
match Options::getopts(args) {
|
||||||
Err(err) => println!("Invalid options:\n{}", err),
|
Err(err) => println!("Invalid options:\n{}", err),
|
||||||
@ -58,9 +59,9 @@ fn exa(opts: &Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match opts.view {
|
match opts.view {
|
||||||
Details(ref cols) => details_view(opts, cols, files),
|
View::Details(ref cols) => details_view(opts, cols, files),
|
||||||
Lines => lines_view(files),
|
View::Lines => lines_view(files),
|
||||||
Grid(across, width) => grid_view(across, width, files),
|
View::Grid(across, width) => grid_view(across, width, files),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -156,7 +157,7 @@ fn details_view(options: &Options, columns: &Vec<Column>, files: Vec<&File>) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let padding = column_widths[num] - field_widths[num];
|
let padding = column_widths[num] - field_widths[num];
|
||||||
print!("{}", column.alignment().pad_string(row.get(num), padding));
|
print!("{}", column.alignment().pad_string(&row[num], padding));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
print!("\n");
|
print!("\n");
|
||||||
|
34
src/file.rs
34
src/file.rs
@ -1,17 +1,17 @@
|
|||||||
use std::io::{fs, IoResult};
|
use std::io::{fs, IoResult};
|
||||||
use std::io;
|
use std::io;
|
||||||
use unicode::str::UnicodeStrSlice;
|
|
||||||
|
|
||||||
use ansi_term::{Paint, Colour, Plain, Style, Red, Green, Yellow, Blue, Purple, Cyan, Fixed};
|
use ansi_term::{Paint, Colour, Plain, Style, Red, Green, Yellow, Blue, Purple, Cyan, Fixed};
|
||||||
|
|
||||||
use column::{Column, Permissions, FileName, FileSize, User, Group, HardLinks, Inode, Blocks};
|
use column::Column;
|
||||||
|
use column::Column::*;
|
||||||
use format::{format_metric_bytes, format_IEC_bytes};
|
use format::{format_metric_bytes, format_IEC_bytes};
|
||||||
use unix::Unix;
|
use unix::Unix;
|
||||||
use sort::SortPart;
|
use sort::SortPart;
|
||||||
use dir::Dir;
|
use dir::Dir;
|
||||||
use filetype::HasType;
|
use filetype::HasType;
|
||||||
|
|
||||||
static Grey: Colour = Fixed(244);
|
pub static GREY: Colour = Fixed(244);
|
||||||
|
|
||||||
// Instead of working with Rust's Paths, we have our own File object
|
// Instead of working with Rust's Paths, we have our own File object
|
||||||
// that holds the Path and various cached information. Each file is
|
// that holds the Path and various cached information. Each file is
|
||||||
@ -32,7 +32,7 @@ pub struct File<'a> {
|
|||||||
impl<'a> File<'a> {
|
impl<'a> File<'a> {
|
||||||
pub fn from_path(path: &'a Path, parent: &'a Dir) -> IoResult<File<'a>> {
|
pub fn from_path(path: &'a Path, parent: &'a Dir) -> IoResult<File<'a>> {
|
||||||
let v = path.filename().unwrap(); // fails if / or . or ..
|
let v = path.filename().unwrap(); // fails if / or . or ..
|
||||||
let filename = String::from_utf8_lossy(v).to_string();
|
let filename = String::from_utf8(v.to_vec()).to_string();
|
||||||
|
|
||||||
// Use lstat here instead of file.stat(), as it doesn't follow
|
// Use lstat here instead of file.stat(), as it doesn't follow
|
||||||
// symbolic links. Otherwise, the stat() call will fail if it
|
// symbolic links. Otherwise, the stat() call will fail if it
|
||||||
@ -129,7 +129,7 @@ impl<'a> File<'a> {
|
|||||||
Cyan.paint(self.stat.unstable.blocks.to_string().as_slice())
|
Cyan.paint(self.stat.unstable.blocks.to_string().as_slice())
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Grey.paint("-")
|
GREY.paint("-")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ impl<'a> File<'a> {
|
|||||||
// that reason anyway.
|
// that reason anyway.
|
||||||
|
|
||||||
match link_target {
|
match link_target {
|
||||||
Ok(file) => format!("{} {}", Grey.paint("=>"), file.file_colour().paint(filename.as_slice())),
|
Ok(file) => format!("{} {}", GREY.paint("=>"), file.file_colour().paint(filename.as_slice())),
|
||||||
Err(_) => format!("{} {}", Red.paint("=>"), Red.underline().paint(filename.as_slice())),
|
Err(_) => format!("{} {}", Red.paint("=>"), Red.underline().paint(filename.as_slice())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ impl<'a> File<'a> {
|
|||||||
// Don't report file sizes for directories. I've never looked
|
// Don't report file sizes for directories. I've never looked
|
||||||
// at one of those numbers and gained any information from it.
|
// at one of those numbers and gained any information from it.
|
||||||
if self.stat.kind == io::TypeDirectory {
|
if self.stat.kind == io::TypeDirectory {
|
||||||
Grey.paint("-")
|
GREY.paint("-")
|
||||||
} else {
|
} else {
|
||||||
let (size, suffix) = if use_iec_prefixes {
|
let (size, suffix) = if use_iec_prefixes {
|
||||||
format_IEC_bytes(self.stat.size)
|
format_IEC_bytes(self.stat.size)
|
||||||
@ -242,15 +242,15 @@ impl<'a> File<'a> {
|
|||||||
|
|
||||||
// The first three are bold because they're the ones used
|
// The first three are bold because they're the ones used
|
||||||
// most often.
|
// most often.
|
||||||
File::permission_bit(bits, io::UserRead, "r", Yellow.bold()),
|
File::permission_bit(bits, io::USER_READ, "r", Yellow.bold()),
|
||||||
File::permission_bit(bits, io::UserWrite, "w", Red.bold()),
|
File::permission_bit(bits, io::USER_WRITE, "w", Red.bold()),
|
||||||
File::permission_bit(bits, io::UserExecute, "x", Green.bold().underline()),
|
File::permission_bit(bits, io::USER_EXECUTE, "x", Green.bold().underline()),
|
||||||
File::permission_bit(bits, io::GroupRead, "r", Yellow.normal()),
|
File::permission_bit(bits, io::GROUP_READ, "r", Yellow.normal()),
|
||||||
File::permission_bit(bits, io::GroupWrite, "w", Red.normal()),
|
File::permission_bit(bits, io::GROUP_WRITE, "w", Red.normal()),
|
||||||
File::permission_bit(bits, io::GroupExecute, "x", Green.normal()),
|
File::permission_bit(bits, io::GROUP_EXECUTE, "x", Green.normal()),
|
||||||
File::permission_bit(bits, io::OtherRead, "r", Yellow.normal()),
|
File::permission_bit(bits, io::OTHER_READ, "r", Yellow.normal()),
|
||||||
File::permission_bit(bits, io::OtherWrite, "w", Red.normal()),
|
File::permission_bit(bits, io::OTHER_WRITE, "w", Red.normal()),
|
||||||
File::permission_bit(bits, io::OtherExecute, "x", Green.normal()),
|
File::permission_bit(bits, io::OTHER_EXECUTE, "x", Green.normal()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,7 +258,7 @@ impl<'a> File<'a> {
|
|||||||
if bits.contains(bit) {
|
if bits.contains(bit) {
|
||||||
style.paint(character.as_slice())
|
style.paint(character.as_slice())
|
||||||
} else {
|
} else {
|
||||||
Grey.paint("-".as_slice())
|
GREY.paint("-".as_slice())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use file::File;
|
use file::{File, GREY};
|
||||||
|
use self::FileType::*;
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::ascii::StrAsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
|
|
||||||
use ansi_term::{Paint, Colour, Plain, Style, Red, Green, Yellow, Blue, Cyan, Fixed};
|
use ansi_term::{Paint, Plain, Style, Red, Green, Yellow, Blue, Cyan, Fixed};
|
||||||
|
|
||||||
static Grey: Colour = Fixed(244);
|
|
||||||
|
|
||||||
pub enum FileType {
|
pub enum FileType {
|
||||||
Normal, Directory, Executable, Immediate, Compiled, Symlink, Special,
|
Normal, Directory, Executable, Immediate, Compiled, Symlink, Special,
|
||||||
@ -64,7 +64,7 @@ impl FileType {
|
|||||||
Crypto => Fixed(109).normal(),
|
Crypto => Fixed(109).normal(),
|
||||||
Document => Fixed(105).normal(),
|
Document => Fixed(105).normal(),
|
||||||
Compressed => Red.normal(),
|
Compressed => Red.normal(),
|
||||||
Temp => Grey.normal(),
|
Temp => GREY.normal(),
|
||||||
Immediate => Yellow.bold().underline(),
|
Immediate => Yellow.bold().underline(),
|
||||||
Compiled => Fixed(137).normal(),
|
Compiled => Fixed(137).normal(),
|
||||||
}
|
}
|
||||||
@ -87,14 +87,14 @@ impl<'a> HasType for File<'a> {
|
|||||||
else if self.stat.kind == io::TypeBlockSpecial || self.stat.kind == io::TypeNamedPipe || self.stat.kind == io::TypeUnknown {
|
else if self.stat.kind == io::TypeBlockSpecial || self.stat.kind == io::TypeNamedPipe || self.stat.kind == io::TypeUnknown {
|
||||||
return Special;
|
return Special;
|
||||||
}
|
}
|
||||||
else if self.stat.perm.contains(io::UserExecute) {
|
else if self.stat.perm.contains(io::USER_EXECUTE) {
|
||||||
return Executable;
|
return Executable;
|
||||||
}
|
}
|
||||||
else if name.starts_with("README") || BUILD_TYPES.iter().any(|&s| s == name) {
|
else if name.starts_with("README") || BUILD_TYPES.iter().any(|&s| s == name) {
|
||||||
return Immediate;
|
return Immediate;
|
||||||
}
|
}
|
||||||
else if self.ext.is_some() {
|
else if self.ext.is_some() {
|
||||||
let e = self.ext.clone().unwrap().as_slice().to_ascii_lower();
|
let e = self.ext.clone().unwrap().to_ascii_lower();
|
||||||
let ext = e.as_slice();
|
let ext = e.as_slice();
|
||||||
if IMAGE_TYPES.iter().any(|&s| s == ext) {
|
if IMAGE_TYPES.iter().any(|&s| s == ext) {
|
||||||
return Image;
|
return Image;
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
|
|
||||||
use file::File;
|
use file::File;
|
||||||
use column::{Column, Permissions, FileName, FileSize, User, Group, HardLinks, Inode, Blocks};
|
use column::Column;
|
||||||
use std::ascii::StrAsciiExt;
|
use column::Column::*;
|
||||||
use term;
|
use term::dimensions;
|
||||||
|
|
||||||
|
use std::ascii::AsciiExt;
|
||||||
|
|
||||||
pub enum SortField {
|
pub enum SortField {
|
||||||
Unsorted, Name, Extension, Size, FileInode
|
Unsorted, Name, Extension, Size, FileInode
|
||||||
@ -12,12 +14,12 @@ pub enum SortField {
|
|||||||
impl SortField {
|
impl SortField {
|
||||||
fn from_word(word: String) -> SortField {
|
fn from_word(word: String) -> SortField {
|
||||||
match word.as_slice() {
|
match word.as_slice() {
|
||||||
"name" => Name,
|
"name" => SortField::Name,
|
||||||
"size" => Size,
|
"size" => SortField::Size,
|
||||||
"ext" => Extension,
|
"ext" => SortField::Extension,
|
||||||
"none" => Unsorted,
|
"none" => SortField::Unsorted,
|
||||||
"inode" => FileInode,
|
"inode" => SortField::FileInode,
|
||||||
_ => fail!("Invalid sorting order"),
|
_ => panic!("Invalid sorting order"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,7 +42,7 @@ pub struct Options {
|
|||||||
|
|
||||||
impl Options {
|
impl Options {
|
||||||
pub fn getopts(args: Vec<String>) -> Result<Options, getopts::Fail_> {
|
pub fn getopts(args: Vec<String>) -> Result<Options, getopts::Fail_> {
|
||||||
let opts = [
|
let opts = &[
|
||||||
getopts::optflag("1", "oneline", "display one entry per line"),
|
getopts::optflag("1", "oneline", "display one entry per line"),
|
||||||
getopts::optflag("a", "all", "show dot-files"),
|
getopts::optflag("a", "all", "show dot-files"),
|
||||||
getopts::optflag("b", "binary", "use binary prefixes in file sizes"),
|
getopts::optflag("b", "binary", "use binary prefixes in file sizes"),
|
||||||
@ -61,7 +63,7 @@ impl Options {
|
|||||||
show_invisibles: matches.opt_present("all"),
|
show_invisibles: matches.opt_present("all"),
|
||||||
reverse: matches.opt_present("reverse"),
|
reverse: matches.opt_present("reverse"),
|
||||||
header: matches.opt_present("header"),
|
header: matches.opt_present("header"),
|
||||||
sort_field: matches.opt_str("sort").map(|word| SortField::from_word(word)).unwrap_or(Name),
|
sort_field: matches.opt_str("sort").map(|word| SortField::from_word(word)).unwrap_or(SortField::Name),
|
||||||
dirs: if matches.free.is_empty() { vec![ ".".to_string() ] } else { matches.free.clone() },
|
dirs: if matches.free.is_empty() { vec![ ".".to_string() ] } else { matches.free.clone() },
|
||||||
view: Options::view(matches),
|
view: Options::view(matches),
|
||||||
})
|
})
|
||||||
@ -70,15 +72,15 @@ impl Options {
|
|||||||
|
|
||||||
fn view(matches: getopts::Matches) -> View {
|
fn view(matches: getopts::Matches) -> View {
|
||||||
if matches.opt_present("long") {
|
if matches.opt_present("long") {
|
||||||
Details(Options::columns(matches))
|
View::Details(Options::columns(matches))
|
||||||
}
|
}
|
||||||
else if matches.opt_present("oneline") {
|
else if matches.opt_present("oneline") {
|
||||||
Lines
|
View::Lines
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
match term::dimensions() {
|
match dimensions() {
|
||||||
None => Lines,
|
None => View::Lines,
|
||||||
Some((width, _)) => Grid(matches.opt_present("across"), width),
|
Some((width, _)) => View::Grid(matches.opt_present("across"), width),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,13 +129,13 @@ impl Options {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
match self.sort_field {
|
match self.sort_field {
|
||||||
Unsorted => {},
|
SortField::Unsorted => {},
|
||||||
Name => files.sort_by(|a, b| a.parts.cmp(&b.parts)),
|
SortField::Name => files.sort_by(|a, b| a.parts.cmp(&b.parts)),
|
||||||
Size => files.sort_by(|a, b| a.stat.size.cmp(&b.stat.size)),
|
SortField::Size => files.sort_by(|a, b| a.stat.size.cmp(&b.stat.size)),
|
||||||
FileInode => files.sort_by(|a, b| a.stat.unstable.inode.cmp(&b.stat.unstable.inode)),
|
SortField::FileInode => files.sort_by(|a, b| a.stat.unstable.inode.cmp(&b.stat.unstable.inode)),
|
||||||
Extension => files.sort_by(|a, b| {
|
SortField::Extension => files.sort_by(|a, b| {
|
||||||
let exts = a.ext.clone().map(|e| e.as_slice().to_ascii_lower()).cmp(&b.ext.clone().map(|e| e.as_slice().to_ascii_lower()));
|
let exts = a.ext.clone().map(|e| e.to_ascii_lower()).cmp(&b.ext.clone().map(|e| e.to_ascii_lower()));
|
||||||
let names = a.name.as_slice().to_ascii_lower().cmp(&b.name.as_slice().to_ascii_lower());
|
let names = a.name.to_ascii_lower().cmp(&b.name.to_ascii_lower());
|
||||||
exts.cmp(&names)
|
exts.cmp(&names)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
13
src/sort.rs
13
src/sort.rs
@ -1,4 +1,5 @@
|
|||||||
use std::ascii::StrAsciiExt;
|
use self::SortPart::*;
|
||||||
|
use std::ascii::AsciiExt;
|
||||||
|
|
||||||
// This is an implementation of "natural sort order". See
|
// This is an implementation of "natural sort order". See
|
||||||
// http://blog.codinghorror.com/sorting-for-humans-natural-sort-order/
|
// http://blog.codinghorror.com/sorting-for-humans-natural-sort-order/
|
||||||
@ -20,11 +21,11 @@ impl SortPart {
|
|||||||
if is_digit {
|
if is_digit {
|
||||||
// numbers too big for a u64 fall back into strings.
|
// numbers too big for a u64 fall back into strings.
|
||||||
match from_str::<u64>(slice) {
|
match from_str::<u64>(slice) {
|
||||||
Some(num) => Numeric(num),
|
Some(num) => SortPart::Numeric(num),
|
||||||
None => Stringular(slice.to_string()),
|
None => SortPart::Stringular(slice.to_string()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Stringular(slice.to_ascii_lower())
|
SortPart::Stringular(slice.to_ascii_lower())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,11 +39,11 @@ impl SortPart {
|
|||||||
return parts
|
return parts
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut is_digit = input.as_slice().char_at(0).is_digit();
|
let mut is_digit = input.as_slice().char_at(0).is_digit(10);
|
||||||
let mut start = 0;
|
let mut start = 0;
|
||||||
|
|
||||||
for (i, c) in input.as_slice().char_indices() {
|
for (i, c) in input.as_slice().char_indices() {
|
||||||
if is_digit != c.is_digit() {
|
if is_digit != c.is_digit(10) {
|
||||||
parts.push(SortPart::from_string(is_digit, input.as_slice().slice(start, i)));
|
parts.push(SortPart::from_string(is_digit, input.as_slice().slice(start, i)));
|
||||||
is_digit = !is_digit;
|
is_digit = !is_digit;
|
||||||
start = i;
|
start = i;
|
||||||
|
@ -21,12 +21,11 @@ mod c {
|
|||||||
|
|
||||||
// Unfortunately the actual command is not standardised...
|
// Unfortunately the actual command is not standardised...
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||||
#[cfg(target_os = "android")]
|
|
||||||
static TIOCGWINSZ: c_ulong = 0x5413;
|
static TIOCGWINSZ: c_ulong = 0x5413;
|
||||||
|
|
||||||
#[cfg(target_os = "freebsd")]
|
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
static TIOCGWINSZ: c_ulong = 0x40087468;
|
static TIOCGWINSZ: c_ulong = 0x40087468;
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
|
10
src/unix.rs
10
src/unix.rs
@ -1,6 +1,6 @@
|
|||||||
use std::string::raw::from_buf;
|
use std::string::raw::from_buf;
|
||||||
use std::ptr::read;
|
use std::ptr::read;
|
||||||
use std::collections::hashmap::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
mod c {
|
mod c {
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
@ -127,13 +127,13 @@ impl Unix {
|
|||||||
pub fn load_group(&mut self, gid: u32) {
|
pub fn load_group(&mut self, gid: u32) {
|
||||||
match unsafe { c::getgrgid(gid).as_ref() } {
|
match unsafe { c::getgrgid(gid).as_ref() } {
|
||||||
None => {
|
None => {
|
||||||
self.group_names.find_or_insert(gid, None);
|
self.group_names.insert(gid, None);
|
||||||
self.groups.find_or_insert(gid, false);
|
self.groups.insert(gid, false);
|
||||||
},
|
},
|
||||||
Some(r) => {
|
Some(r) => {
|
||||||
let group_name = unsafe { Some(from_buf(r.gr_name as *const u8)) };
|
let group_name = unsafe { Some(from_buf(r.gr_name as *const u8)) };
|
||||||
self.groups.find_or_insert(gid, Unix::group_membership(r.gr_mem, &self.username));
|
self.groups.insert(gid, Unix::group_membership(r.gr_mem, &self.username));
|
||||||
self.group_names.find_or_insert(gid, group_name);
|
self.group_names.insert(gid, group_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user