📄 fax_list.cpp
字号:
std::pair<const char*, char* const*> FaxListDialog::get_print_from_stdin_parms(void) { // lock the Prog_config object to stop it being modified or accessed in the initial (GUI) // thread while we are accessing it here Glib::Mutex::Lock lock(*prog_config.mutex_p); std::vector<std::string> print_parms; std::string print_cmd; std::string print_name; std::string::size_type end_pos; try { print_cmd = Glib::filename_from_utf8(prog_config.print_cmd); } catch (Glib::ConvertError&) { write_error("UTF-8 conversion error in FaxListDialog::print_from_stdin()\n"); return std::pair<const char*, char* const*>(0,0); } if ((end_pos = print_cmd.find_first_of(' ')) != std::string::npos) { // we have parms print_name.assign(print_cmd, 0, end_pos); print_parms.push_back(print_name); // find start of next parm std::string::size_type start_pos = print_cmd.find_first_not_of(' ', end_pos); while (start_pos != std::string::npos) { end_pos = print_cmd.find_first_of(' ', start_pos); if (end_pos != std::string::npos) { print_parms.push_back(print_cmd.substr(start_pos, end_pos - start_pos)); start_pos = print_cmd.find_first_not_of(' ', end_pos); // prepare for next interation } else { print_parms.push_back(print_cmd.substr(start_pos, print_cmd.size() - start_pos)); start_pos = end_pos; } } } else { // just a print command without parameters to be passed print_name = print_cmd; print_parms.push_back(print_name); } char** exec_parms = new char*[print_parms.size() + 1]; char** temp_pp = exec_parms; std::vector<std::string>::const_iterator iter; for (iter = print_parms.begin(); iter != print_parms.end(); ++iter, ++temp_pp) { *temp_pp = new char[iter->size() + 1]; std::strcpy(*temp_pp, iter->c_str()); } *temp_pp = 0; char* prog_name = new char[print_name.size() + 1]; std::strcpy(prog_name, print_name.c_str()); return std::pair<const char*, char* const*>(prog_name, exec_parms);}std::pair<const char*, char* const*> FaxListDialog::get_fax_to_ps_parms (const std::string& basename, bool allow_shrink) { // lock the Prog_config object to stop it being modified or accessed in the initial (GUI) // thread while we are accessing it here Glib::Mutex::Lock lock(*prog_config.mutex_p); // set up the parms for efix std::vector<std::string> efix_parms; std::string temp; efix_parms.push_back("efix-0.9a"); // shut up efix (comment out next line and uncomment following one if errors to be reported) efix_parms.push_back("-v"); //efix_parms.push_back("-ve"); efix_parms.push_back("-r300"); efix_parms.push_back("-ops"); temp = "-p"; temp += prog_config.page_dim; efix_parms.push_back(temp);#ifdef HAVE_STRINGSTREAM if (allow_shrink && prog_config.print_shrink.compare("100")) { // if print_shrink is not 100 temp = "-s0."; temp += prog_config.print_shrink; efix_parms.push_back(temp); std::ostringstream strm; if (!prog_config.page_size.compare("a4")) { strm << "-d"; float val = 210 * (100 - std::atoi(prog_config.print_shrink.c_str()))/200.0; strm << static_cast<int>(val + 0.5); val = 297 * (100 - std::atoi(prog_config.print_shrink.c_str()))/200.0; strm << ',' << static_cast<int>(val + 0.5) << "mm"; efix_parms.push_back(strm.str()); } else if (!prog_config.page_size.compare("letter")) { strm << "-d"; float val = 216 * (100 - std::atoi(prog_config.print_shrink.c_str()))/200.0; strm << static_cast<int>(val + 0.5); val = 279 * (100 - std::atoi(prog_config.print_shrink.c_str()))/200.0; strm << ',' << static_cast<int>(val + 0.5) << "mm"; efix_parms.push_back(strm.str()); } else if (!prog_config.page_size.compare("legal")) { strm << "-d"; float val = 216 * (100 - std::atoi(prog_config.print_shrink.c_str()))/200.0; strm << static_cast<int>(val + 0.5); val = 356 * (100 - std::atoi(prog_config.print_shrink.c_str()))/200.0; strm << ',' << static_cast<int>(val + 0.5) << "mm"; efix_parms.push_back(strm.str()); } } int partnumber = 1; std::ostringstream strm; strm << basename.c_str() << std::setfill('0') << std::setw(3) << partnumber; int result = access(strm.str().c_str(), R_OK); while (!result) { efix_parms.push_back(strm.str()); partnumber++; strm.str(""); strm << basename.c_str() << std::setfill('0') << std::setw(3) << partnumber; result = access(strm.str().c_str(), R_OK); }#else if (allow_shrink && prog_config.print_shrink.compare("100")) { // if print_shrink is not 100 temp = "-s0."; temp += prog_config.print_shrink; efix_parms.push_back(temp); std::ostrstream strm; if (!prog_config.page_size.compare("a4")) { strm << "-d"; float val = 210 * (100 - std::atoi(prog_config.print_shrink.c_str()))/200.0; strm << static_cast<int>(val + 0.5); val = 297 * (100 - std::atoi(prog_config.print_shrink.c_str()))/200.0; strm << ',' << static_cast<int>(val + 0.5) << "mm" << std::ends; const char* dim = strm.str(); efix_parms.push_back(dim); delete[] dim; } else if (!prog_config.page_size.compare("letter")) { strm << "-d"; float val = 216 * (100 - std::atoi(prog_config.print_shrink.c_str()))/200.0; strm << static_cast<int>(val + 0.5); val = 279 * (100 - std::atoi(prog_config.print_shrink.c_str()))/200.0; strm << ',' << static_cast<int>(val + 0.5) << "mm" << std::ends; const char* dim = strm.str(); efix_parms.push_back(dim); delete[] dim; } else if (!prog_config.page_size.compare("legal")) { strm << "-d"; float val = 216 * (100 - std::atoi(prog_config.print_shrink.c_str()))/200.0; strm << static_cast<int>(val + 0.5); val = 356 * (100 - std::atoi(prog_config.print_shrink.c_str()))/200.0; strm << ',' << static_cast<int>(val + 0.5) << "mm" << std::ends; const char* dim = strm.str(); efix_parms.push_back(dim); delete[] dim; } } int partnumber = 1; std::ostrstream strm; strm << basename.c_str() << std::setfill('0') << std::setw(3) << partnumber << std::ends; const char* file_name = strm.str(); int result = access(file_name, R_OK); while (!result) { efix_parms.push_back(file_name); delete[] file_name; partnumber++; std::ostrstream strm; strm << basename.c_str() << std::setfill('0') << std::setw(3) << partnumber << std::ends; file_name = strm.str(); result = access(file_name, R_OK); } delete[] file_name;#endif char** exec_parms = new char*[efix_parms.size() + 1]; char** temp_pp = exec_parms; std::vector<std::string>::const_iterator iter; for (iter = efix_parms.begin(); iter != efix_parms.end(); ++iter, ++temp_pp) { *temp_pp = new char[iter->size() + 1]; std::strcpy(*temp_pp, iter->c_str()); } *temp_pp = 0; char* prog_name = new char[std::strlen("efix-0.9a") + 1]; std::strcpy(prog_name, "efix-0.9a"); return std::pair<const char*, char* const*>(prog_name, exec_parms);}void FaxListDialog::write_from_stdin(int dest_fd) { ssize_t read_result; ssize_t write_result; char buffer[PIPE_BUF]; while ((read_result = read(0, buffer, PIPE_BUF)) != 0) { if (read_result == -1) { if (errno == EINTR) continue; else break; } do { write_result = write(dest_fd, buffer, read_result); } while (write_result == -1 && errno == EINTR); } Glib::usleep(50000);}std::pair<const char*, char* const*> FaxListDialog::get_ps_viewer_parms(const char* filename) { // lock the Prog_config object to stop it being modified or accessed in the initial (GUI) // thread while we are accessing it here Glib::Mutex::Lock lock(*prog_config.mutex_p); std::vector<std::string> view_parms; std::string view_cmd; std::string view_name; std::string::size_type end_pos; try { view_cmd = Glib::filename_from_utf8(prog_config.ps_view_cmd); } catch (Glib::ConvertError&) { write_error("UTF-8 conversion error in FaxListDialog::ps_viewer()\n"); return std::pair<const char*, char* const*>(0,0); } if ((end_pos = view_cmd.find_first_of(' ')) != std::string::npos) { // we have parms view_name.assign(view_cmd, 0, end_pos); view_parms.push_back(view_name); // find start of next parm std::string::size_type start_pos = view_cmd.find_first_not_of(' ', end_pos); while (start_pos != std::string::npos) { end_pos = view_cmd.find_first_of(' ', start_pos); if (end_pos != std::string::npos) { view_parms.push_back(view_cmd.substr(start_pos, end_pos - start_pos)); start_pos = view_cmd.find_first_not_of(' ', end_pos); // prepare for next interation } else { view_parms.push_back(view_cmd.substr(start_pos, view_cmd.size() - start_pos)); start_pos = end_pos; } } } else { // just a print command without parameters to be passed view_name = view_cmd; view_parms.push_back(view_name); } view_parms.push_back(filename); char** exec_parms = new char*[view_parms.size() + 1]; char** temp_pp = exec_parms; std::vector<std::string>::const_iterator iter; for (iter = view_parms.begin(); iter != view_parms.end(); ++iter, ++temp_pp) { *temp_pp = new char[iter->size() + 1]; std::strcpy(*temp_pp, iter->c_str()); } *temp_pp = 0; char* prog_name = new char[view_name.size() + 1]; std::strcpy(prog_name, view_name.c_str()); return std::pair<const char*, char* const*>(prog_name, exec_parms);}void FaxListDialog::print_fax(void) { Gtk::TreeModel::iterator row_iter = tree_view.get_selection()->get_selected(); if (row_iter) { // fax_basename_sem is initialised to a count of 1, so this will stop // fax_basename being overwritten until Sem_sync::post() is called in // print_fax_thread() or view_fax_thread() or on Glib::ThreadError being // caught fax_basename_sem.wait(); fax_basename = prog_config.homedir; if (mode == received) fax_basename += "/faxin/"; else fax_basename += "/faxsent/"; fax_basename += (*row_iter)[model_columns.fax_name]; fax_basename += '/'; fax_basename += (*row_iter)[model_columns.fax_name]; fax_basename += '.'; // now block off the signals for which we have set handlers so that the socket server // thread does not receive the signals, otherwise we will have memory synchronisation // issues in multi-processor systems - we will unblock in the initial (GUI) thread // as soon as the socket server thread has been launched sigset_t sig_mask; sigemptyset(&sig_mask); sigaddset(&sig_mask, SIGCHLD); sigaddset(&sig_mask, SIGQUIT); sigaddset(&sig_mask, SIGTERM); sigaddset(&sig_mask, SIGINT); sigaddset(&sig_mask, SIGHUP);#ifdef HAVE_PTHREAD_SIGMASK pthread_sigmask(SIG_BLOCK, &sig_mask, 0);#else sigprocmask(SIG_BLOCK, &sig_mask, 0);#endif try { Glib::Thread::create(sigc::mem_fun(*this, &FaxListDialog::print_fax_thread), false); } catch (Glib::ThreadError&) { write_error("Cannot start new print thread, fax will not be printed\n"); fax_basename_sem.post(); } // now unblock the signals so that the initial (GUI) thread can receive them#ifdef HAVE_PTHREAD_SIGMASK pthread_sigmask(SIG_UNBLOCK, &sig_mask, 0);#else sigprocmask(SIG_UNBLOCK, &sig_mask, 0);#endif }}void FaxListDialog::print_fax_thread(void) { // get the arguments for the exec() calls below (because this is a // multi- threaded program, we must do this before fork()ing because // we use functions to get the arguments which are not async-signal-safe) std::pair<const char*, char* const*> print_from_stdin_parms(get_print_from_stdin_parms()); std::pair<const char*, char* const*> fax_to_ps_parms(get_fax_to_ps_parms(fax_basename, true)); // release main GUI thread in print_fax() or view_fax() // waiting for this use of fax_basename to finish fax_basename_sem.post(); if (print_from_stdin_parms.first) { // this will be 0 if get_print_from_stdin_parms() // threw a Glib::ConvertError) // now launch a new process to control the printing process // the main program process needs to continue while the printing // is going on pid_t pid = fork(); if (pid == -1) { write_error("Fork error - exiting\n"); std::exit(FORK_ERROR); } if (!pid) { // child print process // make the call to connect_to_stderr() in this child process // dependent on calling a print confirmation popupr dialog: if we have // elected not to bring up such a dialog, we are probably using a // print manager such as kprinter, and we can get confusing messages // from stderr from these // no mutex is required for the access to prog_config.print_popup // because we have fork()ed into a separate process if (prog_config.print_popup) connect_to_stderr(); // now create a blocking pipe which the print processes can use to // communicate via stdout/stdin Pipe_fifo fork_pipe(Pipe_fifo::block); pid_t pid = fork(); if (pid == -1) { write_error("Fork error - exiting\n"); _exit(FORK_ERROR); } if (!pid) { // process to exec to print_from_stdin() fork_pipe.connect_to_stdin(); execvp(print_from_stdin_parms.first, print_from_stdin_parms.second); // if we reached this point, then the execvp() call must have failed // write error and then end process - use _exit(), not exit() write_error("Can't find the print program - please check your installation\n" "and the PATH environmental variable\n"); _exit(0); } // this is the process which will send postscript to stdout fork_pipe.connect_to_stdout(); execvp(fax_to_ps_parms.first, fax_to_ps_parms.second); // if we reached this point, then the execvp() call must have failed // report error and then end process - use _exit(), not exit() write_error("Can't find the efix-0.9a program - please check your installation\n" "and the PATH environmental variable\n"); _exit(0); } // release the memory allocated on the heap for // the redundant print_from_stdin_parms and fax_to_ps_parms // we are in the main parent process here - no worries about // only being able to use async-signal-safe functions
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -