mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-08 18:30:18 +00:00
2004-12-19 Roland McGrath <roland@redhat.com>
* iconv/iconvconfig.c (nostdlib, output_file, output_file_len): New variables. (options, parse_opt, main): Take new options --nostdlib and --output/-o to set them. Under --nostdlib, skip GCONV_PATH dirs. (write_output): If output_file is set, write the output there.
This commit is contained in:
parent
4f1a039305
commit
ed2bca567c
@ -28,6 +28,7 @@
|
|||||||
#include <mcheck.h>
|
#include <mcheck.h>
|
||||||
#include <search.h>
|
#include <search.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdio_ext.h>
|
#include <stdio_ext.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -121,16 +122,21 @@ static char *more_help (int key, const char *text, void *input);
|
|||||||
|
|
||||||
/* Definitions of arguments for argp functions. */
|
/* Definitions of arguments for argp functions. */
|
||||||
#define OPT_PREFIX 300
|
#define OPT_PREFIX 300
|
||||||
|
#define OPT_NOSTDLIB 301
|
||||||
static const struct argp_option options[] =
|
static const struct argp_option options[] =
|
||||||
{
|
{
|
||||||
{ "prefix", OPT_PREFIX, "PATH", 0, N_("Prefix used for all file accesses") },
|
{ "prefix", OPT_PREFIX, "PATH", 0, N_("Prefix used for all file accesses") },
|
||||||
|
{ "output", 'o', "FILE", 0, N_("\
|
||||||
|
Put output in FILE instead of installed location\
|
||||||
|
(--prefix does not apply to FILE)") },
|
||||||
|
{ "nostdlib", OPT_NOSTDLIB, NULL, 0,
|
||||||
|
N_("Do not search standard directories, only those on the command line") },
|
||||||
{ NULL, 0, NULL, 0, NULL }
|
{ NULL, 0, NULL, 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Data structure to communicate with argp functions. */
|
/* Data structure to communicate with argp functions. */
|
||||||
static struct argp argp =
|
static struct argp argp =
|
||||||
{
|
{
|
||||||
|
|
||||||
options, parse_opt, args_doc, doc, NULL, more_help
|
options, parse_opt, args_doc, doc, NULL, more_help
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -162,6 +168,14 @@ static const char *prefix = "";
|
|||||||
/* Its length. */
|
/* Its length. */
|
||||||
static size_t prefix_len;
|
static size_t prefix_len;
|
||||||
|
|
||||||
|
/* Directory to place output file in. */
|
||||||
|
static const char *output_file;
|
||||||
|
/* Its length. */
|
||||||
|
static size_t output_file_len;
|
||||||
|
|
||||||
|
/* If true, omit the GCONV_PATH directories and require some arguments. */
|
||||||
|
static bool nostdlib;
|
||||||
|
|
||||||
/* Search tree of the modules we know. */
|
/* Search tree of the modules we know. */
|
||||||
static void *modules;
|
static void *modules;
|
||||||
|
|
||||||
@ -270,8 +284,6 @@ main (int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
int remaining;
|
int remaining;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
char *path;
|
|
||||||
char *tp;
|
|
||||||
|
|
||||||
/* Enable memory use testing. */
|
/* Enable memory use testing. */
|
||||||
/* mcheck_pedantic (NULL); */
|
/* mcheck_pedantic (NULL); */
|
||||||
@ -286,6 +298,9 @@ main (int argc, char *argv[])
|
|||||||
/* Parse and process arguments. */
|
/* Parse and process arguments. */
|
||||||
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
|
argp_parse (&argp, argc, argv, 0, &remaining, NULL);
|
||||||
|
|
||||||
|
if (nostdlib && remaining == argc)
|
||||||
|
error (2, 0, _("Directory arguments required when using --nostdlib"));
|
||||||
|
|
||||||
/* Initialize the string table. */
|
/* Initialize the string table. */
|
||||||
strtab = strtabinit ();
|
strtab = strtabinit ();
|
||||||
|
|
||||||
@ -293,14 +308,16 @@ main (int argc, char *argv[])
|
|||||||
while (remaining < argc)
|
while (remaining < argc)
|
||||||
status |= handle_dir (argv[remaining++]);
|
status |= handle_dir (argv[remaining++]);
|
||||||
|
|
||||||
/* In any case also handle the standard directory. */
|
if (! nostdlib)
|
||||||
path = strdupa (GCONV_PATH);
|
|
||||||
tp = strtok (path, ":");
|
|
||||||
while (tp != NULL)
|
|
||||||
{
|
{
|
||||||
status |= handle_dir (tp);
|
/* In any case also handle the standard directory. */
|
||||||
|
char *path = strdupa (GCONV_PATH), *tp = strsep (&path, ":");
|
||||||
|
while (tp != NULL)
|
||||||
|
{
|
||||||
|
status |= handle_dir (tp);
|
||||||
|
|
||||||
tp = strtok (NULL, ":");
|
tp = strsep (&path, ":");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add the builtin transformations and aliases without overwriting
|
/* Add the builtin transformations and aliases without overwriting
|
||||||
@ -340,6 +357,13 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
|||||||
prefix = arg;
|
prefix = arg;
|
||||||
prefix_len = strlen (prefix);
|
prefix_len = strlen (prefix);
|
||||||
break;
|
break;
|
||||||
|
case 'o':
|
||||||
|
output_file = arg;
|
||||||
|
output_file_len = strlen (output_file);
|
||||||
|
break;
|
||||||
|
case OPT_NOSTDLIB:
|
||||||
|
nostdlib = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return ARGP_ERR_UNKNOWN;
|
return ARGP_ERR_UNKNOWN;
|
||||||
}
|
}
|
||||||
@ -626,7 +650,6 @@ add_module (char *rp, const char *directory)
|
|||||||
static int
|
static int
|
||||||
handle_dir (const char *dir)
|
handle_dir (const char *dir)
|
||||||
{
|
{
|
||||||
char *infile;
|
|
||||||
char *cp;
|
char *cp;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
@ -641,7 +664,8 @@ handle_dir (const char *dir)
|
|||||||
newp[dirlen] = '\0';
|
newp[dirlen] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
cp = infile = (char *) alloca (prefix_len + dirlen + sizeof "gconv-modules");
|
char infile[prefix_len + dirlen + sizeof "gconv-modules"];
|
||||||
|
cp = infile;
|
||||||
if (dir[0] == '/')
|
if (dir[0] == '/')
|
||||||
cp = mempcpy (cp, prefix, prefix_len);
|
cp = mempcpy (cp, prefix, prefix_len);
|
||||||
strcpy (mempcpy (cp, dir, dirlen), "gconv-modules");
|
strcpy (mempcpy (cp, dir, dirlen), "gconv-modules");
|
||||||
@ -1006,9 +1030,9 @@ write_output (void)
|
|||||||
struct iovec iov[6];
|
struct iovec iov[6];
|
||||||
static const gidx_t null_word;
|
static const gidx_t null_word;
|
||||||
size_t total;
|
size_t total;
|
||||||
char tmpfname[prefix_len + sizeof (GCONV_MODULES_CACHE)
|
char finalname[prefix_len + sizeof GCONV_MODULES_CACHE];
|
||||||
|
char tmpfname[(output_file == NULL ? sizeof finalname : output_file_len + 1)
|
||||||
+ strlen (".XXXXXX")];
|
+ strlen (".XXXXXX")];
|
||||||
char finalname[prefix_len + sizeof (GCONV_MODULES_CACHE)];
|
|
||||||
|
|
||||||
/* Function to insert the names. */
|
/* Function to insert the names. */
|
||||||
auto void
|
auto void
|
||||||
@ -1036,15 +1060,20 @@ write_output (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Open the output file. */
|
/* Open the output file. */
|
||||||
assert (GCONV_MODULES_CACHE[0] == '/');
|
if (output_file == NULL)
|
||||||
strcpy (stpcpy (mempcpy (tmpfname, prefix, prefix_len), GCONV_MODULES_CACHE),
|
{
|
||||||
".XXXXXX");
|
assert (GCONV_MODULES_CACHE[0] == '/');
|
||||||
|
strcpy (stpcpy (mempcpy (tmpfname, prefix, prefix_len),
|
||||||
|
GCONV_MODULES_CACHE),
|
||||||
|
".XXXXXX");
|
||||||
|
strcpy (mempcpy (finalname, prefix, prefix_len), GCONV_MODULES_CACHE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy (mempcpy (tmpfname, output_file, output_file_len), ".XXXXXX");
|
||||||
fd = mkstemp (tmpfname);
|
fd = mkstemp (tmpfname);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
strcpy (mempcpy (finalname, prefix, prefix_len), GCONV_MODULES_CACHE);
|
|
||||||
|
|
||||||
/* Create the string table. */
|
/* Create the string table. */
|
||||||
string_table = strtabfinalize (strtab, &string_table_size);
|
string_table = strtabfinalize (strtab, &string_table_size);
|
||||||
|
|
||||||
@ -1197,7 +1226,7 @@ write_output (void)
|
|||||||
/* The file was created with mode 0600. Make it world-readable. */
|
/* The file was created with mode 0600. Make it world-readable. */
|
||||||
|| fchmod (fd, 0644) != 0
|
|| fchmod (fd, 0644) != 0
|
||||||
/* Rename the file, possibly replacing an old one. */
|
/* Rename the file, possibly replacing an old one. */
|
||||||
|| rename (tmpfname, finalname) != 0)
|
|| rename (tmpfname, output_file ?: finalname) != 0)
|
||||||
{
|
{
|
||||||
int save_errno = errno;
|
int save_errno = errno;
|
||||||
close (fd);
|
close (fd);
|
||||||
|
Loading…
Reference in New Issue
Block a user