From daf03c53ee14a0227b43330be2e638b9ad9ce022 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 16 Mar 2010 15:06:11 -0700 Subject: [PATCH] util: New functions get_cwd(), abs_file_name(). 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 46c9a88e..081912b1 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 f710ffd6..88fe6035 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 8f1892ed..19f13ddd 100644 --- a/lib/util.c +++ b/lib/util.c @@ -21,8 +21,12 @@ #include #include #include +#include #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 a9d5048a..9df6db58 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 e3a0ebd2..dac81625 100644 --- a/lib/vlog-modules.def +++ b/lib/vlog-modules.def @@ -84,6 +84,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) -- 2.30.2