summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-09-17 10:03:46 -0500
committerLennart Poettering <lennart@poettering.net>2013-09-17 10:06:50 -0500
commit19f6d710772305610b928bc2678b9d77fe11e770 (patch)
treeca3e7b4f7f20f94137fcef96b92a7a208c72e1c5 /src/shared
parent0aafd43d235982510d1c40564079f7bcec0c7c19 (diff)
specifier: rework specifier calls to return proper error message
Previously the specifier calls could only indicate OOM by returning NULL. With this change they will return negative errno-style error codes like everything else.
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/install-printf.c54
-rw-r--r--src/shared/install-printf.h2
-rw-r--r--src/shared/install.c25
-rw-r--r--src/shared/specifier.c105
-rw-r--r--src/shared/specifier.h14
5 files changed, 123 insertions, 77 deletions
diff --git a/src/shared/install-printf.c b/src/shared/install-printf.c
index 1157ea989b..1ee1243f4d 100644
--- a/src/shared/install-printf.c
+++ b/src/shared/install-printf.c
@@ -27,21 +27,35 @@
#include "util.h"
#include "install-printf.h"
-static char *specifier_prefix_and_instance(char specifier, void *data, void *userdata) {
+static int specifier_prefix_and_instance(char specifier, void *data, void *userdata, char **ret) {
InstallInfo *i = userdata;
+ char *n;
+
assert(i);
- return unit_name_to_prefix_and_instance(i->name);
+ n = unit_name_to_prefix_and_instance(i->name);
+ if (!n)
+ return -ENOMEM;
+
+ *ret = n;
+ return 0;
}
-static char *specifier_prefix(char specifier, void *data, void *userdata) {
+static int specifier_prefix(char specifier, void *data, void *userdata, char **ret) {
InstallInfo *i = userdata;
+ char *n;
+
assert(i);
- return unit_name_to_prefix(i->name);
+ n = unit_name_to_prefix(i->name);
+ if (!n)
+ return -ENOMEM;
+
+ *ret = n;
+ return 0;
}
-static char *specifier_instance(char specifier, void *data, void *userdata) {
+static int specifier_instance(char specifier, void *data, void *userdata, char **ret) {
InstallInfo *i = userdata;
char *instance;
int r;
@@ -50,14 +64,19 @@ static char *specifier_instance(char specifier, void *data, void *userdata) {
r = unit_name_to_instance(i->name, &instance);
if (r < 0)
- return NULL;
- if (instance != NULL)
- return instance;
- else
- return strdup("");
+ return r;
+
+ if (!instance) {
+ instance = strdup("");
+ if (!instance)
+ return -ENOMEM;
+ }
+
+ *ret = instance;
+ return 0;
}
-static char *specifier_user_name(char specifier, void *data, void *userdata) {
+static int specifier_user_name(char specifier, void *data, void *userdata, char **ret) {
InstallInfo *i = userdata;
const char *username;
_cleanup_free_ char *tmp = NULL;
@@ -82,18 +101,20 @@ static char *specifier_user_name(char specifier, void *data, void *userdata) {
r = get_user_creds(&username, &uid, NULL, NULL, NULL);
if (r < 0)
- return NULL;
+ return r;
if (asprintf(&printed, "%d", uid) < 0)
- return NULL;
+ return -ENOMEM;
break;
}}
- return printed;
+
+ *ret = printed;
+ return 0;
}
-char *install_full_printf(InstallInfo *i, const char *format) {
+int install_full_printf(InstallInfo *i, const char *format, char **ret) {
/* This is similar to unit_full_printf() but does not support
* anything path-related.
@@ -129,6 +150,7 @@ char *install_full_printf(InstallInfo *i, const char *format) {
assert(i);
assert(format);
+ assert(ret);
- return specifier_printf(format, table, i);
+ return specifier_printf(format, table, i, ret);
}
diff --git a/src/shared/install-printf.h b/src/shared/install-printf.h
index 46f5294d21..6ffa488b1b 100644
--- a/src/shared/install-printf.h
+++ b/src/shared/install-printf.h
@@ -22,4 +22,4 @@
#pragma once
#include "install.h"
-char *install_full_printf(InstallInfo *i, const char *format);
+int install_full_printf(InstallInfo *i, const char *format, char **ret);
diff --git a/src/shared/install.c b/src/shared/install.c
index 07e06c425f..9722ed4e1c 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -967,14 +967,15 @@ static int config_parse_user(const char *unit,
InstallInfo *i = data;
char* printed;
+ int r;
assert(filename);
assert(lvalue);
assert(rvalue);
- printed = install_full_printf(i, rvalue);
- if (!printed)
- return -ENOMEM;
+ r = install_full_printf(i, rvalue, &printed);
+ if (r < 0)
+ return r;
free(i->user);
i->user = printed;
@@ -1200,9 +1201,9 @@ static int install_info_symlink_alias(
STRV_FOREACH(s, i->aliases) {
_cleanup_free_ char *alias_path = NULL, *dst = NULL;
- dst = install_full_printf(i, *s);
- if (!dst)
- return -ENOMEM;
+ q = install_full_printf(i, *s, &dst);
+ if (q < 0)
+ return q;
alias_path = path_make_absolute(dst, config_path);
if (!alias_path)
@@ -1232,9 +1233,9 @@ static int install_info_symlink_wants(
STRV_FOREACH(s, i->wanted_by) {
_cleanup_free_ char *path = NULL, *dst = NULL;
- dst = install_full_printf(i, *s);
- if (!dst)
- return -ENOMEM;
+ q = install_full_printf(i, *s, &dst);
+ if (q < 0)
+ return q;
if (!unit_name_is_valid(dst, true)) {
r = -EINVAL;
@@ -1269,9 +1270,9 @@ static int install_info_symlink_requires(
STRV_FOREACH(s, i->required_by) {
_cleanup_free_ char *path = NULL, *dst = NULL;
- dst = install_full_printf(i, *s);
- if (!dst)
- return -ENOMEM;
+ q = install_full_printf(i, *s, &dst);
+ if (q < 0)
+ return q;
if (!unit_name_is_valid(dst, true)) {
r = -EINVAL;
diff --git a/src/shared/specifier.c b/src/shared/specifier.c
index bb8859fdfd..8fbf6db5df 100644
--- a/src/shared/specifier.c
+++ b/src/shared/specifier.c
@@ -32,21 +32,22 @@
*
*/
-char *specifier_printf(const char *text, const Specifier table[], void *userdata) {
- char *r, *t;
+int specifier_printf(const char *text, const Specifier table[], void *userdata, char **_ret) {
+ char *ret, *t;
const char *f;
bool percent = false;
size_t l;
+ int r;
assert(text);
assert(table);
l = strlen(text);
- r = new(char, l+1);
- if (!r)
- return NULL;
+ ret = new(char, l+1);
+ if (!ret)
+ return -ENOMEM;
- t = r;
+ t = ret;
for (f = text; *f; f++, l--) {
@@ -61,32 +62,31 @@ char *specifier_printf(const char *text, const Specifier table[], void *userdata
break;
if (i->lookup) {
- char *n, *w;
+ _cleanup_free_ char *w = NULL;
+ char *n;
size_t k, j;
- w = i->lookup(i->specifier, i->data, userdata);
- if (!w) {
- free(r);
- return NULL;
+ r = i->lookup(i->specifier, i->data, userdata, &w);
+ if (r < 0) {
+ free(ret);
+ return r;
}
- j = t - r;
+ j = t - ret;
k = strlen(w);
n = new(char, j + k + l + 1);
if (!n) {
- free(r);
- free(w);
- return NULL;
+ free(ret);
+ return -ENOMEM;
}
- memcpy(n, r, j);
+ memcpy(n, ret, j);
memcpy(n + j, w, k);
- free(r);
- free(w);
+ free(ret);
- r = n;
+ ret = n;
t = n + j + k;
} else {
*(t++) = '%';
@@ -102,58 +102,81 @@ char *specifier_printf(const char *text, const Specifier table[], void *userdata
}
*t = 0;
- return r;
+ *_ret = ret;
+ return 0;
}
/* Generic handler for simple string replacements */
-char* specifier_string(char specifier, void *data, void *userdata) {
- return strdup(strempty(data));
+int specifier_string(char specifier, void *data, void *userdata, char **ret) {
+ char *n;
+
+ n = strdup(strempty(data));
+ if (!n)
+ return -ENOMEM;
+
+ *ret = n;
+ return 0;
}
-char *specifier_machine_id(char specifier, void *data, void *userdata) {
+int specifier_machine_id(char specifier, void *data, void *userdata, char **ret) {
sd_id128_t id;
- char *buf;
+ char *n;
int r;
r = sd_id128_get_machine(&id);
if (r < 0)
- return NULL;
+ return r;
- buf = new(char, 33);
- if (!buf)
- return NULL;
+ n = new(char, 33);
+ if (!n)
+ return -ENOMEM;
- return sd_id128_to_string(id, buf);
+ *ret = sd_id128_to_string(id, n);
+ return 0;
}
-char *specifier_boot_id(char specifier, void *data, void *userdata) {
+int specifier_boot_id(char specifier, void *data, void *userdata, char **ret) {
sd_id128_t id;
- char *buf;
+ char *n;
int r;
r = sd_id128_get_boot(&id);
if (r < 0)
- return NULL;
+ return r;
- buf = new(char, 33);
- if (!buf)
- return NULL;
+ n = new(char, 33);
+ if (!n)
+ return -ENOMEM;
- return sd_id128_to_string(id, buf);
+ *ret = sd_id128_to_string(id, n);
+ return 0;
}
-char *specifier_host_name(char specifier, void *data, void *userdata) {
- return gethostname_malloc();
+int specifier_host_name(char specifier, void *data, void *userdata, char **ret) {
+ char *n;
+
+ n = gethostname_malloc();
+ if (!n)
+ return -ENOMEM;
+
+ *ret = n;
+ return 0;
}
-char *specifier_kernel_release(char specifier, void *data, void *userdata) {
+int specifier_kernel_release(char specifier, void *data, void *userdata, char **ret) {
struct utsname uts;
+ char *n;
int r;
r = uname(&uts);
if (r < 0)
- return NULL;
+ return -errno;
+
+ n = strdup(uts.release);
+ if (!n)
+ return -ENOMEM;
- return strdup(uts.release);
+ *ret = n;
+ return 0;
}
diff --git a/src/shared/specifier.h b/src/shared/specifier.h
index d13e6406b6..fca206f665 100644
--- a/src/shared/specifier.h
+++ b/src/shared/specifier.h
@@ -21,7 +21,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-typedef char* (*SpecifierCallback)(char specifier, void *data, void *userdata);
+typedef int (*SpecifierCallback)(char specifier, void *data, void *userdata, char **ret);
typedef struct Specifier {
const char specifier;
@@ -29,11 +29,11 @@ typedef struct Specifier {
void *data;
} Specifier;
-char *specifier_printf(const char *text, const Specifier table[], void *userdata);
+int specifier_printf(const char *text, const Specifier table[], void *userdata, char **ret);
-char *specifier_string(char specifier, void *data, void *userdata);
+int specifier_string(char specifier, void *data, void *userdata, char **ret);
-char *specifier_machine_id(char specifier, void *data, void *userdata);
-char *specifier_boot_id(char specifier, void *data, void *userdata);
-char *specifier_host_name(char specifier, void *data, void *userdata);
-char *specifier_kernel_release(char specifier, void *data, void *userdata);
+int specifier_machine_id(char specifier, void *data, void *userdata, char **ret);
+int specifier_boot_id(char specifier, void *data, void *userdata, char **ret);
+int specifier_host_name(char specifier, void *data, void *userdata, char **ret);
+int specifier_kernel_release(char specifier, void *data, void *userdata, char **ret);