static void test_getline(void *p) { struct MBuf buf; mbuf_init_dynamic(&buf); tt_assert(foreach_line(filename, addln, &buf)); tt_assert(mbuf_write_byte(&buf, 0)); end: unlink(filename); mbuf_free(&buf); }
static int start_daemon (pam_handle_t *ph, struct passwd *pwd, const char *password) { struct sigaction defsact, oldsact, ignpipe, oldpipe; int inp[2] = { -1, -1 }; int outp[2] = { -1, -1 }; int errp[2] = { -1, -1 }; int ret = PAM_SERVICE_ERR; pid_t pid; char *output = NULL; char *outerr = NULL; int failed, status; assert (pwd); /* * Make sure that SIGCHLD occurs. Otherwise our waitpid below * doesn't work properly. We need to wait on the process to * get the daemon exit status. */ memset (&defsact, 0, sizeof (defsact)); memset (&oldsact, 0, sizeof (oldsact)); defsact.sa_handler = SIG_DFL; sigaction (SIGCHLD, &defsact, &oldsact); /* * Make sure we don't exit with a SIGPIPE while doing this, that * would be very annoying to a user trying to log in. */ memset (&ignpipe, 0, sizeof (ignpipe)); memset (&oldpipe, 0, sizeof (oldpipe)); ignpipe.sa_handler = SIG_IGN; sigaction (SIGPIPE, &ignpipe, &oldpipe); /* Create the necessary pipes */ if (pipe (inp) < 0 || pipe (outp) < 0 || pipe (errp) < 0) { syslog (GKR_LOG_ERR, "gkr-pam: couldn't create pipes: %s", strerror (errno)); goto done; } /* Start up daemon child process */ switch (pid = fork ()) { case -1: syslog (GKR_LOG_ERR, "gkr-pam: couldn't fork: %s", strerror (errno)); goto done; /* This is the child */ case 0: setup_child (inp, outp, errp, ph, pwd); /* Should never be reached */ break; /* This is the parent */ default: break; }; /* Close our unneeded ends of the pipes */ close (inp[READ_END]); close (outp[WRITE_END]); close (errp[WRITE_END]); inp[READ_END] = outp[WRITE_END] = errp[WRITE_END] = -1; /* * We always pass in a --login argument, even when we have a NULL password * since this controls the startup behavior. When using --login daemon waits * for a password. Closing input signifies password is done. */ if (password) write_string (inp[WRITE_END], password); close (inp[WRITE_END]); /* * Note that we're not using select() or any such. We know how the * daemon sends its data. */ /* Read any stdout and stderr data */ output = read_string (outp[READ_END]); outerr = read_string (errp[READ_END]); if (!output || !outerr) { syslog (GKR_LOG_ERR, "gkr-pam: couldn't read data from mate-keyring-daemon: %s", strerror (errno)); goto done; } /* Wait for the initial process to exit */ if (waitpid (pid, &status, 0) < 0) { syslog (GKR_LOG_ERR, "gkr-pam: couldn't wait on mate-keyring-daemon process: %s", strerror (errno)); goto done; } failed = !WIFEXITED (status) || WEXITSTATUS (status) != 0; if (outerr && outerr[0]) foreach_line (outerr, log_problem, &failed); /* Failure from process */ if (failed) { syslog (GKR_LOG_ERR, "gkr-pam: mate-keyring-daemon didn't start properly properly"); goto done; } ret = foreach_line (output, setup_environment, ph); done: /* Restore old handler */ sigaction (SIGCHLD, &oldsact, NULL); sigaction (SIGPIPE, &oldpipe, NULL); close_safe (inp[0]); close_safe (inp[1]); close_safe (outp[0]); close_safe (outp[1]); close_safe (errp[0]); close_safe (errp[1]); free_safe (output); free_safe (outerr); return ret; }
//转换线程 void CDlgFileConv::ConvThreadProc() { std::string srcf, dstf; std::string charset; FILE *fp, *fps; char bom_charset[MAX_CHARSET]; int count; bool success; count = m_convFileInfo.src_files.size(); m_convFileInfo.total = count; for (int i = 0; i < count; i++) { if (m_bTerminate) { PostMessage(WM_USER_CONV_STOP, count - i); return; } srcf = m_convFileInfo.src_files.front(); dstf = m_convFileInfo.dst_files.front(); m_convFileInfo.src_files.pop_front(); m_convFileInfo.dst_files.pop_front(); fp = fps = NULL; fps = xfopen(srcf.c_str(), "rb"); if (!fps) goto finish; create_directories(dstf.c_str()); fp = xfopen(dstf.c_str(), "wb"); if (!fp) goto finish; //忽略源文件的BOM头 m_convFileInfo.src_bom_charset = ""; if (read_file_bom(fps, bom_charset, MAX_CHARSET)) { //如果存在BOM头但是其所代表的字符集与用户选择的字符集不一致 if (strcasecmp(bom_charset, m_convFileInfo.src_charset.c_str())) { //TODO:提醒用户 m_convFileInfo.src_bom_charset = bom_charset; } } charset = m_convFileInfo.src_charset; if (!m_convFileInfo.src_bom_charset.empty()) charset = m_convFileInfo.src_bom_charset; //写入目标文件的BOM头 if (m_bWriteBOM) write_file_bom(fp, m_convFileInfo.dst_charset.c_str()); // 如果原文件是UTF-16/32编码,foreach_line函数不能很好地处理换行 // 因此需要一次性转换 if (charset.find("UTF-16") != NPOS || charset.find("UTF-32") != NPOS) { success = ConvertFileToCharset(fps, fp, charset.c_str(), m_convFileInfo.dst_charset); } else { // 逐行转换原文件 m_convFileInfo.fp = fp; success = foreach_line(fps, convert_line, &m_convFileInfo) == 1; } finish: if (success) { log_dprintf(LOG_INFO, "Converting %s ... %s(%s) -> %s(%s)\n", srcf.c_str(), charset.c_str(), utils::FileSizeReadable(ftell(fps)).c_str(), m_convFileInfo.dst_charset.c_str(), utils::FileSizeReadable(ftell(fp)).c_str()); } else { m_convFileInfo.failed ++; log_dprintf(LOG_ERROR, "Failed to convert %s (%s)\n", srcf.c_str(), charset.c_str()); } if (fps) xfclose(fps); if (fp) xfclose(fp); //总体转换进度 PostMessage(WM_USER_CONV_PROG, i+1, count); } log_flush(DEBUG_LOG); //发送转换完成消息 PostMessage(WM_USER_CONV_DONE); }