PS C:\Users\aa> adb push C:\test\open /data/
C:\test\open: 1 file pushed. 0.7 MB/s (17096 bytes in 0.023s)
目标系统,
# ls /data/open -l
-rw-rw-rw- 1 root root 17096 Mar 11 10:28 /data/open
在handle_send_file()
中的功能如下(我添加了3行Printf)
file_sync_service.c
阅读代码后,我感到困惑。
static int handle_send_file(int s, char *path, mode_t mode, char *buffer)
{
syncmsg msg;
unsigned int timestamp = 0;
int fd;
printf("XXXXXX %s, path: %s, mode: %o\n", __func__, path, mode);
fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
printf("XXXXX fd: %d, errno: %d\n", fd, errno);
if(fd < 0 && errno == ENOENT) {
mkdirs(path);
fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
}
printf("XXXXX fd: %d, errno: %d\n", fd, errno);
if(fd < 0 && errno == EEXIST) {
fd = adb_open_mode(path, O_WRONLY, mode);
}
if(fd < 0) {
if(fail_errno(s))
return -1;
fd = -1;
}
我认为,如果存在
fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
printf("XXXXX fd: %d, errno: %d\n", fd, errno);
,则第203行应以
/data/open
的errno返回-1,并且应该转到第211行以使用EEXIST
打开文件。但这不是!但它显示了以下内容。
O_WRONLY
我再次从PC上推了XXXXXX handle_send_file, path: /data/open, mode: 666
XXXXX fd: 17, errno: 0
XXXXX fd: 17, errno: 0
sync: waiting for command
,然后得到。
open
当存在时,没有错误!这是正确的吗?中定义了XXXXXX handle_send_file, path: /data/open, mode: 666
XXXXX fd: 17, errno: 0
XXXXX fd: 17, errno: 0
sync: waiting for command
和相关的符号。
/data/open
我认为它打电话adb_open_mode()
,如果我错了,请纠正我。,然后,我编写了以下具有类似逻辑的代码,以查看其行为,当打开现有文件
sysdeps.h
.。
/*
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
* <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
* not already defined, then define it here.
*/
#ifndef TEMP_FAILURE_RETRY
/* Used to retry syscalls that can return EINTR. */
#define TEMP_FAILURE_RETRY(exp) ({ \
typeof (exp) _rc; \
do { \
_rc = (exp); \
} while (_rc == -1 && errno == EINTR); \
_rc; })
#endif
static __inline__ int adb_open_mode( const char* pathname, int options, int mode )
{
return TEMP_FAILURE_RETRY( open( pathname, options, mode ) );
}
open
通过预处理
adb_open_mode()
。我明白了,
/data/open
似乎是直接使用
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
int adb_open_mode(const char *path, int flags, mode_t mode) {
return open(path, flags, mode);
}
void fake_mkdirs(const char *path) {
printf("Creating directories for %s\n", path);
}
int main(int argc, char **argv)
{
const char *path = "/tmp/testfile";
/// mode_t mode = 0644;
mode_t mode = 0666;
int fd;
if (argc != 2) {
printf("Usage: %s filetoopen\n", argv[0]);
exit(0);
}
path = argv[1];
fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
printf("%s: %d, fd: %d, errno: %d\n", __func__, __LINE__, fd, errno);
if (fd < 0 && errno == ENOENT) {
fake_mkdirs(path);
fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode);
printf("%s: %d, fd: %d, errno: %d\n", __func__, __LINE__, fd, errno);
}
printf("%s: %d, fd: %d, errno: %d\n", __func__, __LINE__, fd, errno);
if (fd < 0 && errno == EEXIST) {
fd = adb_open_mode(path, O_WRONLY, mode);
}
printf("%s: %d, fd: %d, errno: %d\n", __func__, __LINE__, fd, errno);
if (fd < 0) {
perror("Failed to open file");
} else {
printf("File opened successfully with fd %d\n", fd);
close(fd);
}
return 0;
}
。
then,我尝试了adbd` -ff -o/tmp/a.log# ./a.out /data/open
main: 32, fd: -1, errno: 17
main: 38, fd: -1, errno: 17
main: 42, fd: 3, errno: 17
File opened successfully with fd 3
adbpush c:/inotify/data/data/ad adbpush'.
file_sync_service.c
显示static __inline__ int adb_open_mode( const char* pathname, int options, int mode )
{
return
# 344 "/home/t/android-tools-4.2.2+git20130218/core/adbd/sysdeps.h" 3 4
(__extension__ ({ long int __result; do __result = (long int) (
# 344 "/home/t/android-tools-4.2.2+git20130218/core/adbd/sysdeps.h"
open( pathname, options, mode )
# 344 "/home/t/android-tools-4.2.2+git20130218/core/adbd/sysdeps.h" 3 4 ); while (__result == -1L && (*__errno_location ()) == 4); __result; }))
# 344 "/home/t/android-tools-4.2.2+git20130218/core/adbd/sysdeps.h"
;
}
首先在打开和写入之前。使它清楚。
有更多的测试,我发现了
adbd
开放行为。简短的答案是“这不是出乎意料的”。
open
strace -p \
删除了要在目标目录中推入目标目录的文件。调用, then
创建文件。它来自以下代码。
, I got the log about the
通过删除write(1, "sync: waiting for command\n", 26) = 26
read(15, "STAT\6\0\0\0", 8) = 8
read(15, "/data/", 6) = 6
statx(AT_FDCWD, "/data/", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_BASIC_STATS, {stx_mask=STATX_BASIC_STATS|0x1000, stx_at
write(15, "STAT\375A\0\0`\22\0\0A\t\0\0", 16) = 16
write(1, "sync: waiting for command\n", 26) = 26
read(15, "SEND\23\0\0\0", 8) = 8
read(15, "/data/inotify,33206", 19) = 19
unlink("/data/inotify") = 0
write(1, "XXXXXX handle_send_file, path: /"..., 56) = 56
openat(AT_FDCWD, "/data/inotify", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0666) = 16
write(1, "XXXXX fd: 16, errno: 0\n", 23) = 23
write(1, "XXXXX fd: 16, errno: 0\n", 23) = 23
....
,我可以按照以下方式获得公开行为,
adbd