From e3c4acf1e3ef36c2ab1f48b1261dec9a1d8330a4 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 13 Nov 2014 14:27:25 -0800 Subject: [PATCH] Fix our implementation. Used by toybox. Change-Id: I36a5053423e5cc54ae02a68f4fe110d75134accd --- libc/bionic/mntent.cpp | 37 ++++++++++++++++++++++++++++++++++--- tests/mntent_test.cpp | 22 ++++++++++++++-------- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/libc/bionic/mntent.cpp b/libc/bionic/mntent.cpp index 93b6915ed..f5a8eaa25 100644 --- a/libc/bionic/mntent.cpp +++ b/libc/bionic/mntent.cpp @@ -28,11 +28,42 @@ #include -mntent* getmntent(FILE*) { - return NULL; +#include "private/ThreadLocalBuffer.h" + +GLOBAL_INIT_THREAD_LOCAL_BUFFER(getmntent_mntent); +GLOBAL_INIT_THREAD_LOCAL_BUFFER(getmntent_strings); + +mntent* getmntent(FILE* fp) { + LOCAL_INIT_THREAD_LOCAL_BUFFER(mntent*, getmntent_mntent, sizeof(mntent)); + LOCAL_INIT_THREAD_LOCAL_BUFFER(char*, getmntent_strings, BUFSIZ); + return getmntent_r(fp, getmntent_mntent_tls_buffer, + getmntent_strings_tls_buffer, getmntent_strings_tls_buffer_size); } -mntent* getmntent_r(FILE*, struct mntent*, char*, int) { +mntent* getmntent_r(FILE* fp, struct mntent* e, char* buf, int buf_len) { + memset(e, 0, sizeof(*e)); + while (fgets(buf, buf_len, fp) != NULL) { + // Entries look like "proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0". + // That is: mnt_fsname mnt_dir mnt_type mnt_opts 0 0. + int fsname0, fsname1, dir0, dir1, type0, type1, opts0, opts1; + if (sscanf(buf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d", + &fsname0, &fsname1, &dir0, &dir1, &type0, &type1, &opts0, &opts1, + &e->mnt_freq, &e->mnt_passno) == 2) { + e->mnt_fsname = &buf[fsname0]; + buf[fsname1] = '\0'; + + e->mnt_dir = &buf[dir0]; + buf[dir1] = '\0'; + + e->mnt_type = &buf[type0]; + buf[type1] = '\0'; + + e->mnt_opts = &buf[opts0]; + buf[opts1] = '\0'; + + return e; + } + } return NULL; } diff --git a/tests/mntent_test.cpp b/tests/mntent_test.cpp index 637cb52f7..a1028492c 100644 --- a/tests/mntent_test.cpp +++ b/tests/mntent_test.cpp @@ -19,16 +19,22 @@ #include TEST(mntent, mntent_smoke) { - FILE* fp = setmntent("/no/mnt/tab/on/android", "r"); - ASSERT_TRUE(fp == NULL); + FILE* fp = setmntent("/proc/mounts", "r"); + ASSERT_TRUE(fp != NULL); -#if __BIONIC__ // glibc doesn't let you call getmntent/getmntent_r with a NULL FILE*. - ASSERT_TRUE(getmntent(fp) == NULL); + ASSERT_TRUE(getmntent(fp) != NULL); - struct mntent mbuf; - char cbuf[32]; - ASSERT_TRUE(getmntent_r(fp, &mbuf, cbuf, sizeof(cbuf)) == NULL); -#endif + bool saw_proc = false; + + struct mntent entry; + char buf[BUFSIZ]; + while (getmntent_r(fp, &entry, buf, sizeof(buf)) != NULL) { + if (strcmp(entry.mnt_fsname, "proc") == 0 && strcmp(entry.mnt_dir, "/proc") == 0) { + saw_proc = true; + } + } + + ASSERT_TRUE(saw_proc); ASSERT_EQ(1, endmntent(fp)); }