12b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes/* 22b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * Copyright (C) 2014 The Android Open Source Project 32b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * 42b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * you may not use this file except in compliance with the License. 62b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * You may obtain a copy of the License at 72b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * 82b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * 102b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * Unless required by applicable law or agreed to in writing, software 112b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * See the License for the specific language governing permissions and 142b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes * limitations under the License. 152b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes */ 162b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 172b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include <stdio_ext.h> 182b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 192b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include <gtest/gtest.h> 202b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 212b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include <errno.h> 222b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include <fcntl.h> 232b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include <limits.h> 242b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include <math.h> 252b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include <stdio.h> 262b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include <sys/types.h> 272b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include <sys/stat.h> 282b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include <unistd.h> 292b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include <wchar.h> 302b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include <locale.h> 312b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 322b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes#include "TemporaryFile.h" 3376144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui#include "utils.h" 342b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 352b021e10664c3938249eb18b48eeac253cbb3e20Elliott HughesTEST(stdio_ext, __fbufsize) { 362b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes FILE* fp = fopen("/proc/version", "r"); 372b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 38df8f1a42d1cde97bcd46f5a29a67a44330c5c4f2Elliott Hughes // Initially, there's no buffer in case the first thing you do is disable buffering. 39df8f1a42d1cde97bcd46f5a29a67a44330c5c4f2Elliott Hughes ASSERT_EQ(0U, __fbufsize(fp)); 40df8f1a42d1cde97bcd46f5a29a67a44330c5c4f2Elliott Hughes 41df8f1a42d1cde97bcd46f5a29a67a44330c5c4f2Elliott Hughes // A read forces a buffer to be created. 422b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes char buf[128]; 43df8f1a42d1cde97bcd46f5a29a67a44330c5c4f2Elliott Hughes fgets(buf, sizeof(buf), fp); 44df8f1a42d1cde97bcd46f5a29a67a44330c5c4f2Elliott Hughes ASSERT_EQ(1024U, __fbufsize(fp)); 452b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 462b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(0, setvbuf(fp, buf, _IOFBF, 1)); 472b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(1U, __fbufsize(fp)); 482b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 492b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(0, setvbuf(fp, buf, _IOFBF, 8)); 502b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(8U, __fbufsize(fp)); 512b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 522b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes fclose(fp); 532b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes} 542b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 552b021e10664c3938249eb18b48eeac253cbb3e20Elliott HughesTEST(stdio_ext, __flbf) { 562b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes FILE* fp = fopen("/proc/version", "r"); 572b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 582b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_FALSE(__flbf(fp)); 592b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 602b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes char buf[128]; 612b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(0, setvbuf(fp, buf, _IOLBF, sizeof(buf))); 622b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 632b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_TRUE(__flbf(fp)); 642b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 652b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes fclose(fp); 662b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes} 672b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 682b021e10664c3938249eb18b48eeac253cbb3e20Elliott HughesTEST(stdio_ext, __fpending) { 692b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes FILE* fp = fopen("/dev/null", "w"); 702b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(0U, __fpending(fp)); 712b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ('x', fputc('x', fp)); 722b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(1U, __fpending(fp)); 732b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ('y', fputc('y', fp)); 742b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(2U, __fpending(fp)); 752b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes fflush(fp); 762b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(0U, __fpending(fp)); 772b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes fclose(fp); 782b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes} 792b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 802b021e10664c3938249eb18b48eeac253cbb3e20Elliott HughesTEST(stdio_ext, __fpurge) { 812b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes FILE* fp = tmpfile(); 822b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 832b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ('a', fputc('a', fp)); 842b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(1U, __fpending(fp)); 852b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes __fpurge(fp); 862b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(0U, __fpending(fp)); 872b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 882b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ('b', fputc('b', fp)); 892b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ('\n', fputc('\n', fp)); 902b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(2U, __fpending(fp)); 912b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 922b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes rewind(fp); 932b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 942b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes char buf[16]; 952b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes char* s = fgets(buf, sizeof(buf), fp); 962b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_TRUE(s != NULL); 972b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_STREQ("b\n", s); 982b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 992b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes fclose(fp); 1002b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes} 1012b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 1022b021e10664c3938249eb18b48eeac253cbb3e20Elliott HughesTEST(stdio_ext, _flushlbf) { 1032b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes FILE* fp = fopen("/dev/null", "w"); 1042b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 1052b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes char buf[128]; 1062b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(0, setvbuf(fp, buf, _IOLBF, sizeof(buf))); 1072b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 1082b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ('a', fputc('a', fp)); 1092b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(1U, __fpending(fp)); 1102b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 1112b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes _flushlbf(); 1122b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 1132b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(0U, __fpending(fp)); 1142b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 1152b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes fclose(fp); 1162b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes} 1172b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 1182b021e10664c3938249eb18b48eeac253cbb3e20Elliott HughesTEST(stdio_ext, __freadable__fwritable) { 1192b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes FILE* fp = fopen("/dev/null", "r"); 1202b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_TRUE(__freadable(fp)); 1212b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_FALSE(__fwritable(fp)); 1222b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes fclose(fp); 1232b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 1242b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes fp = fopen("/dev/null", "w"); 1252b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_FALSE(__freadable(fp)); 1262b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_TRUE(__fwritable(fp)); 1272b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes fclose(fp); 1282b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 1292b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes fp = fopen("/dev/null", "w+"); 1302b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_TRUE(__freadable(fp)); 1312b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_TRUE(__fwritable(fp)); 1322b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes fclose(fp); 1332b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes} 1342b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes 1352b021e10664c3938249eb18b48eeac253cbb3e20Elliott HughesTEST(stdio_ext, __fsetlocking) { 1362b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes FILE* fp = fopen("/proc/version", "r"); 1378c4994bbc1a9a01e34ea92c91eb5b2d1a27bd074Elliott Hughes ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_QUERY)); 1388c4994bbc1a9a01e34ea92c91eb5b2d1a27bd074Elliott Hughes ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_BYCALLER)); 1398c4994bbc1a9a01e34ea92c91eb5b2d1a27bd074Elliott Hughes ASSERT_EQ(FSETLOCKING_BYCALLER, __fsetlocking(fp, FSETLOCKING_QUERY)); 1408c4994bbc1a9a01e34ea92c91eb5b2d1a27bd074Elliott Hughes ASSERT_EQ(FSETLOCKING_BYCALLER, __fsetlocking(fp, FSETLOCKING_INTERNAL)); 1412b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes ASSERT_EQ(FSETLOCKING_INTERNAL, __fsetlocking(fp, FSETLOCKING_QUERY)); 1422b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes fclose(fp); 1432b021e10664c3938249eb18b48eeac253cbb3e20Elliott Hughes} 14476144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui 14576144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cuistatic void LockingByCallerHelper(std::atomic<pid_t>* pid) { 14676144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui *pid = gettid(); 14776144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui flockfile(stdout); 14876144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui funlockfile(stdout); 14976144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui} 15076144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui 15176144aaa6397fe9e16893882cf59c5c9c0684a66Yabin CuiTEST(stdio_ext, __fsetlocking_BYCALLER) { 15276144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui // Check if users can use flockfile/funlockfile to protect stdio operations. 15376144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui int old_state = __fsetlocking(stdout, FSETLOCKING_BYCALLER); 15476144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui flockfile(stdout); 15576144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui pthread_t thread; 15676144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui std::atomic<pid_t> pid(0); 15776144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui ASSERT_EQ(0, pthread_create(&thread, nullptr, 15876144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui reinterpret_cast<void* (*)(void*)>(LockingByCallerHelper), &pid)); 15976144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui WaitUntilThreadSleep(pid); 16076144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui funlockfile(stdout); 16176144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui 16276144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui ASSERT_EQ(0, pthread_join(thread, nullptr)); 16376144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui __fsetlocking(stdout, old_state); 16476144aaa6397fe9e16893882cf59c5c9c0684a66Yabin Cui} 165