[systemd-devel] [PATCH v2] localectl: support systems without locale-archive

Lennart Poettering lennart at poettering.net
Mon Jan 7 06:31:19 PST 2013


On Sat, 05.01.13 01:29, Giovanni Campagna (scampa.giovanni at gmail.com) wrote:

> Not all systems ships with locales inside /usr/lib/locale-archive, some
> prefer to have locale data as individual subdirectories of /usr/lib/locale.
> (A notable example of this is OpenEmbeddded, and OSes deriving from it
> like gnome-ostree).
> Given that glibc supports both ways, localectl should too.

Thanks!

Applied!

> ---
>  src/locale/localectl.c | 101 +++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 85 insertions(+), 16 deletions(-)
> 
> diff --git a/src/locale/localectl.c b/src/locale/localectl.c
> index 383a17d..fbb3bb6 100644
> --- a/src/locale/localectl.c
> +++ b/src/locale/localectl.c
> @@ -266,7 +266,7 @@ finish:
>          return r;
>  }
>  
> -static int list_locales(DBusConnection *bus, char **args, unsigned n) {
> +static int add_locales_from_archive(Set *locales) {
>          /* Stolen from glibc... */
>  
>          struct locarhead {
> @@ -304,21 +304,15 @@ static int list_locales(DBusConnection *bus, char **args, unsigned n) {
>          const struct namehashent *e;
>          const void *p = MAP_FAILED;
>          _cleanup_close_ int fd = -1;
> -        _cleanup_strv_free_ char **l = NULL;
> -        char **j;
> -        Set *locales;
>          size_t sz = 0;
>          struct stat st;
>          unsigned i;
>          int r;
>  
> -        locales = set_new(string_hash_func, string_compare_func);
> -        if (!locales)
> -                return log_oom();
> -
>          fd = open("/usr/lib/locale/locale-archive", O_RDONLY|O_NOCTTY|O_CLOEXEC);
>          if (fd < 0) {
> -                log_error("Failed to open locale archive: %m");
> +                if (errno != ENOENT)
> +                        log_error("Failed to open locale archive: %m");
>                  r = -errno;
>                  goto finish;
>          }
> @@ -380,15 +374,93 @@ static int list_locales(DBusConnection *bus, char **args, unsigned n) {
>                  }
>          }
>  
> +        r = 0;
> +
> + finish:
> +        if (p != MAP_FAILED)
> +                munmap((void*) p, sz);
> +
> +        return r;
> +}
> +
> +static int add_locales_from_libdir (Set *locales) {
> +        DIR *dir;
> +        struct dirent *entry;
> +        int r;
> +
> +        dir = opendir("/usr/lib/locale");
> +        if (!dir) {
> +                log_error("Failed to open locale directory: %m");
> +                r = -errno;
> +                goto finish;
> +        }
> +
> +        errno = 0;
> +        while ((entry = readdir(dir))) {
> +                char *z;
> +
> +                if (entry->d_type != DT_DIR)
> +                        continue;
> +
> +                if (ignore_file(entry->d_name))
> +                        continue;
> +
> +                z = strdup(entry->d_name);
> +                if (!z) {
> +                        r = log_oom();
> +                        goto finish;
> +                }
> +
> +                r = set_put(locales, z);
> +                if (r < 0) {
> +                        free(z);
> +
> +                        if (r != -EEXIST) {
> +                                log_error("Failed to add locale: %s", strerror(-r));
> +                                goto finish;
> +                        }
> +                }
> +
> +                errno = 0;
> +        }
> +
> +        if (errno != 0) {
> +                log_error("Failed to read locale directory: %m");
> +                r = -errno;
> +                goto finish;
> +        }
> +
> +        r = 0;
> +
> + finish:
> +        closedir(dir);
> +        return r;
> +}
> +
> +static int list_locales(DBusConnection *bus, char **args, unsigned n) {
> +        Set *locales;
> +        _cleanup_strv_free_ char **l = NULL;
> +        char **j;
> +        int r;
> +
> +        locales = set_new(string_hash_func, string_compare_func);
> +        if (!locales)
> +                return log_oom();
> +
> +        r = add_locales_from_archive(locales);
> +        if (r < 0 && r != -ENOENT)
> +                goto finish;
> +
> +        r = add_locales_from_libdir(locales);
> +        if (r < 0)
> +                goto finish;
> +
>          l = set_get_strv(locales);
>          if (!l) {
>                  r = log_oom();
>                  goto finish;
>          }
>  
> -        set_free(locales);
> -        locales = NULL;
> -
>          strv_sort(l);
>  
>          pager_open_if_enabled();
> @@ -399,10 +471,7 @@ static int list_locales(DBusConnection *bus, char **args, unsigned n) {
>          r = 0;
>  
>  finish:
> -        if (p != MAP_FAILED)
> -                munmap((void*) p, sz);
> -
> -        set_free_free(locales);
> +        set_free(locales);
>  
>          return r;
>  }


Lennart

-- 
Lennart Poettering - Red Hat, Inc.


More information about the systemd-devel mailing list