1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* NetworkManager -- Network link manager
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA.
19 * (C) Copyright 2016 Red Hat, Inc.
22 #include "nm-default.h"
24 #include "nm-shared-utils.h"
28 /*****************************************************************************/
30 /* _nm_utils_ascii_str_to_int64:
32 * A wrapper for g_ascii_strtoll, that checks whether the whole string
33 * can be successfully converted to a number and is within a given
34 * range. On any error, @fallback will be returned and %errno will be set
35 * to a non-zero value. On success, %errno will be set to zero, check %errno
36 * for errors. Any trailing or leading (ascii) white space is ignored and the
37 * functions is locale independent.
39 * The function is guaranteed to return a value between @min and @max
40 * (inclusive) or @fallback. Also, the parsing is rather strict, it does
41 * not allow for any unrecognized characters, except leading and trailing
45 _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback)
49 char buf[64], *s, *str_free = NULL;
52 while (g_ascii_isspace (str[0]))
55 if (!str || !str[0]) {
61 if (g_ascii_isspace (str[--len])) {
62 /* backward search the first non-ws character.
63 * We already know that str[0] is non-ws. */
64 while (g_ascii_isspace (str[--len]))
67 /* str[len] is now the last non-ws character... */
70 if (len >= sizeof (buf))
71 s = str_free = g_malloc (len + 1);
78 nm_assert (len > 0 && len < strlen (str) && len == strlen (s));
79 nm_assert (!g_ascii_isspace (str[len-1]) && g_ascii_isspace (str[len]));
80 nm_assert (strncmp (str, s, len) == 0);
86 v = g_ascii_strtoll (str, &s, base);
93 } else if (v > max || v < min) {
98 if (G_UNLIKELY (str_free))
103 /*****************************************************************************/
105 G_DEFINE_QUARK (nm-utils-error-quark, nm_utils_error)
108 nm_utils_error_set_cancelled (GError **error,
109 gboolean is_disposing,
110 const char *instance_name)
113 g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_CANCELLED_DISPOSING,
114 "Disposing %s instance",
115 instance_name && *instance_name ? instance_name : "source");
117 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
118 "Request cancelled");
123 nm_utils_error_is_cancelled (GError *error,
124 gboolean consider_is_disposing)
127 if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
129 if ( consider_is_disposing
130 && g_error_matches (error, NM_UTILS_ERROR, NM_UTILS_ERROR_CANCELLED_DISPOSING))
136 /*****************************************************************************/
139 * nm_g_object_set_property:
140 * @object: the target object
141 * @property_name: the property name
142 * @value: the #GValue to set
143 * @error: (allow-none): optional error argument
145 * A reimplementation of g_object_set_property(), but instead
146 * returning an error instead of logging a warning. All g_object_set*()
147 * versions in glib require you to not pass invalid types or they will
148 * log a g_warning() -- without reporting an error. We don't want that,
149 * so we need to hack error checking around it.
151 * Returns: whether the value was successfully set.
154 nm_g_object_set_property (GObject *object,
155 const gchar *property_name,
160 nm_auto_unset_gvalue GValue tmp_value = G_VALUE_INIT;
163 g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
164 g_return_val_if_fail (property_name != NULL, FALSE);
165 g_return_val_if_fail (G_IS_VALUE (value), FALSE);
166 g_return_val_if_fail (!error || !*error, FALSE);
168 /* g_object_class_find_property() does g_param_spec_get_redirect_target(),
169 * where we differ from a plain g_object_set_property(). */
170 pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), property_name);
173 g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
174 _("object class '%s' has no property named '%s'"),
175 G_OBJECT_TYPE_NAME (object),
179 if (!(pspec->flags & G_PARAM_WRITABLE)) {
180 g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
181 _("property '%s' of object class '%s' is not writable"),
183 G_OBJECT_TYPE_NAME (object));
186 if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY)) {
187 g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
188 _("construct property \"%s\" for object '%s' can't be set after construction"),
189 pspec->name, G_OBJECT_TYPE_NAME (object));
193 klass = g_type_class_peek (pspec->owner_type);
195 g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
196 _("'%s::%s' is not a valid property name; '%s' is not a GObject subtype"),
197 g_type_name (pspec->owner_type), pspec->name, g_type_name (pspec->owner_type));
201 /* provide a copy to work from, convert (if necessary) and validate */
202 g_value_init (&tmp_value, pspec->value_type);
203 if (!g_value_transform (value, &tmp_value)) {
204 g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
205 _("unable to set property '%s' of type '%s' from value of type '%s'"),
207 g_type_name (pspec->value_type),
208 G_VALUE_TYPE_NAME (value));
211 if ( g_param_value_validate (pspec, &tmp_value)
212 && !(pspec->flags & G_PARAM_LAX_VALIDATION)) {
213 gs_free char *contents = g_strdup_value_contents (value);
215 g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
216 _("value \"%s\" of type '%s' is invalid or out of range for property '%s' of type '%s'"),
218 G_VALUE_TYPE_NAME (value),
220 g_type_name (pspec->value_type));
224 g_object_set_property (object, property_name, &tmp_value);
228 /*****************************************************************************/