From 3b5b7f48848d098c6190781f8790a1b0dcb0217c Mon Sep 17 00:00:00 2001 From: Daniel Hunsaker Date: Fri, 22 Feb 2013 19:17:56 -0700 Subject: Updated exit codes as constant values Re-allocated exit status codes according to three references, which follow: BSD sysexits.h:http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits GNU recomendations:http://www.gnu.org/software/libc/manual/html_node/Exit-Status.html Bash scripting:http://tldp.org/LDP/abs/html/exitcodes.html The GNU recommendations stem from and expand upon the standard C/C++ library (stdlibc) definitions, while also suggesting some best-practice conventions which happen to prevent exit status code collisions with bash, and probably other shells. The re-allocated codes are now mapped to constant values, set in *application/config/constants.php*, and used throughout the CodeIgniter core. They would additionally be used in *index.php*, but the constants file hasn't been loaded at that point, so the integer values are used instead, and a comment follows each such use with amplifying information on why that particular value was selected. Finally, the errors documentation has been updated accordingly. Signed-off-by: Daniel Hunsaker --- application/config/constants.php | 110 +++++++++++++++++++++++++++++++ index.php | 12 ++-- system/core/CodeIgniter.php | 2 +- system/core/Common.php | 16 +++-- system/core/Exceptions.php | 2 +- system/core/Input.php | 2 +- system/core/Output.php | 2 +- system/database/DB_driver.php | 2 +- system/helpers/download_helper.php | 4 +- system/helpers/url_helper.php | 2 +- system/libraries/Driver.php | 2 +- system/libraries/Trackback.php | 4 +- system/libraries/Xmlrpcs.php | 2 +- user_guide_src/source/general/errors.rst | 21 +++++- 14 files changed, 158 insertions(+), 25 deletions(-) diff --git a/application/config/constants.php b/application/config/constants.php index 58264ed5a..32a715952 100644 --- a/application/config/constants.php +++ b/application/config/constants.php @@ -73,6 +73,116 @@ define('FOPEN_READ_WRITE_CREATE_STRICT', 'x+b'); */ define('SHOW_DEBUG_BACKTRACE', TRUE); +/* +|-------------------------------------------------------------------------- +| Exit Status Codes +|-------------------------------------------------------------------------- +| +| Used to indicate the conditions under which the script is exit()ing. +| While there is no universal standard for error codes, there are some +| broad conventions. Three such conventions are presented below, for +| those who wish to make use of them. The CodeIgniter defaults were +| chosen for the least overlap with these conventions, while still +| leaving room for others to be defined in future versions and user +| applications. The CodeIgniter values are defined last so you can +| set them to values used by any of the other conventions, and do so +| by name instead of value. +| +*/ + +/* + * standard C/C++ library (stdlibc): + */ +/* +define('LIBC_EXIT_SUCCESS', 0); +define('LIBC_EXIT_FAILURE', 1); // generic errors +*/ + +/* + * BSD sysexits.h + */ +/* +define('SYS_EX_OK', 0); // successful termination +define('SYS_EX_USAGE', 64); // command line usage error +define('SYS_EX_DATAERR', 65); // data format error +define('SYS_EX_NOINPUT', 66); // cannot open input +define('SYS_EX_NOUSER', 67); // specified user unknown +define('SYS_EX_NOHOST', 68); // specified host name unknown +define('SYS_EX_UNAVAILABLE', 69); // service unavailable +define('SYS_EX_SOFTWARE', 70); // internal software error +define('SYS_EX_OSERR', 71); // system error (e.g., can't fork) +define('SYS_EX_OSFILE', 72); // critical OS file missing +define('SYS_EX_CANTCREAT', 73); // can't create (user) output file +define('SYS_EX_IOERR', 74); // input/output error +define('SYS_EX_TEMPFAIL', 75); // temporary failure; user is invited to retry +define('SYS_EX_PROTOCOL', 76); // remote error in protocol +define('SYS_EX_NOPERM', 77); // permission denied +define('SYS_EX_CONFIG', 78); // configuration error +*/ + +/* + * Bash scripting + */ +/* +define('BASH_EXIT_SUCCESS', 0); +define('BASH_EXIT_ERROR', 1); +define('BASH_EXIT_BUILTIN_MISUSE', 2); +define('BASH_EXIT_CANT_EXEC', 126); +define('BASH_EXIT_CMD_NOT_FOUND', 127); +define('BASH_EXIT_INVALID_EXIT', 128); +define('BASH_EXIT_SIG_HUP', 129); +define('BASH_EXIT_SIG_INT', 130); +define('BASH_EXIT_SIG_QUIT', 131); +define('BASH_EXIT_SIG_ILL', 132); +define('BASH_EXIT_SIG_TRAP', 133); +define('BASH_EXIT_SIG_ABRT', 134); +define('BASH_EXIT_SIG_BUS', 135); +define('BASH_EXIT_SIG_FPE', 136); +define('BASH_EXIT_SIG_KILL', 137); +define('BASH_EXIT_SIG_USR1', 138); +define('BASH_EXIT_SIG_SEGV', 139); +define('BASH_EXIT_SIG_USR2', 140); +define('BASH_EXIT_SIG_PIPE', 141); +define('BASH_EXIT_SIG_ALRM', 142); +define('BASH_EXIT_SIG_TERM', 143); +define('BASH_EXIT_SIG_STKFLT', 144); +define('BASH_EXIT_SIG_CHLD', 145); +define('BASH_EXIT_SIG_CONT', 146); +define('BASH_EXIT_SIG_STOP', 147); +define('BASH_EXIT_SIG_TSTP', 148); +define('BASH_EXIT_SIG_TTIN', 149); +define('BASH_EXIT_SIG_TTOU', 150); +define('BASH_EXIT_SIG_URG', 151); +define('BASH_EXIT_SIG_XCPU', 152); +define('BASH_EXIT_SIG_XFSZ', 153); +define('BASH_EXIT_SIG_VTALRM', 154); +define('BASH_EXIT_SIG_PROF', 155); +define('BASH_EXIT_SIG_WINCH', 156); +define('BASH_EXIT_SIG_IO', 157); +define('BASH_EXIT_SIG_PWR', 158); +define('BASH_EXIT_SIG_SYS', 159); +*/ +/* + * BASH_EXIT_OUTOFRANGE would be 255, and mean an exit status code beyond + * the range of 0-255 was given. However, this code CANNOT BE USED IN PHP, + * so it isn't actually defined, even in a comment. + */ + +/* + * CodeIgniter defaults + */ +define('EXIT_SUCCESS', 0); // no errors +define('EXIT_FAILURE', 1); // generic error +define('EXIT_CONFIG', 3); // configuration error +define('EXIT_404', 4); // file not found; convenience value +define('EXIT_UNK_FILE', 4); // file not found +define('EXIT_UNK_CLASS', 5); // unknown class +define('EXIT_UNK_MEMBER', 6); // unknown class member +define('EXIT_USER_INPUT', 7); // invalid user input +define('EXIT_DATABASE', 8); // database error +define('EXIT__AUTO_MIN', 9); // lowest automatically-assigned error code +define('EXIT__AUTO_MAX', 125); // highest automatically-assigned error code + /* End of file constants.php */ /* Location: ./application/config/constants.php */ \ No newline at end of file diff --git a/index.php b/index.php index be0945740..a52a021ec 100755 --- a/index.php +++ b/index.php @@ -67,7 +67,8 @@ switch (ENVIRONMENT) default: header('HTTP/1.1 503 Service Unavailable.', TRUE, 503); - exit('The application environment is not set correctly.'); + echo 'The application environment is not set correctly.'; + exit(1); // EXIT_* constants not yet defined; 1 is EXIT_FAILURE, a generic error. } /* @@ -190,7 +191,8 @@ switch (ENVIRONMENT) if ( ! is_dir($system_path)) { header('HTTP/1.1 503 Service Unavailable.', TRUE, 503); - exit('Your system folder path does not appear to be set correctly. Please open the following file and correct this: '.pathinfo(__FILE__, PATHINFO_BASENAME)); + echo 'Your system folder path does not appear to be set correctly. Please open the following file and correct this: '.pathinfo(__FILE__, PATHINFO_BASENAME); + exit(3); // EXIT_* constants not yet defined; 3 is EXIT_CONFIG. } /* @@ -225,7 +227,8 @@ switch (ENVIRONMENT) if ( ! is_dir(BASEPATH.$application_folder.'/')) { header('HTTP/1.1 503 Service Unavailable.', TRUE, 503); - exit('Your application folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF); + echo 'Your application folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF; + exit(3); // EXIT_* constants not yet defined; 3 is EXIT_CONFIG. } define('APPPATH', BASEPATH.$application_folder.'/'); @@ -241,7 +244,8 @@ switch (ENVIRONMENT) elseif ( ! is_dir(APPPATH.'views/')) { header('HTTP/1.1 503 Service Unavailable.', TRUE, 503); - exit('Your view folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF); + echo 'Your view folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF; + exit(3); // EXIT_* constants not yet defined; 3 is EXIT_CONFIG. } else { diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index 5a872ef21..8f5271add 100644 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -188,7 +188,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); if ($EXT->call_hook('cache_override') === FALSE && $OUT->_display_cache($CFG, $URI) === TRUE) { - exit(0); + exit(EXIT_SUCCESS); } /* diff --git a/system/core/Common.php b/system/core/Common.php index 3cd97dc2e..479f0da7f 100644 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -177,7 +177,7 @@ if ( ! function_exists('load_class')) // self-referencing loop with the Exceptions class set_status_header(503); echo 'Unable to locate the specified class: '.$class.'.php'; - exit(2); + exit(EXIT_UNK_CLASS); } // Keep track of what we just loaded @@ -251,7 +251,7 @@ if ( ! function_exists('get_config')) { set_status_header(503); echo 'The configuration file does not exist.'; - exit(1); + exit(EXIT_CONFIG); } // Does the $config array exist in the file? @@ -259,7 +259,7 @@ if ( ! function_exists('get_config')) { set_status_header(503); echo 'Your config file does not appear to be formatted correctly.'; - exit(1); + exit(EXIT_CONFIG); } // Are any values being dynamically replaced? @@ -374,12 +374,16 @@ if ( ! function_exists('show_error')) $status_code = abs($status_code); if ($status_code < 100) { - $exit_status = $status_code + 28; + $exit_status = $status_code + EXIT__AUTO_MIN; + if ($exit_status > EXIT__AUTO_MAX) + { + $exit_status = EXIT_FAILURE; + } $status_code = 500; } else { - $exit_status = 27; + $exit_status = EXIT_FAILURE; } $_error =& load_class('Exceptions', 'core'); @@ -407,7 +411,7 @@ if ( ! function_exists('show_404')) { $_error =& load_class('Exceptions', 'core'); $_error->show_404($page, $log_error); - exit(4); + exit(EXIT_UNK_FILE); } } diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php index f799d6027..423387ff9 100644 --- a/system/core/Exceptions.php +++ b/system/core/Exceptions.php @@ -117,7 +117,7 @@ class CI_Exceptions { } echo $this->show_error($heading, $message, 'error_404', 404); - exit(4); + exit(EXIT_UNK_FILE); } // -------------------------------------------------------------------- diff --git a/system/core/Input.php b/system/core/Input.php index 904f4d6e9..8d491e055 100644 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -746,7 +746,7 @@ class CI_Input { { set_status_header(503); echo 'Disallowed Key Characters.'; - exit(6); + exit(EXIT_USER_INPUT); } // Clean UTF-8 if supported diff --git a/system/core/Output.php b/system/core/Output.php index d4abe871d..1025703dc 100644 --- a/system/core/Output.php +++ b/system/core/Output.php @@ -696,7 +696,7 @@ class CI_Output { if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && $last_modified <= strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $this->set_status_header(304); - exit(0); + exit(EXIT_SUCCESS); } else { diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index 6ae1d524d..18dbbc76e 100644 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -1658,7 +1658,7 @@ abstract class CI_DB_driver { $error =& load_class('Exceptions', 'core'); echo $error->show_error($heading, $message, 'error_db'); - exit(5); + exit(EXIT_DATABASE); } // -------------------------------------------------------------------- diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php index daf59f51b..25863eaa4 100644 --- a/system/helpers/download_helper.php +++ b/system/helpers/download_helper.php @@ -142,7 +142,7 @@ if ( ! function_exists('force_download')) if ($data !== NULL) { echo $data; - exit(0); + exit(EXIT_SUCCESS); } // Flush 1MB chunks of data @@ -152,7 +152,7 @@ if ( ! function_exists('force_download')) } fclose($fp); - exit(0); + exit(EXIT_SUCCESS); } } diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php index d6bf7e2c9..7d5ccff35 100644 --- a/system/helpers/url_helper.php +++ b/system/helpers/url_helper.php @@ -550,7 +550,7 @@ if ( ! function_exists('redirect')) header('Location: '.$uri, TRUE, $code); break; } - exit(0); + exit(EXIT_SUCCESS); } } diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php index ba15f81df..9a56013ab 100644 --- a/system/libraries/Driver.php +++ b/system/libraries/Driver.php @@ -290,7 +290,7 @@ class CI_Driver { $trace = debug_backtrace(); _exception_handler(E_ERROR, "No such method '{$method}'", $trace[1]['file'], $trace[1]['line']); - exit(3); + exit(EXIT_UNK_MEMBER); } // -------------------------------------------------------------------- diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php index cc93b2e30..ea8017efd 100644 --- a/system/libraries/Trackback.php +++ b/system/libraries/Trackback.php @@ -212,7 +212,7 @@ class CI_Trackback { public function send_error($message = 'Incomplete Information') { echo '\n\n1\n".$message."\n"; - exit(0); + exit(EXIT_SUCCESS); } // -------------------------------------------------------------------- @@ -228,7 +228,7 @@ class CI_Trackback { public function send_success() { echo '\n\n0\n"; - exit(0); + exit(EXIT_SUCCESS); } // -------------------------------------------------------------------- diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php index 2d2e7f13b..e150c13b7 100644 --- a/system/libraries/Xmlrpcs.php +++ b/system/libraries/Xmlrpcs.php @@ -171,7 +171,7 @@ class CI_Xmlrpcs extends CI_Xmlrpc { header('Content-Type: text/xml'); header('Content-Length: '.strlen($payload)); echo $payload; - exit(0); + exit(EXIT_SUCCESS); } // -------------------------------------------------------------------- diff --git a/user_guide_src/source/general/errors.rst b/user_guide_src/source/general/errors.rst index 8c941aadb..1d6f8120d 100644 --- a/user_guide_src/source/general/errors.rst +++ b/user_guide_src/source/general/errors.rst @@ -18,6 +18,15 @@ procedural interfaces that are available globally throughout the application. This approach permits error messages to get triggered without having to worry about class/function scoping. +CodeIgniter also returns a status code whenever a portion of the core +calls ``exit()``. This exit status code is separate from the HTTP status +code, and serves as a notice to other processes that may be watching of +whether the script completed successfully, or if not, what kind of +problem it encountered that caused it to abort. These values are +defined in *application/config/constants.php*. While exit status codes +are most useful in CLI settings, returning the proper code helps server +software keep track of your scripts and the health of your application. + The following functions let you generate errors: show_error() @@ -36,7 +45,12 @@ following error template:: application/errors/error_general.php The optional parameter ``$status_code`` determines what HTTP status -code should be sent with the error. +code should be sent with the error. If ``$status_code`` is less than 100, +the HTTP status code will be set to 500, and the exit status code will +be set to ``$status_code + EXIT__AUTO_MIN``. If that value is larger than +``EXIT__AUTO_MAX``, or if ``$status_code`` is 100 or higher, the exit +status code will be set to ``EXIT_FAILURE``. You can check in +*application/config/constants.php* for more detail. show_404() ========== @@ -53,8 +67,9 @@ the following error template:: application/errors/error_404.php The function expects the string passed to it to be the file path to the -page that isn't found. Note that CodeIgniter automatically shows 404 -messages if controllers are not found. +page that isn't found. The exit status code will be set to ``EXIT_UNK_FILE``. +Note that CodeIgniter automatically shows 404 messages if controllers are +not found. CodeIgniter automatically logs any ``show_404()`` calls. Setting the optional second parameter to FALSE will skip logging. -- cgit v1.2.3-24-g4f1b