rewrite maketemp() obsoleting tempnam(3) and mkstemp(3) external deps

This commit is contained in:
tg 2012-04-14 16:07:48 +00:00
parent 70e6988d25
commit 5eea59ad57
7 changed files with 86 additions and 73 deletions

View File

@ -1,5 +1,5 @@
#!/bin/sh
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.548 2012/04/14 14:11:07 tg Exp $'
srcversion='$MirOS: src/bin/mksh/Build.sh,v 1.549 2012/04/14 16:07:43 tg Exp $'
#-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012
@ -1402,7 +1402,7 @@ else
#define EXTERN
#define MKSH_INCLUDES_ONLY
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.548 2012/04/14 14:11:07 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/Build.sh,v 1.549 2012/04/14 16:07:43 tg Exp $");
int main(void) { printf("Hello, World!\n"); return (0); }
EOF
case $cm in
@ -1508,12 +1508,6 @@ ac_test mknod '' 'if to use mknod(), makedev() and friends' <<-'EOF'
}
EOF
ac_test mkstemp <<-'EOF'
#include <stdlib.h>
#include <unistd.h>
int main(void) { char tmpl[] = "X"; return (mkstemp(tmpl)); }
EOF
ac_test mmap lock_fcntl 0 'for mmap and munmap' <<-'EOF'
#include <sys/types.h>
#if HAVE_SYS_FILE_H
@ -2103,7 +2097,7 @@ MKSH_NO_EXTERNAL_CAT omit hack to skip cat builtin when flags passed
MKSH_NO_LIMITS omit ulimit code
MKSH_NO_SIGSETJMP define if sigsetjmp is broken or not available
MKSH_SMALL omit some code, optimise hard for size (slower)
MKSH_S_NOVI disable Vi editing mode (default if MKSH_SMALL)
MKSH_S_NOVI=1 disable Vi editing mode (default if MKSH_SMALL)
MKSH_TYPEDEF_SIG_ATOMIC_T define to e.g. 'int' if sig_atomic_t is missing
MKSH_TYPEDEF_SSIZE_T define to e.g. 'long' if your OS has no ssize_t
MKSH_UNEMPLOYED disable job control (but not jobs/co-processes)

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/Makefile,v 1.97 2012/04/07 11:19:46 tg Exp $
# $MirOS: src/bin/mksh/Makefile,v 1.98 2012/04/14 16:07:44 tg Exp $
#-
# Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012
@ -42,7 +42,7 @@ CPPFLAGS+= -DMKSH_ASSUME_UTF8 -DMKSH_DISABLE_DEPRECATED \
-DHAVE_SIG_T=1 -DHAVE_SYS_SIGNAME=1 -DHAVE_SYS_SIGLIST=1 \
-DHAVE_STRSIGNAL=0 -DHAVE_FLOCK=1 -DHAVE_LOCK_FCNTL=1 \
-DHAVE_GETRUSAGE=1 -DHAVE_KILLPG=1 -DHAVE_MKNOD=0 \
-DHAVE_MKSTEMP=1 -DHAVE_MMAP=1 -DHAVE_NICE=1 -DHAVE_REVOKE=1 \
-DHAVE_MMAP=1 -DHAVE_NICE=1 -DHAVE_REVOKE=1 \
-DHAVE_SETLOCALE_CTYPE=0 -DHAVE_LANGINFO_CODESET=0 \
-DHAVE_SELECT=1 -DHAVE_SETRESUGID=1 -DHAVE_SETGROUPS=1 \
-DHAVE_STRLCPY=1 -DHAVE_FLOCK_DECL=1 -DHAVE_REVOKE_DECL=1 \

