66// spell-checker:ignore getloadavg behaviour loadavg uptime upsecs updays upmins uphours boottime nusers utmpxname gettime clockid
77
88use chrono:: { Local , TimeZone , Utc } ;
9- use clap:: ArgMatches ;
9+ #[ cfg( unix) ]
10+ use std:: ffi:: OsString ;
1011use std:: io;
1112use thiserror:: Error ;
1213use uucore:: error:: { UError , UResult } ;
@@ -44,14 +45,10 @@ pub enum UptimeError {
4445 // io::Error wrapper
4546 #[ error( "couldn't get boot time: {0}" ) ]
4647 IoErr ( #[ from] io:: Error ) ,
47-
4848 #[ error( "couldn't get boot time: Is a directory" ) ]
4949 TargetIsDir ,
50-
5150 #[ error( "couldn't get boot time: Illegal seek" ) ]
5251 TargetIsFifo ,
53- #[ error( "extra operand '{0}'" ) ]
54- ExtraOperandError ( String ) ,
5552}
5653
5754impl UError for UptimeError {
@@ -64,41 +61,22 @@ impl UError for UptimeError {
6461pub fn uumain ( args : impl uucore:: Args ) -> UResult < ( ) > {
6562 let matches = uu_app ( ) . try_get_matches_from ( args) ?;
6663
67- #[ cfg( windows) ]
68- return default_uptime ( & matches) ;
69-
7064 #[ cfg( unix) ]
71- {
72- use std:: ffi:: OsString ;
73- use uucore:: error:: set_exit_code;
74- use uucore:: show_error;
75-
76- let argument = matches. get_many :: < OsString > ( options:: PATH ) ;
77-
78- // Switches to default uptime behaviour if there is no argument
79- if argument. is_none ( ) {
80- return default_uptime ( & matches) ;
81- }
82- let mut arg_iter = argument. unwrap ( ) ;
83-
84- let file_path = arg_iter. next ( ) . unwrap ( ) ;
85- if let Some ( path) = arg_iter. next ( ) {
86- // Uptime doesn't attempt to calculate boot time if there is extra arguments.
87- // Its a fatal error
88- show_error ! (
89- "{}" ,
90- UptimeError :: ExtraOperandError ( path. to_owned( ) . into_string( ) . unwrap( ) )
91- ) ;
92- set_exit_code ( 1 ) ;
93- return Ok ( ( ) ) ;
94- }
65+ let file_path = matches. get_one :: < OsString > ( options:: PATH ) ;
66+ #[ cfg( windows) ]
67+ let file_path = None ;
9568
96- uptime_with_file ( file_path)
69+ if matches. get_flag ( options:: SINCE ) {
70+ uptime_since ( )
71+ } else if let Some ( path) = file_path {
72+ uptime_with_file ( path)
73+ } else {
74+ default_uptime ( )
9775 }
9876}
9977
10078pub fn uu_app ( ) -> Command {
101- Command :: new ( uucore:: util_name ( ) )
79+ let cmd = Command :: new ( uucore:: util_name ( ) )
10280 . version ( uucore:: crate_version!( ) )
10381 . about ( ABOUT )
10482 . override_usage ( format_usage ( USAGE ) )
@@ -109,18 +87,20 @@ pub fn uu_app() -> Command {
10987 . long ( options:: SINCE )
11088 . help ( "system up since" )
11189 . action ( ArgAction :: SetTrue ) ,
112- )
113- . arg (
114- Arg :: new ( options:: PATH )
115- . help ( "file to search boot time from" )
116- . action ( ArgAction :: Append )
117- . value_parser ( ValueParser :: os_string ( ) )
118- . value_hint ( ValueHint :: AnyPath ) ,
119- )
90+ ) ;
91+ #[ cfg( unix) ]
92+ cmd. arg (
93+ Arg :: new ( options:: PATH )
94+ . help ( "file to search boot time from" )
95+ . action ( ArgAction :: Set )
96+ . num_args ( 0 ..=1 )
97+ . value_parser ( ValueParser :: os_string ( ) )
98+ . value_hint ( ValueHint :: AnyPath ) ,
99+ )
120100}
121101
122102#[ cfg( unix) ]
123- fn uptime_with_file ( file_path : & std :: ffi :: OsString ) -> UResult < ( ) > {
103+ fn uptime_with_file ( file_path : & OsString ) -> UResult < ( ) > {
124104 use std:: fs;
125105 use std:: os:: unix:: fs:: FileTypeExt ;
126106 use uucore:: error:: set_exit_code;
@@ -212,27 +192,29 @@ fn uptime_with_file(file_path: &std::ffi::OsString) -> UResult<()> {
212192 Ok ( ( ) )
213193}
214194
215- /// Default uptime behaviour i.e. when no file argument is given.
216- fn default_uptime ( matches : & ArgMatches ) -> UResult < ( ) > {
217- if matches. get_flag ( options:: SINCE ) {
218- #[ cfg( unix) ]
219- #[ cfg( not( target_os = "openbsd" ) ) ]
220- let ( boot_time, _) = process_utmpx ( None ) ;
221-
222- #[ cfg( target_os = "openbsd" ) ]
223- let uptime = get_uptime ( None ) ?;
224- #[ cfg( unix) ]
225- #[ cfg( not( target_os = "openbsd" ) ) ]
226- let uptime = get_uptime ( boot_time) ?;
227- #[ cfg( target_os = "windows" ) ]
228- let uptime = get_uptime ( None ) ?;
229- let initial_date = Local
230- . timestamp_opt ( Utc :: now ( ) . timestamp ( ) - uptime, 0 )
231- . unwrap ( ) ;
232- println ! ( "{}" , initial_date. format( "%Y-%m-%d %H:%M:%S" ) ) ;
233- return Ok ( ( ) ) ;
234- }
195+ fn uptime_since ( ) -> UResult < ( ) > {
196+ #[ cfg( unix) ]
197+ #[ cfg( not( target_os = "openbsd" ) ) ]
198+ let ( boot_time, _) = process_utmpx ( None ) ;
235199
200+ #[ cfg( target_os = "openbsd" ) ]
201+ let uptime = get_uptime ( None ) ?;
202+ #[ cfg( unix) ]
203+ #[ cfg( not( target_os = "openbsd" ) ) ]
204+ let uptime = get_uptime ( boot_time) ?;
205+ #[ cfg( target_os = "windows" ) ]
206+ let uptime = get_uptime ( None ) ?;
207+
208+ let initial_date = Local
209+ . timestamp_opt ( Utc :: now ( ) . timestamp ( ) - uptime, 0 )
210+ . unwrap ( ) ;
211+ println ! ( "{}" , initial_date. format( "%Y-%m-%d %H:%M:%S" ) ) ;
212+
213+ Ok ( ( ) )
214+ }
215+
216+ /// Default uptime behaviour i.e. when no file argument is given.
217+ fn default_uptime ( ) -> UResult < ( ) > {
236218 print_time ( ) ;
237219 print_uptime ( None ) ?;
238220 print_nusers ( None ) ;
@@ -251,7 +233,7 @@ fn print_loadavg() {
251233
252234#[ cfg( unix) ]
253235#[ cfg( not( target_os = "openbsd" ) ) ]
254- fn process_utmpx ( file : Option < & std :: ffi :: OsString > ) -> ( Option < time_t > , usize ) {
236+ fn process_utmpx ( file : Option < & OsString > ) -> ( Option < time_t > , usize ) {
255237 let mut nusers = 0 ;
256238 let mut boot_time = None ;
257239
0 commit comments