• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gtest/gtest.h>
18 
19 #include <errno.h>
20 #include <string.h>
21 
TEST(string,strerror)22 TEST(string, strerror) {
23   // Valid.
24   ASSERT_STREQ("Success", strerror(0));
25   ASSERT_STREQ("Operation not permitted", strerror(1));
26 
27   // Invalid.
28   ASSERT_STREQ("Unknown error 4294967295", strerror(-1));
29   ASSERT_STREQ("Unknown error 1234", strerror(1234));
30 }
31 
ConcurrentStrErrorFn(void * arg)32 void* ConcurrentStrErrorFn(void* arg) {
33   bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0);
34   return reinterpret_cast<void*>(equal);
35 }
36 
37 #if __BIONIC__ // glibc's strerror isn't thread safe, only its strsignal.
TEST(string,strerror_concurrent)38 TEST(string, strerror_concurrent) {
39   const char* strerror1001 = strerror(1001);
40   ASSERT_STREQ("Unknown error 1001", strerror1001);
41 
42   pthread_t t;
43   ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrErrorFn, NULL));
44   void* result;
45   ASSERT_EQ(0, pthread_join(t, &result));
46   ASSERT_TRUE(static_cast<bool>(result));
47 
48   ASSERT_STREQ("Unknown error 1001", strerror1001);
49 }
50 #endif
51 
52 #if __BIONIC__ // glibc's strerror_r doesn't even have the same signature as the POSIX one.
TEST(string,strerror_r)53 TEST(string, strerror_r) {
54   char buf[256];
55 
56   // Valid.
57   ASSERT_EQ(0, strerror_r(0, buf, sizeof(buf)));
58   ASSERT_STREQ("Success", buf);
59   ASSERT_EQ(0, strerror_r(1, buf, sizeof(buf)));
60   ASSERT_STREQ("Operation not permitted", buf);
61 
62   // Invalid.
63   ASSERT_EQ(0, strerror_r(-1, buf, sizeof(buf)));
64   ASSERT_STREQ("Unknown error 4294967295", buf);
65   ASSERT_EQ(0, strerror_r(1234, buf, sizeof(buf)));
66   ASSERT_STREQ("Unknown error 1234", buf);
67 
68   // Buffer too small.
69   ASSERT_EQ(-1, strerror_r(0, buf, 2));
70   ASSERT_EQ(ERANGE, errno);
71 }
72 #endif
73 
TEST(string,strsignal)74 TEST(string, strsignal) {
75   // A regular signal.
76   ASSERT_STREQ("Hangup", strsignal(1));
77 
78   // A real-time signal.
79 #ifdef __GLIBC__ // glibc reserves real-time signals for internal use, and doesn't count those.
80   ASSERT_STREQ("Real-time signal 14", strsignal(48));
81 #else
82   ASSERT_STREQ("Real-time signal 16", strsignal(48));
83 #endif
84 
85   // Errors.
86   ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small.
87   ASSERT_STREQ("Unknown signal 0", strsignal(0)); // Still too small.
88   ASSERT_STREQ("Unknown signal 1234", strsignal(1234)); // Too large.
89 }
90 
ConcurrentStrSignalFn(void * arg)91 void* ConcurrentStrSignalFn(void* arg) {
92   bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0);
93   return reinterpret_cast<void*>(equal);
94 }
95 
TEST(string,strsignal_concurrent)96 TEST(string, strsignal_concurrent) {
97   const char* strsignal1001 = strsignal(1001);
98   ASSERT_STREQ("Unknown signal 1001", strsignal1001);
99 
100   pthread_t t;
101   ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrSignalFn, NULL));
102   void* result;
103   ASSERT_EQ(0, pthread_join(t, &result));
104   ASSERT_TRUE(static_cast<bool>(result));
105 
106   ASSERT_STREQ("Unknown signal 1001", strsignal1001);
107 }
108