[lttng-dev] [Babeltrace RFC PATCH 23/28] Add a MinGW substitute for openat() and related functions
Jérémie Galarneau
jeremie.galarneau at efficios.com
Thu May 2 10:56:22 EDT 2013
On Thu, May 2, 2013 at 8:04 AM, Ikaheimonen, JP
<jp_ikaheimonen at mentor.com> wrote:
> 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 | 58 ++++++++++++++++++++++++++++++++++++++
> 6 files changed, 90 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 b11eb99..ac3bb3f 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 (fd < 0) {
> perror("openat");
> diff --git a/converter/babeltrace.c b/converter/babeltrace.c
> index f4a9217..d449ea7 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 <unistd.h>
> #include <inttypes.h>
> #include <babeltrace/compat/ftw.h>
> @@ -409,15 +409,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;
> @@ -430,7 +430,7 @@ static int traverse_trace_dir(const char *fpath, const struct stat *sb,
> perror("close");
> return -1; /* failure */
> }
> - closeret = close(dirfd);
> + closeret = compat_closedirfd(dirfd);
> if (closeret < 0) {
> perror("close");
> return -1; /* failure */
> diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c
> index c6043bc..7878555 100644
> --- a/formats/ctf/ctf.c
> +++ b/formats/ctf/ctf.c
> @@ -1078,7 +1078,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;
> @@ -1624,7 +1624,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;
> @@ -1717,7 +1717,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");
> @@ -1775,7 +1775,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 0707c28..f58a1bf 100644
> --- a/include/babeltrace/compat/fcntl.h
> +++ b/include/babeltrace/compat/fcntl.h
> @@ -2,6 +2,10 @@
> #define _BABELTRACE_INCLUDE_COMPAT_FCNTL_H
>
> #include <fcntl.h>
> +#include <stdlib.h>
> +#include <stdarg.h>
> +#include <stdio.h>
> +
> #ifdef __MINGW32__
> static inline
> int posix_fallocate(int fd, off_t offset, off_t len)
> @@ -10,4 +14,58 @@ 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.
> +*/
> +
> +static inline
> +int compat_openat(const char * dirname, int dirfd, const char *pathname, int flags, ...)
> +{
> +
> +#ifdef BABELTRACE_HAVE_OPENAT
> + 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);
> +#else
> + char szSearch[MAX_PATH] = {0};
> + sprintf(szSearch, "%s/%s", dirname, pathname);
> +#ifdef __MINGW32__
> + flags = flags | O_BINARY;
> +#endif
> + return open(szSearch, flags);
> +#endif
> +}
> +
> +static inline
> +int compat_opendirfd(const char *fpath, int flags)
> +{
> +#ifdef BABELTRACE_HAVE_OPENAT
> + return open(fpath, flags);
Clang issues a warning here:
../include/babeltrace/compat/fcntl.h:77:9: warning: implicit
declaration of function 'close' is
invalid in C99 [-Wimplicit-function-declaration]
I think you are missing an include file (unistd.h).
Regards,
Jérémie
> +#else
> + return 0;
> +#endif
> +}
> +
> +static inline
> +int compat_closedirfd(int dirfd)
> +{
> +#ifdef BABELTRACE_HAVE_OPENAT
> + return close(dirfd);
> +#else
> + return 0;
> +#endif
> +}
> +
> #endif
> \ No newline at end of file
> --
> 1.8.1.msysgit.1
>
>
> _______________________________________________
> lttng-dev mailing list
> lttng-dev at lists.lttng.org
> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
--
Jérémie Galarneau
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list