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