summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2008-07-29 15:15:46 -0700
committerStephen Hemminger <stephen.hemminger@vyatta.com>2008-07-29 15:15:46 -0700
commite0e9b7f85c81c942ee135a5a9aaff7a4992b19f6 (patch)
tree87ef294d7e47784cf8265cfab333eeff3cd54cfc /src
parent24741e4ea23ac8c498046f5dabf0dd07c84bace4 (diff)
downloadvyatta-cfg-e0e9b7f85c81c942ee135a5a9aaff7a4992b19f6.tar.gz
vyatta-cfg-e0e9b7f85c81c942ee135a5a9aaff7a4992b19f6.zip
Avoid needless calls to system()
Add a version of touch and mkdir -p commands coded directly without going out to shell.
Diffstat (limited to 'src')
-rw-r--r--src/cli_new.c73
-rw-r--r--src/cli_val.h2
2 files changed, 59 insertions, 16 deletions
diff --git a/src/cli_new.c b/src/cli_new.c
index 33430bd..c1f5aac 100644
--- a/src/cli_new.c
+++ b/src/cli_new.c
@@ -16,6 +16,7 @@
#include <regex.h>
#include <errno.h>
#include <time.h>
+#include <utime.h>
#include "cli_objects.h"
#include "cli_val_engine.h"
@@ -149,21 +150,49 @@ void print_msg(const char *msg, ...)
va_end(ap);
}
+int mkdir_p(const char *path)
+{
+ if (mkdir(path, 0777) == 0)
+ return 0;
+
+ if (errno != ENOENT)
+ return -1;
+
+ char *tmp = strdup(path);
+ if (tmp == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ char *slash = strrchr(tmp, '/');
+ if (slash == NULL)
+ return -1;
+ *slash = '\0';
+
+ /* recurse to make missing piece of path */
+ int ret = mkdir_p(tmp);
+ if (ret == 0)
+ ret = mkdir(path, 0777);
+
+ free(tmp);
+ return ret;
+}
+
void touch_dir(const char *dp)
{
struct stat statbuf;
+
if (lstat(dp, &statbuf) < 0) {
- char *command;
- command = my_malloc(strlen(dp) + 10, "set");
- sprintf(command, "mkdir -p %s", dp);
- system(command);
- free(command);
- return;
- }
- if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
- bye("directory %s expected, found regular file", dp);
+ if (errno != ENOENT)
+ bye("can't access directory: %s (%s)", dp, strerror(errno));
+
+ if (mkdir_p(dp) < 0)
+ bye("can't make directory: %s (%s)", dp, strerror(errno));
+ } else {
+ if(!S_ISDIR(statbuf.st_mode))
+ bye("directory %s expected, found file", dp);
+ utime(dp, NULL);
}
- return;
}
/*****************************************************
@@ -2094,13 +2123,25 @@ void restore_paths(vtw_mark *markp)
pop_path(&t_path);
}
-void touch()
+void touch_file(const char *filename)
+{
+ int fd = creat(filename, 0666);
+ if (fd < 0)
+ {
+ if (errno == EEXIST)
+ utime(filename, NULL);
+ else
+ bye("can't touch %s (%s)", filename, strerror(errno));
+ }
+ else
+ close(fd);
+}
+
+void touch(void)
{
- char *command;
- command = my_malloc(strlen(get_mdirp()) + 20, "delete");
- sprintf(command, "touch %s/%s", get_mdirp(), MOD_NAME);
- system(command);
- free(command);
+ char filename[strlen(get_mdirp()) + 20];
+ sprintf(filename, "%s/%s", get_mdirp(), MOD_NAME);
+ touch_file(filename);
}
const char *type_to_name(vtw_type_e type) {
diff --git a/src/cli_val.h b/src/cli_val.h
index e190dd1..917f374 100644
--- a/src/cli_val.h
+++ b/src/cli_val.h
@@ -190,10 +190,12 @@ extern void vtw_sort(valstruct *valp, vtw_sorted *sortp);
extern void free_val(valstruct *val);
extern void my_free(void *ptr);
extern void touch(void);
+extern int mkdir_p(const char *path);
extern const char *type_to_name(vtw_type_e type);
extern boolean execute_list(vtw_node *cur, vtw_def *def);
extern void touch_dir(const char *dp);
+extern void touch_file(const char *name);
extern void copy_path(vtw_path *to, vtw_path *from);
extern void free_path(vtw_path *path);