[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