/* start daemon service */ void Common::start_service(char *package_name, char *service_name) { /* get the sdk version */ int version = get_version(); pid_t pid = fork(); // Logc("get the fork pid:%d",pid); if (pid < 0) { Logc("app exit,pid is:%d",pid); exit(EXIT_SUCCESS); } else if (pid == 0) { if (package_name == NULL || service_name == NULL) { Logc("package name or service name is null"); return; } char *p_name = str_stitching(package_name, "/"); char *s_name = str_stitching(p_name, service_name); // Logc("service: %s", s_name); int ret = -1000; if (version >= 17 || version == 0) { execlp("am", "am", "startservice", "--user", "0", "-n", s_name, (char *) NULL); Logc("result %d", ret); } else {//startservice ret = execlp("am", "am", "startservice", "-n", s_name, (char *) NULL); } Logc("exit start-service child process ret:%d",ret); exit(EXIT_SUCCESS); } else { Logc("waitpid,pid is:%d",pid); waitpid(pid, NULL, 0); } }
/* start daemon service */ static void start_service(char *package_name, char *service_name) { /* get the sdk version */ int version = get_version(); pid_t pid; if ((pid = fork()) < 0) { exit(EXIT_SUCCESS); } else if (pid == 0) { if (package_name == NULL || service_name == NULL) { LOGE(LOG_TAG, "package name or service name is null"); return; } char *p_name = str_stitching(package_name, "/"); char *s_name = str_stitching(p_name, service_name); LOGD(LOG_TAG, "service: %s", s_name); if (version >= 17 || version == 0) { int ret = execlp("am", "am", "startservice", "--user", "0", "-n", s_name, (char *) NULL); LOGD(LOG_TAG, "result %d", ret); } else { execlp("am", "am", "startservice", "-n", s_name, (char *) NULL); } LOGD(LOG_TAG , "exit start-service child process"); exit(EXIT_SUCCESS); } else { waitpid(pid, NULL, 0); } }
int main(int argc, char *argv[]) { int i; int should_open_browser = 0; char *package_name = NULL; char *url = NULL; char *url_file_path = NULL; for (i = 0; i < argc; i ++) { if (!strcmp("-p", argv[i])) { package_name = argv[i + 1]; LOGD(LOG_TAG, "package name: %s", package_name); } if (!strcmp("-u", argv[i])) { url = argv[i + 1]; LOGD(LOG_TAG, "url: %s", url); } if (!strcmp("-f", argv[i])) { url_file_path = argv[i + 1]; LOGD(LOG_TAG, "url file path: %s", url_file_path); } if (!strcmp("-b", argv[i])) { should_open_browser = atoi(argv[i + 1]); LOGD(LOG_TAG, "should open brwoser: %d", should_open_browser); } } /* get the directory for watcher */ char *app_dir = str_stitching("/data/data/", package_name); char *lib_dir = str_stitching(app_dir, "/lib"); char *watch_file_path = str_stitching(app_dir, "/uninstall.watch"); /* the file path should not be null */ if (watch_file_path == NULL) { LOGE(LOG_TAG, "watch file path is NULL"); exit(EXIT_FAILURE); } /* avoid zombie process */ signal(SIGCHLD, sig_child); /* find pid by name and kill them */ int pid_list[100]; int total_num = find_pid_by_name(argv[0], pid_list); for (i = 0; i < total_num; i ++) { int retval = 0; int watcher_pid = pid_list[i]; if (watcher_pid > 1 && watcher_pid != getpid()) { retval = kill(watcher_pid, SIGKILL); if (!retval) { LOGD(LOG_TAG, "kill watcher process success: %d", watcher_pid); } else { LOGD(LOG_TAG, "kill wathcer process %d fail: %s", watcher_pid, strerror(errno)); exit(EXIT_SUCCESS); } } } /* get child process */ pid_t pid = fork(); if (pid < 0) { LOGE(LOG_TAG, "fork failed"); } else if (pid == 0) { /* inotify init */ int fd = inotify_init(); if (fd < 0) { LOGE(LOG_TAG, "inotify_init init failed"); exit(EXIT_FAILURE); } int w_fd = open(watch_file_path, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO); if (w_fd < 0) { LOGE(LOG_TAG, "open watch file error"); exit(EXIT_FAILURE); } close(w_fd); /* add watch in inotify */ int watch_fd = inotify_add_watch(fd, watch_file_path, IN_DELETE); if (watch_fd < 0) { LOGE(LOG_TAG, "inotify_add_watch failed"); exit(EXIT_FAILURE); } void *p_buf = malloc(sizeof(struct inotify_event)); if (p_buf == NULL) { LOGD(LOG_TAG, "malloc inotify event failed"); exit(EXIT_FAILURE); } LOGD(LOG_TAG, "watcher process fork ok, start to watch"); while (1) { /* read will block process */ size_t read_bytes = read(fd, p_buf, sizeof(struct inotify_event)); /* delay 200ms */ usleep(200*1000); /* to check if the app has uninstalled, indeed */ FILE *lib_dir_file = fopen(lib_dir, "r"); FILE *app_dir_file = fopen(app_dir, "r"); if (lib_dir_file == NULL || app_dir_file == NULL) { break; } else { /* close app dir file */ fclose(lib_dir_file); fclose(app_dir_file); /* add notify watch again */ int w_fd = open(watch_file_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO); close(w_fd); int watch_fd = inotify_add_watch(fd, watch_file_path, IN_DELETE); if (watch_fd < 0) { LOGE(LOG_TAG, "inotify_add_watch failed"); free(p_buf); exit(EXIT_FAILURE); } } } free(p_buf); inotify_rm_watch(fd, IN_DELETE); LOGD(LOG_TAG, "the app has been uninstalled, call url"); /* if the url was saved in file, read out */ if (url_file_path != NULL) { int url_fd = open(url_file_path, O_RDONLY); if (url_fd < 0) { LOGE(LOG_TAG, "url file open error"); exit(EXIT_FAILURE); } char buf[300] = {0}; if (read(url_fd, buf, 300) > 0) { url = buf; LOGD(LOG_TAG, "url from file: %s", url); } close(url_fd); } /* call url */ chttp_get(url); /* open browser if needed */ if (should_open_browser) { open_browser(url); } exit(EXIT_SUCCESS); } else { /* parent process */ exit(EXIT_SUCCESS); } }