tizen 2.3 release tizen_2.3 submit/tizen_2.3/20150202.063743 tizen_2.3_release
authorjk7744.park <jk7744.park@samsung.com>
Sun, 1 Feb 2015 04:52:01 +0000 (13:52 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Sun, 1 Feb 2015 04:52:01 +0000 (13:52 +0900)
22 files changed:
AUTHORS [deleted file]
Makefile.am
TC/unit/Makefile
TC/unit/tslist
TC/unit/utc_ApplicationFW_dlog_print_func.c [new file with mode: 0644]
TC/unit/utc_ApplicationFW_dlog_vprint_func.c [new file with mode: 0644]
configure.ac
dlog.pc.in
doc/dlog_doc.h [new file with mode: 0755]
include/SLP_Dlog_PG.h [deleted file]
include/dlog.h
include/logprint.h
packaging/dlog.spec
packaging/dlog_logger.conf-micro-debug.in [new file with mode: 0644]
packaging/dlog_logger.conf-micro.in
packaging/dlog_logger.conf.in
packaging/dlog_logger.service
src/libdlog/log.c
src/libdlog/loglimiter.c
src/logger/logger.c
src/logutil/logutil.c
src/shared/logprint.c

diff --git a/AUTHORS b/AUTHORS
deleted file mode 100755 (executable)
index 2190840..0000000
--- a/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-juho son <juho80.son at samsung dot com>
-Suchang Woo <suchang.woo at samsung dot com>
-kyungmin Park <kyungmin Park at samsung dot com>
index a822503..e057c51 100755 (executable)
@@ -1,4 +1,7 @@
-AM_CFLAGS = -I$(srcdir)/include $(DEBUG_CFLAGS) -Werror
+AM_CFLAGS = -I$(srcdir)/include \
+       $(DEBUG_CFLAGS) \
+       -Werror \
+       $(CAPI_BASE_COMMON_CFLAGS)
 
 dlog_includedir = $(includedir)/dlog
 dlog_include_HEADERS = \
@@ -14,7 +17,9 @@ libdlog_la_SOURCES =  \
        src/libdlog/loglimiter.c \
        include/loglimiter.h
 
-libdlog_la_LIBADD = -lpthread $(systemd_journal_LIBS)
+libdlog_la_LIBADD = -lpthread \
+       $(systemd_journal_LIBS) \
+       $(CAPI_BASE_COMMON_LIBS)
 
 bin_PROGRAMS = dlogutil dlog_logger
 
index 7be4c17..276344d 100644 (file)
@@ -1,7 +1,9 @@
 CC ?= gcc
 
 TARGETS =  utc_ApplicationFW___dlog_print_func \
-         utc_ApplicationFW___dlog_vprint_func
+         utc_ApplicationFW___dlog_vprint_func \
+         utc_ApplicationFW_dlog_print_func \
+         utc_ApplicationFW_dlog_vprint_func
 
 PKGS = dlog
 
index 0d9e63d..9345449 100644 (file)
@@ -1,2 +1,4 @@
+/unit/utc_ApplicationFW_dlog_print_func
+/unit/utc_ApplicationFW_dlog_vprint_func
 /unit/utc_ApplicationFW___dlog_print_func
 /unit/utc_ApplicationFW___dlog_vprint_func
diff --git a/TC/unit/utc_ApplicationFW_dlog_print_func.c b/TC/unit/utc_ApplicationFW_dlog_print_func.c
new file mode 100644 (file)
index 0000000..517edc4
--- /dev/null
@@ -0,0 +1,66 @@
+#include <tet_api.h>
+#include "dlog.h"
+#define LOG_BUF_SIZE 1024
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+static void utc_ApplicationFW_dlog_print_func_01(void);
+static void utc_ApplicationFW_dlog_print_func_02(void);
+
+enum {
+       POSITIVE_TC_IDX = 0x01,
+       NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+       { utc_ApplicationFW_dlog_print_func_01, POSITIVE_TC_IDX },
+       { utc_ApplicationFW_dlog_print_func_02, NEGATIVE_TC_IDX },
+       { NULL, 0 }
+};
+
+//static int pid;
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+
+/**
+ * @brief Positive test case of dlog_print()
+ */
+static void utc_ApplicationFW_dlog_print_func_01(void)
+{
+       int r = 0;
+
+       r = dlog_print(DLOG_DEBUG, "DLOG_TEST", "dlog test message for tetware\n");
+
+       if (r<0) {
+               tet_printf("dlog_print() failed in positive test case");
+               tet_result(TET_FAIL);
+               return;
+       }
+       tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of ug_init dlog_print()
+ */
+static void utc_ApplicationFW_dlog_print_func_02(void)
+{
+       int r = 0;
+
+       r = dlog_print(DLOG_UNKNOWN, "DLOG_TEST", "dlog test message for tetware\n");
+
+       if (r>=0) {
+               tet_printf("dlog_print() failed in negative test case");
+               tet_result(TET_FAIL);
+               return;
+       }
+       tet_result(TET_PASS);
+}
diff --git a/TC/unit/utc_ApplicationFW_dlog_vprint_func.c b/TC/unit/utc_ApplicationFW_dlog_vprint_func.c
new file mode 100644 (file)
index 0000000..eb736a2
--- /dev/null
@@ -0,0 +1,76 @@
+#include <stdarg.h>
+#include <tet_api.h>
+#include "dlog.h"
+#define LOG_BUF_SIZE 1024
+static void startup(void);
+static void cleanup(void);
+
+void (*tet_startup)(void) = startup;
+void (*tet_cleanup)(void) = cleanup;
+
+static void utc_ApplicationFW_dlog_vprint_func_01(void);
+static void utc_ApplicationFW_dlog_vprint_func_02(void);
+
+enum {
+       POSITIVE_TC_IDX = 0x01,
+       NEGATIVE_TC_IDX,
+};
+
+struct tet_testlist tet_testlist[] = {
+       { utc_ApplicationFW_dlog_vprint_func_01, POSITIVE_TC_IDX },
+       { utc_ApplicationFW_dlog_vprint_func_02, NEGATIVE_TC_IDX },
+       { NULL, 0 }
+};
+
+static int pid;
+char *fmt = "dlog test message for tetware\n";
+
+static void startup(void)
+{
+}
+
+static void cleanup(void)
+{
+}
+/**
+ * @brief Positive test case of dlog_vprint()
+ */
+void utc_ApplicationFW_dlog_vprint_func_01(void)
+{
+       int r = 0;
+       char buf[LOG_BUF_SIZE];
+       va_list ap;
+
+       /*      va_start(ap, fmt);*/
+
+       r = dlog_vprint(DLOG_DEBUG, "DLOG_TEST", buf, ap );
+       /*      va_end(ap);*/
+
+       if (r<0) {
+               tet_printf("dlog_vprint() failed in positive test case");
+               tet_result(TET_FAIL);
+               return;
+       }
+       tet_result(TET_PASS);
+}
+
+/**
+ * @brief Negative test case of ug_init dlog_vprint()
+ */
+void utc_ApplicationFW_dlog_vprint_func_02(void)
+{
+       int r = 0;
+       char buf[LOG_BUF_SIZE];
+       va_list ap;
+//     va_start(ap, fmt);
+
+       r = dlog_vprint(DLOG_UNKNOWN, "DLOG_TEST", fmt, ap );
+//     va_end(ap);
+
+       if (r>=0) {
+               tet_printf("dlog_vprint() failed in negative test case");
+               tet_result(TET_FAIL);
+               return;
+       }
+       tet_result(TET_PASS);
+}
index a5f2a1e..cbd9996 100755 (executable)
@@ -81,6 +81,9 @@ AC_FUNC_MALLOC
 AC_FUNC_STAT
 AC_CHECK_FUNCS([memset])
 
+PKG_PROG_PKG_CONFIG
+PKG_CHECK_MODULES([CAPI_BASE_COMMON], [capi-base-common])
+
 # output files
 AC_CONFIG_FILES([Makefile dlog.pc])
 AC_OUTPUT
index db6484a..9d902a1 100755 (executable)
@@ -6,7 +6,7 @@ includedir=${prefix}/include
 Name: dlog
 Description: logging service
 Version: 1.0
-Requires:
+Requires: capi-base-common
 Requires(post): @systemd_journal@
-Libs: -L${libdir} -ldlog -lpthread @systemd_journal_LIBS@
+Libs: -L${libdir} -ldlog -lpthread @systemd_journal_LIBS@ @CAPI_BASE_COMMON_LIBS@
 Cflags: -I${includedir}/dlog
diff --git a/doc/dlog_doc.h b/doc/dlog_doc.h
new file mode 100755 (executable)
index 0000000..1d825b1
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TIZEN_SYSTEM_DLOG_DOC_H__
+#define __TIZEN_SYSTEM_DLOG_DOC_H__
+
+/**
+ * @defgroup CAPI_SYSTEM_DLOG dlog
+ * @brief The Dlog API provides functions for sending log output.
+ * @ingroup CAPI_SYSTEM_FRAMEWORK
+ * @section CAPI_SYSTEM_DLOG_HEADER Required Header
+ *   \#include <dlog.h>
+ *
+ * @section CAPI_SYSTEM_DLOG_OVERVIEW Overview
+ *
+Sending log message to circular buffer. dlog APIs include Priority and Tag. By using priority and Tag, we can easily filtered messages what we want to see.
+<h2 class="pg">priority</h2>
+priority level indicates the urgency of log message
+
+<table>
+<tr>
+       <th>Priority</th>
+       <th>Description</th>
+</tr>
+<tr>
+       <td>DLOG_DEBUG</td>
+       <td>Debug messasge. - Log message which developer want to check.</td>
+</tr>
+<tr>
+       <td>DLOG_INFO</td>
+       <td>Information message - Normal operational messages. above of this priority will always be logged.</td>
+</tr>
+<tr>
+       <td>DLOG_WARN</td>
+       <td>Warning messages - Not an error, but indication that an error will occur if action is not taken.</td>
+</tr>
+<tr>
+       <td>DLOG_ERROR</td>
+       <td>Error message - Indicate error.</td>
+</tr>
+</table>
+*
+**/
+#endif /* __TIZEN_SYSTEM_DLOG_DOC_H__ */
diff --git a/include/SLP_Dlog_PG.h b/include/SLP_Dlog_PG.h
deleted file mode 100755 (executable)
index a108b5f..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/**
- @ingroup      SLP_PG  
- @defgroup     SLP_PG_Dlog dlog
- @{
-
-<h1 class="pg">Introduction</h1>
-Dlog logging service support sending log message to circular log device
-       
-<h1 class="pg">dlog Architecture</h1>
-@image html SLP_Dlog_PG_image001.png System Architecture of dlog
-
-<h1 class="pg">dlog properties</h1>
-Sending log message to circular buffer. dlog APIs include Priority and Tag. By using priority and Tag, we can easily filtered messages what we want to see.
-       <h2 class="pg">priority</h2>
-priority level incdicates the urgency of log message
-
-<table>
-<tr>
-       <th>Priority</th>
-       <th>Description</th>
-</tr>
-<tr>
-       <td>VERBOSE </td>
-       <td>Verbose message. - compiled into application and logged at runtime only when debug mode. on release mode, this log message is strip.</td>
-</tr>
-<tr>
-       <td>DEBUG</td>
-       <td>Debug messasge. - always compiled into application, but not logged at runtime by default on release mode. on debug mode, this message will be logged at runtime.</td>
-</tr>
-<tr>
-       <td>INFO</td>
-       <td>Information message - Normal operational messages. above of this priority will always be logged.</td>
-</tr>
-<tr>
-       <td>WARN</td>
-       <td>Warning messages - not an error, but indication that an error will occur if action is not taken</td>
-</tr>
-<tr>
-       <td>ERROR</td>
-       <td>Error message - indicate error. </td>
-</tr>
-<tr>
-       <td>FATAL</td>
-       <td>Fatal message - Should be corrected immediately ( not used yet )</td>
-</tr>
-</table>
-
-       <h2 class="pg">Tag</h2>
-Used to identify the source of a log message. 
-There is no naming limitation, but do not forget that tag is identification of module. Tag must be distinguishable from other tag. 
-Simplified macro like LOGV, LOGD, LOGI, LOGW, LOGE uses declared LOG_TAG constant, so declare a LOG_TAG constant before you use dlog macro is a good convention.
-@code
-#define LOG_TAG "MyApp"
-@endcode
-
-<h1 class="pg">list of dlog macro</h1>
-Macro name start with LOG prefix is for application. start with SLOG prefix is for framework, start with RLOG prefix is for radio. each macro write log message to separated log device such as main, system, radio. 
-
-<h1 class="pg">sample code</h1>
-Using simplified macro with current LOG_TAG
-
-@code
-#define LOG_TAG "YOUR_APP"
-#include <dlog.h>
-
-int function () {
-       LOGD( "debug message from YOUR_APP \n");
-       LOGI( "information message from YOUR_APP \n");
-       LOGW( "warning message from YOUR_APP \n");
-       LOGE( "error message from YOUR_APP \n");
-}
-@endcode
-
-Using log macro allows you to specify a priority and a tag
-
-@code
-#include <dlog.h>
-
-#define TAG_DRM_SVC "drm_svc"
-#define TAG_DRM_WM "drm_wm"
-#define TAG_DRM_OEM "drm_oem"
-
-int function () {
-       LOG(LOG_DEBUG,TAG_DRM_SVC, "information message from drm_svc \n");
-       LOG(LOG_WARN,TAG_DRM_WM, "warning message from drm_wm \n");
-       LOG(LOG_ERROR,TAG_DRM_OEM, "error message from drm_oem \n");
-}
-@endcode
-
-Using log macro allows you to pass in a varargs
-
-@code
-#include <dlog.h>
-
-#define TAG_DRM_SVC "drm_svc"
-#define TAG_DRM_WM "drm_wm"
-#define TAG_DRM_OEM "drm_oem"
-
-int function (const char *fmt, ...) {
-       va_list ap;
-       va_start(ap, fmt);
-       LOG_VA(LOG_DEBUG,TAG_DRM_WM, fmt, args);
-       va_end(ap);
-}
-@endcode
-<h1 class="pg">dlogutil</h1>
-       <h2 class="pg">Introduction</h2>
-You can use dlogutil command to view and follow the contents of the log buffers. The general usage is :
-@code
-dlogutil [<option>] Â¡Â¦ [<filter-spec>] Â¡Â¦
-@endcode
-
-       <h2 class="pg">Filtering log output</h2>
-Every log message has a <I>tag</I> and a <I>priority</I> associated with it.
-Filter expression follows this format <B><I>tag:priority</I></B> where <I>tag</I> indicates the tag of interest and <I>priority</I> indicates the minimum level of priority to report for that tag. You can add any number of tag:priority specifications in a single filter expression. 
-The tag of a log message is a short indicating the system component from which the message originates 
-The <I>priority</I> is one of the following character values, orderd from lowest to highest priority:<br>
-V - verbose<br> 
-D - debug<br>
-I - info<br>
-W - warning<br>
-E - Error<br>
-F - Fatal<br>
-
-for example, if you want to see MyApp tag and above of debug priority, 
-@code
-# dlogutil MyApp:D
-@endcode
-if you want to see all log message above of info priority also, 
-@code
-# dlogutil MyApp:D *:E
-@endcode
-
-       <h2 class="pg">List of logutil command options</h2>
-
-<table>
-<tr>
-       <th>Option</th>
-       <th>Description</th>
-</tr>
-<tr>
-       <td>-b <buffer> </td>
-       <td>Alternate log buffer. The main buffer is used by default buffer. </td>
-</tr>
-<tr>
-       <td>-c</td>
-       <td>Clears the entire log and exits</td>
-</tr>
-<tr>
-       <td>-d</td>
-       <td>Dumps the log and exits.</td>
-</tr>
-<tr>
-       <td>-f <filename></td>
-       <td>Writes log to <filename>. The default is stdout</td>
-</tr>
-<tr>
-       <td>-g</td>
-       <td>Print the size of the specified log buffer and exits.</td>
-</tr>
-<tr>
-       <td>-n <count></td>
-       <td>Sets the maximum number of rotated logs to <count>. The default value is 4. Requires the -r option</td>
-</tr>
-<tr>
-       <td>-r <Kbytes></td>
-       <td>Rotates the log file every <Kbytes> of output. The default value is 16. Requires the -f option.</td>
-</tr>
-<tr>
-       <td>-s</td>
-       <td>Sets the default filter spec to silent.</td>
-</tr>
-<tr>
-       <td>-v <format></td>
-       <td>Sets the output format for log messages. The default is brief format. </td>
-</tr>
-
-</table>
-
-
-
-@}
-**/
index acc4656..709451a 100755 (executable)
  * @version    0.4
  * @brief      This file is the header file of interface of dlog.
  */
-/**
- * @addtogroup CAPI_BASE_DLOG_MODULE
- * @{
- *
- */
 #ifndef        _DLOG_H_
 #define        _DLOG_H_
 
+#include <tizen_error.h>
 #include <stdarg.h>
 #include <string.h>
 
@@ -55,22 +51,54 @@ extern "C" {
 #endif
 #endif
 
-/*
- * log priority values, in ascending priority order.
+/**
+ * @addtogroup CAPI_SYSTEM_DLOG
+ * @{
+ *
+ */
+/**
+ * @brief Enumeration for Dlog Error.
+ * @since_tizen 2.3
+ */
+typedef enum {
+       DLOG_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+       DLOG_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+       DLOG_ERROR_NOT_PERMITTED = TIZEN_ERROR_NOT_PERMITTED, /**< Operation not permitted */
+} dlog_error_e;
+/**
+ * @}
+ */
+
+/**
+ * @addtogroup CAPI_SYSTEM_DLOG
+ * @{
+ *
+ */
+/**
+ * @brief log priority values, in ascending priority order.
+ * @since_tizen 2.3
  */
 typedef enum {
-       DLOG_UNKNOWN = 0,
-       DLOG_DEFAULT,
-       DLOG_VERBOSE,
-       DLOG_DEBUG,
-       DLOG_INFO,
-       DLOG_WARN,
-       DLOG_ERROR,
-       DLOG_FATAL,
-       DLOG_SILENT,
-       DLOG_PRIO_MAX   /* Keep this always at the end. */
+       DLOG_UNKNOWN = 0, /**< Keep this always at the start */
+       DLOG_DEFAULT, /**< Default */
+       DLOG_VERBOSE, /**< Verbose */
+       DLOG_DEBUG, /**< Debug */
+       DLOG_INFO, /**< Info */
+       DLOG_WARN, /**< Warning */
+       DLOG_ERROR, /**< Error */
+       DLOG_FATAL, /**< Fatal */
+       DLOG_SILENT, /**< Silent */
+       DLOG_PRIO_MAX   /**< Keep this always at the end. */
 } log_priority;
+/**
+ * @}
+ */
 
+/**
+ * @internal
+ * @brief log id
+ * @since_tizen 2.3
+ */
 typedef enum {
     LOG_ID_MAIN = 0,
        LOG_ID_RADIO,
@@ -79,8 +107,10 @@ typedef enum {
        LOG_ID_MAX
 } log_id_t;
 
+static inline int __dlog_no_print(const char *fmt __attribute__((unused)), ...) { return 0; }
+
 #define CONDITION(cond)     (__builtin_expect((cond) != 0, 0))
-#define NOP(fmt, arg...) ({ do { } while (0); })
+#define NOP(...) ({ do { __dlog_no_print(__VA_ARGS__); } while (0); })
 
 // Macro inner work---------------------------------------------------------------
 #undef LOG_
@@ -109,13 +139,15 @@ typedef enum {
 #endif
 // ---------------------------------------------------------------------
 /**
- * For Secure Log.
- * Normally we strip Secure log from release builds.
+ * @internal
+ * @brief For Secure Log.
+ * @remarks Normally we strip Secure log from release builds.
  * Please use this macros.
  */
 /**
- * For Application and etc.
- * Simplified macro to send a main log message using the current LOG_TAG.
+ * @internal
+ * @brief For Application and etc.
+ * @details Simplified macro to send a main log message using the current LOG_TAG.
  * Example:
  *  SECURE_LOGD("app debug %d", num);
  *  SECURE_LOGE("app error %d", num);
@@ -126,8 +158,9 @@ typedef enum {
 #define SECURE_LOGE(format, arg...) SECURE_LOG_(LOG_ID_MAIN, DLOG_ERROR, LOG_TAG, format, ##arg)
 #define SECURE_LOGF(format, arg...) SECURE_LOG_(LOG_ID_MAIN, DLOG_FATAL, LOG_TAG, format, ##arg)
 /**
- * For Framework and system etc.
- * Simplified macro to send a system log message using the current LOG_TAG.
+ * @internal
+ * @brief For Framework and system etc.
+ * @details Simplified macro to send a system log message using the current LOG_TAG.
  * Example:
  *  SECURE_SLOGD("system debug %d", num);
  *  SECURE_SLOGE("system error %d", num);
@@ -138,8 +171,9 @@ typedef enum {
 #define SECURE_SLOGE(format, arg...) SECURE_LOG_(LOG_ID_SYSTEM, DLOG_ERROR, LOG_TAG, format, ##arg)
 #define SECURE_SLOGF(format, arg...) SECURE_LOG_(LOG_ID_SYSTEM, DLOG_FATAL, LOG_TAG, format, ##arg)
 /**
- * For Modem and radio etc.
- * Simplified macro to send a radio log message using the current LOG_TAG.
+ * @internal
+ * @brief For Modem and radio etc.
+ * @details Simplified macro to send a radio log message using the current LOG_TAG.
  * Example:
  *  SECURE_RLOGD("radio debug %d", num);
  *  SECURE_RLOGE("radio error %d", num);
@@ -150,7 +184,8 @@ typedef enum {
 #define SECURE_RLOGE(format, arg...) SECURE_LOG_(LOG_ID_RADIO, DLOG_ERROR, LOG_TAG, format, ##arg)
 #define SECURE_RLOGF(format, arg...) SECURE_LOG_(LOG_ID_RADIO, DLOG_FATAL, LOG_TAG, format, ##arg)
 /**
- * For Tizen OSP Application macro.
+ * @internal
+ * @brief For Tizen OSP Application macro.
  */
 #define SECURE_ALOGD(format, arg...) SECURE_LOG_(LOG_ID_APPS, DLOG_DEBUG, LOG_TAG, format, ##arg)
 #define SECURE_ALOGI(format, arg...) SECURE_LOG_(LOG_ID_APPS, DLOG_INFO, LOG_TAG, format, ##arg)
@@ -158,7 +193,8 @@ typedef enum {
 #define SECURE_ALOGE(format, arg...) SECURE_LOG_(LOG_ID_APPS, DLOG_ERROR, LOG_TAG, format, ##arg)
 #define SECURE_ALOGF(format, arg...) SECURE_LOG_(LOG_ID_APPS, DLOG_FATAL, LOG_TAG, format, ##arg)
 /**
- * If you want use redefined macro.
+ * @internal
+ * @details If you want use redefined macro.
  * You can use this macro.
  * This macro need priority and tag arguments.
  */
@@ -168,8 +204,9 @@ typedef enum {
 #define SECURE_ALOG(priority, tag, format, arg...) SECURE_LOG_(LOG_ID_APPS, D##priority, tag, format, ##arg)
 
 /**
- * For Application and etc.
- * Simplified macro to send a main log message using the current LOG_TAG.
+ * @internal
+ * @brief For Application and etc.
+ * @details Simplified macro to send a main log message using the current LOG_TAG.
  * Example:
  *  LOGD("app debug %d", num);
  *  LOGE("app error %d", num);
@@ -184,8 +221,9 @@ typedef enum {
 #define LOGE(format, arg...) LOG_(LOG_ID_MAIN, DLOG_ERROR, LOG_TAG, format, ##arg)
 #define LOGF(format, arg...) LOG_(LOG_ID_MAIN, DLOG_FATAL, LOG_TAG, format, ##arg)
 /**
- * For Framework and system etc.
- * Simplified macro to send a system log message using the current LOG_TAG.
+ * @internal
+ * @brief For Framework and system etc.
+ * @details Simplified macro to send a system log message using the current LOG_TAG.
  * Example:
  *  SLOGD("system debug %d", num);
  *  SLOGE("system error %d", num);
@@ -200,8 +238,9 @@ typedef enum {
 #define SLOGE(format, arg...) LOG_(LOG_ID_SYSTEM, DLOG_ERROR, LOG_TAG, format, ##arg)
 #define SLOGF(format, arg...) LOG_(LOG_ID_SYSTEM, DLOG_FATAL, LOG_TAG, format, ##arg)
 /**
- * For Modem and radio etc.
- * Simplified macro to send a radio log message using the current LOG_TAG.
+ * @internal
+ * @brief For Modem and radio etc.
+ * @details Simplified macro to send a radio log message using the current LOG_TAG.
  * Example:
  *  RLOGD("radio debug %d", num);
  *  RLOGE("radio error %d", num);
@@ -216,7 +255,8 @@ typedef enum {
 #define RLOGE(format, arg...) LOG_(LOG_ID_RADIO, DLOG_ERROR, LOG_TAG, format, ##arg)
 #define RLOGF(format, arg...) LOG_(LOG_ID_RADIO, DLOG_FATAL, LOG_TAG, format, ##arg)
 /**
- * For Tizen OSP Application macro.
+ * @internal
+ * @brief For Tizen OSP Application macro.
  */
 #ifdef TIZEN_DEBUG_ENABLE
 #define ALOGD(format, arg...) LOG_(LOG_ID_APPS, DLOG_DEBUG, LOG_TAG, format, ##arg)
@@ -229,7 +269,9 @@ typedef enum {
 #define ALOGF(format, arg...) LOG_(LOG_ID_APPS, DLOG_FATAL, LOG_TAG, format, ##arg)
 
 /**
- * Basic log message macro that allows you to specify a priority and a tag
+ * @internal
+ * @brief Basic log message macro
+ * @details This macro allows you to specify a priority and a tag
  * if you want to use this macro directly, you must add this messages for unity of messages.
  * (LOG(prio, tag, "%s: %s(%d) > " format, __MODULE__, __func__, __LINE__, ##arg))
  *
@@ -246,7 +288,9 @@ typedef enum {
 #define SLOG(priority, tag, format, arg...) LOG_(LOG_ID_SYSTEM, D##priority, tag, format, ##arg)
 #define RLOG(priority, tag, format, arg...) LOG_(LOG_ID_RADIO, D##priority, tag, format, ##arg)
 #define ALOG(priority, tag, format, arg...) LOG_(LOG_ID_APPS, D##priority, tag, format, ##arg)
-
+/**
+ * @internal
+ */
 #define LOG_VA(priority, tag, fmt, args) \
        vprint_log(D##priority, tag, fmt, args)
 #define ALOG_VA(priority, tag, fmt, args) \
@@ -277,8 +321,9 @@ typedef enum {
 #define COMPATIBILITY_ON
 #ifdef COMPATIBILITY_ON
 /**
- * Conditional Macro.
- * Don't use this macro. It's just compatibility.
+ * @internal
+ * @breif Conditional Macro.
+ * @remarks Don't use this macro. It's just compatibility.
  * It will be deprecated.
  */
 #define LOGD_IF(cond, format, arg...) \
@@ -381,59 +426,133 @@ typedef enum {
 #define RLOGV_IF(cond, format, arg...) NOP(format, ##arg)
 #define SECLOG(...) ({ do { } while (0); })
 #endif
-// Don't use above macro no more!! It will be removed -Verbose, Warning and Fatal priority macro.
 // ---------------------------------------------------------------------
+
+/**
+ * @addtogroup CAPI_SYSTEM_DLOG
+ * @{
+ */
+/**
+ * @brief     Send log with priority and tag.
+ * @details   for application
+ * @since_tizen 2.3
+ * @param[in] prio log_priority
+ * @param[in] tag tag
+ * @param[in] fmt format string
+ * @return On success, the function returns the number of bytes written.
+ *         On error, a negative errno-style error code
+ * @retval #DLOG_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DLOG_ERROR_NOT_PERMITTED Operation not permitted
+ * @pre       none
+ * @post      none
+ * @see       dlog_vprint
+ * @code
+#include<dlog.h>
+int main(void)
+{
+    int integer = 21;
+    char string[] = "test dlog";
+
+       dlog_print(DLOG_INFO, "USR_TAG", "test dlog");
+       dlog_print(DLOG_INFO, "USR_TAG", "%s, %d", string, integer);
+    return 0;
+}
+ * @endcode
+ */
+int dlog_print(log_priority prio, const char *tag, const char *fmt, ...);
+
+/**
+ * @brief     Send log with priority, tag and va_list.
+ * @details   for application
+ * @since_tizen 2.3
+ * @param[in] prio log_priority
+ * @param[in] tag tag
+ * @param[in] fmt format string
+ * @param[in] ap va_list
+ * @return On success, the function returns the number of bytes written.
+ *         On error, a negative errno-style error code
+ * @retval #DLOG_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #DLOG_ERROR_NOT_PERMITTED Operation not permitted
+ * @pre       none
+ * @post      none
+ * @see       dlog_print
+ * @code
+#include<dlog.h>
+void my_debug_print(char *format, ...)
+{
+    va_list ap;
+
+    va_start(ap, format);
+    dlog_vprint(DLOG_INFO, "USR_TAG", format, ap);
+    va_end(ap);
+}
+
+int main(void)
+{
+    my_debug_print("%s", "test dlog");
+    my_debug_print("%s, %d", "test dlog", 21);
+    return 0;
+}
+ * @endcode
+ */
+int dlog_vprint(log_priority prio, const char *tag, const char *fmt, va_list ap);
+/**
+ * @}
+ */
+
+
 /*
  * The stuff in the rest of this file should not be used directly.
  */
 /**
- * @brief              send log. must specify log_id ,priority, tag and format string.
- * @pre                none
- * @post               none
- * @see                __dlog_print
- * @remarks    you must not use this API directly. use macros instead.
- * @param[in]  log_id  log device id
- * @param[in]  prio    priority
- * @param[in]  tag     tag
- * @param[in]  fmt     format string
- * @return                     Operation result
- * @retval             0>=     Success
- * @retval              -1     Error
+ * @internal
+ * @brief     Send log.
+ * @details   Use LOG(), SLOG(), RLOG() family
+ *            not to use __dlog_print() directly
+ * @remarks   Must not use this API directly. use macros instead.
+ * @param[in] log_id log device id
+ * @param[in] prio priority
+ * @param[in] tag tag
+ * @param[in] fmt format string
+ * @return    Operation result
+ * @retval    0>= Success
+ * @retval    -1  Error
+ * @pre       none
+ * @post      none
+ * @see       __dlog_print
  * @code
-// you have to use LOG(), SLOG(), RLOG() family not to use __dlog_print() directly
-// so below example is just for passing Documentation Verification !!!
-#define LOG_TAG USR_TAG
-#include<dlog.h>
- __dlog_print(LOG_ID_MAIN, DLOG_INFO, USR_TAG, "you must not use this API directly");
+    #define LOG_TAG USR_TAG
+    #include<dlog.h>
+     __dlog_print(LOG_ID_MAIN, DLOG_INFO, USR_TAG, "you must not use this API directly");
  * @endcode
  */
 int __dlog_print(log_id_t log_id, int prio, const char *tag, const char *fmt, ...);
 
 /**
- * @brief              send log with va_list. must specify log_id ,priority, tag and format string.
- * @pre                none
- * @post               none
- * @see                __dlog_print
- * @remarks    you must not use this API directly. use macros instead.
- * @param[in]  log_id  log device id
- * @param[in]  prio    priority
- * @param[in]  tag     tag
- * @param[in]  fmt     format string
- * @param[in]  ap      va_list
- * @return                     Operation result
- * @retval             0>=     Success
- * @retval              -1     Error
+ * @internal
+ * @brief     Send log with va_list.
+ * @details   Use LOG_VA(), SLOG_VA(), RLOG_VA() family
+              not to use __dlog_vprint() directly
+ * @remarks   Must not use this API directly. use macros instead.
+ * @param[in] log_id log device id
+ * @param[in] prio priority
+ * @param[in] tag tag
+ * @param[in] fmt format string
+ * @param[in] ap va_list
+ * @return    Operation result
+ * @retval    0>= Success
+ * @retval    -1  Error
+ * @pre       none
+ * @post      none
+ * @see       __dlog_vprint
  * @code
- // you have to use LOG_VA(), SLOG_VA(), RLOG_VA() family not to use __dlog_print() directly
- // so below example is just for passing Documentation Verification !!!
-#define LOG_TAG USR_TAG
-#include<dlog.h>
-  __dlog_vprint(LOG_ID_MAIN, DLOG_INFO, USR_TAG, "you must not use this API directly", ap);
+    #define LOG_TAG USR_TAG
+    #include<dlog.h>
+     __dlog_vprint(LOG_ID_MAIN, DLOG_INFO, USR_TAG, "you must not use this API directly", ap);
  * @endcode
   */
 int __dlog_vprint(log_id_t log_id, int prio, const char *tag, const char *fmt, va_list ap);
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
-/** @} */
 #endif /* _DLOG_H_*/
index 3cd79bc..45792f4 100755 (executable)
@@ -38,6 +38,7 @@ typedef enum {
     FORMAT_RAW,
     FORMAT_TIME,
     FORMAT_THREADTIME,
+    FORMAT_DUMP,
     FORMAT_LONG,
 } log_print_format;
 
index 545f669..30f1b07 100755 (executable)
@@ -10,8 +10,13 @@ Source102:  packaging/libdlog.manifest
 Source201:  packaging/dlog.conf.in
 Source202:  packaging/dlog_logger.conf.in
 Source203:  packaging/dlog_logger.conf-micro.in
+Source204:  packaging/dlog_logger.conf-micro-debug.in
 Source301:  packaging/dlog_logger.service
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: libtool
 BuildRequires: pkgconfig(libsystemd-journal)
+BuildRequires: pkgconfig(capi-base-common)
 Requires(post): coreutils
 
 %description
@@ -83,11 +88,9 @@ cp LICENSE.Apache-2.0 %{buildroot}/usr/share/license/dlogutil
 
 mkdir -p %{buildroot}/opt/etc
 cp %SOURCE201 %{buildroot}/opt/etc/dlog.conf
-%if "%{_repository}" == "wearable"
-cp %SOURCE203 %{buildroot}/opt/etc/dlog_logger.conf
-%else
+
+# default set log output to external files
 cp %SOURCE202 %{buildroot}/opt/etc/dlog_logger.conf
-%endif
 
 %preun -n dlogutil
 
diff --git a/packaging/dlog_logger.conf-micro-debug.in b/packaging/dlog_logger.conf-micro-debug.in
new file mode 100644 (file)
index 0000000..a9c892f
--- /dev/null
@@ -0,0 +1,3 @@
+dlogutil -b system -r 5120 -n 1 -f /var/log/dlog_system -v dump *:I
+dlogutil -b main -r 3072 -n 1 -f /var/log/dlog_main -v dump *:W
+dlogutil -b radio -r 2048 -n 4 -f /var/log/dlog_radio -v dump
index df7feb8..d8c301d 100644 (file)
@@ -1,3 +1,3 @@
-dlogutil -b system -r 5120 -n 1 -f /var/log/dlog_system -v threadtime *:I
-dlogutil -b main -r 3072 -n 1 -f /var/log/dlog_main -v threadtime *:W
-dlogutil -b radio -r 1024 -n 1 -f /var/log/dlog_radio -v threadtime
+dlogutil -b system -r 5120 -n 1 -f /var/log/dlog_system -v dump *:I
+dlogutil -b main -r 3072 -n 1 -f /var/log/dlog_main -v dump *:W
+dlogutil -b radio -r 1024 -n 1 -f /var/log/dlog_radio -v dump
index 88cc06e..5445824 100644 (file)
@@ -1,4 +1,3 @@
-dlogutil -b system -r 5120 -n 1 -f /var/log/dlog_system -v threadtime *:I
-dlogutil -b main -r 3072 -n 1 -f /var/log/dlog_main -v threadtime *:W
-dlogutil -b radio -f /var/log/seq.radio.log  -v threadtime -r 2048 -n 4
-dlogutil -b system -r 1024 -n 1 -f /var/log/msg.log -v threadtime MSG_SERVICE
+dlogutil -b system -r 512 -n 1 -f /var/log/dlog_system -v dump *:I
+dlogutil -b main -r 256 -n 1 -f /var/log/dlog_main -v dump *:W
+dlogutil -b radio -r 512 -n 1 -f /var/log/dlog_radio -v dump
index 17d9761..b20dd1d 100644 (file)
@@ -3,7 +3,7 @@ Description=Dumps dlog logs onto disk
 DefaultDependencies=no
 
 [Service]
-ExecStart=/usr/bin/dlog_logger
+ExecStart=/usr/bin/dlog_logger -b 99 -t 600
 Restart=always
 
 [Install]
index d0f3ad4..46fa2d1 100755 (executable)
@@ -72,7 +72,7 @@ static inline int dlog_pri_to_journal_pri(log_priority prio)
        };
 
        if (prio < 0 || prio >= DLOG_PRIO_MAX)
-               return -EINVAL;
+               return DLOG_ERROR_INVALID_PARAMETER;
 
        return pri_table[prio];
 }
@@ -107,7 +107,7 @@ static int __write_to_log_sd_journal(log_id_t log_id, log_priority prio, const c
 #else
 static int __write_to_log_null(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
 {
-       return -1;
+       return DLOG_ERROR_NOT_PERMITTED;
 }
 
 static int __write_to_log_kernel(log_id_t log_id, log_priority prio, const char *tag, const char *msg)
@@ -119,13 +119,16 @@ static int __write_to_log_kernel(log_id_t log_id, log_priority prio, const char
        if (log_id < LOG_ID_MAX)
                log_fd = log_fds[log_id];
        else
-               return -1; // for TC
+               return DLOG_ERROR_INVALID_PARAMETER;
+
+       if (prio < DLOG_VERBOSE || prio >= DLOG_PRIO_MAX)
+               return DLOG_ERROR_INVALID_PARAMETER;
 
        if (!tag)
                tag = "";
 
        if (!msg)
-               return -1;
+               return DLOG_ERROR_INVALID_PARAMETER;
 
        vec[0].iov_base = (unsigned char *) &prio;
        vec[0].iov_len  = 1;
@@ -135,6 +138,8 @@ static int __write_to_log_kernel(log_id_t log_id, log_priority prio, const char
        vec[2].iov_len  = strlen(msg) + 1;
 
        ret = writev(log_fd, vec, 3);
+       if (ret < 0)
+           ret = errno;
 
        return ret;
 }
@@ -164,15 +169,16 @@ static void __dlog_init(void)
 #else
        /* open device */
        log_fds[LOG_ID_MAIN] = open("/dev/"LOG_MAIN, O_WRONLY);
-       log_fds[LOG_ID_RADIO] = open("/dev/"LOG_RADIO, O_WRONLY);
        log_fds[LOG_ID_SYSTEM] = open("/dev/"LOG_SYSTEM, O_WRONLY);
+       log_fds[LOG_ID_RADIO] = open("/dev/"LOG_RADIO, O_WRONLY);
        log_fds[LOG_ID_APPS] = open("/dev/"LOG_APPS, O_WRONLY);
-       if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0) {
+       if (log_fds[LOG_ID_MAIN] < 0) {
                write_to_log = __write_to_log_null;
        } else {
                write_to_log = __write_to_log_kernel;
        }
-
+       if (log_fds[LOG_ID_RADIO] < 0)
+               log_fds[LOG_ID_RADIO] = log_fds[LOG_ID_MAIN];
        if (log_fds[LOG_ID_SYSTEM] < 0)
                log_fds[LOG_ID_SYSTEM] = log_fds[LOG_ID_MAIN];
        if (log_fds[LOG_ID_APPS] < 0)
@@ -194,30 +200,30 @@ static int dlog_should_log(log_id_t log_id, const char* tag, int prio)
 
 #ifndef TIZEN_DEBUG_ENABLE
        if (prio <= DLOG_DEBUG)
-               return 0;
+               return DLOG_ERROR_INVALID_PARAMETER;
 #endif
        if (!tag)
-               return 0;
+               return DLOG_ERROR_INVALID_PARAMETER;
 
        if (log_id < 0 || LOG_ID_MAX <= log_id)
-               return 0;
+               return DLOG_ERROR_INVALID_PARAMETER;
 
        if (log_id != LOG_ID_APPS && !config.lc_plog)
-               return 0;
+               return DLOG_ERROR_NOT_PERMITTED;
 
        if (config.lc_limiter) {
                should_log = __log_limiter_pass_log(tag, prio);
 
                if (!should_log) {
-                       return 0;
+                       return DLOG_ERROR_NOT_PERMITTED;
                } else if (should_log < 0) {
                        write_to_log(log_id, prio, tag,
                                     "Your log has been blocked due to limit of log lines per minute.");
-                       return 0;
+                       return DLOG_ERROR_NOT_PERMITTED;
                }
        }
 
-       return 1;
+       return DLOG_ERROR_NONE;
 }
 
 int __dlog_vprint(log_id_t log_id, int prio, const char *tag, const char *fmt, va_list ap)
@@ -228,8 +234,10 @@ int __dlog_vprint(log_id_t log_id, int prio, const char *tag, const char *fmt, v
        if (write_to_log == NULL)
                __dlog_init();
 
-       if (!dlog_should_log(log_id, tag, prio))
-               return 0;
+       ret = dlog_should_log(log_id, tag, prio);
+
+       if (ret < 0)
+               return ret;
 
        vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
        ret = write_to_log(log_id, prio, tag, buf);
@@ -248,8 +256,10 @@ int __dlog_print(log_id_t log_id, int prio, const char *tag, const char *fmt, ..
        if (write_to_log == NULL)
                __dlog_init();
 
-       if (!dlog_should_log(log_id, tag, prio))
-               return 0;
+       ret = dlog_should_log(log_id, tag, prio);
+
+       if (ret < 0)
+               return ret;
 
        va_start(ap, fmt);
        vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
@@ -262,6 +272,33 @@ int __dlog_print(log_id_t log_id, int prio, const char *tag, const char *fmt, ..
        return ret;
 }
 
+int dlog_vprint(log_priority prio, const char *tag, const char *fmt, va_list ap)
+{
+       char buf[LOG_BUF_SIZE];
+
+       if (write_to_log == NULL)
+               __dlog_init();
+
+       vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
+
+       return write_to_log(LOG_ID_APPS, prio, tag, buf);
+}
+
+int dlog_print(log_priority prio, const char *tag, const char *fmt, ...)
+{
+       va_list ap;
+       char buf[LOG_BUF_SIZE];
+
+       if (write_to_log == NULL)
+               __dlog_init();
+
+       va_start(ap, fmt);
+       vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
+       va_end(ap);
+
+       return write_to_log(LOG_ID_APPS, prio, tag, buf);
+}
+
 void __attribute__((destructor)) __dlog_fini(void)
 {
        __log_limiter_destroy();
index c83af75..a0e874e 100644 (file)
@@ -97,7 +97,7 @@ static int rule_compare(struct rule* r1, struct rule* r2)
 {
        if (r1->hash == r2->hash) {
                if (r1->prio == r2->prio) {
-                       return strncmp(r1->tag, r2->tag, TAG_REASONABLE_LEN);
+                       return strncmp(r1->tag, r2->tag, strlen(r2->tag));
                } else {
                        return (r1->prio > r2->prio ? 1 : (-1));
                }
@@ -110,7 +110,7 @@ static int rule_match(struct rule* r1, unsigned key, const char* s, int prio)
 {
        if (r1->hash == key) {
                if (r1->prio == prio) {
-                       return strncmp(r1->tag, s, TAG_REASONABLE_LEN);
+                       return strncmp(r1->tag, s, strlen(s));
                } else {
                        return (r1->prio > prio ? 1 : (-1));
                }
@@ -199,16 +199,16 @@ static struct hashmap* hashmap_create(int size, hash_cmp_func_t cmp_func,
        internal_size |= internal_size >> 16;
        internal_size++;
 
-       hm = malloc(sizeof(*hm) + internal_size * sizeof(void*));
+       hm = malloc(sizeof(struct hashmap) + internal_size * sizeof(void*));
        if (!hm) {
                return NULL;
        }
+       /* Initialize hash field to correct value */
+       memset((void*)hm, 0, sizeof(struct hashmap) + internal_size * sizeof(void*));
 
        hm->size = internal_size;
        hm->cmp = cmp_func;
        hm->match = match_func;
-       /* Initialize hash field to correct value */
-       memset((void*)hm + sizeof(*hm), 0, hm->size * sizeof(void*));
 
        return hm;
 }
@@ -321,13 +321,13 @@ int __log_limiter_add_rule(const char* tag, int prio, int limit)
                return (-1);
        }
 
-       r = (struct rule*) malloc(sizeof(*r));
+       r = (struct rule*) malloc(sizeof(struct rule));
        if (NULL == r) {
                return (-1);
        }
-       memset(r, 0, sizeof(*r));
+       memset(r, 0, sizeof(struct rule));
 
-       strncpy(r->tag, tag, TAG_REASONABLE_LEN);
+       snprintf(r->tag, TAG_REASONABLE_LEN, "%s", tag);
        r->prio = util_prio_to_char(prio);
        r->hash = util_hash_key(tag, r->prio);
        r->limit = limit;
index d3d5fc6..6b3a5cf 100644 (file)
@@ -48,6 +48,9 @@
 #define FILE_PERMS (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH)
 #define MAX_ARGS 16
 #define MAX_ROTATED 4
+#define MAX_QUEUED 4096
+#define BUFFER_MAX 100
+#define INTERVAL_MAX 60*60
 
 #define CONFIG_FILE "/opt/etc/dlog_logger.conf"
 
@@ -113,6 +116,9 @@ static int device_list[] = {
        [LOG_ID_MAX] = false,
 };
 
+static int buffer_size = 0;
+static int min_interval = 0;
+
 /*
  * get log device id from device path table by device name
  */
@@ -135,7 +141,7 @@ static int get_device_id_by_name(const char *name)
  */
 static int check_device(int id)
 {
-       if (id < 0 || LOG_ID_MAX < id)
+       if (id < 0 || LOG_ID_MAX <= id)
                return 0;
 
        return (device_list[id] == true) ? 0 : -1;
@@ -146,7 +152,7 @@ static int check_device(int id)
  */
 static int register_device(int id)
 {
-       if (id < 0 || LOG_ID_MAX < id)
+       if (id < 0 || LOG_ID_MAX <= id)
                return -1;
        device_list[id] = true;
 
@@ -234,7 +240,6 @@ static void process_buffer(struct log_device *dev, struct logger_entry *buf)
        struct log_task_link *task;
 
        err = log_process_log_buffer(buf, &entry);
-
        if (err < 0)
                goto exit;
 
@@ -256,6 +261,7 @@ static void process_buffer(struct log_device *dev, struct logger_entry *buf)
                        rotate_logs(logwork);
                }
        }
+
 exit:
        return;
 }
@@ -325,6 +331,7 @@ static void print_next_entry(struct log_device *dev)
  */
 static void do_logger(struct log_device *dev)
 {
+       time_t commit_time = 0, current_time = 0;
        struct log_device *pdev;
        int ret, result;
        fd_set readset;
@@ -332,6 +339,9 @@ static void do_logger(struct log_device *dev)
        int queued_lines = 0;
        int max = 0;
 
+       if (min_interval)
+               commit_time = current_time = time(NULL);
+
        for (pdev = dev; pdev; pdev = pdev->next) {
                if (pdev->fd > max)
                        max = pdev->fd;
@@ -390,6 +400,29 @@ static void do_logger(struct log_device *dev)
 
                                enqueue(pdev, entry);
                                ++queued_lines;
+
+                               if (MAX_QUEUED < queued_lines) {
+                                       _D("queued_lines = %d\n", queued_lines);
+                                       while (true) {
+                                               choose_first(dev, &pdev);
+                                               if (pdev == NULL)
+                                                       break;
+                                               print_next_entry(pdev);
+                                               --queued_lines;
+                                       }
+                                       if (min_interval)
+                                               commit_time = time(NULL);
+                                       break;
+                               }
+                       }
+               }
+
+               if (min_interval) {
+                       current_time = time(NULL);
+                       if (current_time - commit_time < min_interval &&
+                                       queued_lines < buffer_size) {
+                               sleep = true;
+                               continue;
                        }
                }
 
@@ -401,6 +434,8 @@ static void do_logger(struct log_device *dev)
                                        break;
                                print_next_entry(pdev);
                                --queued_lines;
+                               if (min_interval)
+                                       commit_time = current_time;
                        }
                } else {
                        /* print all that aren't the last in their list */
@@ -411,6 +446,8 @@ static void do_logger(struct log_device *dev)
                                        break;
                                print_next_entry(pdev);
                                --queued_lines;
+                               if (min_interval)
+                                       commit_time = current_time;
                        }
                }
 next:
@@ -428,7 +465,7 @@ static struct log_work *work_new(void)
 {
        struct log_work *work;
 
-       work = malloc(sizeof(*work));
+       work = malloc(sizeof(struct log_work));
        if (work == NULL) {
                _E("failed to malloc log_work\n");
                return NULL;
@@ -546,9 +583,9 @@ static struct log_device *device_new(int id)
 {
        struct log_device *dev;
 
-       if (LOG_ID_MAX < id)
+       if (LOG_ID_MAX <= id)
                return NULL;
-       dev = malloc(sizeof(*dev));
+       dev = malloc(sizeof(struct log_device));
        if (dev == NULL) {
                _E("failed to malloc log_device\n");
                return NULL;
@@ -559,6 +596,7 @@ static struct log_device *device_new(int id)
                _E("Unable to open log device '%s': %s\n",
                                device_path_table[id],
                                strerror(errno));
+               free(dev);
                return NULL;
        }
        _D("device new id %d fd %d\n", dev->id, dev->fd);
@@ -712,7 +750,7 @@ static int parse_command_line(char *linebuffer, struct log_command *cmd)
                case 'b':
                        id = get_device_id_by_name(optarg);
                        _D("command device name %s id %d\n", optarg, id);
-                       if (id < 0 || LOG_ID_MAX < id)
+                       if (id < 0 || LOG_ID_MAX <= id)
                                break;
                        cmd->option_buffer = true;
                        /* enable to log in device on/off struct */
@@ -774,7 +812,7 @@ static int parse_command_line(char *linebuffer, struct log_command *cmd)
        /* If it have not the -b option,
           set the default devices to open and log */
        if (cmd->option_buffer == false) {
-               _D("set default device\n", cmd->filename);
+               _D("set default device\n");
                cmd->devices[LOG_ID_MAIN] = true;
                cmd->devices[LOG_ID_SYSTEM] = true;
                register_device(LOG_ID_MAIN);
@@ -848,9 +886,66 @@ static void sig_handler(int signo)
        exit(EXIT_SUCCESS);
 }
 
+static int help(void) {
+
+       printf("%s [OPTIONS...] \n\n"
+                       "Logger, records log messages to files.\n\n"
+                       "  -h      Show this help\n"
+                       "  -b N    Set number of logs to keep logs in memory buffer bafore write files (default:0, MAX:100)\n"
+                       "  -t N    Set minimum interval time to write files (default:0, MAX:3600, seconds)\n",
+                       program_invocation_short_name);
+
+       return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+       int ret = 1, option;
+
+       while ((option = getopt(argc, argv, "hb:t:")) != -1) {
+               switch (option) {
+                       case 't':
+                               if (!isdigit(optarg[0])) {
+                                       ret = -EINVAL;
+                                       printf("Wrong argument!\n");
+                                       help();
+                                       goto exit;
+                               }
+                               min_interval = atoi(optarg);
+                               if (min_interval < 0 || INTERVAL_MAX < min_interval)
+                                       min_interval = 0;
+                               ret = 1;
+                               break;
+                       case 'b':
+                               if (!isdigit(optarg[0])) {
+                                       ret = -EINVAL;
+                                       printf("Wrong argument!\n");
+                                       help();
+                                       goto exit;
+                               }
+                               buffer_size = atoi(optarg);
+                               if (buffer_size < 0 || BUFFER_MAX < buffer_size)
+                                       buffer_size = 0;
+                               ret = 1;
+                               break;
+                       case 'h':
+                               help();
+                               ret = 0;
+                               goto exit;
+                       default:
+                               ret = -EINVAL;
+               }
+       }
+exit:
+       optarg = NULL;
+       optind = 1;
+       optopt = 0;
+       return ret;
+}
+
+
 int main(int argc, char **argv)
 {
-       int i, ncmd;
+       int i, r, ncmd;
        struct stat statbuf;
        struct log_device *dev;
        struct log_work *work;
@@ -858,7 +953,7 @@ int main(int argc, char **argv)
        struct sigaction act;
 
        /* set the signal handler for free dynamically allocated memory. */
-       memset(&act, 0, sizeof(act));
+       memset(&act, 0, sizeof(struct sigaction));
        sigemptyset(&act.sa_mask);
        act.sa_handler = (void *)sig_handler;
        act.sa_flags = 0;
@@ -870,9 +965,13 @@ int main(int argc, char **argv)
        if (sigaction(SIGTERM, &act, NULL) < 0)
                _E("failed to sigaction for SIGTERM");
 
+       if (argc != 1) {
+               r = parse_argv(argc, argv);
+               if (r <= 0)
+                       goto exit;
+       }
        /* parse command from command configuration file. */
        ncmd = parse_command(command_list);
-
        /* If it have nothing command, exit. */
        if (!ncmd)
                goto exit;
index d421451..ea96cfb 100755 (executable)
@@ -37,7 +37,7 @@
 
 #define DEFAULT_LOG_ROTATE_SIZE_KBYTES 16
 #define DEFAULT_MAX_ROTATED_LOGS 4
-
+#define MAX_QUEUED 4096
 #define LOG_FILE_DIR    "/dev/log_"
 
 static log_format* g_logformat;
@@ -62,8 +62,7 @@ struct queued_entry_t {
 static int cmp(struct queued_entry_t* a, struct queued_entry_t* b)
 {
        int n = a->entry.sec - b->entry.sec;
-       if (n != 0)
-       {
+       if (n != 0) {
                return n;
        }
        return a->entry.nsec - b->entry.nsec;
@@ -80,43 +79,38 @@ struct log_device_t {
 
 static void enqueue(struct log_device_t* device, struct queued_entry_t* entry)
 {
-       if( device->queue == NULL)
-       {
+       if (device->queue == NULL) {
                device->queue = entry;
-       }
-       else
-       {
+       } else {
                struct queued_entry_t** e = &device->queue;
-               while(*e && cmp(entry, *e) >= 0 )
-               {
+               while (*e && cmp(entry, *e) >= 0 ) {
                        e = &((*e)->next);
                }
                entry->next = *e;
                *e = entry;
-    }
+       }
 }
 
 static int open_logfile (const char *pathname)
 {
-    return open(pathname, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
+       return open(pathname, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
 }
 
 static void rotate_logs()
 {
-    int err;
+       int err;
        int i;
        char file0[256]={0};
        char file1[256]={0};
 
-    // Can't rotate logs if we're not outputting to a file
-    if (g_output_filename == NULL) {
-        return;
-    }
+       // Can't rotate logs if we're not outputting to a file
+       if (g_output_filename == NULL) {
+               return;
+       }
 
-    close(g_outfd);
+       close(g_outfd);
 
-    for (i = g_max_rotated_logs ; i > 0 ; i--)
-       {
+       for (i = g_max_rotated_logs ; i > 0 ; i--) {
                snprintf(file1, 255, "%s.%d", g_output_filename, i);
 
                if (i - 1 == 0) {
@@ -130,16 +124,16 @@ static void rotate_logs()
                if (err < 0 && errno != ENOENT) {
                        perror("while rotating log files");
                }
-    }
+       }
 
-    g_outfd = open_logfile (g_output_filename);
+       g_outfd = open_logfile (g_output_filename);
 
-    if (g_outfd < 0) {
-        perror ("couldn't open output file");
-        exit(-1);
-    }
+       if (g_outfd < 0) {
+               perror ("couldn't open output file");
+               exit(-1);
+       }
 
-    g_out_byte_count = 0;
+       g_out_byte_count = 0;
 
 }
 
@@ -159,12 +153,10 @@ static void processBuffer(struct log_device_t* dev, struct logger_entry *buf)
 
        if (log_should_print_line(g_logformat, entry.tag, entry.priority)) {
                if (false && g_dev_count > 1) {
-                       // FIXME
                        mgs_buf[0] = dev->device[0];
                        mgs_buf[1] = ' ';
                        bytes_written = write(g_outfd, mgs_buf, 2);
-                       if (bytes_written < 0)
-                       {
+                       if (bytes_written < 0) {
                                perror("output error");
                                exit(-1);
                        }
@@ -172,8 +164,7 @@ static void processBuffer(struct log_device_t* dev, struct logger_entry *buf)
 
                bytes_written = log_print_log_line(g_logformat, g_outfd, &entry);
 
-               if (bytes_written < 0)
-               {
+               if (bytes_written < 0) {
                        perror("output error");
                        exit(-1);
                }
@@ -190,15 +181,14 @@ static void processBuffer(struct log_device_t* dev, struct logger_entry *buf)
        }
 
 error:
-       //fprintf (stderr, "Error processing record\n");
        return;
 }
 
 static void chooseFirst(struct log_device_t* dev, struct log_device_t** firstdev)
 {
        for (*firstdev = NULL; dev != NULL; dev = dev->next) {
-               if (dev->queue != NULL && (*firstdev == NULL || cmp(dev->queue, (*firstdev)->queue) < 0))
-               {
+               if (dev->queue != NULL && (*firstdev == NULL ||
+                                       cmp(dev->queue, (*firstdev)->queue) < 0)) {
                        *firstdev = dev;
                }
        }
@@ -260,109 +250,119 @@ static void read_log_lines(struct log_device_t* devices)
                        result = select(max + 1, &readset, NULL, NULL, sleep ? NULL : &timeout);
                } while (result == -1 && errno == EINTR);
 
-        if (result >= 0) {
-            for (dev=devices; dev; dev = dev->next) {
-                if (FD_ISSET(dev->fd, &readset)) {
-                    struct queued_entry_t* entry = (struct queued_entry_t *)malloc(sizeof( struct queued_entry_t));
+               if (result >= 0) {
+                       for (dev=devices; dev; dev = dev->next) {
+                               if (FD_ISSET(dev->fd, &readset)) {
+                                       struct queued_entry_t* entry = (struct queued_entry_t *)malloc(sizeof( struct queued_entry_t));
                                        if (entry == NULL) {
                                                fprintf(stderr,"Can't malloc queued_entry\n");
                                                exit(-1);
                                        }
                                        entry->next = NULL;
 
-                    /* NOTE: driver guarantees we read exactly one full entry */
-                    ret = read(dev->fd, entry->buf, LOGGER_ENTRY_MAX_LEN);
-                    if (ret < 0) {
-                        if (errno == EINTR) {
-                            free(entry);
-                            goto next;
-                        }
-                        if (errno == EAGAIN) {
-                            free(entry);
-                            break;
-                        }
-                        perror("dlogutil read");
-                        exit(EXIT_FAILURE);
-                    }
-                    else if (!ret) {
-                        free(entry);
-                        fprintf(stderr, "read: Unexpected EOF!\n");
-                        exit(EXIT_FAILURE);
+                                       /* NOTE: driver guarantees we read exactly one full entry */
+                                       ret = read(dev->fd, entry->buf, LOGGER_ENTRY_MAX_LEN);
+                                       if (ret < 0) {
+                                               if (errno == EINTR) {
+                                                       free(entry);
+                                                       goto next;
+                                               }
+                                               if (errno == EAGAIN) {
+                                                       free(entry);
+                                                       break;
+                                               }
+                                               perror("dlogutil read");
+                                               exit(EXIT_FAILURE);
+                                       }
+                                       else if (!ret) {
+                                               free(entry);
+                                               fprintf(stderr, "read: Unexpected EOF!\n");
+                                               exit(EXIT_FAILURE);
                                        }
                                        else if (entry->entry.len != ret - sizeof(struct logger_entry)) {
-                        free(entry);
                                                fprintf(stderr, "read: unexpected length. Expected %d, got %d\n",
                                                                entry->entry.len, ret - sizeof(struct logger_entry));
+                                               free(entry);
                                                exit(EXIT_FAILURE);
                                        }
 
 
-                    entry->entry.msg[entry->entry.len] = '\0';
-
-                    enqueue(dev, entry);
-                    ++queued_lines;
-                }
-            }
-
-            if (result == 0) {
-                // we did our short timeout trick and there's nothing new
-                // print everything we have and wait for more data
-                sleep = true;
-                while (true) {
-                    chooseFirst(devices, &dev);
-                    if (dev == NULL) {
-                        break;
-                    }
-                    if (g_tail_lines == 0 || queued_lines <= g_tail_lines) {
-                        printNextEntry(dev);
-                    } else {
-                        skipNextEntry(dev);
-                    }
-                    --queued_lines;
-                }
-
-                // the caller requested to just dump the log and exit
-                if (g_nonblock) {
-                    exit(0);
-                }
-            } else {
-                // print all that aren't the last in their list
-                sleep = false;
-                while (g_tail_lines == 0 || queued_lines > g_tail_lines) {
-                    chooseFirst(devices, &dev);
-                    if (dev == NULL || dev->queue->next == NULL) {
-                        break;
-                    }
-                    if (g_tail_lines == 0) {
-                        printNextEntry(dev);
-                    } else {
-                        skipNextEntry(dev);
-                    }
-                    --queued_lines;
-                }
-            }
-        }
+                                       entry->entry.msg[entry->entry.len] = '\0';
+
+                                       enqueue(dev, entry);
+                                       ++queued_lines;
+                                       if (g_nonblock && MAX_QUEUED < queued_lines) {
+                                               while (true) {
+                                                       chooseFirst(devices, &dev);
+                                                       if (dev == NULL)
+                                                               break;
+                                                       printNextEntry(dev);
+                                                       --queued_lines;
+                                               }
+                                               break;
+                                       }
+                               }
+                       }
+
+                       if (result == 0) {
+                               /* we did our short timeout trick and there's nothing new
+                                print everything we have and wait for more data */
+                               sleep = true;
+                               while (true) {
+                                       chooseFirst(devices, &dev);
+                                       if (dev == NULL) {
+                                               break;
+                                       }
+                                       if (g_tail_lines == 0 || queued_lines <= g_tail_lines) {
+                                               printNextEntry(dev);
+                                       } else {
+                                               skipNextEntry(dev);
+                                       }
+                                       --queued_lines;
+                               }
+
+                               /* the caller requested to just dump the log and exit */
+                               if (g_nonblock) {
+                                       exit(0);
+                               }
+                       } else {
+                               /* print all that aren't the last in their list */
+                               sleep = false;
+                               while (g_tail_lines == 0 || queued_lines > g_tail_lines) {
+                                       chooseFirst(devices, &dev);
+                                       if (dev == NULL || dev->queue->next == NULL) {
+                                               break;
+                                       }
+                                       if (g_tail_lines == 0) {
+                                               printNextEntry(dev);
+                                       } else {
+                                               skipNextEntry(dev);
+                                       }
+                                       --queued_lines;
+                               }
+                       }
+               }
 next:
-        ;
-    }
+               ;
+       }
 }
 
 
 static int clear_log(int logfd)
 {
-    return ioctl(logfd, LOGGER_FLUSH_LOG);
+       return ioctl(logfd, LOGGER_FLUSH_LOG);
 }
 
 /* returns the total size of the log's ring buffer */
 static int get_log_size(int logfd)
 {
-    return ioctl(logfd, LOGGER_GET_LOG_BUF_SIZE);
+       return ioctl(logfd, LOGGER_GET_LOG_BUF_SIZE);
 }
 
 /* returns the readable size of the log's ring buffer (that is, amount of the log consumed) */
 static int get_log_readable_size(int logfd)
 {
-    return ioctl(logfd, LOGGER_GET_LOG_LEN);
+       return ioctl(logfd, LOGGER_GET_LOG_LEN);
 }
 
 static void setup_output()
@@ -394,7 +394,7 @@ static int set_log_format(const char * formatString)
        format = log_format_from_string(formatString);
 
        if (format == FORMAT_OFF) {
-               // FORMAT_OFF means invalid string
+               /* FORMAT_OFF means invalid string */
                return -1;
        }
 
@@ -405,36 +405,36 @@ static int set_log_format(const char * formatString)
 
 static void show_help(const char *cmd)
 {
-    fprintf(stderr,"Usage: %s [options] [filterspecs]\n", cmd);
-
-    fprintf(stderr, "options include:\n"
-                    "  -s              Set default filter to silent.\n"
-                    "                  Like specifying filterspec '*:s'\n"
-                    "  -f <filename>   Log to file. Default to stdout\n"
-                    "  -r [<kbytes>]   Rotate log every kbytes. (16 if unspecified). Requires -f\n"
-                    "  -n <count>      Sets max number of rotated logs to <count>, default 4\n"
-                    "  -v <format>     Sets the log print format, where <format> is one of:\n\n"
-                    "                  brief(by default) process tag thread raw time threadtime long\n\n"
-                    "  -c              clear (flush) the entire log and exit, conflicts with '-g'\n"
-                    "  -d              dump the log and then exit (don't block)\n"
-                    "  -t <count>      print only the most recent <count> lines (implies -d)\n"
-                    "  -g              get the size of the log's ring buffer and exit, conflicts with '-c'\n"
-                    "  -b <buffer>     request alternate ring buffer\n"
-                    "                  ('main' (default), 'radio', 'system')");
-
-
-    fprintf(stderr,"\nfilterspecs are a series of \n"
-                   "  <tag>[:priority]\n\n"
-                   "where <tag> is a log component tag (or * for all) and priority is:\n"
-                   "  V    Verbose\n"
-                   "  D    Debug\n"
-                   "  I    Info\n"
-                   "  W    Warn\n"
-                   "  E    Error\n"
-                   "  F    Fatal\n"
-                   "  S    Silent (supress all output)\n"
-                   "\n'*' means '*:D' and <tag> by itself means <tag>:V\n"
-                   "If no filterspec is found, filter defaults to '*:I'\n\n");
+       fprintf(stderr,"Usage: %s [options] [filterspecs]\n", cmd);
+
+       fprintf(stderr, "options include:\n"
+                       "  -s              Set default filter to silent.\n"
+                       "                  Like specifying filterspec '*:s'\n"
+                       "  -f <filename>   Log to file. Default to stdout\n"
+                       "  -r [<kbytes>]   Rotate log every kbytes. (16 if unspecified). Requires -f\n"
+                       "  -n <count>      Sets max number of rotated logs to <count>, default 4\n"
+                       "  -v <format>     Sets the log print format, where <format> is one of:\n\n"
+                       "                  brief(by default) process tag thread raw time threadtime long\n\n"
+                       "  -c              clear (flush) the entire log and exit, conflicts with '-g'\n"
+                       "  -d              dump the log and then exit (don't block)\n"
+                       "  -t <count>      print only the most recent <count> lines (implies -d)\n"
+                       "  -g              get the size of the log's ring buffer and exit, conflicts with '-c'\n"
+                       "  -b <buffer>     request alternate ring buffer\n"
+                       "                  ('main' (default), 'radio', 'system')");
+
+
+       fprintf(stderr,"\nfilterspecs are a series of \n"
+                       "  <tag>[:priority]\n\n"
+                       "where <tag> is a log component tag (or * for all) and priority is:\n"
+                       "  V    Verbose\n"
+                       "  D    Debug\n"
+                       "  I    Info\n"
+                       "  W    Warn\n"
+                       "  E    Error\n"
+                       "  F    Fatal\n"
+                       "  S    Silent (supress all output)\n"
+                       "\n'*' means '*:D' and <tag> by itself means <tag>:V\n"
+                       "If no filterspec is found, filter defaults to '*:I'\n\n");
 }
 
 
@@ -531,61 +531,61 @@ static int log_devices_add_to_tail(struct log_device_t *devices, struct log_devi
 
 int main(int argc, char **argv)
 {
-    int err;
-    int has_set_log_format = 0;
-    int is_clear_log = 0;
-    int getLogSize = 0;
-    int mode = O_RDONLY;
+       int err;
+       int has_set_log_format = 0;
+       int is_clear_log = 0;
+       int getLogSize = 0;
+       int mode = O_RDONLY;
+       int accessmode = R_OK;
        int i;
-//    const char *forceFilters = NULL;
        struct log_device_t* devices = NULL;
        struct log_device_t* dev;
 
-    g_logformat = (log_format *)log_format_new();
+       g_logformat = (log_format *)log_format_new();
 
-    if (argc == 2 && 0 == strcmp(argv[1], "--test")) {
-        logprint_run_tests();
-        exit(0);
-    }
+       if (argc == 2 && 0 == strcmp(argv[1], "--test")) {
+               logprint_run_tests();
+               exit(0);
+       }
 
-    if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
-        show_help(argv[0]);
-        exit(0);
-    }
+       if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
+               show_help(argv[0]);
+               exit(0);
+       }
 
-    for (;;) {
-        int ret;
+       for (;;) {
+               int ret;
 
-        ret = getopt(argc, argv, "cdt:gsf:r:n:v:b:D");
+               ret = getopt(argc, argv, "cdt:gsf:r:n:v:b:D");
 
-        if (ret < 0) {
-            break;
-        }
+               if (ret < 0) {
+                       break;
+               }
 
-        switch(ret) {
-            case 's':
-                // default to all silent
-                log_add_filter_rule(g_logformat, "*:s");
-            break;
+               switch(ret) {
+                       case 's':
+                               /* default to all silent */
+                               log_add_filter_rule(g_logformat, "*:s");
+                               break;
 
-            case 'c':
-                is_clear_log = 1;
-                mode = O_WRONLY;
-            break;
+                       case 'c':
+                               is_clear_log = 1;
+                               mode = O_WRONLY;
+                               break;
 
-            case 'd':
-                g_nonblock = true;
-            break;
+                       case 'd':
+                               g_nonblock = true;
+                               break;
 
-            case 't':
-                g_nonblock = true;
-                g_tail_lines = atoi(optarg);
-            break;
+                       case 't':
+                               g_nonblock = true;
+                               g_tail_lines = atoi(optarg);
+                               break;
 
 
-            case 'g':
-                getLogSize = 1;
-            break;
+                       case 'g':
+                               getLogSize = 1;
+                               break;
 
                        case 'b': {
                                                  char *buf;
@@ -609,58 +609,49 @@ int main(int argc, char **argv)
                                                          g_dev_count = 1;
                                                  }
                                          }
-            break;
-
-            case 'f':
-                // redirect output to a file
-
-                g_output_filename = optarg;
-
-            break;
-
-            case 'r':
-//                if (optarg == NULL) {
-//                                     fprintf(stderr,"optarg == null\n");
- //                  g_log_rotate_size_kbytes = DEFAULT_LOG_ROTATE_SIZE_KBYTES;
- //              } else {
-                    //long logRotateSize;
-                    //char *lastDigit;
-
-                    if (!isdigit(optarg[0])) {
-                        fprintf(stderr,"Invalid parameter to -r\n");
-                        show_help(argv[0]);
-                        exit(-1);
-                    }
-                    g_log_rotate_size_kbytes = atoi(optarg);
-   //             }
-            break;
-
-            case 'n':
-                if (!isdigit(optarg[0])) {
-                    fprintf(stderr,"Invalid parameter to -r\n");
-                    show_help(argv[0]);
-                    exit(-1);
-                }
-
-                g_max_rotated_logs = atoi(optarg);
-            break;
-
-            case 'v':
-                err = set_log_format (optarg);
-                if (err < 0) {
-                    fprintf(stderr,"Invalid parameter to -v\n");
-                    show_help(argv[0]);
-                    exit(-1);
-                }
-
-                has_set_log_format = 1;
-            break;
+                                         break;
+
+                       case 'f':
+                                         /* redirect output to a file */
+                                         g_output_filename = optarg;
+
+                                         break;
+
+                       case 'r':
+                                         if (!isdigit(optarg[0])) {
+                                                 fprintf(stderr,"Invalid parameter to -r\n");
+                                                 show_help(argv[0]);
+                                                 exit(-1);
+                                         }
+                                         g_log_rotate_size_kbytes = atoi(optarg);
+                                         break;
+
+                       case 'n':
+                                         if (!isdigit(optarg[0])) {
+                                                 fprintf(stderr,"Invalid parameter to -r\n");
+                                                 show_help(argv[0]);
+                                                 exit(-1);
+                                         }
+
+                                         g_max_rotated_logs = atoi(optarg);
+                                         break;
+
+                       case 'v':
+                                         err = set_log_format (optarg);
+                                         if (err < 0) {
+                                                 fprintf(stderr,"Invalid parameter to -v\n");
+                                                 show_help(argv[0]);
+                                                 exit(-1);
+                                         }
+
+                                         has_set_log_format = 1;
+                                         break;
 
                        default:
-                               fprintf(stderr,"Unrecognized Option\n");
-                               show_help(argv[0]);
-                               exit(-1);
-                       break;
+                                         fprintf(stderr,"Unrecognized Option\n");
+                                         show_help(argv[0]);
+                                         exit(-1);
+                                         break;
                }
        }
 
@@ -676,165 +667,111 @@ int main(int argc, char **argv)
                        fprintf(stderr,"Can't add log device: %s\n", LOGGER_LOG_MAIN);
                        exit(-1);
                }
-        g_dev_count = 1;
+               g_dev_count = 1;
 
-        int accessmode =
-                  (mode == O_RDONLY) ? R_OK : (mode == O_WRONLY) ? W_OK : 0;
+               if (mode == O_WRONLY)
+                       accessmode = W_OK;
 
-       // only add this if it's available
-       if (0 == access("/dev/"LOGGER_LOG_SYSTEM, accessmode)) {
-               if (log_devices_add_to_tail(devices, log_devices_new("/dev/"LOGGER_LOG_SYSTEM))) {
-                       fprintf(stderr,"Can't add log device: %s\n", LOGGER_LOG_SYSTEM);
-                       exit(-1);
+               /* only add this if it's available */
+               if (0 == access("/dev/"LOGGER_LOG_SYSTEM, accessmode)) {
+                       if (log_devices_add_to_tail(devices, log_devices_new("/dev/"LOGGER_LOG_SYSTEM))) {
+                               fprintf(stderr,"Can't add log device: %s\n", LOGGER_LOG_SYSTEM);
+                               exit(-1);
+                       }
                }
-       }
-       if (0 == access("/dev/"LOGGER_LOG_APPS, accessmode)) {
-               if (log_devices_add_to_tail(devices, log_devices_new("/dev/"LOGGER_LOG_APPS))) {
-                       fprintf(stderr,"Can't add log device: %s\n", LOGGER_LOG_APPS);
-                       exit(-1);
+               if (0 == access("/dev/"LOGGER_LOG_APPS, accessmode)) {
+                       if (log_devices_add_to_tail(devices, log_devices_new("/dev/"LOGGER_LOG_APPS))) {
+                               fprintf(stderr,"Can't add log device: %s\n", LOGGER_LOG_APPS);
+                               exit(-1);
+                       }
                }
+
        }
 
-/*
-        // only add this if it's available
-       int fd;
-       if ((fd = open("/dev/"LOGGER_LOG_SYSTEM, mode)) != -1) {
-               devices->next = (struct log_device_t *)malloc( sizeof(struct log_device_t));
-               devices->next->device = strdup("/dev/"LOGGER_LOG_SYSTEM);
-               devices->next->fd = -1;
-               devices->next->printed = false;
-               devices->next->queue = NULL;
-               devices->next->next = NULL;
-               g_dev_count ++;
-
-               close(fd);
-        }
-*/
-    }
-
-    if (g_log_rotate_size_kbytes != 0 && g_output_filename == NULL)
+       if (g_log_rotate_size_kbytes != 0 && g_output_filename == NULL)
        {
                fprintf(stderr,"-r requires -f as well\n");
                show_help(argv[0]);
                exit(-1);
        }
 
-    setup_output();
+       setup_output();
 
 
        if (has_set_log_format == 0) {
                err = set_log_format("brief");
        }
-/*
-               const char* logFormat = getenv("DLOG_PRINTF_LOG");
+       fprintf(stderr,"arc = %d, optind = %d ,Kb %d, rotate %d\n", argc, optind,g_log_rotate_size_kbytes,g_max_rotated_logs);
 
-               if (logFormat != NULL) {
-                       err = set_log_format("brief");
+       if(argc == optind ) {
+               /* Add from environment variable
+               char *env_tags_orig = getenv("DLOG_TAGS");*/
+               log_add_filter_string(g_logformat, "*:d");
+       } else {
+
+               for (i = optind ; i < argc ; i++) {
+                       err = log_add_filter_string(g_logformat, argv[i]);
 
                        if (err < 0) {
-                               fprintf(stderr, "invalid format in DLOG_PRINTF_LOG '%s'\n", logFormat);
+                               fprintf (stderr, "Invalid filter expression '%s'\n", argv[i]);
+                               show_help(argv[0]);
+                               exit(-1);
                        }
                }
        }
-       if (forceFilters) {
-               err = log_add_filter_string(g_logformat, forceFilters);
-               if (err < 0) {
-                       fprintf (stderr, "Invalid filter expression in -logcat option\n");
-                       exit(0);
+       dev = devices;
+       while (dev) {
+               dev->fd = open(dev->device, mode);
+               if (dev->fd < 0) {
+                       fprintf(stderr, "Unable to open log device '%s': %s\n",
+                                       dev->device, strerror(errno));
+                       exit(EXIT_FAILURE);
                }
-       } else if (argc == optind) {
-        // Add from environment variable
-               char *env_tags_orig = getenv("DLOG_LOG_TAGS");
 
-               if (env_tags_orig != NULL) {
-                       err = log_add_filter_string(g_logformat, env_tags_orig);
-
-                       if (err < 0) {
-                               fprintf(stderr, "Invalid filter expression in DLOG_LOG_TAGS\n");
-                               show_help(argv[0]);
-                               exit(-1);
+               if (is_clear_log) {
+                       int ret;
+                       ret = clear_log(dev->fd);
+                       if (ret) {
+                               perror("ioctl");
+                               exit(EXIT_FAILURE);
                        }
                }
-       } else {
-        // Add from commandline
-*/
-       fprintf(stderr,"arc = %d, optind = %d ,Kb %d, rotate %d\n", argc, optind,g_log_rotate_size_kbytes,g_max_rotated_logs);
 
-       if(argc == optind )
-       {
-               // Add from environment variable
-        //char *env_tags_orig = getenv("DLOG_TAGS");
-               log_add_filter_string(g_logformat, "*:d");
-       }
-       else
-       {
+               if (getLogSize) {
+                       int size, readable;
 
-               for (i = optind ; i < argc ; i++) {
-                       err = log_add_filter_string(g_logformat, argv[i]);
+                       size = get_log_size(dev->fd);
+                       if (size < 0) {
+                               perror("ioctl");
+                               exit(EXIT_FAILURE);
+                       }
 
-                       if (err < 0) {
-                               fprintf (stderr, "Invalid filter expression '%s'\n", argv[i]);
-                               show_help(argv[0]);
-                               exit(-1);
+                       readable = get_log_readable_size(dev->fd);
+                       if (readable < 0) {
+                               perror("ioctl");
+                               exit(EXIT_FAILURE);
                        }
+
+                       printf("%s: ring buffer is %dKb (%dKb consumed), "
+                                       "max entry is %db, max payload is %db\n", dev->device,
+                                       size / 1024, readable / 1024,
+                                       (int) LOGGER_ENTRY_MAX_LEN, (int) LOGGER_ENTRY_MAX_PAYLOAD);
                }
+
+               dev = dev->next;
        }
-/*
-    }
-*/
-    dev = devices;
-    while (dev) {
-        dev->fd = open(dev->device, mode);
-        if (dev->fd < 0) {
-            fprintf(stderr, "Unable to open log device '%s': %s\n",
-                dev->device, strerror(errno));
-            exit(EXIT_FAILURE);
-        }
-
-        if (is_clear_log) {
-            int ret;
-            ret = clear_log(dev->fd);
-            if (ret) {
-                perror("ioctl");
-                exit(EXIT_FAILURE);
-            }
-        }
-
-        if (getLogSize) {
-            int size, readable;
-
-            size = get_log_size(dev->fd);
-            if (size < 0) {
-                perror("ioctl");
-                exit(EXIT_FAILURE);
-            }
-
-            readable = get_log_readable_size(dev->fd);
-            if (readable < 0) {
-                perror("ioctl");
-                exit(EXIT_FAILURE);
-            }
-
-            printf("%s: ring buffer is %dKb (%dKb consumed), "
-                   "max entry is %db, max payload is %db\n", dev->device,
-                   size / 1024, readable / 1024,
-                   (int) LOGGER_ENTRY_MAX_LEN, (int) LOGGER_ENTRY_MAX_PAYLOAD);
-        }
-
-        dev = dev->next;
-    }
-
-    if (getLogSize) {
-        return 0;
-    }
-
-    if (is_clear_log) {
-        return 0;
-    }
-
-    read_log_lines(devices);
+
+       if (getLogSize) {
+               return 0;
+       }
+
+       if (is_clear_log) {
+               return 0;
+       }
+
+       read_log_lines(devices);
 
        log_devices_chain_free(devices);
 
-    return 0;
+       return 0;
 }
index 449732c..9215b4c 100755 (executable)
@@ -43,6 +43,8 @@ static FilterInfo * filterinfo_new(const char *tag, log_priority pri)
 {
        FilterInfo *p_ret;
        p_ret = (FilterInfo *)calloc(1, sizeof(FilterInfo));
+       if (!p_ret)
+               return NULL;
        p_ret->mTag = strdup(tag);
        p_ret->mPri = pri;
 
@@ -172,6 +174,8 @@ log_format *log_format_new()
 
        p_ret = calloc(1, sizeof(log_format));
 
+       if (!p_ret)
+               return NULL;
        p_ret->global_pri = DLOG_SILENT;
        p_ret->format = FORMAT_BRIEF;
 
@@ -219,6 +223,8 @@ log_print_format log_format_from_string(const char * formatString)
                format = FORMAT_TIME;
        else if (strcmp(formatString, "threadtime") == 0)
                format = FORMAT_THREADTIME;
+       else if (strcmp(formatString, "dump") == 0)
+               format = FORMAT_DUMP;
        else if (strcmp(formatString, "long") == 0)
                format = FORMAT_LONG;
        else format = FORMAT_OFF;
@@ -339,34 +345,54 @@ static inline char * strip_end(char *str)
  * Returns 0 on success and -1 on invalid wire format (entry will be
  * in unspecified state)
  */
-int log_process_log_buffer(struct logger_entry *buf,log_entry *entry)
+int log_process_log_buffer(struct logger_entry *buf, log_entry *entry)
 {
-       size_t tag_len;
+       int i, start = -1, end = -1;
+
+       if (buf->len < 3) {
+               fprintf(stderr, "Entry too small\n");
+               return -1;
+       }
 
        entry->tv_sec = buf->sec;
        entry->tv_nsec = buf->nsec;
        entry->pid = buf->pid;
        entry->tid = buf->tid;
 
-       if (buf->msg[0] < 0 || buf->msg[0] > DLOG_SILENT) { /* char can be signed too */
+       entry->priority = buf->msg[0];
+       if (entry->priority < 0 || entry->priority > DLOG_SILENT) {
+               fprintf(stderr, "Wrong priority message\n");
+               return -1;
+       }
 
-               /* There is no tag in this message - which is an error, but it might
-                * happen when sombody redirects stdout/err to /dev/log_*.
-                *
-                * Pick ERROR priority as this shouldn't happen.
-                */
-               entry->priority = DLOG_ERROR;
-               entry->tag = "[NO TAG]";
-               entry->messageLen = buf->len;
-               entry->message = buf->msg;
-       } else {
-               entry->priority = buf->msg[0];
-               entry->tag = buf->msg + 1;
-               tag_len = strlen(entry->tag);
-               entry->messageLen = buf->len - tag_len - 3;
-               entry->message = entry->tag + tag_len + 1;
+       entry->tag = buf->msg + 1;
+       if (!strlen(entry->tag)) {
+               fprintf(stderr, "No tag message\n");
+               return -1;
        }
 
+       for (i = 0; i < buf->len; i++) {
+               if (buf->msg[i] == '\0') {
+                       if (start == -1) {
+                               start = i + 1;
+                       } else {
+                               end = i;
+                               break;
+                       }
+               }
+       }
+       if (start == -1) {
+               fprintf(stderr, "Malformed log message\n");
+               return -1;
+       }
+       if (end == -1) {
+               end = buf->len - 1;
+               buf->msg[end] = '\0';
+       }
+
+       entry->message = buf->msg + start;
+       entry->messageLen = end - start;
+
        return 0;
 }
 
@@ -388,7 +414,7 @@ char *log_format_log_line (
        struct tm tmBuf;
 #endif
        struct tm* ptm;
-       char timeBuf[32];
+       char timeBuf[32], tzBuf[16];
        char prefixBuf[128], suffixBuf[128];
        char priChar;
        int prefixSuffixIsHeaderFooter = 0;
@@ -411,6 +437,7 @@ char *log_format_log_line (
        ptm = localtime(&(entry->tv_sec));
 #endif
        strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
+       strftime(tzBuf, sizeof(tzBuf), "%z", ptm);
 
        /*
         * Construct a buffer containing the log header and log message.
@@ -443,15 +470,23 @@ char *log_format_log_line (
                break;
        case FORMAT_TIME:
                prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
-                               "%s.%03ld %c/%-8s(%5d): ", timeBuf, entry->tv_nsec / 1000000,
-                               priChar, entry->tag, (int)entry->pid);
+                               "%s.%03ld%s %c/%-8s(%5d): ", timeBuf, entry->tv_nsec / 1000000,
+                               tzBuf, priChar, entry->tag, (int)entry->pid);
                strcpy(suffixBuf, "\n");
                suffixLen = 1;
                break;
        case FORMAT_THREADTIME:
                prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
-                               "%s.%03ld %5d %5d %c %-8s: ", timeBuf, entry->tv_nsec / 1000000,
-                               (int)entry->pid, (int)entry->tid, priChar, entry->tag);
+                               "%s.%03ld%s %5d %5d %c %-8s: ", timeBuf, entry->tv_nsec / 1000000,
+                               tzBuf, (int)entry->pid, (int)entry->tid, priChar, entry->tag);
+               strcpy(suffixBuf, "\n");
+               suffixLen = 1;
+               break;
+       case FORMAT_DUMP:
+               prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),
+                               "%s.%03ld%s %5d %5d %c %-8s: ", timeBuf,
+                               entry->tv_nsec / 1000000, tzBuf, (int)entry->pid,
+                               (int)entry->tid, priChar, entry->tag);
                strcpy(suffixBuf, "\n");
                suffixLen = 1;
                break;