1 /* 2 * Copyright (C) 2014 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 <errno.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <syslog.h> 21 #include <unistd.h> 22 23 #include <async_safe/log.h> 24 25 static const char* syslog_log_tag = nullptr; 26 static int syslog_priority_mask = 0xff; 27 static int syslog_options = 0; 28 closelog()29 void closelog() { 30 syslog_log_tag = nullptr; 31 syslog_options = 0; 32 } 33 openlog(const char * log_tag,int options,int)34 void openlog(const char* log_tag, int options, int /*facility*/) { 35 syslog_log_tag = log_tag; 36 syslog_options = options; 37 } 38 setlogmask(int new_mask)39 int setlogmask(int new_mask) { 40 int old_mask = syslog_priority_mask; 41 // 0 is used to query the current mask. 42 if (new_mask != 0) { 43 syslog_priority_mask = new_mask; 44 } 45 return old_mask; 46 } 47 syslog(int priority,const char * fmt,...)48 void syslog(int priority, const char* fmt, ...) { 49 va_list args; 50 va_start(args, fmt); 51 vsyslog(priority, fmt, args); 52 va_end(args); 53 } 54 vsyslog(int priority,const char * fmt,va_list args)55 void vsyslog(int priority, const char* fmt, va_list args) { 56 // Check whether we're supposed to be logging messages of this priority. 57 if ((syslog_priority_mask & LOG_MASK(LOG_PRI(priority))) == 0) { 58 return; 59 } 60 61 // What's our log tag? 62 const char* log_tag = syslog_log_tag; 63 if (log_tag == nullptr) { 64 log_tag = getprogname(); 65 } 66 67 // What's our Android log priority? 68 priority &= LOG_PRIMASK; 69 int android_log_priority; 70 if (priority <= LOG_ERR) { 71 android_log_priority = ANDROID_LOG_ERROR; 72 } else if (priority == LOG_WARNING) { 73 android_log_priority = ANDROID_LOG_WARN; 74 } else if (priority <= LOG_INFO) { 75 android_log_priority = ANDROID_LOG_INFO; 76 } else { 77 android_log_priority = ANDROID_LOG_DEBUG; 78 } 79 80 // We can't let async_safe_format_log do the formatting because it doesn't 81 // support all the printf functionality. 82 char log_line[1024]; 83 int n = vsnprintf(log_line, sizeof(log_line), fmt, args); 84 if (n < 0) return; 85 86 async_safe_format_log(android_log_priority, log_tag, "%s", log_line); 87 if ((syslog_options & LOG_PERROR) != 0) { 88 bool have_newline = 89 (n > 0 && n < static_cast<int>(sizeof(log_line)) && log_line[n - 1] == '\n'); 90 dprintf(STDERR_FILENO, "%s: %s%s", log_tag, log_line, have_newline ? "" : "\n"); 91 } 92 } 93