mirror of
https://git.savannah.gnu.org/git/coreutils.git
synced 2025-09-10 07:59:52 +02:00
New program: mktemp.
* NEWS: Mention this. * README: Add mktemp to the list. * AUTHORS: Add this: mktemp: Jim Meyering * src/mktemp.c: New file. * src/Makefile.am (bin_PROGRAMS): Add mktemp. (mktemp_LDADD): Add $(LIB_GETHRXTIME). * man/mktemp.x: New file. * man/Makefile.am (dist_man_MANS): Add mktemp.1. (mktemp.1): New dependency. * man/.cvsignore: Add mktemp.1. * man/.gitignore: New file. * src/.cvsignore, src/.gitignore: Add mktemp. * tests/misc/mktemp: New file. * tests/misc/Makefile.am (TESTS): Add mktemp. * tests/Coreutils.pm (run_tests): Give the POST-test function access to stdout and stderr contents, so it can verify that the named-on-stdout file/dir does indeed exist and has proper permissions, etc. [po/ChangeLog] * POTFILES.in: Add src/mktemp.c.
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -46,6 +46,7 @@ md5sum: Ulrich Drepper, Scott Miller, David Madore
|
||||
mkdir: David MacKenzie
|
||||
mkfifo: David MacKenzie
|
||||
mknod: David MacKenzie
|
||||
mktemp: Jim Meyering
|
||||
mv: Mike Parker, David MacKenzie, Jim Meyering
|
||||
nice: David MacKenzie
|
||||
nl: Scott Bartram, David MacKenzie
|
||||
|
||||
22
ChangeLog
22
ChangeLog
@@ -1,5 +1,27 @@
|
||||
2007-10-07 Jim Meyering <meyering@redhat.com>
|
||||
|
||||
New program: mktemp.
|
||||
* NEWS: Mention this.
|
||||
* README: Add mktemp to the list.
|
||||
* AUTHORS: Add this: mktemp: Jim Meyering
|
||||
* src/mktemp.c: New file.
|
||||
* src/Makefile.am (bin_PROGRAMS): Add mktemp.
|
||||
(mktemp_LDADD): Add $(LIB_GETHRXTIME).
|
||||
* man/mktemp.x: New file.
|
||||
* man/Makefile.am (dist_man_MANS): Add mktemp.1.
|
||||
(mktemp.1): New dependency.
|
||||
* man/.cvsignore: Add mktemp.1.
|
||||
* man/.gitignore: New file.
|
||||
* src/.cvsignore, src/.gitignore: Add mktemp.
|
||||
* tests/misc/mktemp: New file.
|
||||
* tests/misc/Makefile.am (TESTS): Add mktemp.
|
||||
* tests/Coreutils.pm (run_tests): Give the POST-test function
|
||||
access to stdout and stderr contents, so it can verify that
|
||||
the named-on-stdout file/dir does indeed exist and has proper
|
||||
permissions, etc.
|
||||
[po/ChangeLog]
|
||||
* POTFILES.in: Add src/mktemp.c.
|
||||
|
||||
Make tempname more random, via the randint module.
|
||||
* gl/modules/tempname (Depends-on): Add randint and stdbool.
|
||||
* gl/lib/tempname.c: Include randint.h and stdbool.h.
|
||||
|
||||
2
NEWS
2
NEWS
@@ -7,6 +7,8 @@ GNU coreutils NEWS -*- outline -*-
|
||||
arch: equivalent to uname -m, not installed by default
|
||||
But don't install this program on Solaris systems.
|
||||
|
||||
mktemp: create a temporary file or directory (or names)
|
||||
|
||||
** Programs no longer installed by default
|
||||
|
||||
hostname, su
|
||||
|
||||
4
README
4
README
@@ -9,8 +9,8 @@ The programs that can be built with this package are:
|
||||
|
||||
[ arch base64 basename cat chcon chgrp chmod chown chroot cksum comm cp
|
||||
csplit cut date dd df dir dircolors dirname du echo env expand expr
|
||||
factor false fmt fold groups head hostid hostname id install join
|
||||
kill link ln logname ls md5sum mkdir mkfifo mknod mv nice nl nohup
|
||||
factor false fmt fold groups head hostid hostname id install join kill
|
||||
link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup
|
||||
od paste pathchk pinky pr printenv printf ptx pwd readlink rm rmdir
|
||||
runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred shuf
|
||||
sleep sort split stat stty su sum sync tac tail tee test touch tr true
|
||||
|
||||
@@ -32,7 +32,7 @@ AC_CONFIG_AUX_DIR(build-aux)
|
||||
AC_CONFIG_HEADERS([lib/config.h:lib/config.hin])
|
||||
|
||||
AB_INIT()
|
||||
AM_INIT_AUTOMAKE([1.10 dist-bzip2])
|
||||
AM_INIT_AUTOMAKE([1.10 dist-lzma])
|
||||
|
||||
AC_PROG_CC_STDC
|
||||
AM_PROG_CC_C_O
|
||||
|
||||
98
man/.gitignore
vendored
Normal file
98
man/.gitignore
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
base64.1
|
||||
basename.1
|
||||
cat.1
|
||||
chgrp.1
|
||||
chmod.1
|
||||
chown.1
|
||||
chroot.1
|
||||
cksum.1
|
||||
comm.1
|
||||
cp.1
|
||||
csplit.1
|
||||
cut.1
|
||||
date.1
|
||||
dd.1
|
||||
df.1
|
||||
dir.1
|
||||
dircolors.1
|
||||
dirname.1
|
||||
du.1
|
||||
echo.1
|
||||
env.1
|
||||
expand.1
|
||||
expr.1
|
||||
factor.1
|
||||
false.1
|
||||
fmt.1
|
||||
fold.1
|
||||
groups.1
|
||||
head.1
|
||||
hostid.1
|
||||
hostname.1
|
||||
id.1
|
||||
install.1
|
||||
join.1
|
||||
kill.1
|
||||
link.1
|
||||
ln.1
|
||||
logname.1
|
||||
ls.1
|
||||
md5sum.1
|
||||
mkdir.1
|
||||
mkfifo.1
|
||||
mknod.1
|
||||
mktemp.1
|
||||
mv.1
|
||||
nice.1
|
||||
nl.1
|
||||
nohup.1
|
||||
od.1
|
||||
paste.1
|
||||
pathchk.1
|
||||
pinky.1
|
||||
pr.1
|
||||
printenv.1
|
||||
printf.1
|
||||
ptx.1
|
||||
pwd.1
|
||||
readlink.1
|
||||
rm.1
|
||||
rmdir.1
|
||||
seq.1
|
||||
sha1sum.1
|
||||
sha224sum.1
|
||||
sha256sum.1
|
||||
sha384sum.1
|
||||
sha512sum.1
|
||||
shred.1
|
||||
shuf.1
|
||||
sleep.1
|
||||
sort.1
|
||||
split.1
|
||||
stat.1
|
||||
stty.1
|
||||
su.1
|
||||
sum.1
|
||||
sync.1
|
||||
tac.1
|
||||
tail.1
|
||||
tee.1
|
||||
test.1
|
||||
touch.1
|
||||
tr.1
|
||||
true.1
|
||||
tsort.1
|
||||
tty.1
|
||||
uname.1
|
||||
unexpand.1
|
||||
uniq.1
|
||||
unlink.1
|
||||
uptime.1
|
||||
users.1
|
||||
vdir.1
|
||||
wc.1
|
||||
who.1
|
||||
whoami.1
|
||||
yes.1
|
||||
@@ -75,6 +75,7 @@ md5sum.1: $(common_dep) $(srcdir)/md5sum.x ../src/md5sum.c
|
||||
mkdir.1: $(common_dep) $(srcdir)/mkdir.x ../src/mkdir.c
|
||||
mkfifo.1: $(common_dep) $(srcdir)/mkfifo.x ../src/mkfifo.c
|
||||
mknod.1: $(common_dep) $(srcdir)/mknod.x ../src/mknod.c
|
||||
mktemp.1: $(common_dep) $(srcdir)/mktemp.x ../src/mktemp.c
|
||||
mv.1: $(common_dep) $(srcdir)/mv.x ../src/mv.c
|
||||
nice.1: $(common_dep) $(srcdir)/nice.x ../src/nice.c
|
||||
nl.1: $(common_dep) $(srcdir)/nl.x ../src/nl.c
|
||||
|
||||
6
man/mktemp.x
Normal file
6
man/mktemp.x
Normal file
@@ -0,0 +1,6 @@
|
||||
[NAME]
|
||||
mktemp \- create a temporary file or directory
|
||||
[DESCRIPTION]
|
||||
.\" Add any additional description here
|
||||
[SEE ALSO]
|
||||
mkstemp(3), mkdtemp(3), mktemp(3)
|
||||
@@ -11,6 +11,10 @@
|
||||
|
||||
* POTFILES.in: Remove lib/human.c.
|
||||
|
||||
2007-05-19 Jim Meyering <jim@meyering.net>
|
||||
|
||||
* POTFILES.in: Add src/mktemp.c.
|
||||
|
||||
2007-02-02 Jim Meyering <jim@meyering.net>
|
||||
|
||||
* POTFILES.in: Add src/runcon.c.
|
||||
|
||||
@@ -74,6 +74,7 @@ src/md5sum.c
|
||||
src/mkdir.c
|
||||
src/mkfifo.c
|
||||
src/mknod.c
|
||||
src/mktemp.c
|
||||
src/mv.c
|
||||
src/nice.c
|
||||
src/nl.c
|
||||
|
||||
1
src/.gitignore
vendored
1
src/.gitignore
vendored
@@ -47,6 +47,7 @@ md5sum
|
||||
mkdir
|
||||
mkfifo
|
||||
mknod
|
||||
mktemp
|
||||
mv
|
||||
nice
|
||||
nl
|
||||
|
||||
@@ -31,7 +31,8 @@ EXTRA_PROGRAMS = \
|
||||
$(build_if_possible__progs) \
|
||||
[ chcon chgrp chown chmod cp dd dircolors du \
|
||||
ginstall link ln dir vdir ls mkdir \
|
||||
mkfifo mknod mv nohup readlink rm rmdir shred stat sync touch unlink \
|
||||
mkfifo mknod mktemp \
|
||||
mv nohup readlink rm rmdir shred stat sync touch unlink \
|
||||
cat cksum comm csplit cut expand fmt fold head join md5sum \
|
||||
nl od paste pr ptx sha1sum sha224sum sha256sum sha384sum sha512sum \
|
||||
shuf sort split sum tac tail tr tsort unexpand uniq wc \
|
||||
@@ -96,6 +97,7 @@ ls_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX)
|
||||
pr_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME)
|
||||
shred_LDADD = $(LDADD) $(LIB_GETHRXTIME) $(LIB_FDATASYNC)
|
||||
shuf_LDADD = $(LDADD) $(LIB_GETHRXTIME)
|
||||
mktemp_LDADD = $(LDADD) $(LIB_GETHRXTIME)
|
||||
vdir_LDADD = $(LDADD) $(LIB_CLOCK_GETTIME) $(LIB_SELINUX)
|
||||
|
||||
## If necessary, add -lm to resolve use of pow in lib/strtod.c.
|
||||
|
||||
292
src/mktemp.c
Normal file
292
src/mktemp.c
Normal file
@@ -0,0 +1,292 @@
|
||||
/* Create a temporary file or directory, safely.
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* Jim Meyering */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include "error.h"
|
||||
#include "filenamecat.h"
|
||||
#include "long-options.h"
|
||||
#include "quote.h"
|
||||
#include "tempname.h"
|
||||
|
||||
/* The official name of this program (e.g., no `g' prefix). */
|
||||
#define PROGRAM_NAME "mktemp"
|
||||
|
||||
#define AUTHORS "Jim Meyering"
|
||||
|
||||
static const char *default_template = "tmp.XXXXXXXXXX";
|
||||
|
||||
/* The name this program was run with. */
|
||||
char *program_name;
|
||||
|
||||
/* For long options that have no equivalent short option, use a
|
||||
non-character as a pseudo short option, starting with CHAR_MAX + 1. */
|
||||
enum
|
||||
{
|
||||
TMPDIR_OPTION = CHAR_MAX + 1
|
||||
};
|
||||
|
||||
static struct option const longopts[] =
|
||||
{
|
||||
{"directory", no_argument, NULL, 'd'},
|
||||
{"quiet", no_argument, NULL, 'q'},
|
||||
{"dry-run", no_argument, NULL, 'u'},
|
||||
{"tmpdir", optional_argument, NULL, TMPDIR_OPTION},
|
||||
{GETOPT_HELP_OPTION_DECL},
|
||||
{GETOPT_VERSION_OPTION_DECL},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
void
|
||||
usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_name);
|
||||
else
|
||||
{
|
||||
printf (_("Usage: %s [OPTION]... [TEMPLATE]\n"), program_name);
|
||||
fputs (_("\
|
||||
Create a temporary file or directory, safely, and print its name.\n\
|
||||
If TEMPLATE is not specified, use tmp.XXXXXXXXXX.\n\
|
||||
"), stdout);
|
||||
fputs ("\n", stdout);
|
||||
fputs (_("\
|
||||
-d, --directory create a directory, not a file\n\
|
||||
"), stdout);
|
||||
fputs (_("\
|
||||
-q, --quiet suppress diagnostics about file/dir-creation failure\n\
|
||||
"), stdout);
|
||||
fputs (_("\
|
||||
-u, --dry-run do not create anything; merely print a name (unsafe)\n\
|
||||
"), stdout);
|
||||
fputs (_("\
|
||||
--tmpdir[=DIR] interpret TEMPLATE relative to DIR. If DIR is\n\
|
||||
not specified, use $TMPDIR if set, else /tmp.\n\
|
||||
With this option, TEMPLATE must not be an absolute name.\n\
|
||||
Unlike with -t, TEMPLATE may contain slashes, but even\n\
|
||||
here, mktemp still creates only the final component.\n\
|
||||
"), stdout);
|
||||
fputs ("\n", stdout);
|
||||
fputs (_("\
|
||||
-p DIR use DIR as a prefix; implies -t [deprecated]\n\
|
||||
"), stdout);
|
||||
fputs (_("\
|
||||
-t interpret TEMPLATE as a single file name component,\n\
|
||||
relative to a directory: $TMPDIR, if set; else the\n\
|
||||
directory specified via -p; else /tmp [deprecated]\n\
|
||||
"), stdout);
|
||||
fputs ("\n", stdout);
|
||||
fputs (HELP_OPTION_DESCRIPTION, stdout);
|
||||
fputs (VERSION_OPTION_DESCRIPTION, stdout);
|
||||
emit_bug_reporting_address ();
|
||||
}
|
||||
|
||||
exit (status);
|
||||
}
|
||||
|
||||
static size_t
|
||||
count_trailing_X_s (const char *s)
|
||||
{
|
||||
size_t len = strlen (s);
|
||||
size_t n = 0;
|
||||
for ( ; len && s[len-1] == 'X'; len--)
|
||||
++n;
|
||||
return n;
|
||||
}
|
||||
|
||||
static int
|
||||
mkstemp_len (char *tmpl, size_t suff_len, bool dry_run)
|
||||
{
|
||||
return gen_tempname_len (tmpl, dry_run ? GT_NOCREATE : GT_FILE, suff_len);
|
||||
}
|
||||
|
||||
static int
|
||||
mkdtemp_len (char *tmpl, size_t suff_len, bool dry_run)
|
||||
{
|
||||
return gen_tempname_len (tmpl, dry_run ? GT_NOCREATE : GT_DIR, suff_len);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char *dest_dir;
|
||||
char *dest_dir_arg = NULL;
|
||||
bool suppress_stderr = false;
|
||||
int c;
|
||||
unsigned int n_args;
|
||||
char *template;
|
||||
bool use_dest_dir = false;
|
||||
bool deprecated_t_option = false;
|
||||
bool create_directory = false;
|
||||
bool dry_run = false;
|
||||
int status = EXIT_SUCCESS;
|
||||
size_t x_count;
|
||||
char *dest_name;
|
||||
|
||||
initialize_main (&argc, &argv);
|
||||
program_name = argv[0];
|
||||
setlocale (LC_ALL, "");
|
||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
textdomain (PACKAGE);
|
||||
|
||||
atexit (close_stdout);
|
||||
|
||||
while ((c = getopt_long (argc, argv, "dp:qtuV", longopts, NULL)) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'd':
|
||||
create_directory = true;
|
||||
break;
|
||||
case 'p':
|
||||
dest_dir_arg = optarg;
|
||||
use_dest_dir = true;
|
||||
break;
|
||||
case 'q':
|
||||
suppress_stderr = true;
|
||||
break;
|
||||
case 't':
|
||||
use_dest_dir = true;
|
||||
deprecated_t_option = true;
|
||||
break;
|
||||
case 'u':
|
||||
dry_run = true;
|
||||
break;
|
||||
|
||||
case TMPDIR_OPTION:
|
||||
use_dest_dir = true;
|
||||
dest_dir_arg = optarg;
|
||||
break;
|
||||
|
||||
case_GETOPT_HELP_CHAR;
|
||||
|
||||
case 'V':
|
||||
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (suppress_stderr)
|
||||
{
|
||||
/* From here on, redirect stderr to /dev/null.
|
||||
A diagnostic from getopt_long, above, would still go to stderr. */
|
||||
freopen ("/dev/null", "wb", stderr);
|
||||
}
|
||||
|
||||
n_args = argc - optind;
|
||||
if (2 <= n_args)
|
||||
{
|
||||
error (0, 0, _("too many templates"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (n_args == 0)
|
||||
{
|
||||
use_dest_dir = true;
|
||||
template = (char *) default_template;
|
||||
}
|
||||
else
|
||||
{
|
||||
template = argv[optind];
|
||||
}
|
||||
|
||||
x_count = count_trailing_X_s (template);
|
||||
if (x_count < 3)
|
||||
error (EXIT_FAILURE, 0, _("too few X's in template %s"), quote (template));
|
||||
|
||||
if (use_dest_dir)
|
||||
{
|
||||
if (deprecated_t_option)
|
||||
{
|
||||
char *env = getenv ("TMPDIR");
|
||||
dest_dir = (env && *env
|
||||
? env
|
||||
: (dest_dir_arg ? dest_dir_arg : "/tmp"));
|
||||
|
||||
if (last_component (template) != template)
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid template, %s, contains directory separator"),
|
||||
quote (template));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dest_dir_arg && *dest_dir_arg)
|
||||
dest_dir = dest_dir_arg;
|
||||
else
|
||||
{
|
||||
char *env = getenv ("TMPDIR");
|
||||
dest_dir = (env && *env ? env : "/tmp");
|
||||
}
|
||||
if (IS_ABSOLUTE_FILE_NAME (template))
|
||||
error (EXIT_FAILURE, 0,
|
||||
_("invalid template, %s; with --tmpdir,"
|
||||
" it may not be absolute"),
|
||||
quote (template));
|
||||
}
|
||||
|
||||
dest_name = file_name_concat (dest_dir, template, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
dest_name = xstrdup (template);
|
||||
}
|
||||
|
||||
if (create_directory)
|
||||
{
|
||||
int err = mkdtemp_len (dest_name, x_count, dry_run);
|
||||
if (err != 0)
|
||||
{
|
||||
error (0, errno, _("failed to create directory via template %s"),
|
||||
quote (dest_name));
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int fd = mkstemp_len (dest_name, x_count, dry_run);
|
||||
if (fd < 0 || (!dry_run && close (fd) != 0))
|
||||
{
|
||||
error (0, errno, _("failed to create file via template %s"),
|
||||
quote (dest_name));
|
||||
status = EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (status == EXIT_SUCCESS)
|
||||
puts (dest_name);
|
||||
|
||||
#ifdef lint
|
||||
free (dest_name);
|
||||
#endif
|
||||
|
||||
exit (status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,8 +1,7 @@
|
||||
package Coreutils;
|
||||
# This is a testing framework.
|
||||
|
||||
# Copyright (C) 1998, 2000, 2001, 2002, 2004, 2005, 2006 Free Software
|
||||
# Foundation, Inc.
|
||||
# Copyright (C) 1998, 2000-2002, 2004-2007 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -478,6 +477,23 @@ sub run_tests ($$$$$)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
my %actual_data;
|
||||
# Record actual stdout and stderr contents, if POST may need them.
|
||||
if ($expect->{POST})
|
||||
{
|
||||
foreach my $eo (qw (OUT ERR))
|
||||
{
|
||||
my $out_file = $actual{$eo};
|
||||
open IN, $out_file
|
||||
or (warn "$program_name: cannot open $out_file for reading: $!\n"),
|
||||
$fail = 1, next;
|
||||
$actual_data{$eo} = <IN>;
|
||||
close IN
|
||||
or (warn "$program_name: failed to read $out_file: $!\n"),
|
||||
$fail = 1;
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $eo (qw (OUT ERR))
|
||||
{
|
||||
my $subst_expr = $expect->{RESULT_SUBST}->{$eo};
|
||||
@@ -525,7 +541,8 @@ sub run_tests ($$$$$)
|
||||
}
|
||||
|
||||
cleanup:
|
||||
&{$expect->{POST}} if $expect->{POST};
|
||||
$expect->{POST}
|
||||
and &{$expect->{POST}} ($actual_data{OUT}, $actual_data{ERR});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ TESTS = \
|
||||
date \
|
||||
xstrtol \
|
||||
od \
|
||||
mktemp \
|
||||
arch \
|
||||
pr \
|
||||
df-P \
|
||||
|
||||
121
tests/misc/mktemp
Executable file
121
tests/misc/mktemp
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/bin/sh
|
||||
# Test "mktemp".
|
||||
|
||||
# Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
|
||||
: ${PERL=perl}
|
||||
: ${srcdir=.}
|
||||
|
||||
$PERL -e 1 > /dev/null 2>&1 || {
|
||||
echo 1>&2 "$0: configure didn't find a usable version of Perl," \
|
||||
"so can't run this test"
|
||||
exit 77
|
||||
}
|
||||
|
||||
me=`echo $0|sed 's,.*/,,'`
|
||||
exec $PERL -w -I$srcdir/.. -MCoreutils -M"CuTmpdir qw($me)" -- - <<\EOF
|
||||
require 5.003;
|
||||
use strict;
|
||||
|
||||
(my $ME = $0) =~ s|.*/||;
|
||||
|
||||
sub check_tmp($$)
|
||||
{
|
||||
my ($file, $file_or_dir) = @_;
|
||||
|
||||
my (undef, undef, $mode, undef) = stat $file
|
||||
or die "$ME: failed to stat $file: $!\n";
|
||||
my $required_mode;
|
||||
if ($file_or_dir eq 'D') {
|
||||
-d $file or die "$ME: $file isn't a directory\n";
|
||||
-x $file or die "$ME: $file isn't owner-searchable\n";
|
||||
$required_mode = 0700;
|
||||
} elsif ($file_or_dir eq 'F') {
|
||||
-f $file or die "$ME: $file isn't a regular file\n";
|
||||
$required_mode = 0600;
|
||||
}
|
||||
-r $file or die "$ME: $file isn't owner-readable\n";
|
||||
-w $file or die "$ME: $file isn't owner-writable\n";
|
||||
($mode & 0777) == $required_mode
|
||||
or die "$ME: $file doesn't have required permissions\n";
|
||||
|
||||
$file_or_dir eq 'D'
|
||||
and do { rmdir $file or die "$ME: failed to rmdir $file: $!\n" };
|
||||
$file_or_dir eq 'F'
|
||||
and do { unlink $file or die "$ME: failed to unlink $file: $!\n" };
|
||||
}
|
||||
|
||||
# Turn off localisation of executable's ouput.
|
||||
@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
|
||||
my $prog = 'mktemp';
|
||||
|
||||
my @Tests =
|
||||
(
|
||||
# test-name, [option, option, ...] {OUT=>"expected-output"}
|
||||
#
|
||||
['too-many', 'a b',
|
||||
{ERR=>"$prog: too many templates\n"
|
||||
. "Try `$prog --help' for more information.\n"}, {EXIT => 1} ],
|
||||
['too-many-q', '-q a b', {EXIT => 1} ],
|
||||
|
||||
['too-few-x', 'foo.XX',
|
||||
{ERR=>"$prog: too few X's in template `foo.XX'\n"}, {EXIT => 1} ],
|
||||
|
||||
['1f', 'bar.XXXX', {OUT => "bar.ZZZZ\n"},
|
||||
{OUT_SUBST => 's,\.....$,.ZZZZ,'},
|
||||
{POST => sub { my ($f) = @_; defined $f or return; chomp $f;
|
||||
check_tmp $f, 'F'; }}
|
||||
],
|
||||
|
||||
# Create a temporary directory.
|
||||
['1d', '-d f.XXXX', {OUT => "f.ZZZZ\n"},
|
||||
{OUT_SUBST => 's,\.....$,.ZZZZ,'},
|
||||
{POST => sub { my ($f) = @_; defined $f or return; chomp $f;
|
||||
check_tmp $f, 'D'; }}
|
||||
],
|
||||
|
||||
# Use a template consisting solely of X's
|
||||
['1d-allX', '-d XXXX', {OUT => "ZZZZ\n"},
|
||||
{OUT_SUBST => 's,^....$,ZZZZ,'},
|
||||
{POST => sub { my ($f) = @_; defined $f or return; chomp $f;
|
||||
check_tmp $f, 'D'; }}
|
||||
],
|
||||
|
||||
['invalid-tmpl', '-t a/bXXXX',
|
||||
{ERR=>"$prog: invalid template, `a/bXXXX', "
|
||||
. "contains directory separator\n"}, {EXIT => 1} ],
|
||||
|
||||
['invalid-t2', '--tmpdir=a /bXXXX',
|
||||
{ERR=>"$prog: invalid template, `/bXXXX'; "
|
||||
. "with --tmpdir, it may not be absolute\n"}, {EXIT => 1} ],
|
||||
|
||||
['tmp-w-slash', '--tmpdir=. a/bXXXX',
|
||||
{PRE => sub {mkdir 'a',0755 or die "a: $!\n"}},
|
||||
{OUT_SUBST => 's,b....$,bZZZZ,'},
|
||||
{OUT => "./a/bZZZZ\n"},
|
||||
{POST => sub { my ($f) = @_; defined $f or return; chomp $f;
|
||||
check_tmp $f, 'F'; unlink $f; rmdir 'a' or die "rmdir a: $!\n" }}
|
||||
],
|
||||
);
|
||||
|
||||
my $save_temps = $ENV{DEBUG};
|
||||
my $verbose = $ENV{VERBOSE};
|
||||
|
||||
my $fail = run_tests ($ME, $prog, \@Tests, $save_temps, $verbose);
|
||||
exit $fail;
|
||||
EOF
|
||||
Reference in New Issue
Block a user