rewrite maketemp() obsoleting tempnam(3) and mkstemp(3) external deps
This commit is contained in:
85
main.c
85
main.c
@ -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);
|
||||
|
Reference in New Issue
Block a user