diff --git a/libc/Android.mk b/libc/Android.mk index c5846474e..fbde75ccc 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -225,6 +225,7 @@ libc_bionic_src_files := \ bionic/libc_init_common.cpp \ bionic/libc_logging.cpp \ bionic/libgen.cpp \ + bionic/mkfifo.cpp \ bionic/pthread_attr.cpp \ bionic/pthread_detach.cpp \ bionic/pthread_equal.cpp \ diff --git a/libc/bionic/mkfifo.cpp b/libc/bionic/mkfifo.cpp new file mode 100644 index 000000000..08ffad1d6 --- /dev/null +++ b/libc/bionic/mkfifo.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +int mkfifo(const char* path, mode_t mode) { + return mknod(path, (mode & ~S_IFMT) | S_IFIFO, 0); +} diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h index 95e83d8ee..84e367fa9 100644 --- a/libc/include/sys/stat.h +++ b/libc/include/sys/stat.h @@ -178,10 +178,7 @@ mode_t umask(mode_t mode) { #define fstat64 fstat #define lstat64 lstat -static __inline__ int mkfifo(const char *__p, mode_t __m) -{ - return mknod(__p, (__m & ~S_IFMT) | S_IFIFO, (dev_t)0); -} +extern int mkfifo(const char*, mode_t); extern int fstatat(int dirfd, const char *path, struct stat *buf, int flags); extern int mkdirat(int dirfd, const char *pathname, mode_t mode); diff --git a/tests/sys_stat_test.cpp b/tests/sys_stat_test.cpp index a23100a6c..176d46243 100644 --- a/tests/sys_stat_test.cpp +++ b/tests/sys_stat_test.cpp @@ -20,6 +20,8 @@ #include #include +#include "TemporaryFile.h" + TEST(sys_stat, futimens) { FILE* fp = tmpfile(); ASSERT_TRUE(fp != NULL); @@ -51,3 +53,18 @@ TEST(sys_stat, futimens_EBADF) { ASSERT_EQ(-1, futimens(-1, times)); ASSERT_EQ(EBADF, errno); } + +TEST(sys_stat, mkfifo) { + // Racy but probably sufficient way to get a suitable filename. + std::string path; + { + TemporaryFile tf; + path = tf.filename; + } + + ASSERT_EQ(0, mkfifo(path.c_str(), 0666)); + struct stat sb; + ASSERT_EQ(0, stat(path.c_str(), &sb)); + ASSERT_TRUE(S_ISFIFO(sb.st_mode)); + unlink(path.c_str()); +}