Change the return type of the main function

Since Rust 1.61.0, the `main` function can return a type that
implements the `Termination` trait.
By this, the `main` function can return custom exit codes, so use this.
This commit is contained in:
Shun Sakai
2022-06-13 11:26:50 +08:00
committed by ty
parent a1bfdd2864
commit f57d50659f
10 changed files with 59 additions and 53 deletions
Generated
+7 -7
View File
@@ -623,12 +623,6 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9feedaea5a9f602932e78b512b2fde69aaefd2ef4fd5fd744238f7424b246186"
[[package]]
name = "exitcode"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193"
[[package]]
name = "fake-simd"
version = "0.1.2"
@@ -2092,7 +2086,6 @@ dependencies = [
"daemonize",
"directories",
"env_logger",
"exitcode",
"futures",
"ipnet",
"jemallocator",
@@ -2108,6 +2101,7 @@ dependencies = [
"serde",
"shadowsocks-service",
"snmalloc-rs",
"sysexits",
"tcmalloc",
"thiserror",
"tokio",
@@ -2285,6 +2279,12 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sysexits"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c24dea646d0a2a4209a2d960275fd4416be9ab32c77927f51279a621e2b629"
[[package]]
name = "tcmalloc"
version = "0.3.0"
+1 -1
View File
@@ -153,7 +153,7 @@ thiserror = "1.0"
clap = { version = "3.1", features = ["wrap_help", "suggestions"] }
cfg-if = "1"
qrcode = { version = "0.12", default-features = false, optional = true }
exitcode = "1"
sysexits = "0.3"
build-time = "0.1"
directories = "4.0"
xdg = "2.4"
+4 -2
View File
@@ -4,15 +4,17 @@
//! or you could specify a configuration file. The format of configuration file is defined
//! in mod `config`.
use std::process::ExitCode;
use clap::Command;
use shadowsocks_rust::service::local;
fn main() {
fn main() -> ExitCode {
let mut app = Command::new("shadowsocks")
.version(shadowsocks_rust::VERSION)
.about("A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)");
app = local::define_command_line_options(app);
let matches = app.get_matches();
local::main(&matches);
local::main(&matches)
}
+4 -2
View File
@@ -7,15 +7,17 @@
//! *It should be notice that the extended configuration file is not suitable for the server
//! side.*
use std::process::ExitCode;
use clap::Command;
use shadowsocks_rust::service::manager;
fn main() {
fn main() -> ExitCode {
let mut app = Command::new("shadowsocks")
.version(shadowsocks_rust::VERSION)
.about("A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)");
app = manager::define_command_line_options(app);
let matches = app.get_matches();
manager::main(&matches);
manager::main(&matches)
}
+4 -2
View File
@@ -7,15 +7,17 @@
//! *It should be notice that the extended configuration file is not suitable for the server
//! side.*
use std::process::ExitCode;
use clap::Command;
use shadowsocks_rust::service::server;
fn main() {
fn main() -> ExitCode {
let mut app = Command::new("shadowsocks")
.version(shadowsocks_rust::VERSION)
.about("A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)");
app = server::define_command_line_options(app);
let matches = app.get_matches();
server::main(&matches);
server::main(&matches)
}
+2 -2
View File
@@ -7,12 +7,12 @@
//! *It should be notice that the extended configuration file is not suitable for the server
//! side.*
use std::{env, path::Path};
use std::{env, path::Path, process::ExitCode};
use clap::Command;
use shadowsocks_rust::service::{local, manager, server};
fn main() {
fn main() -> ExitCode {
let app = Command::new("shadowsocks")
.version(shadowsocks_rust::VERSION)
.about("A fast tunnel proxy that helps you bypass firewalls. (https://shadowsocks.org)");
+4 -4
View File
@@ -13,13 +13,13 @@ pub mod sys;
pub mod validator;
/// Exit code when server exits unexpectly
pub const EXIT_CODE_SERVER_EXIT_UNEXPECTEDLY: i32 = exitcode::SOFTWARE;
pub const EXIT_CODE_SERVER_EXIT_UNEXPECTEDLY: sysexits::ExitCode = sysexits::ExitCode::Software;
/// Exit code when server aborted
pub const EXIT_CODE_SERVER_ABORTED: i32 = exitcode::SOFTWARE;
pub const EXIT_CODE_SERVER_ABORTED: sysexits::ExitCode = sysexits::ExitCode::Software;
/// Exit code when loading configuration from file fails
pub const EXIT_CODE_LOAD_CONFIG_FAILURE: i32 = exitcode::CONFIG;
pub const EXIT_CODE_LOAD_CONFIG_FAILURE: sysexits::ExitCode = sysexits::ExitCode::Config;
/// Exit code when loading ACL from file fails
pub const EXIT_CODE_LOAD_ACL_FAILURE: i32 = exitcode::CONFIG;
pub const EXIT_CODE_LOAD_ACL_FAILURE: sysexits::ExitCode = sysexits::ExitCode::Config;
/// Build timestamp in UTC
pub const BUILD_TIME: &str = build_time::build_time_utc!();
+11 -11
View File
@@ -1,6 +1,6 @@
//! Local server launchers
use std::{net::IpAddr, path::PathBuf, process, time::Duration};
use std::{net::IpAddr, path::PathBuf, process::ExitCode, time::Duration};
use clap::{Arg, ArgGroup, ArgMatches, Command, ErrorKind as ClapErrorKind};
use futures::future::{self, Either};
@@ -376,7 +376,7 @@ pub fn define_command_line_options(mut app: Command<'_>) -> Command<'_> {
}
/// Program entrance `main`
pub fn main(matches: &ArgMatches) {
pub fn main(matches: &ArgMatches) -> ExitCode {
let (config, runtime) = {
let config_path_opt = matches.value_of("CONFIG").map(PathBuf::from).or_else(|| {
if !matches.is_present("SERVER_CONFIG") {
@@ -397,7 +397,7 @@ pub fn main(matches: &ArgMatches) {
Ok(c) => c,
Err(err) => {
eprintln!("loading config {:?}, {}", config_path, err);
process::exit(crate::EXIT_CODE_LOAD_CONFIG_FAILURE);
return crate::EXIT_CODE_LOAD_CONFIG_FAILURE.into();
}
},
None => ServiceConfig::default(),
@@ -421,7 +421,7 @@ pub fn main(matches: &ArgMatches) {
Ok(cfg) => cfg,
Err(err) => {
eprintln!("loading config {:?}, {}", cpath, err);
process::exit(crate::EXIT_CODE_LOAD_CONFIG_FAILURE);
return crate::EXIT_CODE_LOAD_CONFIG_FAILURE.into();
}
},
None => Config::new(ConfigType::Local),
@@ -703,7 +703,7 @@ pub fn main(matches: &ArgMatches) {
Ok(acl) => acl,
Err(err) => {
eprintln!("loading ACL \"{}\", {}", acl_file, err);
process::exit(crate::EXIT_CODE_LOAD_ACL_FAILURE);
return crate::EXIT_CODE_LOAD_ACL_FAILURE.into();
}
};
config.acl = Some(acl);
@@ -763,12 +763,12 @@ pub fn main(matches: &ArgMatches) {
"missing `local_address`, consider specifying it by --local-addr command line option, \
or \"local_address\" and \"local_port\" in configuration file"
);
return;
return ExitCode::SUCCESS;
}
if let Err(err) = config.check_integrity() {
eprintln!("config integrity check failed, {}", err);
return;
return ExitCode::SUCCESS;
}
#[cfg(unix)]
@@ -816,17 +816,17 @@ pub fn main(matches: &ArgMatches) {
// Server future resolved without an error. This should never happen.
Either::Left((Ok(..), ..)) => {
eprintln!("server exited unexpectedly");
process::exit(crate::EXIT_CODE_SERVER_EXIT_UNEXPECTEDLY);
crate::EXIT_CODE_SERVER_EXIT_UNEXPECTEDLY.into()
}
// Server future resolved with error, which are listener errors in most cases
Either::Left((Err(err), ..)) => {
eprintln!("server aborted with {}", err);
process::exit(crate::EXIT_CODE_SERVER_ABORTED);
crate::EXIT_CODE_SERVER_ABORTED.into()
}
// The abort signal future resolved. Means we should just exit.
Either::Right(_) => (),
Either::Right(_) => ExitCode::SUCCESS,
}
});
})
}
#[cfg(unix)]
+11 -11
View File
@@ -1,6 +1,6 @@
//! Server Manager launchers
use std::{net::IpAddr, path::PathBuf, process, time::Duration};
use std::{net::IpAddr, path::PathBuf, process::ExitCode, time::Duration};
use clap::{Arg, ArgGroup, ArgMatches, Command, ErrorKind as ClapErrorKind};
use futures::future::{self, Either};
@@ -209,7 +209,7 @@ pub fn define_command_line_options(mut app: Command<'_>) -> Command<'_> {
}
/// Program entrance `main`
pub fn main(matches: &ArgMatches) {
pub fn main(matches: &ArgMatches) -> ExitCode {
let (config, runtime) = {
let config_path_opt = matches.value_of("CONFIG").map(PathBuf::from).or_else(|| {
if !matches.is_present("SERVER_CONFIG") {
@@ -230,7 +230,7 @@ pub fn main(matches: &ArgMatches) {
Ok(c) => c,
Err(err) => {
eprintln!("loading config {:?}, {}", config_path, err);
process::exit(crate::EXIT_CODE_LOAD_CONFIG_FAILURE);
return crate::EXIT_CODE_LOAD_CONFIG_FAILURE.into();
}
},
None => ServiceConfig::default(),
@@ -254,7 +254,7 @@ pub fn main(matches: &ArgMatches) {
Ok(cfg) => cfg,
Err(err) => {
eprintln!("loading config {:?}, {}", cpath, err);
process::exit(crate::EXIT_CODE_LOAD_CONFIG_FAILURE);
return crate::EXIT_CODE_LOAD_CONFIG_FAILURE.into();
}
},
None => Config::new(ConfigType::Manager),
@@ -375,7 +375,7 @@ pub fn main(matches: &ArgMatches) {
Ok(acl) => acl,
Err(err) => {
eprintln!("loading ACL \"{}\", {}", acl_file, err);
process::exit(crate::EXIT_CODE_LOAD_ACL_FAILURE);
return crate::EXIT_CODE_LOAD_ACL_FAILURE.into();
}
};
config.acl = Some(acl);
@@ -435,12 +435,12 @@ pub fn main(matches: &ArgMatches) {
"missing `manager_address`, consider specifying it by --manager-address command line option, \
or \"manager_address\" and \"manager_port\" keys in configuration file"
);
return;
return ExitCode::SUCCESS;
}
if let Err(err) = config.check_integrity() {
eprintln!("config integrity check failed, {}", err);
return;
return ExitCode::SUCCESS;
}
#[cfg(unix)]
@@ -485,15 +485,15 @@ pub fn main(matches: &ArgMatches) {
// Server future resolved without an error. This should never happen.
Either::Left((Ok(..), ..)) => {
eprintln!("server exited unexpectedly");
process::exit(crate::EXIT_CODE_SERVER_EXIT_UNEXPECTEDLY);
crate::EXIT_CODE_SERVER_EXIT_UNEXPECTEDLY.into()
}
// Server future resolved with error, which are listener errors in most cases
Either::Left((Err(err), ..)) => {
eprintln!("server aborted with {}", err);
process::exit(crate::EXIT_CODE_SERVER_ABORTED);
crate::EXIT_CODE_SERVER_ABORTED.into()
}
// The abort signal future resolved. Means we should just exit.
Either::Right(_) => (),
Either::Right(_) => ExitCode::SUCCESS,
}
});
})
}
+11 -11
View File
@@ -1,6 +1,6 @@
//! Server launchers
use std::{net::IpAddr, path::PathBuf, process, time::Duration};
use std::{net::IpAddr, path::PathBuf, process::ExitCode, time::Duration};
use clap::{Arg, ArgGroup, ArgMatches, Command, ErrorKind as ClapErrorKind};
use futures::future::{self, Either};
@@ -221,7 +221,7 @@ pub fn define_command_line_options(mut app: Command<'_>) -> Command<'_> {
}
/// Program entrance `main`
pub fn main(matches: &ArgMatches) {
pub fn main(matches: &ArgMatches) -> ExitCode {
let (config, runtime) = {
let config_path_opt = matches.value_of("CONFIG").map(PathBuf::from).or_else(|| {
if !matches.is_present("SERVER_CONFIG") {
@@ -242,7 +242,7 @@ pub fn main(matches: &ArgMatches) {
Ok(c) => c,
Err(err) => {
eprintln!("loading config {:?}, {}", config_path, err);
process::exit(crate::EXIT_CODE_LOAD_CONFIG_FAILURE);
return crate::EXIT_CODE_LOAD_CONFIG_FAILURE.into();
}
},
None => ServiceConfig::default(),
@@ -266,7 +266,7 @@ pub fn main(matches: &ArgMatches) {
Ok(cfg) => cfg,
Err(err) => {
eprintln!("loading config {:?}, {}", cpath, err);
process::exit(crate::EXIT_CODE_LOAD_CONFIG_FAILURE);
return crate::EXIT_CODE_LOAD_CONFIG_FAILURE.into();
}
},
None => Config::new(ConfigType::Server),
@@ -387,7 +387,7 @@ pub fn main(matches: &ArgMatches) {
Ok(acl) => acl,
Err(err) => {
eprintln!("loading ACL \"{}\", {}", acl_file, err);
process::exit(crate::EXIT_CODE_LOAD_ACL_FAILURE);
return crate::EXIT_CODE_LOAD_ACL_FAILURE.into();
}
};
config.acl = Some(acl);
@@ -448,12 +448,12 @@ pub fn main(matches: &ArgMatches) {
--server-addr, --encrypt-method, --password command line option, \
or configuration file, check more details in https://shadowsocks.org/en/config/quick-guide.html"
);
return;
return ExitCode::SUCCESS;
}
if let Err(err) = config.check_integrity() {
eprintln!("config integrity check failed, {}", err);
return;
return ExitCode::SUCCESS;
}
#[cfg(unix)]
@@ -498,15 +498,15 @@ pub fn main(matches: &ArgMatches) {
// Server future resolved without an error. This should never happen.
Either::Left((Ok(..), ..)) => {
eprintln!("server exited unexpectedly");
process::exit(crate::EXIT_CODE_SERVER_EXIT_UNEXPECTEDLY);
crate::EXIT_CODE_SERVER_EXIT_UNEXPECTEDLY.into()
}
// Server future resolved with error, which are listener errors in most cases
Either::Left((Err(err), ..)) => {
eprintln!("server aborted with {}", err);
process::exit(crate::EXIT_CODE_SERVER_ABORTED);
crate::EXIT_CODE_SERVER_ABORTED.into()
}
// The abort signal future resolved. Means we should just exit.
Either::Right(_) => (),
Either::Right(_) => ExitCode::SUCCESS,
}
});
})
}