📄 00000017.htm
字号:
char *acct_file; <BR>char eofc = '\004'; /* Control-D = PostScript EOF */ <BR>int psfd = STDOUT_FILENO; <BR>int start_page = -1; <BR>int end_page = -1; <BR>int debug; <BR>int in_job; <BR>volatile sig_atomic_t intr_flag; <BR>volatile sig_atomic_t alrm_flag; <BR>enum status status = INVALID; <BR>_______________________________________________________________________ <BR>________ <BR>程序17.2 声明全局变量 <BR>_______________________________________________________________________ <BR>________ <BR>#include "lprps.h" <BR>static void usage(void); <BR>int <BR>main(int argc, char *argv[]) <BR>{ <BR> int c; <BR> log_open("lprps", LOG_PID, LOG_LPR); <BR> opterr = 0; /* don't want getopt() writing to stderr */ <BR> while ( (c = getopt(argc, argv, "cdh:i:l:n:x:y:w:")) != EOF) { <BR> switch (c) { <BR> case 'c': /* control chars to be passed */ <BR> case 'x': /* horizontal page size */ <BR> case 'y': /* vertical page size */ <BR> case 'w': /* width */ <BR> case 'l': /* length */ <BR> case 'i': /* indent */ <BR> break; /* not interested in these */ <BR> case 'd': /* debug (interactive) */ <BR> debug = 1; <BR> break; <BR> case 'n': /* login name of user */ <BR> loginname = optarg; <BR> break; <BR> case 'h': /* host name of user */ <BR> hostname = optarg; <BR> break; <BR> case '?': <BR> log_msg("unrecognized option: -%c", optopt); <BR> usage(); <BR> } <BR> } <BR> if (hostname == NULL || loginname == NULL) <BR> usage(); /* require both hostname and loginname */ <BR> if (optind < argc) <BR> acct_file = argv[optind]; /* remaining arg = acct file */ <BR> if (debug) <BR> tty_open(); <BR> if (atexit(close_mailfp) < 0) /* register func for exit() */ <BR> log_sys("main: atexit error"); <BR> get_status(); <BR> get_page(&start_page); <BR> send_file(); /* copies stdin to printer */ <BR> get_page(&end_page); <BR> do_acct(); <BR> exit(EXIT_SUCCESS); <BR>} <BR>static void <BR>usage(void) <BR>{ <BR> log_msg("lprps: invalid arguments"); <BR> exit(EXIT_THROW_AWAY); <BR>} <BR>_______________________________________________________________________ <BR>________ <BR>程序17.3 main函数 <BR> 然后处理命令行参数,很多参数会被PostScript打印机所忽略。我们使用-d标 <BR>志指示这个程序是交互运行,而不是作为精灵进程。如果设置了这个标志,我们需 <BR>要初始化终端模式(tty_open)。然后我们将函数close_mailfp指定为退出处理程 <BR>序。 <BR> 我们就可以调用在图17.6中提到的函数:取得打印机状态保证它是就绪的(ge <BR>t_status),得到打印机的起始页码(get_page),发送文件(PostScript程序)到 <BR>打印机(send_file),得到打印机的结束页码(get_page),写记帐记录(do_acct), <BR>然后终止。 <BR> 文件acct.c定义了函数do_acct(程序17。4)。它在main函数的结尾处被调用, <BR>用来写下记帐记录。记帐文件的路径和名字从printcap文件中的相应记录项(图1 <BR>7.4)获得,并作为命令行的最后一个参数。 <BR>_______________________________________________________________________ <BR>________ <BR>#include "lprps.h" <BR>/* Write the number of pages, hostname, and loginname to the <BR> * accounting file. This function is called by main() at the end <BR> * (if all was OK, by printer_flushing(), and by handle_intr() if <BR> * an interrupt is received. */ <BR>void <BR>do_acct(void) <BR>{ <BR> FILE *fp; <BR> if (end_page > start_page && <BR> acct_file != NULL && <BR> (fp = fopen(acct_file, "a")) != NULL) { <BR> fprintf(fp, "%7.2f %s:%s\n", <BR> (double)(end_page - start_page), <BR> hostname, loginname); <BR> if (fclose(fp) == EOF) <BR> log_sys("do_acct: fclose error"); <BR> } <BR>} <BR>_______________________________________________________________________ <BR>________ <BR>程序17.4 do_acct函数 <BR> 从历史上看,所有的BSD打印过滤器都使用%7.2f的printf格式,把输出的页数 <BR>写到记帐文件中。这样就允许光栅设备不使用页数,而以英尺为单位报告输出长度 <BR>。 <BR> 下面一个文件是tty.c(程序17.5),它包含了所有的终端I/O函数。它们调用 <BR>我们在第三章中提到的函数(fcntl, write和open)和第11章中的POSIX..1终端函 <BR>数(tcflush, tcgetattr, tcsetattr, cfsetispeed 和cfsetospeed)。如果我们 <BR>允许发生写阻塞,那么要调用block_write函数。如果我们不希望发生阻塞,则调 <BR>用set_nonblock函数,然后再调用read或者write函数。因为PostScript是一个全 <BR>双工的设备,打印机有可能发送数据回来(例如出错消息等),所以我们不希望阻 <BR>塞一个方向的写操作。如果打印机发送错误消息时,我们正因向其发送数据而处于 <BR>阻塞状态,则会出现死锁。 <BR> 一般是核心为终端输入和输出进行缓冲,所以如果发生错误,我们可以调用t <BR>ty_flush来刷清输入和输出队列。 <BR> 如果以交互方式运行该程序,那么main函数将调用函数tty_open。我们需要把 <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -