Browse Source

[settings] Expose exit status of failed command via ${errno}

Allow scripts to report errors in more detail by exposing the most
recent error via the ${errno} setting.  For example:

    chain ${filename} || goto failed
    ...
    :failed
    imgfree http://192.168.0.1/ipxe_error.php?error=${errno}

Note that ${errno} is valid only immediately after executing a failed
command.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
c5c257788f
1 changed files with 120 additions and 0 deletions
  1. 120
    0
      src/core/settings.c

+ 120
- 0
src/core/settings.c View File

@@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
31 31
 #include <ipxe/dhcp.h>
32 32
 #include <ipxe/uuid.h>
33 33
 #include <ipxe/uri.h>
34
+#include <ipxe/init.h>
34 35
 #include <ipxe/settings.h>
35 36
 
36 37
 /** @file
@@ -1893,3 +1894,122 @@ struct setting priority_setting __setting ( SETTING_MISC ) = {
1893 1894
 	.tag = DHCP_EB_PRIORITY,
1894 1895
 	.type = &setting_type_int8,
1895 1896
 };
1897
+
1898
+/******************************************************************************
1899
+ *
1900
+ * Built-in settings block
1901
+ *
1902
+ ******************************************************************************
1903
+ */
1904
+
1905
+/** Built-in setting tag magic */
1906
+#define BUILTIN_SETTING_TAG_MAGIC 0xb1
1907
+
1908
+/**
1909
+ * Construct built-in setting tag
1910
+ *
1911
+ * @v id		Unique identifier
1912
+ * @ret tag		Setting tag
1913
+ */
1914
+#define BUILTIN_SETTING_TAG( id ) ( ( BUILTIN_SETTING_TAG_MAGIC << 24 ) | (id) )
1915
+
1916
+/** "errno" setting tag */
1917
+#define BUILTIN_SETTING_TAG_ERRNO BUILTIN_SETTING_TAG ( 0x01 )
1918
+
1919
+/** Error number setting */
1920
+struct setting errno_setting __setting ( SETTING_MISC ) = {
1921
+	.name = "errno",
1922
+	.description = "Last error",
1923
+	.tag = BUILTIN_SETTING_TAG_ERRNO,
1924
+	.type = &setting_type_uint32,
1925
+};
1926
+
1927
+/**
1928
+ * Fetch error number setting
1929
+ *
1930
+ * @v settings		Settings block
1931
+ * @v setting		Setting to fetch
1932
+ * @v data		Setting data, or NULL to clear setting
1933
+ * @v len		Length of setting data
1934
+ * @ret rc		Return status code
1935
+ */
1936
+static int errno_fetch ( struct settings *settings __unused,
1937
+			 struct setting *setting __unused,
1938
+			 void *data, size_t len ) {
1939
+	uint32_t content;
1940
+
1941
+	/* Return current error */
1942
+	content = htonl ( errno );
1943
+	if ( len > sizeof ( content ) )
1944
+		len = sizeof ( content );
1945
+	memcpy ( data, &content, len );
1946
+	return sizeof ( content );
1947
+}
1948
+
1949
+/**
1950
+ * Fetch built-in setting
1951
+ *
1952
+ * @v settings		Settings block
1953
+ * @v setting		Setting to fetch
1954
+ * @v data		Setting data, or NULL to clear setting
1955
+ * @v len		Length of setting data
1956
+ * @ret rc		Return status code
1957
+ */
1958
+static int builtin_fetch ( struct settings *settings __unused,
1959
+			   struct setting *setting,
1960
+			   void *data, size_t len ) {
1961
+
1962
+	if ( setting_cmp ( setting, &errno_setting ) == 0 ) {
1963
+		return errno_fetch ( settings, setting, data, len );
1964
+	} else {
1965
+		return -ENOENT;
1966
+	}
1967
+}
1968
+
1969
+/**
1970
+ * Check applicability of built-in setting
1971
+ *
1972
+ * @v settings		Settings block
1973
+ * @v setting		Setting
1974
+ * @ret applies		Setting applies within this settings block
1975
+ */
1976
+static int builtin_applies ( struct settings *settings __unused,
1977
+			     struct setting *setting ) {
1978
+	unsigned int tag_magic;
1979
+
1980
+	/* Check tag magic */
1981
+	tag_magic = ( setting->tag >> 24 );
1982
+	return ( tag_magic == BUILTIN_SETTING_TAG_MAGIC );
1983
+}
1984
+
1985
+/** Built-in settings operations */
1986
+static struct settings_operations builtin_settings_operations = {
1987
+	.applies = builtin_applies,
1988
+	.fetch = builtin_fetch,
1989
+};
1990
+
1991
+/** Built-in settings */
1992
+static struct settings builtin_settings = {
1993
+	.refcnt = NULL,
1994
+	.tag_magic = BUILTIN_SETTING_TAG ( 0 ),
1995
+	.siblings = LIST_HEAD_INIT ( builtin_settings.siblings ),
1996
+	.children = LIST_HEAD_INIT ( builtin_settings.children ),
1997
+	.op = &builtin_settings_operations,
1998
+};
1999
+
2000
+/** Initialise built-in settings */
2001
+static void builtin_init ( void ) {
2002
+	int rc;
2003
+
2004
+	if ( ( rc = register_settings ( &builtin_settings, NULL,
2005
+					"builtin" ) ) != 0 ) {
2006
+		DBG ( "Could not register built-in settings: %s\n",
2007
+		      strerror ( rc ) );
2008
+		return;
2009
+	}
2010
+}
2011
+
2012
+/** Built-in settings initialiser */
2013
+struct init_fn builtin_init_fn __init_fn ( INIT_NORMAL ) = {
2014
+	.initialise = builtin_init,
2015
+};

Loading…
Cancel
Save