<div style="line-height:1.7;color:#000000;font-size:14px;font-family:arial"><br><div class="moz-cite-prefix">Hi Tanu,<br>
<br>
On 06/11/2013 12:22 AM, Tanu Kaskinen wrote:<br>
</div>
<blockquote cite="mid:1370881344.2639.50.camel@dev-laptop" type="cite">
<pre wrap="">On Mon, 2013-05-20 at 23:49 +0800, Shuai Fan wrote:
</pre>
<blockquote type="cite">
<pre wrap="">---
src/daemon/daemon-conf.c | 75 +++++----------------
src/daemon/daemon-conf.h | 3 +-
src/daemon/main.c | 11 +--
src/pulsecore/cli-command.c | 49 +++++++-------
src/pulsecore/log.c | 161 ++++++++++++++++++++++++++++++++++++++++++--
src/pulsecore/log.h | 22 ++++--
6 files changed, 221 insertions(+), 100 deletions(-)
diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index f1e5476..7726c90 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -179,65 +179,21 @@ void pa_daemon_conf_free(pa_daemon_conf *c) {
#define PA_LOG_MAX_SUFFIX_NUMBER 100
int pa_daemon_conf_set_log_target(pa_daemon_conf *c, const char *string) {
+ pa_log_target *log_target = NULL;
+
pa_assert(c);
pa_assert(string);
- if (pa_streq(string, "auto"))
- c->auto_log_target = 1;
- else if (pa_streq(string, "syslog")) {
- c->auto_log_target = 0;
- c->log_target = PA_LOG_SYSLOG;
- } else if (pa_streq(string, "stderr")) {
- c->auto_log_target = 0;
- c->log_target = PA_LOG_STDERR;
- } else if (pa_startswith(string, "file:")) {
- char file_path[512];
- int log_fd;
-
- pa_strlcpy(file_path, string + 5, sizeof(file_path));
-
- /* Open target file with user rights */
- if ((log_fd = open(file_path, O_RDWR|O_TRUNC|O_CREAT, S_IRUSR | S_IWUSR)) >= 0) {
- c->auto_log_target = 0;
- c->log_target = PA_LOG_FD;
- pa_log_set_fd(log_fd);
- } else {
- printf("Failed to open target file %s, error : %s\n", file_path, pa_cstrerror(errno));
- return -1;
- }
- } else if (pa_startswith(string, "newfile:")) {
- char file_path[512];
- int log_fd;
- int version = 0;
- int left_size;
- char *p;
-
- pa_strlcpy(file_path, string + 8, sizeof(file_path));
-
- left_size = sizeof(file_path) - strlen(file_path);
- p = file_path + strlen(file_path);
-
- do {
- memset(p, 0, left_size);
-
- if (version > 0)
- pa_snprintf(p, left_size, ".%d", version);
- } while (++version <= PA_LOG_MAX_SUFFIX_NUMBER &&
- (log_fd = open(file_path, O_RDWR|O_TRUNC|O_CREAT|O_EXCL, S_IRUSR | S_IWUSR)) < 0);
-
- if (version > PA_LOG_MAX_SUFFIX_NUMBER) {
- memset(p, 0, left_size);
- printf("Tried to open target files '%s', '%s.1', '%s.2' ... '%s.%d', but all failed.\n",
- file_path, file_path, file_path, file_path, PA_LOG_MAX_SUFFIX_NUMBER - 1);
+ if (!pa_streq(string, "auto")) {
+ log_target = pa_log_parse_target(string);
+
+ if (!log_target) {
+ c->log_target = log_target;
return -1;
</pre>
</blockquote>
<pre wrap="">If a function fails, it should not have any side effects (if possible).
Here you're setting c->log_target to NULL if
pa_daemon_conf_set_log_target() fails. That probably doesn't have
problems in practice, but it's not good style.</pre>
</blockquote>
I'm sorry for doing that. I think it works like this:<br>
<br>
if (!pa_streq(string, "auto")) { <br>
log_target = pa_log_parse_target(string); <br>
} <br>
<br>
if (log_target) <br>
c->log_target = log_target;<br>
<br>
<br>
and the the following ...<br>
<blockquote cite="mid:1370881344.2639.50.camel@dev-laptop" type="cite">
<blockquote type="cite">
<pre wrap="">- } else {
- printf("Opened target file %s\n", file_path);
- c->auto_log_target = 0;
- c->log_target = PA_LOG_FD;
- pa_log_set_fd(log_fd);
}
- } else
- return -1;
+ }
+
+ c->log_target = log_target;</pre>
</blockquote>
</blockquote>
... should be moved.<br>
<blockquote cite="mid:1370881344.2639.50.camel@dev-laptop" type="cite">
<blockquote type="cite">
<pre wrap="">
return 0;
}
diff --git a/src/pulsecore/log.c b/src/pulsecore/log.c
index 8eaef54..f95031a 100644
--- a/src/pulsecore/log.c
+++ b/src/pulsecore/log.c
@@ -63,9 +66,11 @@
#define ENV_LOG_BACKTRACE "PULSE_LOG_BACKTRACE"
#define ENV_LOG_BACKTRACE_SKIP "PULSE_LOG_BACKTRACE_SKIP"
#define ENV_LOG_NO_RATELIMIT "PULSE_LOG_NO_RATE_LIMIT"
+#define LOG_MAX_SUFFIX_NUMBER 100
static char *ident = NULL; /* in local charset format */
-static pa_log_target_t target = PA_LOG_STDERR, target_override;
+static pa_log_target target = { PA_LOG_STDERR, NULL };
+static pa_log_target_type_t target_override;
static pa_bool_t target_override_set = FALSE;
static pa_log_level_t maximum_level = PA_LOG_ERROR, maximum_level_override = PA_LOG_ERROR;
static unsigned show_backtrace = 0, show_backtrace_override = 0, skip_backtrace = 0;
@@ -113,10 +118,62 @@ void pa_log_set_level(pa_log_level_t l) {
maximum_level = l;
}
-void pa_log_set_target(pa_log_target_t t) {
- pa_assert(t < PA_LOG_TARGET_MAX);
+int pa_log_set_target(pa_log_target *t) {
+ char *file_path = NULL;
+ int length = 0;
+ int fd = -1;
+ int version = 0;
+ int left_size = 0;
+ char *p = NULL;
+
+ pa_assert(t);
+
+ switch (t->type) {
+ case PA_LOG_STDERR:
+ case PA_LOG_SYSLOG:
+ case PA_LOG_NULL:
+ target = *t;
+ break;
+ case PA_LOG_FILE:
+ if ((fd = pa_open_cloexec(t->file, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)) >= 0) {
+ target = *t;
+ pa_log_set_fd(fd);
+ } else {
+ pa_log(_("Failed to open target file '%s'."), t->file);
+ return -1;
+ }
+ break;
+ case PA_LOG_NEWFILE:
+ left_size = LOG_MAX_SUFFIX_NUMBER / 10 + 2;
+ length = strlen(t->file) + left_size;
+ file_path = pa_xmalloc(length);
+ pa_strlcpy(file_path, t->file, length);
+ p = file_path + strlen(t->file);
</pre>
</blockquote>
<pre wrap="">These last five lines are redundant, because...
</pre>
<blockquote type="cite"><pre wrap="">+
+ do {
+ memset(p, 0, left_size);
+
+ if (version > 0)
+ pa_snprintf(p, left_size, ".%d", version);
</pre></blockquote>
<pre wrap="">...it's easier to do just
file_path = pa_sprintf_malloc("%s.%d", t->file, version);</pre>
</blockquote>
<br>
Yes, it is shorter.<br>
<br>
I tried this:<br>
<br>
file_path = pa_sprintf_malloc("%s.%d", t->file, version); <br>
left_size = strlen(file_path) - strlen(t->file) + 1; <br>
p = file_path + strlen(t->file); <br>
<br>
do { <br>
memset(p, 0, left_size); <br>
<br>
if (version > 0) <br>
pa_snprintf(p, left_size, ".%d", version); <br>
} while (++version < LOG_MAX_SUFFIX_NUMBER && <br>
(fd = pa_open_cloexec(file_path, O_WRONLY | O_TRUNC | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) < 0);<br>
<br>
<br>
It seems better and works fine.<br>
<br>
I found a bug in this function(? or maybe I misunderstood it ?). Currently, LOG_MAX_SUFFIX_NUMBER is set to 100.<br>
#define LOG_MAX_SUFFIX_NUMBER 100<br>
Then I changed it to 5 in order to test the number of new_log_target files.<br>
#define LOG_MAX_SUFFIX_NUMBER 5<br>
and use command "set-log-target newfile:/home/shuai/newlog.txt" in src/pacmd, 6 times(to see the error message).<br>
<br>
Then, I got newlog.txt, newlog.txt.1, newlog.txt.2, newlog.txt.3. That is to say, only 4 files, and the max suffix is only 3. <br>
<br>
The following code is the same(Fixed something which has noting to do with this stuff).<br>
<br>
In the above while loop:<br>
<br>
when version == 4, file_path = "/home/shuai/newlog.txt.4"<br>
but when ++version, version = 5, so (++version < LOG_MAX_SUFFIX_NUMBER) failed.<br>
so, the log-target "/home/shuai/newlog.txt.4" not opened(created). And
fd < 0, so, the log target "*.txt.4" not be set. And the loop is
ended.<br>
<br>
And, of course, the version > LOG_MAX_SUFFIX_NUMBER test will always
false. So, the error message(log message) will not be showed.<br>
<pre wrap="">+ if (version > LOG_MAX_SUFFIX_NUMBER) {<br>+ memset(p, 0, left_size);
+ pa_log(_("Tried to open target file '%s', '%s.1', '%s.2' ... '%s.%d', but all failed."),
+ file_path, file_path, file_path, file_path, LOG_MAX_SUFFIX_NUMBER - 1);
+ pa_xfree(file_path);<br>+ return -1;
+ } else {
+ pa_log_debug("Opened target file %s\n", file_path);
+ pa_log_set_fd(fd);
+ }
+ break;</pre>
<br>
I think there are 2 ways to fix this stuff:<br>
<br>
1. Change this:<br>
++version < LOG_MAX_SUFFIX_NUMBER<br>
to<br>
version++ < LOG_MAX_SUFFIX_NUMBER<br>
<br>
Then there will be 5 log target files(i. e. *, *.1, *.2, *.3, *.4), and the test will be changed:<br>
<pre wrap=""> if (version > LOG_MAX_SUFFIX_NUMBER) {</pre>
to<br>
<pre wrap=""> if (version >= LOG_MAX_SUFFIX_NUMBER) {<br></pre>
to show the error message.<br>
<br>
<br>
2. Change this:<br>
version++ < LOG_MAX_SUFFIX_NUMBER<br>
to <br>
version++ <= LOG_MAX_SUFFIX_NUMBER<br>
<br>
Then there will be 6 log target files(i. e. *, *.1, *.2, *.3, *.4, and *.5 included), and the largest suffix number is 5.<br>
<br>
<br>
Which one is better? I prefer the second.<br>
<br>
<br>
<br>
Well, I should have found this bug(?) earlier, the code is copied from other file. It's all my fault.<br>
<br>
<br>
<blockquote cite="mid:1370881344.2639.50.camel@dev-laptop" type="cite">
<blockquote type="cite"><pre wrap="">+ } while (++version < LOG_MAX_SUFFIX_NUMBER &&
+ (fd = pa_open_cloexec(file_path, O_WRONLY | O_TRUNC | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) < 0);
+
+ if (version > LOG_MAX_SUFFIX_NUMBER) {
+ memset(p, 0, left_size);
+ pa_log(_("Tried to open target file '%s', '%s.1', '%s.2' ... '%s.%d', but all failed."),
+ file_path, file_path, file_path, file_path, LOG_MAX_SUFFIX_NUMBER - 1);
+ return -1;
+ } else {
+ pa_log_debug("Opened target file %s\n", file_path);
+ target = *t;
+ pa_log_set_fd(fd);
+ }
+ break;
+ default:
+ return -1;
</pre></blockquote>
<pre wrap="">Don't bother having a default section. It prevents the compiler from
giving a warning if pa_log_target_type_t is some day extended and this
code is not updated accordingly.
</pre>
<blockquote type="cite"><pre wrap="">+ }
- target = t;
</pre></blockquote>
<pre wrap="">You could still have target = *t here, instead of duplicating it in
every branch of the switch statement.
</pre>
<blockquote type="cite">
<pre wrap="">+ return 0;
}
void pa_log_set_flags(pa_log_flags_t _flags, pa_log_merge_t merge) {
<br></pre>
</blockquote>
</blockquote>
<br>
<br>
Best wishes,<br>
Shuai<br>
</div>