[ovs-dev] [PATCH 2/4] util: New functions get_cwd(), abs_file_name().
Ben Pfaff
blp at nicira.com
Tue Mar 16 22:24:37 UTC 2010
These will be used further in an upcoming commit.
---
lib/daemon.c | 6 ++--
lib/unixctl.c | 12 +--------
lib/util.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++
lib/util.h | 2 +
lib/vlog-modules.def | 1 +
5 files changed, 70 insertions(+), 13 deletions(-)
diff --git a/lib/daemon.c b/lib/daemon.c
index 46c9a88..081912b 100644
--- a/lib/daemon.c
+++ b/lib/daemon.c
@@ -58,9 +58,9 @@ static bool monitor;
char *
make_pidfile_name(const char *name)
{
- return (!name ? xasprintf("%s/%s.pid", ovs_rundir, program_name)
- : *name == '/' ? xstrdup(name)
- : xasprintf("%s/%s", ovs_rundir, name));
+ return (!name
+ ? xasprintf("%s/%s.pid", ovs_rundir, program_name)
+ : abs_file_name(ovs_rundir, name));
}
/* Sets up a following call to daemonize() to create a pidfile named 'name'.
diff --git a/lib/unixctl.c b/lib/unixctl.c
index f710ffd..88fe603 100644
--- a/lib/unixctl.c
+++ b/lib/unixctl.c
@@ -186,11 +186,7 @@ unixctl_server_create(const char *path, struct unixctl_server **serverp)
list_init(&server->conns);
if (path) {
- if (path[0] == '/') {
- server->path = xstrdup(path);
- } else {
- server->path = xasprintf("%s/%s", ovs_rundir, path);
- }
+ server->path = abs_file_name(ovs_rundir, path);
} else {
server->path = xasprintf("%s/%s.%ld.ctl", ovs_rundir,
program_name, (long int) getpid());
@@ -461,11 +457,7 @@ unixctl_client_create(const char *path, struct unixctl_client **clientp)
/* Determine location. */
client = xmalloc(sizeof *client);
- if (path[0] == '/') {
- client->connect_path = xstrdup(path);
- } else {
- client->connect_path = xasprintf("%s/%s", ovs_rundir, path);
- }
+ client->connect_path = abs_file_name(ovs_rundir, path);
client->bind_path = xasprintf("/tmp/vlog.%ld.%d",
(long int) getpid(), counter++);
diff --git a/lib/util.c b/lib/util.c
index 8f1892e..19f13dd 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -21,8 +21,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "coverage.h"
+#define THIS_MODULE VLM_util
+#include "vlog.h"
+
const char *program_name;
void
@@ -358,6 +362,37 @@ hexit_value(int c)
NOT_REACHED();
}
+/* Returns the current working directory as a malloc()'d string, or a null
+ * pointer if the current working directory cannot be determined. */
+char *
+get_cwd(void)
+{
+ long int path_max;
+ size_t size;
+
+ /* Get maximum path length or at least a reasonable estimate. */
+ path_max = pathconf(".", _PC_PATH_MAX);
+ size = (path_max < 0 ? 1024
+ : path_max > 10240 ? 10240
+ : path_max);
+
+ /* Get current working directory. */
+ for (;;) {
+ char *buf = xmalloc(size);
+ if (getcwd(buf, size)) {
+ return xrealloc(buf, strlen(buf) + 1);
+ } else {
+ int error = errno;
+ free(buf);
+ if (error != ERANGE) {
+ VLOG_WARN("getcwd failed (%s)", strerror(error));
+ return NULL;
+ }
+ size *= 2;
+ }
+ }
+}
+
/* Returns the directory name portion of 'file_name' as a malloc()'d string,
* similar to the POSIX dirname() function but thread-safe. */
char *
@@ -384,6 +419,33 @@ dir_name(const char *file_name)
}
}
+/* If 'file_name' starts with '/', returns a copy of 'file_name'. Otherwise,
+ * returns an absolute path to 'file_name' considering it relative to 'dir',
+ * which itself must be absolute. 'dir' may be null or the empty string, in
+ * which case the current working directory is used.
+ *
+ * Returns a null pointer if 'dir' is null and getcwd() fails. */
+char *
+abs_file_name(const char *dir, const char *file_name)
+{
+ if (file_name[0] == '/') {
+ return xstrdup(file_name);
+ } else if (dir && dir[0]) {
+ char *separator = dir[strlen(dir) - 1] == '/' ? "" : "/";
+ return xasprintf("%s%s%s", dir, separator, file_name);
+ } else {
+ char *cwd = get_cwd();
+ if (cwd) {
+ char *abs_name = xasprintf("%s/%s", cwd, file_name);
+ free(cwd);
+ return abs_name;
+ } else {
+ return NULL;
+ }
+ }
+}
+
+
/* Pass a value to this function if it is marked with
* __attribute__((warn_unused_result)) and you genuinely want to ignore
* its return value. (Note that every scalar type can be implicitly
diff --git a/lib/util.h b/lib/util.h
index a9d5048..9df6db5 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -123,7 +123,9 @@ bool str_to_double(const char *, double *);
int hexit_value(int c);
+char *get_cwd(void);
char *dir_name(const char *file_name);
+char *abs_file_name(const char *dir, const char *file_name);
void ignore(bool x OVS_UNUSED);
diff --git a/lib/vlog-modules.def b/lib/vlog-modules.def
index f012e10..b8a001c 100644
--- a/lib/vlog-modules.def
+++ b/lib/vlog-modules.def
@@ -83,6 +83,7 @@ VLOG_MODULE(tty)
VLOG_MODULE(socket_util)
VLOG_MODULE(switchui)
VLOG_MODULE(unixctl)
+VLOG_MODULE(util)
VLOG_MODULE(vconn_tcp)
VLOG_MODULE(vconn_ssl)
VLOG_MODULE(vconn_stream)
--
1.6.6.1
More information about the dev
mailing list