View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.531 2012/04/07 11:19:47 tg Exp $
# $MirOS: src/bin/mksh/check.t,v 1.532 2012/04/14 16:07:44 tg Exp $
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
@ -29,7 +29,7 @@
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
expected-stdout:
@(#)MIRBSD KSH R40 2012/04/07
@(#)MIRBSD KSH R40 2012/04/14
description:
Check version of shell.
stdin:

12
exec.c
View File

@ -1,7 +1,8 @@
/* $OpenBSD: exec.c,v 1.49 2009/01/29 23:27:26 jaredy Exp $ */
/*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012
* Thorsten Glaser <tg@mirbsd.org>
*
* Provided that these terms and disclaimer and all copyright notices
@ -22,7 +23,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.97 2012/03/31 17:29:58 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.98 2012/04/14 16:07:46 tg Exp $");
#ifndef MKSH_DEFAULT_EXECSHELL
#define MKSH_DEFAULT_EXECSHELL "/bin/sh"
@ -1467,10 +1468,10 @@ herein(const char *content, int sub, char **resbuf)
* so temp doesn't get removed too soon).
*/
h = maketemp(ATEMP, TT_HEREDOC_EXP, &e->temps);
if (!(shf = h->shf) || (fd = open(h->name, O_RDONLY, 0)) < 0) {
if (!(shf = h->shf) || (fd = open(h->tffn, O_RDONLY, 0)) < 0) {
i = errno;
warningf(true, "can't %s temporary file %s: %s",
!shf ? "create" : "open", h->name, strerror(i));
!shf ? "create" : "open", h->tffn, strerror(i));
if (shf)
shf_close(shf);
/* special to iosetup(): don't print error */
@ -1486,7 +1487,8 @@ herein(const char *content, int sub, char **resbuf)
if (shf_close(shf) == EOF) {
i = errno;
close(fd);
warningf(true, "%s: %s: %s", "write", h->name, strerror(i));
warningf(true, "can't %s temporary file %s: %s",
"write", h->tffn, strerror(i));
/* special to iosetup(): don't print error */
return (-2);
}

View File

@ -27,7 +27,7 @@
#include <sys/file.h>
#endif
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.122 2012/04/06 13:29:00 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.123 2012/04/14 16:07:47 tg Exp $");
Trap sigtraps[NSIG + 1];
static struct sigaction Sigact_ign;
@ -297,7 +297,7 @@ c_fc(const char **wp)
tf = maketemp(ATEMP, TT_HIST_EDIT, &e->temps);
if (!(shf = tf->shf)) {
bi_errorf("can't %s temporary file %s: %s",
"create", tf->name, strerror(errno));
"create", tf->tffn, strerror(errno));
return (1);
}
for (hp = rflag ? hlast : hfirst;
@ -305,12 +305,12 @@ c_fc(const char **wp)
shf_fprintf(shf, "%s\n", *hp);
if (shf_close(shf) == EOF) {
bi_errorf("can't %s temporary file %s: %s",
"write", tf->name, strerror(errno));
"write", tf->tffn, strerror(errno));
return (1);
}
/* Ignore setstr errors here (arbitrary) */
setstr(local("_", false), tf->name, KSH_RETURN_ERROR);
setstr(local("_", false), tf->tffn, KSH_RETURN_ERROR);
/* XXX: source should not get trashed by this.. */
{
@ -329,13 +329,13 @@ c_fc(const char **wp)
char *xp;
ssize_t n;
if (!(shf = shf_open(tf->name, O_RDONLY, 0, 0))) {
if (!(shf = shf_open(tf->tffn, O_RDONLY, 0, 0))) {
bi_errorf("can't %s temporary file %s: %s",
"open", tf->name, strerror(errno));
"open", tf->tffn, strerror(errno));
return (1);
}
if (stat(tf->name, &statb) < 0)
if (stat(tf->tffn, &statb) < 0)
n = 128;
else if ((off_t)statb.st_size > MKSH_MAXHISTFSIZE) {
bi_errorf("%s %s too large: %lu", Thistory,
@ -351,7 +351,7 @@ c_fc(const char **wp)
}
if (n < 0) {
bi_errorf("can't %s temporary file %s: %s",
"read", tf->name, strerror(shf_errno(shf)));
"read", tf->tffn, strerror(shf_errno(shf)));
errout:
shf_close(shf);
return (1);

85
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.215 2012/04/06 12:59:26 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.216 2012/04/14 16:07:47 tg Exp $");
extern char **environ;
@ -1015,7 +1015,7 @@ remove_temps(struct temp *tp)
{
for (; tp != NULL; tp = tp->next)
if (tp->pid == procpid)
unlink(tp->name);
unlink(tp->tffn);
}
/*
@ -1499,42 +1499,61 @@ coproc_cleanup(int reuse)
struct temp *
maketemp(Area *ap, Temp_type type, struct temp **tlist)
{
struct temp *tp;
char *cp;
size_t len;
int fd;
char *pathname;
int i;
struct temp *tp;
const char *dir;
struct stat sb;
dir = tmpdir ? tmpdir : MKSH_DEFAULT_TMPDIR;
#if HAVE_MKSTEMP
len = strlen(dir) + 6 + 10 + 1;
#else
pathname = tempnam(dir, "mksh.");
len = ((pathname == NULL) ? 0 : strlen(pathname)) + 1;
#endif
/* reasonably sure that this will not overflow */
tp = alloc(sizeof(struct temp) + len, ap);
tp->name = (char *)&tp[1];
#if !HAVE_MKSTEMP
if (pathname == NULL)
tp->name[0] = '\0';
else {
memcpy(tp->name, pathname, len);
free_ostempnam(pathname);
}
#endif
pathname = tp->name;
tp->shf = NULL;
tp->type = type;
#if HAVE_MKSTEMP
shf_snprintf(pathname, len, "%s%s", dir, "/mksh.XXXXXXXXXX");
if ((fd = mkstemp(pathname)) >= 0)
#else
if (tp->name[0] && (fd = open(tp->name, O_CREAT | O_RDWR, 0600)) >= 0)
#endif
tp->shf = shf_fdopen(fd, SHF_WR, NULL);
tp->pid = procpid;
/* add "/shXXXXXX.tmp" plus NUL */
len = strlen(dir);
checkoktoadd(len, offsetof(struct temp, tffn[0]) + 14);
tp = alloc(offsetof(struct temp, tffn[0]) + 14 + len, ap);
tp->shf = NULL;
tp->pid = procpid;
tp->type = type;
if (stat(dir, &sb) || !S_ISDIR(sb.st_mode)) {
tp->tffn[0] = '\0';
goto maketemp_out;
}
cp = (void *)tp;
cp += offsetof(struct temp, tffn[0]);
memcpy(cp, dir, len);
cp += len;
memcpy(cp, "/shXXXXXX.tmp", 14);
/* point to the first of six Xes */
cp += 3;
/* generate random part of filename */
len = -1;
do {
i = rndget() % 36;
cp[++len] = i < 26 ? 'a' + i : '0' + i - 26;
} while (len < 5);
/* cyclically attempt to open a temporary file */
while ((i = open(tp->tffn, O_CREAT | O_EXCL | O_RDWR, 0600)) == -1) {
if (errno != EEXIST)
goto maketemp_out;
/* count down from z to a then from 9 to 0 */
while (cp[len] == '0')
if (!len--)
goto maketemp_out;
if (cp[len] == 'a')
cp[len] = '9';
else
--cp[len];
/* do another cycle */
}
/* shf_fdopen cannot fail, so no fd leak */
tp->shf = shf_fdopen(i, SHF_WR, NULL);
maketemp_out:
tp->next = *tlist;
*tlist = tp;
return (tp);

26
sh.h
View File

@ -152,9 +152,9 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.548 2012/04/14 14:35:12 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.549 2012/04/14 16:07:48 tg Exp $");
#endif
#define MKSH_VERSION "R40 2012/04/07"
#define MKSH_VERSION "R40 2012/04/14"
/* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES
@ -535,11 +535,6 @@ im_sorry_dave(void)
#define free_ossetmode(p) free(p)
#endif
#if !HAVE_MKSTEMP
/* tempnam(3) -> free(3) */
#define free_ostempnam(p) free(p)
#endif
#ifdef NO_PATH_MAX
/* GNU libc: get_current_dir_name(3) -> free(3) */
#define free_gnu_gcdn(p) free(p)
@ -704,18 +699,21 @@ EXTERN const char Tgbuiltin[] E_INIT("=builtin");
EXTERN const char T_function[] E_INIT(" function");
#define Tfunction (T_function + 1) /* "function" */
enum temp_type {
TT_HEREDOC_EXP, /* expanded heredoc */
TT_HIST_EDIT /* temp file used for history editing (fc -e) */
};
typedef enum temp_type Temp_type;
typedef uint8_t Temp_type;
/* expanded heredoc */
#define TT_HEREDOC_EXP 0
/* temp file used for history editing (fc -e) */
#define TT_HIST_EDIT 1
/* temp/heredoc files. The file is removed when the struct is freed. */
struct temp {
struct temp *next;
struct shf *shf;
char *name;
int pid; /* pid of process parsed here-doc */
/* pid of process parsed here-doc */
pid_t pid;
Temp_type type;
/* actually longer: name (variable length) */
char tffn[3];
};
/*