- added instructions how to update the online documentation
[bochs-mirror.git] / misc / spoolpipe.c
blobbd642ea5ac01e10a217ec8f78e3a2079aee5d153
1 /* $Id: spoolpipe.c,v 1.1 2002/09/23 19:25:06 bdenney Exp $
3 * spoolpipe.c
4 * by Carl Sopchak
6 * Read a pipe that stays open, send the data to a temp file. Print
7 * the temp file if no new input data is seen within a period of time. This
8 * is useful, e.g., to create separate spool files without exiting a program
9 * that doesn't close it's printer output file.
11 * ---------------------------------------------------------------------------
13 * Copyright (c) 2002 Cegis Enterprises, Inc. Syracuse, NY 13215
15 * ---------------------------------------------------------------------------
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 * --------------------------------------------------------------------------
32 * Modification log:
34 * 2002/05/20 - Initial programming
36 * --------------------------------------------------------------------------
39 #define BUF_SIZE 4*1024
40 #define DEBUG 0
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <sys/stat.h>
47 #include <sys/types.h>
48 #include <sys/wait.h>
49 #include <unistd.h>
51 int infd, outfd;
53 unsigned int delay = 60; // default delay, in seconds
54 unsigned int count_down = 0;
56 char buffer[BUF_SIZE];
57 ssize_t readcnt, writecnt;
59 int didwait = 0; // have we already waited?
60 int havedata = 0; // have we read anything in?
62 int q;
64 pid_t pid, wait_pid;
65 int wait_status;
67 int main (int argc, char *argv[]) {
69 #if DEBUG
70 printf("Command line arguments (%d):\n", argc);
71 for (q = 0; q < argc ; q++) {
72 printf(" %d = %s\n", q, argv[q]);
74 #endif
76 if ((argc < 3) || (argc > 4)) {
77 printf("usage: %s <inpipe> <tempfilename> [<maxdelay>]\n", argv[0]);
78 exit(1);
81 if (argc == 4) { // get delay
82 delay = strtol(argv[3], (char **) NULL, 10);
83 if (delay < 0) {
84 printf("Unable to convert maximum delay value: %s\n", argv[3]);
85 exit(2);
87 } // get delay
89 #if DEBUG
90 printf("Delay is set to %d seconds.\n", delay);
91 #endif
93 infd = open(argv[1], O_RDONLY | O_NONBLOCK);
94 if (infd == -1) {
95 printf("Error opening input pipe %s: %d - %s\n", argv[1], errno, strerror(errno));
96 exit(3);
99 outfd = open(argv[2], O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);
100 if (outfd == -1) {
101 printf("Error opening output file %s: %d - %s\n", argv[2], errno, strerror(errno));
102 exit(4);
105 count_down = delay;
106 while (1) { // must kill with a signal....
107 readcnt = read(infd, buffer, (size_t) BUF_SIZE);
108 #if DEBUG
109 printf("read() returned with readcnt = %d, errno = %d\n", readcnt, errno);
110 #endif
111 if ((readcnt == -1) && (errno != EAGAIN)) { // EAGAIN - no data waiting, can ignore
112 printf("Error reading input pipe: %d - %s\n", errno, strerror(errno));
113 exit(5);
114 } else { // no errors reading input pipe
115 if (readcnt > 0) {
116 writecnt = write(outfd, buffer, readcnt);
117 if (writecnt == -1) {
118 printf("Error writing output file: %d - %s\n", errno, strerror(errno));
119 exit(6);
121 didwait = 0; // reset wait flag (wait again)
122 count_down = delay;
123 havedata = 1; // set flag that we got some data
124 } else { //readcnt must = 0
125 if (!didwait) { //have not waited yet...
126 if (count_down > 0) { // sleep a bit
127 sleep(1);
128 count_down -= 1;
129 } else {
130 didwait = 1; // set wait flag (don't wait again)
132 } else { // already waited
133 if (havedata) { // have data to print, close & reopen output file
134 if (close(outfd) != 0) {
135 printf("Error closing output file: %d - %s\n", errno, strerror(errno));
136 exit(7);
139 #if DEBUG
140 printf("Spooling temp file...\n");
141 #endif
143 pid = fork();
144 if (pid == -1) {
145 printf("Error forking new process: %d - %s\n", errno, strerror(errno));
146 exit(9);
148 if (pid == 0) { // we're now running in the child process...
149 execlp("lpr", "lpr", argv[2], NULL);
150 exit(99); // should never get here...
151 } // we're now running in the child process...
152 if (pid > 0) { // we're running in the parent process...
153 wait_pid = waitpid(pid, (int *)&wait_status, 0);
154 if (wait_pid != pid) { // some sort of error
155 printf("Wait for 'lpr' command returned abnormally!\n");
156 if (WIFEXITED(wait_status)) {
157 printf(" 'lpr' exited normally.\n");
158 } else {
159 printf(" 'lpr' exited abnormally, return code = %d.\n", WEXITSTATUS(wait_status));
161 if (WIFSIGNALED(wait_status)) {
162 printf(" 'lpr' received uncaught signal %d\n", WTERMSIG(wait_status));
164 } // some sort of error
165 } // we're running in the parent process...
166 outfd = open(argv[2], O_RDWR | O_TRUNC);
167 if (outfd == -1) {
168 printf("Error re-opening output file: %d - %s\n", errno, strerror(errno));
169 exit(8);
171 } // have data to print, close & repoen output file.
172 havedata = 0; // no more data waiting
173 count_down = delay;
174 didwait = 0; // reset wait flag (wait again)
175 } // already waited
176 } // readcnt must = 0
177 } // no errors reading input pipe
178 } // must kill with a signal...
180 exit(0);
181 } // eof(spoolpipe.c)