After porting busybox to Android, I want to play with syslogd. So I first link busybox into a syslogd to facilitate subsequent direct command start:
Ln-s busybox syslogd
Ls-l
Lrwxrwxrwx Root syslogd-> busybox
OK. Now you can start it:
1 | root @ Android:/data/test #./syslogd
./Syslogd
Root @ Android:/data/test #
I thought the execution was successful, but PS found that the syslogd process does not exist. Then, add the-n parameter to run it on the foreground to see if there is any prompt:
Root @ Android:/data/test #./syslogd-n
./Syslogd-n
Syslogd: BIND: no such file or directory
Binding failed. Next, you can only check the code to further troubleshoot the problem.
Busybox uses UNIX socket communication. The/dev/log file is used by default as the socket file, which is implemented in the create_socket function:
static NOINLINE int create_socket(void){。。。/* Unlink old /dev/log or object it points to. *//* (if it exists, bind will fail) */strcpy(sunx.sun_path, "/dev/log");dev_log_name = xmalloc_follow_symlinks("/dev/log");if (dev_log_name) {safe_strncpy(sunx.sun_path, dev_log_name, sizeof(sunx.sun_path));free(dev_log_name);}。。。
The problem actually exists here.
Because on my Samsung Android phone, there is/dev/log, and here the log is still a folder with other files, as a result, the above Code fails to call BIND (the Code indicates/dev/log is a socket file), so the error "address already in use" is returned.
The cause of the problem is clear. In Android, only the/data directory is readable. For example, all my test programs are stored in the/data/test directory, all databases are stored in the/data/APP directory.
Therefore, modify the directory above to/data/test/dev/log (to search for code, there are several places to change, but actually there are only two places to use, all others are log-recorded, but we recommend that you modify them all to ensure consistency.
Then, after creating the dev directory under the/data/test directory, run syslogd again.
Root @ Android:/data/test # mkdir Dev
Mkdir Dev
Root @ Android:/data/test #./syslogd
./Syslogd
Root @ Android:/data/test # ps | grep syslogd
PS | grep syslogd
Root 27628 1 2196 240 c0c27c24 running a86c S./syslogd
Root @ Android:/data/test #
After the preceding modification, syslogd can be started normally, but syslog cannot be written. Why?
After using strace tracking, we found the following prints:
BRK (0x32000) = 0x32000
Gettimeofday ({1357486044,584 293}, null) = 0
Open ("/etc/localtime", o_rdonly) =-1 enoent (no such file or directory)
Getpid () = 1, 32223
Socket (pf_file, sock_dgram | sock_cloexec, 0) = 3
Connect (3, {sa_family = af_file, sun_path = "/dev/log" },110) =-1 econnrefused (connection refused)
Close (3) = 0
Open ("/dev/console", o_wronly | o_noctty) =-1 enodev (no such device)
Exit_group (0) =?
++ Exited with 0 ++
That is, functions such as openlog and syslog are connected to the/dev/log socket by default. If they cannot be connected, they cannot write logs. Since openlog and syslog are implemented in the libc library, the worst consequence is to modify the libc library. We have to study how to change it.
From the code, this is defined in the libc library through macro _ path_log. The corresponding file is:
Bits/syslog-path.h
The original thought that modifying the macro definition in this header file can solve the problem, but found that the libc file has been compiled into/dev/log, so you must re-compile libc to make the modification take effect.