• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "stdio.h"
17 #include <stdarg.h>
18 #include <securec.h>
19 #include "fcntl.h"
20 #include "unistd.h"
21 #include <log.h>
22 
23 #ifndef LOSCFG_BASE_CORE_HILOG
24 #include <stdatomic.h>
25 #include "hilog_trace.h"
26 #endif
27 
28 typedef int SecInt32;
29 typedef unsigned int SecUnsignedInt32;
30 typedef long long SecInt64;
31 typedef unsigned long long SecUnsignedInt64;
32 
33 #ifndef LOSCFG_BASE_CORE_HILOG
34 static RegisterFunc g_registerFunc = NULL;
35 static atomic_int g_hiLogGetIdCallCount = 0;
36 #endif
37 
38 #ifndef SECUREC_BUFFER_SIZE
39 #define SECUREC_BUFFER_SIZE 256
40 #endif
41 
42 #define SECUREC_MAX_PRECISION SECUREC_BUFFER_SIZE
43 /* max. # bytes in multibyte char  ,see MB_LEN_MAX */
44 #define SECUREC_MB_LEN 16
45 
46 /* state definitions */
47 #define SECUREC_FLAG_SIGN 0x00001U
48 #define SECUREC_FLAG_SIGN_SPACE 0x00002U
49 #define SECUREC_FLAG_LEFT 0x00004U
50 #define SECUREC_FLAG_LEADZERO 0x00008U
51 #define SECUREC_FLAG_LONG 0x00010U
52 #define SECUREC_FLAG_SHORT 0x00020U
53 #define SECUREC_FLAG_SIGNED 0x00040U
54 #define SECUREC_FLAG_ALTERNATE 0x00080U
55 #define SECUREC_FLAG_NEGATIVE 0x00100U
56 #define SECUREC_FLAG_FORCE_OCTAL 0x00200U
57 #define SECUREC_FLAG_LONG_DOUBLE 0x00400U
58 #define SECUREC_FLAG_WIDECHAR 0x00800U
59 #define SECUREC_FLAG_LONGLONG 0x01000U
60 #define SECUREC_FLAG_CHAR 0x02000U
61 #define SECUREC_FLAG_POINTER 0x04000U
62 #define SECUREC_FLAG_I64 0x08000U
63 #define SECUREC_FLAG_PTRDIFF 0x10000U
64 #define SECUREC_FLAG_SIZE 0x20000U
65 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
66 #define SECUREC_FLAG_INTMAX 0x40000U
67 #endif
68 
69 
70 typedef enum {
71     STAT_NORMAL,
72     STAT_PERCENT,
73     STAT_FLAG,
74     STAT_WIDTH,
75     STAT_DOT,
76     STAT_PRECIS,
77     STAT_SIZE,
78     STAT_TYPE,
79     STAT_INVALID
80 } SecFmtState;
81 
82 #define SECUREC_PRINTF_TRUNCATE (-2)
83 typedef struct {
84     int count;
85     char *cur;
86 } SecPrintfStream;
87 #define SECUREC_ERROR_INVALID_PARAMTER(msg) printf("%s invalid argument\n", msg)
88 #define SECUREC_ERROR_INVALID_RANGE(msg) printf("%s invalid dest buffer size\n", msg)
89 #define SECUREC_ERROR_BUFFER_OVERLAP(msg) printf("%s buffer overlap\n", msg)
90 
91 // Log type
92 #define LOG_BUF_SIZE (1024)
93 #define MAX_DOMAIN_TAG_SIZE 64
94 #define IOV_SIZE (3)
95 #define HILOG_IOV_SIZE 4
96 #define HITRACE_BUF_SIZE 128
97 #define MAX_INIT_RETRIES (500)
98 #define DOMAIN_MIN 0x0D000000
99 #define DOMAIN_MAX 0x0E000000
100 
101 #define SECUREC_FLOAT_BUFSIZE (309 + 40)     /* max float point value */
102 #define SECUREC_FLOAT_BUFSIZE_LB (4932 + 40) /* max long double value */
103 
104 #define SECUREC_INT_MAX 2147483647
105 
106 #define SECUREC_MUL10(x) ((((x) << 2) + (x)) << 1)
107 #define SECUREC_INT_MAX_DIV_TEN 21474836
108 #define SECUREC_MUL10_ADD_BEYOND_MAX(val) (((val) > SECUREC_INT_MAX_DIV_TEN))
109 
110 #ifdef SECUREC_STACK_SIZE_LESS_THAN_1K
111 #define SECUREC_FMT_STR_LEN (8)
112 #else
113 #define SECUREC_FMT_STR_LEN (16)
114 #endif
115 
116 #ifndef SECUREC_PUTC
117 #define SECUREC_PUTC(_c, _stream) ((--(_stream)->count >= 0) ? (*(_stream)->cur++ = (char)(_c)) : EOF)
118 #endif
119 /* to clear e835 */
120 #ifndef SECUREC_PUTC_ZERO
121 #define SECUREC_PUTC_ZERO(_stream) ((--(_stream)->count >= 0) ? ((*(_stream)->cur++ = (char)('\0'))) : EOF)
122 #endif
123 
124 #ifndef SECUREC_MALLOC
125 #define SECUREC_MALLOC(x) malloc((size_t)(x))
126 #endif
127 
128 #ifndef SECUREC_FREE
129 #define SECUREC_FREE(x) free((void *)(x))
130 #endif
131 
132 typedef char SecChar;
133 #define SECUREC_CHAR(x) x
134 /* put a char to output */
135 #define SECUREC_PUTC(_c, _stream) ((--(_stream)->count >= 0) ? (*(_stream)->cur++ = (char)(_c)) : EOF)
136 /* to clear e835 */
137 
138 #define SECUREC_PUTC_ZERO(_stream) ((--(_stream)->count >= 0) ? ((*(_stream)->cur++ = (char)('\0'))) : EOF)
139 
SecPutWcharStrEndingZero(SecPrintfStream * str,int zeroNum)140 int SecPutWcharStrEndingZero(SecPrintfStream *str, int zeroNum)
141 {
142     int succeed = 0;
143     int i;
144 
145     for (i = 0; i < zeroNum && (SECUREC_PUTC_ZERO(str) != EOF); ++i) {
146     }
147     if (i == zeroNum) {
148         succeed = 1;
149     }
150     return succeed;
151 }
152 
SecWriteMultiChar(char ch,int num,SecPrintfStream * f,int * pnumwritten)153 void SecWriteMultiChar(char ch, int num, SecPrintfStream *f, int *pnumwritten)
154 {
155     int count = num;
156     while (count-- > 0) {
157         if (SECUREC_PUTC(ch, f) == EOF) {
158             *pnumwritten = -1;
159             break;
160         } else {
161             ++(*pnumwritten);
162         }
163     }
164 }
165 
SecWriteString(const char * string,int len,SecPrintfStream * f,int * pnumwritten)166 void SecWriteString(const char *string, int len, SecPrintfStream *f, int *pnumwritten)
167 {
168     const char *str = string;
169     int count = len;
170     while (count-- > 0) {
171         if (SECUREC_PUTC(*str, f) == EOF) {
172             *pnumwritten = -1;
173             break;
174         } else {
175             ++(*pnumwritten);
176             ++str;
177         }
178     }
179 }
180 
181 #ifndef LOSCFG_BASE_CORE_HILOG
HiLogRegisterGetIdFun(RegisterFunc registerFunc)182 int HiLogRegisterGetIdFun(RegisterFunc registerFunc)
183 {
184     if (g_registerFunc != NULL) {
185         return -1;
186     }
187     g_registerFunc = registerFunc;
188     return 0;
189 }
190 
HiLogUnregisterGetIdFun(RegisterFunc registerFunc)191 void HiLogUnregisterGetIdFun(RegisterFunc registerFunc)
192 {
193     if (g_registerFunc != registerFunc) {
194         return;
195     }
196 
197     g_registerFunc = NULL;
198     while (atomic_load(&g_hiLogGetIdCallCount) != 0) {
199         /* do nothing, just wait current callback return */
200     }
201 
202     return;
203 }
204 #endif
205 
206 #define SECUREC_WRITE_MULTI_CHAR SecWriteMultiChar
207 #define SECUREC_WRITE_STRING SecWriteString
208 
209 typedef struct {
210     unsigned int flags;
211     int fldWidth;
212     int precision;
213     int bufferIsWide; /* flag for buffer contains wide chars */
214     int dynWidth;     /* %*   1 width from variable parameter ;0 not */
215     int dynPrecision; /* %.*  1 precision from variable parameter ;0 not */
216 } SecFormatAttr;
217 
218 typedef union {
219     char *str; /* not a null terminated  string */
220     wchar_t *wStr;
221 } SecFormatBuf;
222 
223 typedef union {
224     char str[SECUREC_BUFFER_SIZE + 1];
225 #ifdef SECUREC_FOR_WCHAR
226     wchar_t wStr[SECUREC_BUFFER_SIZE + 1];
227 #endif
228 } SecBuffer;
229 
230 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
231 /* to clear e506 warning */
SecIsSameSize(size_t sizeA,size_t sizeB)232 static int SecIsSameSize(size_t sizeA, size_t sizeB)
233 {
234     return sizeA == sizeB;
235 }
236 #endif
237 #define SECUREC_WHILE_ZERO while (0)
238 
239 #define SECUREC_SPECIAL(_val, Base) case Base:                                      \
240         do {                                        \
241             *--formatBuf.str = digits[_val % Base]; \
242         } while ((_val /= Base) != 0)
243 
244 #define SECUREC_SAFE_WRITE_PREFIX(src, txtLen, _stream, outChars) \
245     do {                                                          \
246         for (ii = 0; ii < txtLen; ++ii) {                         \
247             *((SecChar *)(void *)(_stream->cur)) = *(src);        \
248             _stream->cur += sizeof(SecChar);                      \
249             ++(src);                                              \
250         }                                                         \
251         _stream->count -= txtLen * (int)(sizeof(SecChar));        \
252         *(outChars) = *(outChars) + (txtLen);                     \
253     }                                                             \
254     SECUREC_WHILE_ZERO
255 #define MOBILE_NUMBER_LENGTH 12
256 #define SECUREC_SAFE_WRITE_STR(src, txtLen, _stream, outChars)                                    \
257     do {                                                                                          \
258         if (txtLen < MOBILE_NUMBER_LENGTH) {                                                      \
259             for (ii = 0; ii < txtLen; ++ii) {                                                     \
260                 *((SecChar *)(void *)(_stream->cur)) = *(src);                                    \
261                 _stream->cur += sizeof(SecChar);                                                  \
262                 ++(src);                                                                          \
263             }                                                                                     \
264         } else {                                                                                  \
265             (void)memcpy_s(_stream->cur, ((size_t)(unsigned int)txtLen * (sizeof(SecChar))), src, \
266                 ((size_t)(unsigned int)txtLen * (sizeof(SecChar))));                              \
267             _stream->cur += (size_t)(unsigned int)txtLen * (sizeof(SecChar));                     \
268         }                                                                                         \
269         _stream->count -= txtLen * (int)(sizeof(SecChar));                                        \
270         *(outChars) = *(outChars) + (txtLen);                                                     \
271     }                                                                                             \
272     SECUREC_WHILE_ZERO
273 
274 #define SECUREC_SAFE_WRITE_CHAR(_ch, _stream, outChars) do {                                                     \
275         *((SecChar *)(void *)(_stream->cur)) = (SecChar)_ch; \
276         _stream->cur += sizeof(SecChar);                     \
277         _stream->count -= (int)(sizeof(SecChar));            \
278         *(outChars) = *(outChars) + 1;                       \
279     }                                                        \
280     SECUREC_WHILE_ZERO
281 
282 #define SECUREC_SAFE_PADDING(padChar, padLen, _stream, outChars)     \
283     do {                                                             \
284         for (ii = 0; ii < padLen; ++ii) {                            \
285             *((SecChar *)(void *)(_stream->cur)) = (SecChar)padChar; \
286             _stream->cur += sizeof(SecChar);                         \
287         }                                                            \
288         _stream->count -= padLen * (int)(sizeof(SecChar));           \
289         *(outChars) = *(outChars) + (padLen);                        \
290     }                                                                \
291     SECUREC_WHILE_ZERO
292 
293 /* The count variable can be reduced to 0, and the external function complements the \0 terminator. */
294 #define SECUREC_IS_REST_BUF_ENOUGH(needLen) ((int)(stream->count - (int)needLen * (int)(sizeof(SecChar))) >= 0)
295 
296 #define SECUREC_FMT_STATE_OFFSET 256
297 #ifdef SECUREC_FOR_WCHAR
298 #define SECUREC_FMT_TYPE(c, fmtTable) \
299     ((((unsigned int)(int)(c)) <= (unsigned int)(int)SECUREC_CHAR('~')) ? (fmtTable[(unsigned char)(c)]) : 0)
300 #define SECUREC_DECODE_STATE(c, fmtTable, laststate)                                               \
301     (SecFmtState)(((fmtTable[(SECUREC_FMT_TYPE(c, fmtTable)) * ((unsigned char)STAT_INVALID + 1) + \
302         (unsigned char)(laststate) + SECUREC_FMT_STATE_OFFSET])))
303 #else
304 #define SECUREC_DECODE_STATE(c, fmtTable, laststate)                                             \
305     (SecFmtState)((fmtTable[(fmtTable[(unsigned char)(c)]) * ((unsigned char)STAT_INVALID + 1) + \
306         (unsigned char)(laststate) + SECUREC_FMT_STATE_OFFSET]))
307 #endif
308 
SecDecodeFlags(SecChar ch,SecFormatAttr * attr)309 static void SecDecodeFlags(SecChar ch, SecFormatAttr *attr)
310 {
311     switch (ch) {
312         case SECUREC_CHAR(' '):
313             attr->flags |= SECUREC_FLAG_SIGN_SPACE;
314             break;
315         case SECUREC_CHAR('+'):
316             attr->flags |= SECUREC_FLAG_SIGN;
317             break;
318         case SECUREC_CHAR('-'):
319             attr->flags |= SECUREC_FLAG_LEFT;
320             break;
321         case SECUREC_CHAR('0'):
322             attr->flags |= SECUREC_FLAG_LEADZERO; /* add zero th the front */
323             break;
324         case SECUREC_CHAR('#'):
325             attr->flags |= SECUREC_FLAG_ALTERNATE; /* output %x with 0x */
326             break;
327         default:
328             break;
329     }
330     return;
331 }
332 
SecDecodeSize(SecChar ch,SecFormatAttr * attr,const SecChar ** format)333 static int SecDecodeSize(SecChar ch, SecFormatAttr *attr, const SecChar **format)
334 {
335     switch (ch) {
336 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
337         case SECUREC_CHAR('j'):
338             attr->flags |= SECUREC_FLAG_INTMAX;
339             break;
340 #endif
341         case SECUREC_CHAR('q'): /* fall-through */ /* FALLTHRU */
342         case SECUREC_CHAR('L'):
343             attr->flags |= SECUREC_FLAG_LONGLONG | SECUREC_FLAG_LONG_DOUBLE;
344             break;
345         case SECUREC_CHAR('l'):
346             if (**format == SECUREC_CHAR('l')) {
347                 ++(*format);
348                 attr->flags |= SECUREC_FLAG_LONGLONG; /* long long */
349             } else {
350                 attr->flags |= SECUREC_FLAG_LONG; /* long int or wchar_t */
351             }
352             break;
353         case SECUREC_CHAR('t'):
354             attr->flags |= SECUREC_FLAG_PTRDIFF;
355             break;
356 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
357         case SECUREC_CHAR('z'):
358             attr->flags |= SECUREC_FLAG_SIZE;
359             break;
360         case SECUREC_CHAR('Z'):
361             attr->flags |= SECUREC_FLAG_SIZE;
362             break;
363 #endif
364 
365         case SECUREC_CHAR('I'):
366 #ifdef SECUREC_ON_64BITS
367             attr->flags |= SECUREC_FLAG_I64; /* %I  to  INT64 */
368 #endif
369             if ((**format == SECUREC_CHAR('6')) && (*((*format) + 1) == SECUREC_CHAR('4'))) {
370                 (*format) += 2;
371                 attr->flags |= SECUREC_FLAG_I64; /* %I64  to  INT64 */
372             } else if ((**format == SECUREC_CHAR('3')) && (*((*format) + 1) == SECUREC_CHAR('2'))) {
373                 (*format) += 2;
374                 attr->flags &= ~SECUREC_FLAG_I64; /* %I64  to  INT32 */
375             } else if ((**format == SECUREC_CHAR('d')) || (**format == SECUREC_CHAR('i')) ||
376                 (**format == SECUREC_CHAR('o')) || (**format == SECUREC_CHAR('u')) || (**format == SECUREC_CHAR('x')) ||
377                 (**format == SECUREC_CHAR('X'))) {
378                 /* do nothing */
379             } else {
380                 /* Compatibility  code for "%I" just print I */
381                 return -1;
382             }
383             break;
384 
385         case SECUREC_CHAR('h'):
386             if (**format == SECUREC_CHAR('h'))
387                 attr->flags |= SECUREC_FLAG_CHAR; /* char */
388             else
389                 attr->flags |= SECUREC_FLAG_SHORT; /* short int */
390             break;
391 
392         case SECUREC_CHAR('w'):
393             attr->flags |= SECUREC_FLAG_WIDECHAR; /* wide char */
394             break;
395         default:
396             break;
397     }
398 
399     return 0;
400 }
401 
SecDecodeTypeC(SecFormatAttr * attr,unsigned int cValue,SecFormatBuf * formatBuf,SecBuffer * buffer)402 static int SecDecodeTypeC(SecFormatAttr *attr, unsigned int cValue, SecFormatBuf *formatBuf, SecBuffer *buffer)
403 {
404     int textLen;
405     wchar_t wchar;
406 
407 #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && !(defined(__hpux)) && !(defined(SECUREC_ON_SOLARIS))
408     attr->flags &= ~SECUREC_FLAG_LEADZERO;
409 #endif
410 
411 #ifdef SECUREC_FOR_WCHAR
412     attr->bufferIsWide = 1;
413     wchar = (wchar_t)cValue;
414     if (attr->flags & SECUREC_FLAG_SHORT) {
415         /* multibyte character to wide  character */
416         char tempchar[2];
417         tempchar[0] = (char)(wchar & 0x00ff);
418         tempchar[1] = '\0';
419 
420         if (mbtowc(buffer->wStr, tempchar, sizeof(tempchar)) < 0) {
421             return -1;
422         }
423     } else {
424         buffer->wStr[0] = wchar;
425     }
426     formatBuf->wStr = buffer->wStr;
427     textLen = 1; /* only 1 wide character */
428 #else
429     attr->bufferIsWide = 0;
430     if (attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) {
431         wchar = (wchar_t)cValue;
432         /* wide  character  to multibyte character */
433         // SECUREC_MASK_MSVC_CRT_WARNING
434         textLen = wctomb(buffer->str, wchar);
435         // SECUREC_END_MASK_MSVC_CRT_WARNING
436         if (textLen < 0) {
437             return -1;
438         }
439     } else {
440         /* get  multibyte character from argument */
441         unsigned short temp;
442         temp = (unsigned short)cValue;
443         buffer->str[0] = (char)temp;
444         textLen = 1;
445     }
446     formatBuf->str = buffer->str;
447 #endif
448 
449     return textLen;
450 }
451 
SecDecodeTypeS(SecFormatAttr * attr,char * argPtr,SecFormatBuf * formatBuf)452 static int SecDecodeTypeS(SecFormatAttr *attr, char *argPtr, SecFormatBuf *formatBuf)
453 {
454     /* literal string to print null ptr, define it on stack rather than const text area
455        is to avoid gcc warning with pointing const text with variable */
456     static char strNullString[8] = "(null)";
457     static wchar_t wStrNullString[8] = { L'(', L'n', L'u', L'l', L'l', L')', L'\0', L'\0' };
458 
459     int finalPrecision;
460     char *strEnd = NULL;
461     wchar_t *wStrEnd = NULL;
462     int textLen;
463 
464 #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT)) && (!defined(SECUREC_ON_UNIX))
465     attr->flags &= ~SECUREC_FLAG_LEADZERO;
466 #endif
467     finalPrecision = (attr->precision == -1) ? SECUREC_INT_MAX : attr->precision;
468     formatBuf->str = argPtr;
469 
470 #ifdef SECUREC_FOR_WCHAR
471 #if defined(SECUREC_COMPATIBLE_LINUX_FORMAT)
472     if (!(attr->flags & SECUREC_FLAG_LONG)) {
473         attr->flags |= SECUREC_FLAG_SHORT;
474     }
475 #endif
476     if (attr->flags & SECUREC_FLAG_SHORT) {
477         if (formatBuf->str == NULL) { /* NULL passed, use special string */
478             formatBuf->str = strNullString;
479         }
480         strEnd = formatBuf->str;
481         for (textLen = 0; textLen < finalPrecision && *strEnd; textLen++) {
482             ++strEnd;
483         }
484         /* textLen now contains length in multibyte chars */
485     } else {
486         if (formatBuf->wStr == NULL) { /* NULL passed, use special string */
487             formatBuf->wStr = wStrNullString;
488         }
489         attr->bufferIsWide = 1;
490         wStrEnd = formatBuf->wStr;
491         while (finalPrecision-- && *wStrEnd) {
492             ++wStrEnd;
493         }
494         textLen = (int)(wStrEnd - formatBuf->wStr); /* in wchar_ts */
495         /* textLen now contains length in wide chars */
496     }
497 #else /* SECUREC_FOR_WCHAR */
498     if (attr->flags & (SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR)) {
499         if (formatBuf->wStr == NULL) { /* NULL passed, use special string */
500             formatBuf->wStr = wStrNullString;
501         }
502         attr->bufferIsWide = 1;
503         wStrEnd = formatBuf->wStr;
504         while (finalPrecision-- && *wStrEnd) {
505             ++wStrEnd;
506         }
507         textLen = (int)(wStrEnd - formatBuf->wStr);
508     } else {
509         if (formatBuf->str == NULL) { /* meet NULL, use special string */
510             formatBuf->str = strNullString;
511         }
512 
513         if (finalPrecision == SECUREC_INT_MAX) {
514             /* precision NOT assigned */
515             /* The strlen performance is high when the string length is greater than 32 */
516             textLen = (int)strlen(formatBuf->str);
517         } else {
518             /* precision assigned */
519             strEnd = formatBuf->str;
520             while (finalPrecision-- && *strEnd) {
521                 ++strEnd;
522             }
523             textLen = (int)(strEnd - formatBuf->str); /* length of the string */
524         }
525     }
526 
527 #endif /* SECUREC_FOR_WCHAR */
528     return textLen;
529 }
530 
531 #define PUBLIC_FLAG_LEN (8)
532 #define PRIVATE_FLAG_LEN (9)
533 #define PUBLIC_FLAG "{public}"
534 #define PRIVATE_FLAG "{private}"
535 #define bool _Bool
536 static int HILOG_TRUE = 1;
537 static int HILOG_FALSE = 0;
538 
HiLogSecOutputS(SecPrintfStream * stream,bool isDebugMode,const char * cformat,va_list arglist)539 int HiLogSecOutputS(SecPrintfStream *stream, bool isDebugMode, const char *cformat, va_list arglist)
540 {
541     const SecChar *format = cformat;
542 
543     char *floatBuf = NULL;
544     SecFormatBuf formatBuf;
545     static const char *itoaUpperDigits = "0123456789ABCDEFX";
546     static const char *itoaLowerDigits = "0123456789abcdefx";
547     const char *digits = itoaUpperDigits;
548     int ii = 0;
549 
550     unsigned int radix;
551     int charsOut; /* characters written */
552 
553     int prefixLen = 0;
554     int padding = 0;
555 
556     int textLen;        /* length of the text */
557     int bufferSize = 0; /* size of formatBuf.str */
558     int noOutput = 0;
559 
560     SecFmtState state;
561     SecFmtState laststate;
562 
563     SecChar prefix[2] = { 0 };
564     SecChar ch; /* currently read character */
565     static char PRIVACY_STRING[] = "<private>";
566     static wchar_t WPRIVACY_STRING[] = { L'<', L'p', L'r', L'i', L'v', L'a', L't', L'e', L'>', L'\0'};
567     bool isPrivacy = HILOG_TRUE;
568 
569     static const unsigned char fmtCharTable[337] = {
570         /* type 0:    nospecial meanin;
571            1:   '%';
572            2:    '.'
573            3:    '*'
574            4:    '0'
575            5:    '1' ... '9'
576            6:    ' ', '+', '-', '#'
577            7:     'h', 'l', 'L', 'F', 'w' , 'N','z','q','t','j'
578            8:     'd','o','u','i','x','X','e','f','g'
579          */
580         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582         0x06, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x00, 0x06, 0x02, 0x00,
583         0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584         0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x08, 0x08, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00,
585         0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
586         0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x08, 0x07, 0x00, 0x07, 0x00, 0x00, 0x08,
587         0x08, 0x07, 0x00, 0x08, 0x07, 0x08, 0x00, 0x07, 0x08, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
588         /* fill zero  for normal char 128 byte for 0x80 - 0xff */
589         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597         /* state  0: normal
598            1: percent
599            2: flag
600            3: width
601            4: dot
602            5: precis
603            6: size
604            7: type
605            8: invalid
606          */
607         0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,
608         0x01, 0x00, 0x00, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03, 0x08, 0x05,
609         0x08, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x03, 0x03,
610         0x03, 0x05, 0x05, 0x08, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
611         0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x00,
612         0x00
613     };
614 
615     SecFormatAttr formatAttr;
616     SecBuffer buffer;
617     formatAttr.flags = 0;
618     formatAttr.bufferIsWide = 0; /* flag for buffer contains wide chars */
619     formatAttr.fldWidth = 0;
620     formatAttr.precision = 0;
621     formatAttr.dynWidth = 0;
622     formatAttr.dynPrecision = 0;
623 
624     charsOut = 0;
625     textLen = 0;
626     state = STAT_NORMAL; /* starting state */
627     formatBuf.str = NULL;
628 
629     /* loop each format character */
630     /* remove format != NULL */
631     while ((ch = *format++) != SECUREC_CHAR('\0') && charsOut >= 0) {
632         laststate = state;
633         state = SECUREC_DECODE_STATE(ch, fmtCharTable, laststate);
634 
635         switch (state) {
636             case STAT_NORMAL:
637 
638             NORMAL_CHAR:
639 
640                 /* normal state, write character */
641                 if (SECUREC_IS_REST_BUF_ENOUGH(1 /* only one char */)) {
642                     SECUREC_SAFE_WRITE_CHAR(ch, stream, &charsOut); /* char * cast to wchar * */
643                 } else {
644 #ifdef SECUREC_FOR_WCHAR
645                     SECUREC_WRITE_CHAR(ch, stream, &charsOut);
646 #else
647                     /* optimize function call to code */
648                     charsOut = -1;
649                     stream->count = -1;
650 #endif
651                 }
652 
653                 continue;
654 
655             case STAT_PERCENT:
656                 /* set default values */
657                 prefixLen = 0;
658                 noOutput = 0;
659                 formatAttr.flags = 0;
660                 formatAttr.fldWidth = 0;
661                 formatAttr.precision = -1;
662                 formatAttr.bufferIsWide = 0;
663                 isPrivacy = HILOG_TRUE;
664                 if (0 == strncmp(format, PUBLIC_FLAG, PUBLIC_FLAG_LEN)) {
665                     isPrivacy = HILOG_FALSE;
666                     format += PUBLIC_FLAG_LEN;
667                     break;
668                 }
669                 if (0 == strncmp(format, PRIVATE_FLAG, PRIVATE_FLAG_LEN)) {
670                     isPrivacy = HILOG_TRUE;
671                     format += PRIVATE_FLAG_LEN;
672                     break;
673                 }
674 
675                 if (*format == SECUREC_CHAR('%')) {
676                     isPrivacy = HILOG_FALSE;
677                 }
678 
679                 break;
680 
681             case STAT_FLAG:
682                 /* set flag based on which flag character */
683                 SecDecodeFlags(ch, &formatAttr);
684                 break;
685 
686             case STAT_WIDTH:
687                 /* update width value */
688                 if (ch == SECUREC_CHAR('*')) {
689                     /* get width */
690                     formatAttr.fldWidth = (int)va_arg(arglist, int);
691                     if (formatAttr.fldWidth < 0) {
692                         formatAttr.flags |= SECUREC_FLAG_LEFT;
693                         formatAttr.fldWidth = -formatAttr.fldWidth;
694                     }
695                     formatAttr.dynWidth = 1;
696                 } else {
697                     if (laststate != STAT_WIDTH) {
698                         formatAttr.fldWidth = 0;
699                     }
700                     if (SECUREC_MUL10_ADD_BEYOND_MAX(formatAttr.fldWidth)) {
701                         return -1;
702                     }
703                     formatAttr.fldWidth =
704                         (int)SECUREC_MUL10((unsigned int)formatAttr.fldWidth) + (ch - SECUREC_CHAR('0'));
705                     formatAttr.dynWidth = 0;
706                 }
707                 break;
708 
709             case STAT_DOT:
710                 formatAttr.precision = 0;
711                 break;
712 
713             case STAT_PRECIS:
714                 /* update precison value */
715                 if (ch == SECUREC_CHAR('*')) {
716                     /* get precision from arg list */
717                     formatAttr.precision = (int)va_arg(arglist, int);
718                     if (formatAttr.precision < 0) {
719                         formatAttr.precision = -1;
720                     }
721                     formatAttr.dynPrecision = 1;
722                 } else {
723                     /* add digit to current precision */
724                     if (SECUREC_MUL10_ADD_BEYOND_MAX(formatAttr.precision)) {
725                         return -1;
726                     }
727                     formatAttr.precision =
728                         (int)SECUREC_MUL10((unsigned int)formatAttr.precision) + (ch - SECUREC_CHAR('0'));
729                     formatAttr.dynPrecision = 0;
730                 }
731                 break;
732 
733             case STAT_SIZE:
734                 /* read a size specifier, set the formatAttr.flags based on it */
735                 if (SecDecodeSize(ch, &formatAttr, &format) != 0) {
736                     /* Compatibility  code for "%I" just print I */
737                     state = STAT_NORMAL;
738                     goto NORMAL_CHAR;
739                 }
740                 break;
741 
742             case STAT_TYPE:
743 
744                 switch (ch) {
745                     case SECUREC_CHAR('C'):
746                         /* wide char */
747                         if (!(formatAttr.flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR))) {
748 #ifdef SECUREC_FOR_WCHAR
749                             formatAttr.flags |= SECUREC_FLAG_SHORT;
750 #else
751                             formatAttr.flags |= SECUREC_FLAG_WIDECHAR;
752 #endif
753                         }
754                         /* fall-through */
755                         /* FALLTHRU */
756                     case SECUREC_CHAR('c'): {
757                         unsigned int cValue = (unsigned int)va_arg(arglist, int);
758                         textLen = SecDecodeTypeC(&formatAttr, cValue, &formatBuf, &buffer);
759                         if (textLen < 0) {
760                             noOutput = 1;
761                         }
762                     } break;
763                     case SECUREC_CHAR('S'): /* wide char string */
764 #ifndef SECUREC_FOR_WCHAR
765                         if (!(formatAttr.flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR))) {
766                             formatAttr.flags |= SECUREC_FLAG_WIDECHAR;
767                         }
768 #else
769                         if (!(formatAttr.flags & (SECUREC_FLAG_SHORT | SECUREC_FLAG_LONG | SECUREC_FLAG_WIDECHAR))) {
770                             formatAttr.flags |= SECUREC_FLAG_SHORT;
771                         }
772 #endif
773                         /* fall-through */
774                         /* FALLTHRU */
775                     case SECUREC_CHAR('s'): {
776                         char *argPtr = (char *)va_arg(arglist, char *);
777                         textLen = SecDecodeTypeS(&formatAttr, argPtr, &formatBuf);
778                     } break;
779 
780                     case SECUREC_CHAR('n'):
781                         /* higher risk disable it */
782                         return -1;
783 
784                     case SECUREC_CHAR('E'): /* fall-through */ /* FALLTHRU */
785                     case SECUREC_CHAR('F'): /* fall-through */ /* FALLTHRU */
786                     case SECUREC_CHAR('G'): /* fall-through */ /* FALLTHRU */
787                     case SECUREC_CHAR('A'): /* fall-through */ /* FALLTHRU */
788                         /* convert format char to lower , use Explicit conversion to clean up compilation warning */
789                         ch = (SecChar)(ch + ((SecChar)(SECUREC_CHAR('a')) - (SECUREC_CHAR('A'))));
790                         /* fall-through */
791                         /* FALLTHRU */
792                     case SECUREC_CHAR('e'): /* fall-through */ /* FALLTHRU */
793                     case SECUREC_CHAR('f'): /* fall-through */ /* FALLTHRU */
794                     case SECUREC_CHAR('g'): /* fall-through */ /* FALLTHRU */
795                     case SECUREC_CHAR('a'): {
796                         /* floating point conversion */
797                         formatBuf.str = buffer.str; /* output buffer for float string with default size */
798 
799                         /* compute the precision value */
800                         if (formatAttr.precision < 0) {
801                             formatAttr.precision = 6;
802                         } else if (formatAttr.precision == 0 && ch == SECUREC_CHAR('g')) {
803                             formatAttr.precision = 1;
804                         }
805 
806                         /* calc buffer size to store long double value */
807                         if (formatAttr.flags & SECUREC_FLAG_LONG_DOUBLE) {
808                             if (formatAttr.precision > (SECUREC_INT_MAX - SECUREC_FLOAT_BUFSIZE_LB)) {
809                                 noOutput = 1;
810                                 break;
811                             }
812                             bufferSize = SECUREC_FLOAT_BUFSIZE_LB + formatAttr.precision;
813                         } else {
814                             if (formatAttr.precision > (SECUREC_INT_MAX - SECUREC_FLOAT_BUFSIZE)) {
815                                 noOutput = 1;
816                                 break;
817                             }
818                             bufferSize = SECUREC_FLOAT_BUFSIZE + formatAttr.precision;
819                         }
820                         if (formatAttr.fldWidth > bufferSize) {
821                             bufferSize = formatAttr.fldWidth;
822                         }
823 
824                         if (bufferSize >= SECUREC_BUFFER_SIZE) {
825                             /* the current vlaue of SECUREC_BUFFER_SIZE could NOT store the formatted float string */
826                             /* size include '+' and '\0' */
827                             floatBuf = (char *)SECUREC_MALLOC(((size_t)(unsigned int)bufferSize + (size_t)2));
828                             if (floatBuf != NULL) {
829                                 formatBuf.str = floatBuf;
830                             } else {
831                                 noOutput = 1;
832                                 break;
833                             }
834                         }
835 
836                         {
837                             /* add following code to call system sprintf API for float number */
838                             const SecChar *pFltFmt = format - 2; /* point to the position before 'f' or 'g' */
839                             int k = 0;
840                             int fltFmtStrLen;
841                             char fltFmtBuf[SECUREC_FMT_STR_LEN];
842                             char *fltFmtStr = fltFmtBuf;
843                             char *fltFmtHeap = NULL; /* to clear warning */
844 
845                             while (SECUREC_CHAR('%') != *pFltFmt && SECUREC_CHAR('}') != *pFltFmt) { /* must meet '%' */
846                                 --pFltFmt;
847                             }
848 
849                             fltFmtStrLen = (int)((format - pFltFmt) + 1); /* with ending terminator */
850                             if (fltFmtStrLen > SECUREC_FMT_STR_LEN) {
851                                 /* if SECUREC_FMT_STR_LEN is NOT enough, alloc a new buffer */
852                                 fltFmtHeap = (char *)SECUREC_MALLOC((size_t)((unsigned int)fltFmtStrLen));
853                                 if (fltFmtHeap == NULL) {
854                                     noOutput = 1;
855                                     break;
856                                 } else {
857                                     if (SECUREC_CHAR('%') != *pFltFmt) {
858                                         fltFmtHeap[0] = '%';
859                                         ++k;
860                                     }
861                                     for (; k < fltFmtStrLen - 1; ++k) {
862                                         /* convert wchar to char */
863                                         fltFmtHeap[k] = (char)(pFltFmt[k]); /* copy the format string */
864                                     }
865                                     fltFmtHeap[k] = '\0';
866 
867                                     fltFmtStr = fltFmtHeap;
868                                 }
869                             } else {
870                                 if (SECUREC_CHAR('%') != *pFltFmt) {
871                                     fltFmtBuf[0] = '%';
872                                     ++k;
873                                 }
874                                 /* purpose of the repeat code is to solve the tool alarm  Redundant_Null_Check */
875                                 for (; k < fltFmtStrLen - 1; ++k) {
876                                     /* convert wchar to char */
877                                     fltFmtBuf[k] = (char)(pFltFmt[k]); /* copy the format string */
878                                 }
879                                 fltFmtBuf[k] = '\0';
880                             }
881 
882 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
883                             if (formatAttr.flags & SECUREC_FLAG_LONG_DOUBLE) {
884                                 long double tmp = (long double)va_arg(arglist, long double);
885                                 /* call system sprintf to format float value */
886                                 if (formatAttr.dynWidth && formatAttr.dynPrecision) {
887                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr,
888                                         formatAttr.fldWidth, formatAttr.precision, tmp);
889                                 } else if (formatAttr.dynWidth) {
890                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr,
891                                         formatAttr.fldWidth, tmp);
892                                 } else if (formatAttr.dynPrecision) {
893                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr,
894                                         formatAttr.precision, tmp);
895                                 } else {
896                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr, tmp);
897                                 }
898                             } else
899 #endif
900                             {
901                                 double tmp = (double)va_arg(arglist, double);
902                                 if (formatAttr.dynWidth && formatAttr.dynPrecision) {
903                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr,
904                                         formatAttr.fldWidth, formatAttr.precision, tmp);
905                                 } else if (formatAttr.dynWidth) {
906                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr,
907                                         formatAttr.fldWidth, tmp);
908                                 } else if (formatAttr.dynPrecision) {
909                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr,
910                                         formatAttr.precision, tmp);
911                                 } else {
912                                     textLen = sprintf_s(formatBuf.str, SECUREC_BUFFER_SIZE + 1, (char *)fltFmtStr, tmp);
913                                 }
914                             }
915 
916                             if (fltFmtHeap != NULL) {
917                                 /* if buffer is alloced on heap, free it */
918                                 SECUREC_FREE(fltFmtHeap);
919                                 fltFmtHeap = NULL;
920                             }
921                             if (textLen < 0) {
922                                 /* bufferSize is large enough,just validation the return value */
923                                 noOutput = 1;
924                                 break;
925                             }
926 
927                             formatAttr.fldWidth =
928                                 textLen;          /* no padding ,this variable to calculate amount of padding */
929                             prefixLen = 0;        /* no padding ,this variable to  calculate amount of padding */
930                             formatAttr.flags = 0; /* clear all internal formatAttr.flags */
931                             break;
932                         }
933                     }
934 
935                     case SECUREC_CHAR('p'):
936                         /* print a pointer */
937 #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
938                         formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
939 #else
940                         formatAttr.flags |= SECUREC_FLAG_POINTER;
941 #endif
942 
943 #ifdef SECUREC_ON_64BITS
944                         formatAttr.flags |= SECUREC_FLAG_I64; /* converting an int64 */
945 #else
946                         formatAttr.flags |= SECUREC_FLAG_LONG; /* converting a long */
947 #endif
948 
949 #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM)) && (!defined(SECUREC_ON_UNIX))
950 
951 #if defined(SECUREC_VXWORKS_PLATFORM)
952                         formatAttr.precision = 1;
953 #else
954                         formatAttr.precision = 0;
955 #endif
956                         formatAttr.flags |= SECUREC_FLAG_ALTERNATE; /* "0x" is not default prefix in UNIX */
957                         digits = itoaLowerDigits;
958                         goto OUTPUT_HEX;
959 #else
960                                                                /* not linux vxwoks */
961 #if defined(_AIX) || defined(SECUREC_ON_SOLARIS)
962                         formatAttr.precision = 1;
963 #else
964                         formatAttr.precision = 2 * sizeof(void *);
965 #endif
966 
967 #endif
968 
969 #if defined(SECUREC_ON_UNIX)
970                         digits = itoaLowerDigits;
971                         goto OUTPUT_HEX;
972 #endif
973 
974                         /* fall-through */
975                         /* FALLTHRU */
976                     case SECUREC_CHAR('X'):
977                         /* unsigned upper hex output */
978                         digits = itoaUpperDigits;
979                         goto OUTPUT_HEX;
980 
981                     case SECUREC_CHAR('x'):
982                         /* unsigned lower hex output */
983                         digits = itoaLowerDigits;
984 
985                     OUTPUT_HEX:
986                         radix = 16;
987                         if (formatAttr.flags & SECUREC_FLAG_ALTERNATE) {
988                             /* alternate form means '0x' prefix */
989                             prefix[0] = SECUREC_CHAR('0');
990                             prefix[1] = (SecChar)(digits[16]); /* 'x' or 'X' */
991 
992 #if (defined(SECUREC_COMPATIBLE_LINUX_FORMAT) || defined(SECUREC_VXWORKS_PLATFORM))
993                             if (ch == 'p') {
994                                 prefix[1] = SECUREC_CHAR('x');
995                             }
996 #endif
997 #if defined(_AIX) || defined(SECUREC_ON_SOLARIS)
998                             if (ch == 'p') {
999                                 prefixLen = 0;
1000                             } else {
1001                                 prefixLen = 2;
1002                             }
1003 #else
1004                             prefixLen = 2;
1005 #endif
1006                         }
1007                         goto OUTPUT_INT;
1008                     case SECUREC_CHAR('i'): /* fall-through */ /* FALLTHRU */
1009                     case SECUREC_CHAR('d'): /* fall-through */ /* FALLTHRU */
1010                         /* signed decimal output */
1011                         formatAttr.flags |= SECUREC_FLAG_SIGNED;
1012                         /* fall-through */
1013                         /* FALLTHRU */
1014                     case SECUREC_CHAR('u'):
1015                         radix = 10;
1016                         goto OUTPUT_INT;
1017                     case SECUREC_CHAR('o'):
1018                         /* unsigned octal output */
1019                         radix = 8;
1020                         if (formatAttr.flags & SECUREC_FLAG_ALTERNATE) {
1021                             /* alternate form means force a leading 0 */
1022                             formatAttr.flags |= SECUREC_FLAG_FORCE_OCTAL;
1023                         }
1024                     OUTPUT_INT : {
1025                         SecUnsignedInt64 number = 0; /* number to convert */
1026                         SecInt64 l;                  /* temp long value */
1027                         unsigned char tch;
1028 #if defined(SECUREC_VXWORKS_VERSION_5_4) && !defined(SECUREC_ON_64BITS)
1029                         SecUnsignedInt32 digit = 0; /* ascii value of digit */
1030                         SecUnsignedInt32 quotientHigh = 0;
1031                         SecUnsignedInt32 quotientLow = 0;
1032 #endif
1033 
1034                         /* read argument into variable l */
1035                         if (formatAttr.flags & SECUREC_FLAG_I64) {
1036                             l = (SecInt64)va_arg(arglist, SecInt64);
1037                         } else if (formatAttr.flags & SECUREC_FLAG_LONGLONG) {
1038                             l = (SecInt64)va_arg(arglist, SecInt64);
1039                         } else
1040 #ifdef SECUREC_ON_64BITS
1041                             if (formatAttr.flags & SECUREC_FLAG_LONG) {
1042                             l = (long)va_arg(arglist, long);
1043                         } else
1044 #endif /* SECUREC_ON_64BITS */
1045                             if (formatAttr.flags & SECUREC_FLAG_CHAR) {
1046                             if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
1047                                 l = (char)va_arg(arglist, int); /* sign extend */
1048                                 if (l >= 128) {                 /* on some platform, char is always unsigned */
1049                                     SecUnsignedInt64 tmpL = (SecUnsignedInt64)l;
1050                                     formatAttr.flags |= SECUREC_FLAG_NEGATIVE;
1051                                     tch = (unsigned char)(~(tmpL));
1052                                     l = tch + 1;
1053                                 }
1054                             } else {
1055                                 l = (unsigned char)va_arg(arglist, int); /* zero-extend */
1056                             }
1057                         } else if (formatAttr.flags & SECUREC_FLAG_SHORT) {
1058                             if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
1059                                 l = (short)va_arg(arglist, int); /* sign extend */
1060                             } else {
1061                                 l = (unsigned short)va_arg(arglist, int); /* zero-extend */
1062                             }
1063                         }
1064 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
1065                         else if (formatAttr.flags & SECUREC_FLAG_PTRDIFF) {
1066                             l = (ptrdiff_t)va_arg(arglist, ptrdiff_t); /* sign extend */
1067                         } else if (formatAttr.flags & SECUREC_FLAG_SIZE) {
1068                             if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
1069                                 /* No suitable macros were found to handle the branch */
1070                                 if (SecIsSameSize(sizeof(size_t), sizeof(long))) {
1071                                     l = va_arg(arglist, long); /* sign extend */
1072                                 } else if (SecIsSameSize(sizeof(size_t), sizeof(long long))) {
1073                                     l = va_arg(arglist, long long); /* sign extend */
1074                                 } else {
1075                                     l = va_arg(arglist, int); /* sign extend */
1076                                 }
1077                             } else {
1078                                 l = (SecInt64)(size_t)va_arg(arglist, size_t); /* sign extend */
1079                             }
1080                         } else if (formatAttr.flags & SECUREC_FLAG_INTMAX) {
1081                             if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
1082                                 l = va_arg(arglist, SecInt64); /* sign extend */
1083                             } else {
1084                                 l = (SecInt64)(SecUnsignedInt64)va_arg(arglist, SecUnsignedInt64); /* sign extend */
1085                             }
1086                         }
1087 #endif
1088                         else {
1089                             if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
1090                                 l = va_arg(arglist, int); /* sign extend */
1091                             } else {
1092                                 l = (unsigned int)va_arg(arglist, int); /* zero-extend */
1093                             }
1094                         }
1095 
1096                         /* check for negative; copy into number */
1097                         if ((formatAttr.flags & SECUREC_FLAG_SIGNED) && l < 0) {
1098                             number = (SecUnsignedInt64)(-l);
1099                             formatAttr.flags |= SECUREC_FLAG_NEGATIVE;
1100                         } else {
1101                             number = (SecUnsignedInt64)l;
1102                         }
1103 
1104                         if (((formatAttr.flags & SECUREC_FLAG_I64) == 0) &&
1105 #ifdef SECUREC_COMPATIBLE_LINUX_FORMAT
1106                             ((formatAttr.flags & SECUREC_FLAG_INTMAX) == 0) &&
1107 #endif
1108 #ifdef SECUREC_ON_64BITS
1109                             ((formatAttr.flags & SECUREC_FLAG_PTRDIFF) == 0) &&
1110                             ((formatAttr.flags & SECUREC_FLAG_SIZE) == 0) &&
1111 #if !defined(SECUREC_COMPATIBLE_WIN_FORMAT) /* on window 64 system sizeof long is 32bit */
1112                             ((formatAttr.flags & SECUREC_FLAG_LONG) == 0) &&
1113 #endif
1114 #endif
1115                             ((formatAttr.flags & SECUREC_FLAG_LONGLONG) == 0)) {
1116 
1117                             number &= 0xffffffff;
1118                         }
1119 
1120                         /* check precision value for default */
1121                         if (formatAttr.precision < 0) {
1122                             formatAttr.precision = 1; /* default precision */
1123                         } else {
1124 #if defined(SECUREC_COMPATIBLE_WIN_FORMAT)
1125                             formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
1126 #else
1127                             if (!(formatAttr.flags & SECUREC_FLAG_POINTER)) {
1128                                 formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
1129                             }
1130 #endif
1131                             if (formatAttr.precision > SECUREC_MAX_PRECISION) {
1132                                 formatAttr.precision = SECUREC_MAX_PRECISION;
1133                             }
1134                         }
1135 
1136                         /* Check if data is 0; if so, turn off hex prefix,if 'p',add 0x prefix,else not add prefix */
1137                         if (number == 0) {
1138 #if !(defined(SECUREC_VXWORKS_PLATFORM) || defined(__hpux))
1139                             prefixLen = 0;
1140 #else
1141                             if ((ch == 'p') && (formatAttr.flags & SECUREC_FLAG_ALTERNATE))
1142                                 prefixLen = 2;
1143                             else
1144                                 prefixLen = 0;
1145 #endif
1146                         }
1147 
1148                         /* Convert data to ASCII */
1149                         formatBuf.str = &buffer.str[SECUREC_BUFFER_SIZE];
1150 
1151                         if (number > 0) {
1152 #ifdef SECUREC_ON_64BITS
1153                             switch (radix) {
1154                                 /* the compiler will optimize each one */
1155                                 SECUREC_SPECIAL(number, 10);
1156                                 break;
1157                                 SECUREC_SPECIAL(number, 16);
1158                                 break;
1159                                 SECUREC_SPECIAL(number, 8);
1160                                 break;
1161                                 default:
1162                                     break;
1163                             }
1164 #else /* for 32 bits system */
1165                             if (number <= 0xFFFFFFFFUL) {
1166                                 /* in most case, the value to be converted is small value */
1167                                 SecUnsignedInt32 n32Tmp = (SecUnsignedInt32)number;
1168                                 switch (radix) {
1169                                     SECUREC_SPECIAL(n32Tmp, 16);
1170                                     break;
1171                                     SECUREC_SPECIAL(n32Tmp, 8);
1172                                     break;
1173 
1174 #ifdef _AIX
1175                                     /* the compiler will optimize div 10 */
1176                                     SECUREC_SPECIAL(n32Tmp, 10);
1177                                     break;
1178 #else
1179                                     case 10: {
1180                                         /* fast div 10 */
1181                                         SecUnsignedInt32 q;
1182                                         SecUnsignedInt32 r;
1183                                         do {
1184                                             *--formatBuf.str = digits[n32Tmp % 10];
1185                                             q = (n32Tmp >> 1) + (n32Tmp >> 2);
1186                                             q = q + (q >> 4);
1187                                             q = q + (q >> 8);
1188                                             q = q + (q >> 16);
1189                                             q = q >> 3;
1190                                             r = n32Tmp - (((q << 2) + q) << 1);
1191                                             n32Tmp = (r > 9) ? (q + 1) : q;
1192                                         } while (n32Tmp != 0);
1193                                     } break;
1194 #endif
1195                                     default:
1196                                         break;
1197                                 } /* end switch */
1198                             } else {
1199                                 /* the value to be converted is greater than 4G */
1200 #if defined(SECUREC_VXWORKS_VERSION_5_4)
1201                                 do {
1202                                     if (0 != SecU64Div32((SecUnsignedInt32)((number >> 16) >> 16),
1203                                         (SecUnsignedInt32)number, (SecUnsignedInt32)radix, &quotientHigh, &quotientLow,
1204                                         &digit)) {
1205                                         noOutput = 1;
1206                                         break;
1207                                     }
1208                                     *--formatBuf.str = digits[digit];
1209 
1210                                     number = (SecUnsignedInt64)quotientHigh;
1211                                     number = (number << 32) + quotientLow;
1212                                 } while (number != 0);
1213 #else
1214                                 switch (radix) {
1215                                     /* the compiler will optimize div 10 */
1216                                     SECUREC_SPECIAL(number, 10);
1217                                     break;
1218                                     SECUREC_SPECIAL(number, 16);
1219                                     break;
1220                                     SECUREC_SPECIAL(number, 8);
1221                                     break;
1222                                     default:
1223                                         break;
1224                                 }
1225 #endif
1226                             }
1227 #endif
1228                         } /* END if (number > 0) */
1229                         /* compute length of number,.if textLen > 0, then formatBuf.str must be in buffer.str */
1230                         textLen = (int)((char *)&buffer.str[SECUREC_BUFFER_SIZE] - formatBuf.str);
1231                         if (formatAttr.precision > textLen) {
1232                             for (ii = 0; ii < formatAttr.precision - textLen; ++ii) {
1233                                 *--formatBuf.str = '0';
1234                             }
1235                             textLen = formatAttr.precision;
1236                         }
1237 
1238                         /* Force a leading zero if FORCEOCTAL flag set */
1239                         if ((formatAttr.flags & SECUREC_FLAG_FORCE_OCTAL) &&
1240                             (textLen == 0 || formatBuf.str[0] != '0')) {
1241                             *--formatBuf.str = '0';
1242                             ++textLen; /* add a zero */
1243                         }
1244                     } break;
1245                     default:
1246                         break;
1247                 }
1248 
1249                 if (noOutput == 0) {
1250                     if (formatAttr.flags & SECUREC_FLAG_SIGNED) {
1251                         if (formatAttr.flags & SECUREC_FLAG_NEGATIVE) {
1252                             /* prefix is a '-' */
1253                             prefix[0] = SECUREC_CHAR('-');
1254                             prefixLen = 1;
1255                         } else if (formatAttr.flags & SECUREC_FLAG_SIGN) {
1256                             /* prefix is '+' */
1257                             prefix[0] = SECUREC_CHAR('+');
1258                             prefixLen = 1;
1259                         } else if (formatAttr.flags & SECUREC_FLAG_SIGN_SPACE) {
1260                             /* prefix is ' ' */
1261                             prefix[0] = SECUREC_CHAR(' ');
1262                             prefixLen = 1;
1263                         }
1264                     }
1265 
1266 #if defined(SECUREC_COMPATIBLE_LINUX_FORMAT) && (!defined(SECUREC_ON_UNIX))
1267                     if ((formatAttr.flags & SECUREC_FLAG_POINTER) && (0 == textLen)) {
1268                         formatAttr.flags &= ~SECUREC_FLAG_LEADZERO;
1269                         formatBuf.str = &buffer.str[SECUREC_BUFFER_SIZE - 1];
1270                         *formatBuf.str-- = '\0';
1271                         *formatBuf.str-- = ')';
1272                         *formatBuf.str-- = 'l';
1273                         *formatBuf.str-- = 'i';
1274                         *formatBuf.str-- = 'n';
1275                         *formatBuf.str = '(';
1276                         textLen = 5;
1277                     }
1278 #endif
1279 
1280                     /* calculate amount of padding */
1281                     padding = (formatAttr.fldWidth - textLen) - prefixLen;
1282 
1283                     /* put out the padding, prefix, and text, in the correct order */
1284 
1285                     if (!(formatAttr.flags & (SECUREC_FLAG_LEFT | SECUREC_FLAG_LEADZERO)) && padding > 0) {
1286                         /* pad on left with blanks */
1287                         if (SECUREC_IS_REST_BUF_ENOUGH(padding)) {
1288                             /* char * cast to wchar * */
1289                             SECUREC_SAFE_PADDING(SECUREC_CHAR(' '), padding, stream, &charsOut);
1290                         } else {
1291                             SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR(' '), padding, stream, &charsOut);
1292                         }
1293                     }
1294 
1295 
1296                     /* write prefix */
1297                     if (prefixLen > 0) {
1298                         SecChar *pPrefix = prefix;
1299                         if (SECUREC_IS_REST_BUF_ENOUGH(prefixLen)) {
1300                             /* max prefix len is 2, use loop copy */ /* char * cast to wchar * */
1301                             SECUREC_SAFE_WRITE_PREFIX(pPrefix, prefixLen, stream, &charsOut);
1302                         } else {
1303                             SECUREC_WRITE_STRING(prefix, prefixLen, stream, &charsOut);
1304                         }
1305                     }
1306 
1307                     if ((formatAttr.flags & SECUREC_FLAG_LEADZERO) && !(formatAttr.flags & SECUREC_FLAG_LEFT) &&
1308                         padding > 0) {
1309                         /* write leading zeros */
1310                         if (SECUREC_IS_REST_BUF_ENOUGH(padding)) {
1311                             /* char * cast to wchar * */
1312                             SECUREC_SAFE_PADDING(SECUREC_CHAR('0'), padding, stream, &charsOut);
1313                         } else {
1314                             SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR('0'), padding, stream, &charsOut);
1315                         }
1316                     }
1317 
1318                     /* write text */
1319 #ifndef SECUREC_FOR_WCHAR
1320                     if (!isDebugMode && isPrivacy) {
1321                         if (formatAttr.bufferIsWide) {
1322                             formatBuf.wStr = WPRIVACY_STRING;
1323                             textLen = sizeof(WPRIVACY_STRING) / sizeof(wchar_t) - 1;
1324                         } else {
1325                             formatBuf.str = PRIVACY_STRING;
1326                             textLen = strlen(PRIVACY_STRING);
1327                         }
1328                     }
1329                     if (formatAttr.bufferIsWide && (textLen > 0)) {
1330                         wchar_t *p = formatBuf.wStr;
1331                         int count = textLen;
1332                         while (count--) {
1333                             char tmpBuf[SECUREC_MB_LEN + 1];
1334                             // SECUREC_MASK_MSVC_CRT_WARNING
1335                             int retVal = wctomb(tmpBuf, *p++);
1336                             // SECUREC_END_MASK_MSVC_CRT_WARNING
1337                             if (retVal <= 0) {
1338                                 charsOut = -1;
1339                                 break;
1340                             }
1341                             SECUREC_WRITE_STRING(tmpBuf, retVal, stream, &charsOut);
1342                         }
1343                     } else {
1344                         if (SECUREC_IS_REST_BUF_ENOUGH(textLen)) {
1345                             SECUREC_SAFE_WRITE_STR(formatBuf.str, textLen, stream, &charsOut);
1346                         } else {
1347                             SECUREC_WRITE_STRING(formatBuf.str, textLen, stream, &charsOut);
1348                         }
1349                     }
1350 #else /* SECUREC_FOR_WCHAR */
1351                     if (formatAttr.bufferIsWide == 0 && textLen > 0) {
1352                         int count = textLen;
1353                         char *p = formatBuf.str;
1354 
1355                         while (count > 0) {
1356                             wchar_t wchar = L'\0';
1357                             int retVal = mbtowc(&wchar, p, (size_t)MB_CUR_MAX);
1358                             if (retVal <= 0) {
1359                                 charsOut = -1;
1360                                 break;
1361                             }
1362                             SECUREC_WRITE_CHAR(wchar, stream, &charsOut);
1363                             p += retVal;
1364                             count -= retVal;
1365                         }
1366                     } else {
1367                         if (SECUREC_IS_REST_BUF_ENOUGH(textLen)) {
1368                             SECUREC_SAFE_WRITE_STR(formatBuf.wStr, textLen, stream,
1369                                 &charsOut); /* char * cast to wchar * */
1370                         } else {
1371                             SECUREC_WRITE_STRING(formatBuf.wStr, textLen, stream, &charsOut);
1372                         }
1373                     }
1374 #endif /* SECUREC_FOR_WCHAR */
1375 
1376                     if (charsOut >= 0 && (formatAttr.flags & SECUREC_FLAG_LEFT) && padding > 0) {
1377                         /* pad on right with blanks */
1378                         if (SECUREC_IS_REST_BUF_ENOUGH(padding)) {
1379                             /* char * cast to wchar * */
1380                             SECUREC_SAFE_PADDING(SECUREC_CHAR(' '), padding, stream, &charsOut);
1381                         } else {
1382                             SECUREC_WRITE_MULTI_CHAR(SECUREC_CHAR(' '), padding, stream, &charsOut);
1383                         }
1384                     }
1385 
1386                     /* we're done! */
1387                 }
1388                 if (floatBuf != NULL) {
1389                     SECUREC_FREE(floatBuf);
1390                     floatBuf = NULL;
1391                 }
1392                 break;
1393             case STAT_INVALID:
1394                 return -1;
1395             default:
1396                 return -1; /* input format is wrong, directly return */
1397         }
1398     }
1399 
1400     if (state != STAT_NORMAL && state != STAT_TYPE) {
1401         return -1;
1402     }
1403 
1404     return charsOut; /* the number of characters written */
1405 } /* arglist must not be declare as const */
1406 
1407 
HiLogSecVsnprintfImpl(char * string,size_t count,bool isDebugMode,const char * format,va_list arglist)1408 int HiLogSecVsnprintfImpl(char *string, size_t count, bool isDebugMode, const char *format, va_list arglist)
1409 {
1410     SecPrintfStream str;
1411     int retVal;
1412 
1413     str.count = (int)count; /* this count include \0 character */
1414     str.cur = string;
1415 
1416     retVal = HiLogSecOutputS(&str, isDebugMode, format, arglist);
1417     if ((retVal >= 0) && (SECUREC_PUTC_ZERO(&str) != EOF)) {
1418         return (retVal);
1419     } else if (str.count < 0) {
1420         /* the buffer was too small; we return truncation */
1421         string[count - 1] = 0;
1422         return SECUREC_PRINTF_TRUNCATE;
1423     }
1424 
1425     return -1;
1426 }
1427 
1428 
HiLog_Printf(char * strDest,size_t destMax,size_t count,bool isDebugMode,const char * format,va_list arglist)1429 int HiLog_Printf(char *strDest, size_t destMax, size_t count, bool isDebugMode, const char *format, va_list arglist)
1430 {
1431     int retVal;
1432 
1433     if (format == NULL || strDest == NULL || destMax == 0 || destMax > SECUREC_STRING_MAX_LEN ||
1434         (count > (SECUREC_STRING_MAX_LEN - 1) && count != (size_t)-1)) {
1435         if (strDest != NULL && destMax > 0) {
1436             strDest[0] = '\0';
1437         }
1438         SECUREC_ERROR_INVALID_PARAMTER("hilog_printf");
1439         return -1;
1440     }
1441 
1442     if (destMax > count) {
1443         retVal = HiLogSecVsnprintfImpl(strDest, count + 1, isDebugMode, format, arglist);
1444         if (retVal == SECUREC_PRINTF_TRUNCATE) { /* lsd add to keep dest buffer not destroyed 2014.2.18 */
1445             /* the string has been truncated, return  -1 */
1446             return -1; /* to skip error handler,  return strlen(strDest) or -1 */
1447         }
1448     } else { /* destMax <= count */
1449         retVal = HiLogSecVsnprintfImpl(strDest, destMax, isDebugMode, format, arglist);
1450 #ifdef SECUREC_COMPATIBLE_WIN_FORMAT
1451         if (retVal == SECUREC_PRINTF_TRUNCATE && count == (size_t)-1) {
1452             return -1;
1453         }
1454 #endif
1455     }
1456 
1457     if (retVal < 0) {
1458         strDest[0] = '\0'; /* empty the dest strDest */
1459 
1460         if (retVal == SECUREC_PRINTF_TRUNCATE) {
1461             /* Buffer too small */
1462             SECUREC_ERROR_INVALID_RANGE("hilog_printf");
1463         }
1464 
1465         SECUREC_ERROR_INVALID_PARAMTER("hilog_printf");
1466         return -1;
1467     }
1468 
1469     return retVal;
1470 }
1471 
1472 #define HILOG_DRIVER "/dev/hilog"
1473 static char g_logLevelInfo[HILOG_LEVEL_MAX] = {
1474     'N', // "NONE"
1475     'N', // "NONE"
1476     'N', // "NONE"
1477     'D', // "DEBUG"
1478     'I', // "INFO"
1479     'W', // "WARN"
1480     'E', // "ERROR"
1481     'F'  // "FATAL"
1482 };
1483 
1484 #ifdef LOSCFG_BASE_CORE_HILOG
1485 extern int HiLogWriteInternal(const char *buffer, size_t bufLen);
1486 #else
1487 static int g_hilogFd = -1;
1488 #endif
1489 
HiLogPrintArgs(LogType bufID,LogLevel prio,unsigned int domain,const char * tag,const char * fmt,va_list ap)1490 int HiLogPrintArgs(LogType bufID, LogLevel prio, unsigned int domain, const char *tag, const char *fmt, va_list ap)
1491 {
1492     int ret;
1493     char buf[LOG_BUF_SIZE] = {0};
1494     bool isDebugMode = 1;
1495     unsigned int bufLen;
1496     (void)bufID;
1497 
1498 #ifdef OHOS_RELEASE
1499     isDebugMode = 0;
1500 #endif
1501 #ifdef DISABLE_HILOG_PRIVACY
1502     isDebugMode = 1;
1503 #endif
1504     if (snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "%c %05X/%s: ", g_logLevelInfo[prio], (domain & DOMAIN_FILTER),
1505         tag) == -1) {
1506         return 0;
1507     }
1508 
1509     bufLen = strlen(buf);
1510     if (bufLen >= MAX_DOMAIN_TAG_SIZE) {
1511         return 0;
1512     }
1513 
1514 #ifndef LOSCFG_BASE_CORE_HILOG
1515     /* print traceid */
1516     if (g_registerFunc != NULL) {
1517         char *logBuf = buf;
1518         int traceBufLen = 0;
1519         uint64_t chainId = 0;
1520         uint32_t flag = 0;
1521         uint64_t spanId = 0;
1522         uint64_t parentSpanId = 0;
1523         ret = -1;  /* default value -1: invalid trace id */
1524         atomic_fetch_add_explicit(&g_hiLogGetIdCallCount, 1, memory_order_relaxed);
1525         RegisterFunc func = g_registerFunc;
1526         if (g_registerFunc != NULL) {
1527             ret = func(&chainId, &flag, &spanId, &parentSpanId);
1528         }
1529         atomic_fetch_sub_explicit(&g_hiLogGetIdCallCount, 1, memory_order_relaxed);
1530         if (ret == 0) {  /* 0: trace id with span id */
1531             traceBufLen = snprintf_s(logBuf, LOG_BUF_SIZE, LOG_BUF_SIZE - 1, "[%llx, %llx, %llx] ",
1532                 (unsigned long long)chainId, (unsigned long long)spanId, (unsigned long long)parentSpanId);
1533         } else if (ret != -1) {  /* trace id without span id, -1: invalid trace id */
1534             traceBufLen = snprintf_s(logBuf, LOG_BUF_SIZE, LOG_BUF_SIZE - 1, "[%llx] ",
1535                 (unsigned long long)chainId);
1536         }
1537         if (traceBufLen > 0) {
1538             logBuf += traceBufLen;
1539         } else {
1540             traceBufLen = 0;
1541         }
1542     }
1543 #endif
1544 
1545     HiLog_Printf(buf + bufLen, LOG_BUF_SIZE - bufLen, LOG_BUF_SIZE - bufLen - 1, isDebugMode, fmt, ap);
1546 
1547 #ifdef LOSCFG_BASE_CORE_HILOG
1548     ret = HiLogWriteInternal(buf, strlen(buf) + 1);
1549 #else
1550     if (g_hilogFd == -1) {
1551         g_hilogFd = open(HILOG_DRIVER, O_WRONLY | O_CLOEXEC);
1552     }
1553     if (g_hilogFd == -1) {
1554         return 0;
1555     }
1556     ret = write(g_hilogFd, buf, strlen(buf) + 1);
1557 #endif
1558     return ret;
1559 }
1560 
HiLogPrint(LogType bufID,LogLevel prio,unsigned int domain,const char * tag,const char * fmt,...)1561 int HiLogPrint(LogType bufID, LogLevel prio, unsigned int domain, const char *tag, const char *fmt, ...)
1562 {
1563     int ret;
1564     va_list ap;
1565     va_start(ap, fmt);
1566     ret = HiLogPrintArgs(bufID, prio, domain, tag, fmt, ap);
1567     va_end(ap);
1568     return ret;
1569 }
1570 
FlushHilog(void)1571 int FlushHilog(void)
1572 {
1573     int ret;
1574 #define FLUSH_LOG_WRITE_LEN 3
1575     char buf[FLUSH_LOG_WRITE_LEN] = {0x07, 0x07, '\0'};
1576 #ifdef LOSCFG_BASE_CORE_HILOG
1577     ret = HiLogWriteInternal(buf, strlen(buf) + 1);
1578 #else
1579     if (g_hilogFd == -1) {
1580         g_hilogFd = open(HILOG_DRIVER, O_WRONLY);
1581     }
1582     if (g_hilogFd == -1) {
1583         return 0;
1584     }
1585     ret = write(g_hilogFd, buf, strlen(buf) + 1);
1586 #endif
1587     return ret;
1588 }
1589