commit d35fecb8fc8458463883abd05bbcb1a6105feaaf Author: Thierry FOURNIER Date: Thu Sep 19 16:52:40 2013 +0200 BUILTIN: Add builtin names mkstemp, it is a mktemp like mkstemp -p [-o ] The mkstemp utility build unique temporary file. The `-p' is mandatory parameter, it's specify the path into the file is created. If the `-o' flag is set, return the file in shell variable names in place of stdout. This function return 0 if no error encountered, else return 1. diff --git ./builtins/Makefile.in ./builtins/Makefile.in index 0ba3427..e625f6d 100644 --- ./builtins/Makefile.in +++ ./builtins/Makefile.in @@ -124,6 +124,7 @@ DEFSRC = $(srcdir)/alias.def $(srcdir)/bind.def $(srcdir)/break.def \ $(srcdir)/usleep.def \ $(srcdir)/sendlog.def \ $(srcdir)/fgets.def \ + $(srcdir)/mkstemp.def \ $(srcdir)/builtin.def $(srcdir)/caller.def \ $(srcdir)/cd.def $(srcdir)/colon.def \ $(srcdir)/command.def $(srcdir)/declare.def $(srcdir)/echo.def \ @@ -147,6 +148,7 @@ OFILES = builtins.o \ usleep.o \ sendlog.o \ fgets.o \ + mkstemp.o \ alias.o bind.o break.o builtin.o caller.o cd.o colon.o command.o \ common.o declare.o echo.o enable.o eval.o evalfile.o \ evalstring.o exec.o \ @@ -289,6 +291,7 @@ getopts.o: getopts.def reserved.o: reserved.def complete.o: complete.def sleep.o: sleep.def +mkstemp.o: mkstemp.def usleep.o: usleep.def sendlog.o: sendlog.def fgets.o: fgets.def diff --git ./builtins/mkstemp.def ./builtins/mkstemp.def new file mode 100644 index 0000000..ad2ab3d --- /dev/null +++ ./builtins/mkstemp.def @@ -0,0 +1,131 @@ +$BUILTIN mkstemp +$FUNCTION mkstemp_builtin +$PRODUCES mkstemp.c +$SHORT_DOC mkstemp -p [-o ] +The mkstemp utility build unique temporary file. The `-p' is +mandatory parameter, it's specify the path into the file is +created. If the `-o' flag is set, return the file in shell +variable names in place of stdout. + +This function return 0 if no error encountered, else return 1. +$END + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "../bashtypes.h" +#include "../shell.h" +#include "../jobs.h" +#include "common.h" +#include "bashgetopt.h" + +#define MAXLEN 128 +#define PATTERN "tmp.XXXXXX" + +int mkstemp_builtin(WORD_LIST *list) +{ + int opt; + char *dir = NULL; + char *var = NULL; + char tmp[MAXLEN]; + int len; + char *p; + int f = 0; + int l; + struct stat buf; + + /* check options */ + reset_internal_getopt(); + while ((opt = internal_getopt (list, "p:o:")) != -1) { + switch (opt) { + case 'p': + dir = list_optarg; + break; + case 'o': + var = list_optarg; + break; + default: + builtin_usage(); + return (EX_USAGE); + } + } + + /* input check */ + if (dir == NULL) { + builtin_usage(); + return (EX_USAGE); + } + + /* remove multiple / */ + l = strlen(dir); + for (p = dir; *p != '\0'; p++) { + if (*p == '/') { + if (f) { + while (*p == '/') { + memmove(p, p+1, l); + } + if (*p == '\0') { + break; + } + } else { + f = 1; + } + } else { + f = 0; + } + l--; + } + + /* remove final '/' */ + p--; + if (p > dir && *p == '/') + *p = '\0'; + + /* make dir and check length */ + len = snprintf(tmp, MAXLEN, "%s/" PATTERN, dir); + if (len >= MAXLEN) { + builtin_error("path name too long"); + return 1; + } + + /* try to create directories */ + if (stat(tmp, &buf) == -1) { + p = tmp; + if (*p == '/') + p++; + while (1) { + p = strchr(p, '/'); + if (!p) + break; + + *p = '\0'; + mkdir(tmp, 0777); + *p = '/'; + p++; + } + } + + /* build temporary file */ + if (mkstemp(tmp) == -1) { + builtin_error("%s: %s", tmp, strerror(errno)); + return 1; + } + + /* place the result in the output var */ + if (var) + bind_variable(var, tmp); + + /* return the path name on stderr */ + else + printf("%s\n", tmp); + + return 0; +}