[lttng-dev] [Babeltrace PATCH 19/23] Add MinGW substitutes for openat and related

Ikaheimonen, JP jp_ikaheimonen at mentor.com
Wed May 22 04:07:33 EDT 2013


Check if the build system has openat() support.
If it does not, we have to open files based on the directory name
instead of the directory handle. Substitute openat() with
compat_openat() that also takes the directory path name as a
parameter.
If we don't have openat(), replace the function dirfd() with a dummy.
Also, if we don't have openat(), open() and close() will not
work for directories. Replace those with compat_opendirfd and
compat_closedirfd() with dummy equivalents, as the function
compat_openat() takes care of opening the file.
---
 configure.ac                       |  7 ++++
 converter/babeltrace-log.c         | 10 +++---
 converter/babeltrace.c             | 10 +++---
 formats/ctf/ctf.c                  |  8 ++---
 include/babeltrace/compat/dirent.h | 11 ++++++
 include/babeltrace/compat/fcntl.h  | 69 ++++++++++++++++++++++++++++++++++++++
 6 files changed, 101 insertions(+), 14 deletions(-)

diff --git a/configure.ac b/configure.ac
index 5f9e38d..168fb91 100644
--- a/configure.ac
+++ b/configure.ac
@@ -84,6 +84,13 @@ AC_CHECK_LIB([c], [open_memstream],
 ]
 )
 
+# Check for openat
+AC_CHECK_LIB([c], [openat],
+[
+	AC_DEFINE_UNQUOTED([BABELTRACE_HAVE_OPENAT], 1, [Has openat support.])
+]
+)
+
 AC_CHECK_LIB([popt], [poptGetContext], [],
         [AC_MSG_ERROR([Cannot find popt.])]
 )
diff --git a/converter/babeltrace-log.c b/converter/babeltrace-log.c
index ee9b309..a2db91a 100644
--- a/converter/babeltrace-log.c
+++ b/converter/babeltrace-log.c
@@ -32,9 +32,9 @@
 #include <config.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <fcntl.h>
+#include <babeltrace/compat/fcntl.h>
 #include <babeltrace/compat/mman.h>
-#include <dirent.h>
+#include <babeltrace/compat/dirent.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
@@ -343,20 +343,20 @@ int main(int argc, char **argv)
 		perror("opendir");
 		goto error_rmdir;
 	}
-	dir_fd = dirfd(dir);
+	dir_fd = compat_dirfd(dir);
 	if (dir_fd < 0) {
 		perror("dirfd");
 		goto error_closedir;
 	}
 
