Back to index

glibc  2.9
Classes | Defines | Functions | Variables
getconf.c File Reference
#include <unistd.h>
#include <errno.h>
#include <error.h>
#include <libintl.h>
#include <locale.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "../version.h"

Go to the source code of this file.

Classes

struct  conf

Defines

#define PACKAGE   _libc_intl_domainname

Functions

static void usage (void)
static void print_all (const char *path)
int main (int argc, char *argv[])

Variables

static struct conf []
struct {
const char * name
int num
specs []
static const int nspecs = sizeof (specs) / sizeof (specs[0])
const char * __progname

Define Documentation

Definition at line 28 of file getconf.c.


Function Documentation

int main ( int  argc,
char *  argv[] 
)

Definition at line 997 of file getconf.c.

{
  register const struct conf *c;

  /* Set locale.  Do not set LC_ALL because the other categories must
     not be affected (according to POSIX.2).  */
  setlocale (LC_CTYPE, "");
  setlocale (LC_MESSAGES, "");

  /* Initialize the message catalog.  */
  textdomain (PACKAGE);

  if (argc > 1 && strcmp (argv[1], "--version") == 0)
    {
      fprintf (stderr, "getconf (GNU %s) %s\n", PACKAGE, VERSION);
      fprintf (stderr, gettext ("\
Copyright (C) %s Free Software Foundation, Inc.\n\
This is free software; see the source for copying conditions.  There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
"), "2008");
      fprintf (stderr, gettext ("Written by %s.\n"), "Roland McGrath");
      return 0;
    }

  const char *getconf_dir = getenv ("GETCONF_DIR") ?: GETCONF_DIR;
  size_t getconf_dirlen = strlen (getconf_dir);

  const char *spec = NULL;
  char buf[sizeof "POSIX_V6_LPBIG_OFFBIG"];
  char *argv0 = argv[0];
  if (argc > 1 && strncmp (argv[1], "-v", 2) == 0)
    {
      if (argv[1][2] == '\0')
       {
         if (argc < 3)
           usage ();

         spec = argv[2];
         argv += 2;
         argc -= 2;
       }
      else
       {
         spec = &argv[1][2];
         argv += 1;
         argc += 1;
       }
    }
  else
    {
      char default_name[getconf_dirlen + sizeof "/default"];
      memcpy (mempcpy (default_name, getconf_dir, getconf_dirlen),
             "/default", sizeof "/default");
      int len = readlink (default_name, buf, sizeof buf - 1);
      if (len > 0)
       {
         buf[len] = '\0';
         spec = buf;
       }
    }

  /* Check for the specifications we know.  */
  if (spec != NULL)
    {
      int i;
      for (i = 0; i < nspecs; ++i)
       if (strcmp (spec, specs[i].name) == 0)
         break;

      if (i == nspecs)
       error (2, 0, _("unknown specification \"%s\""), spec);

      switch (specs[i].num)
       {
#ifndef _POSIX_V6_ILP32_OFF32
         case _SC_V6_ILP32_OFF32:
#endif
#ifndef _POSIX_V6_ILP32_OFFBIG
         case _SC_V6_ILP32_OFFBIG:
#endif
#ifndef _POSIX_V6_LP64_OFF64
         case _SC_V6_LP64_OFF64:
#endif
#ifndef _POSIX_V6_LPBIG_OFFBIG
         case _SC_V6_LPBIG_OFFBIG:
#endif
           {
             const char *args[argc + 3];
             size_t spec_len = strlen (spec);
             char getconf_name[getconf_dirlen + 1 + spec_len + 1];
             memcpy (mempcpy (mempcpy (getconf_name, getconf_dir,
                                   getconf_dirlen),
                            "/", 1), spec, spec_len + 1);
             args[0] = argv0;
             args[1] = "-v";
             args[2] = spec;
             memcpy (&args[3], &argv[1], argc * sizeof (argv[1]));
             execv (getconf_name, (char * const *) args);
             error (4, errno, _("Couldn't execute %s"), getconf_name);
           }
         default:
           break;
       }
    }

  if (argc > 1 && strcmp (argv[1], "-a") == 0)
    {
      if (argc == 2)
       print_all ("/");
      else if (argc == 3)
       print_all (argv[2]);
      else
       usage ();
    }

  if (argc < 2 || argc > 3)
    usage ();

  for (c = vars; c->name != NULL; ++c)
    if (strcmp (c->name, argv[1]) == 0
       || (strncmp (c->name, "_POSIX_", 7) == 0
           && strcmp (c->name + 7, argv[1]) == 0))
      {
       long int value;
       size_t clen;
       char *cvalue;
       switch (c->call)
         {
         case PATHCONF:
           if (argc < 3)
             usage ();
           errno = 0;
           value = pathconf (argv[2], c->call_name);
           if (value == -1)
             {
              if (errno)
                error (3, errno, "pathconf: %s", argv[2]);
              else
                puts (_("undefined"));
             }
           else
             printf ("%ld\n", value);
           exit (0);

         case SYSCONF:
           if (argc > 2)
             usage ();
           value = sysconf (c->call_name);
           if (value == -1l)
             {
              if (c->call_name == _SC_UINT_MAX
                  || c->call_name == _SC_ULONG_MAX)
                printf ("%lu\n", value);
              else
                puts (_("undefined"));
             }
           else
             printf ("%ld\n", value);
           exit (0);

         case CONFSTR:
           if (argc > 2)
             usage ();
           clen = confstr (c->call_name, (char *) NULL, 0);
           cvalue = (char *) malloc (clen);
           if (cvalue == NULL)
             error (3, 0, _("memory exhausted"));

           if (confstr (c->call_name, cvalue, clen) != clen)
             error (3, errno, "confstr");

           printf ("%.*s\n", (int) clen, cvalue);
           exit (0);
         }
      }

  error (2, 0, _("Unrecognized variable `%s'"), argv[1]);
  /* NOTREACHED */
  return 2;
}

Here is the call graph for this function:

static void print_all ( const char *  path) [static]

Definition at line 953 of file getconf.c.

{
  register const struct conf *c;
  size_t clen;
  long int value;
  char *cvalue;
  for (c = vars; c->name != NULL; ++c) {
    printf("%-35s", c->name);
    switch (c->call) {
      case PATHCONF:
        value = pathconf (path, c->call_name);
        if (value != -1) {
          printf("%ld", value);
        }
        printf("\n");
        break;
      case SYSCONF:
        value = sysconf (c->call_name);
        if (value == -1l) {
          if (c->call_name == _SC_UINT_MAX
            || c->call_name == _SC_ULONG_MAX)
            printf ("%lu", value);
        }
        else {
          printf ("%ld", value);
        }
        printf ("\n");
        break;
      case CONFSTR:
        clen = confstr (c->call_name, (char *) NULL, 0);
        cvalue = (char *) malloc (clen);
        if (cvalue == NULL)
          error (3, 0, _("memory exhausted"));
        if (confstr (c->call_name, cvalue, clen) != clen)
          error (3, errno, "confstr");
        printf ("%.*s\n", (int) clen, cvalue);
       free (cvalue);
        break;
    }
  }
  exit (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void usage ( void  ) [static]

Definition at line 942 of file getconf.c.

{
  fprintf (stderr,
          _("Usage: %s [-v specification] variable_name [pathname]\n"),
          __progname);
  fprintf (stderr,
          _("       %s -a [pathname]\n"), __progname);
  exit (2);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 24 of file init-misc.c.

struct conf[] [static]

Definition at line 37 of file getconf.c.

const int nspecs = sizeof (specs) / sizeof (specs[0]) [static]

Definition at line 936 of file getconf.c.

struct { ... } specs[] [static]