-	fd = openat(dir_fd, "datastream", O_RDWR|O_CREAT,
+	fd = compat_openat(s_outputname, dir_fd, "datastream", O_RDWR|O_CREAT,
 		    S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
 	if (fd < 0) {
 		perror("openat");
 		goto error_closedirfd;
 	}
 
-	metadata_fd = openat(dir_fd, "metadata", O_RDWR|O_CREAT,
+	metadata_fd = compat_openat(s_outputname, dir_fd, "metadata", O_RDWR|O_CREAT,
 			     S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
 	if (metadata_fd < 0) {
 		perror("openat");
diff --git a/converter/babeltrace.c b/converter/babeltrace.c
index 5cc9949..2658c2e 100644
--- a/converter/babeltrace.c
+++ b/converter/babeltrace.c
@@ -45,7 +45,7 @@
 #include <ctype.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <fcntl.h>
+#include <babeltrace/compat/fcntl.h>
 #include <babeltrace/compat/unistd.h>
 #include <inttypes.h>
 #include <babeltrace/compat/ftw.h>
@@ -435,15 +435,15 @@ static int traverse_trace_dir(const char *fpath, const struct stat *sb,
 	if (tflag != FTW_D)
 		return 0;
 
-	dirfd = open(fpath, 0);
+	dirfd = compat_opendirfd(fpath, 0);
 	if (dirfd < 0) {
 		fprintf(stderr, "[error] [Context] Unable to open trace "
 			"directory file descriptor.\n");
 		return 0;	/* partial error */
 	}
-	metafd = openat(dirfd, "metadata", O_RDONLY);
+	metafd = compat_openat(fpath, dirfd, "metadata", O_RDONLY);
 	if (metafd < 0) {
-		closeret = close(dirfd);
+		closeret = compat_closedirfd(dirfd);
 		if (closeret < 0) {
 			perror("close");
 			return -1;
@@ -458,7 +458,7 @@ static int traverse_trace_dir(const char *fpath, const struct stat *sb,
 			perror("close");
 			err_close = 1;
 		}
-		closeret = close(dirfd);
+		closeret = compat_closedirfd(dirfd);
 		if (closeret < 0) {
 			perror("close");
 			err_close = 1;
diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c
index ad3c3b1..ffa5387 100644
--- a/formats/ctf/ctf.c
+++ b/formats/ctf/ctf.c
@@ -1098,7 +1098,7 @@ int ctf_open_trace_metadata_read(struct ctf_trace *td,
 		metadata_stream->pos.fd = -1;
 	} else {
 		td->metadata = &metadata_stream->parent;
-		metadata_stream->pos.fd = openat(td->dirfd, "metadata", O_RDONLY);
+		metadata_stream->pos.fd = compat_openat(td->parent.path, td->dirfd, "metadata", O_RDONLY);
 		if (metadata_stream->pos.fd < 0) {
 			fprintf(stderr, "Unable to open metadata.\n");
 			ret = -1;
@@ -1681,7 +1681,7 @@ int ctf_open_file_stream_read(struct ctf_trace *td, const char *path, int flags,
 	struct ctf_file_stream *file_stream;
 	struct stat statbuf;
 
-	fd = openat(td->dirfd, path, flags);
+	fd = compat_openat(td->parent.path, td->dirfd, path, flags);
 	if (fd < 0) {
 		perror("File stream openat()");
 		ret = fd;
@@ -1774,7 +1774,7 @@ int ctf_open_trace_read(struct ctf_trace *td,
 		goto error;
 	}
 
-	td->dirfd = open(path, 0);
+	td->dirfd = compat_opendirfd(path, 0);
 	if (td->dirfd < 0) {
 		fprintf(stderr, "[error] Unable to open trace directory file descriptor for path \"%s\".\n", path);
 		perror("Trace directory open");
@@ -1832,7 +1832,7 @@ int ctf_open_trace_read(struct ctf_trace *td,
 readdir_error:
 	free(dirent);
 error_metadata:
-	closeret = close(td->dirfd);
+	closeret = compat_closedirfd(td->dirfd);
 	if (closeret) {
 		perror("Error on fd close");
 	}
diff --git a/include/babeltrace/compat/dirent.h b/include/babeltrace/compat/dirent.h
index 281f40b..a7d6227 100644
--- a/include/babeltrace/compat/dirent.h
+++ b/include/babeltrace/compat/dirent.h
@@ -17,4 +17,15 @@ int readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
 }
 #endif
 
+static inline
+int compat_dirfd(DIR * dirp)
+{
+#ifdef BABELTRACE_HAVE_OPENAT
+	return dirfd(dirp);
+#else
+	/* ignore dirfd - see compat_openat() */
+	return 0;
+#endif
+}
+
 #endif
diff --git a/include/babeltrace/compat/fcntl.h b/include/babeltrace/compat/fcntl.h
index 9fc7539..2d6f8e5 100644
--- a/include/babeltrace/compat/fcntl.h
+++ b/include/babeltrace/compat/fcntl.h
@@ -2,10 +2,79 @@
 #define _BABELTRACE_INCLUDE_COMPAT_FCNTL_H
 
 #include <fcntl.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <unistd.h>
+
 #ifdef __MINGW32__
 
 int posix_fallocate(int fd, off_t offset, off_t len);
 
 #endif
 
+/*
+   If we have BABELTRACE_HAVE_OPENAT, then
+   openat() and dirfd() work, and open() and close() can
+   work on directories.
+
+   If we don't have BABELTRACE_HAVE_OPENAT,
+   then we have to open files based on the directory name,
+   not the directory handle. The functions
+   compat_[opendirfd | closedirfd | dirfd] all are dummied
+   to return zero, and compat_openat() takes care of the
+   opening of the file, using the given path.
+*/
+#ifdef BABELTRACE_HAVE_OPENAT
+static inline
+int compat_openat(const char * dirname, int dirfd, const char *pathname, int flags, ...)
+{
+	mode_t mode = 0;
+	va_list args;
+
+	va_start (args, flags);
+	mode = (mode_t)va_arg(args, int);
+	va_end(args);
+	return openat(dirfd, pathname, flags, mode);
+}
+
+static inline
+int compat_opendirfd(const char *fpath, int flags)
+{
+	return open(fpath, flags);
+}
+
+static inline
+int compat_closedirfd(int dirfd)
+{
+	return close(dirfd);
+}
+
+#else
+
+static inline
+int compat_openat(const char * dirname, int dirfd, const char *pathname, int flags, ...)
+{
+	char szSearch[MAX_PATH] = {0};
+
+	sprintf(szSearch, "%s/%s", dirname, pathname);
+#ifdef __MINGW32__
+	flags = flags | O_BINARY;
 #endif
+	return open(szSearch, flags);
+}
+
+static inline
+int compat_opendirfd(const char *fpath, int flags)
+{
+	return 0;
+}
+
+static inline
+int compat_closedirfd(int dirfd)
+{
+	return 0;
+}
+#endif /* BABELTRACE_HAVE_OPENAT */
+
+#endif /* _BABELTRACE_INCLUDE_COMPAT_FCNTL_H */
-- 
1.8.1.msysgit.1




More information about the lttng-dev mailing list