Printing multiple copies on remote printers
russell-cups at stuart.id.au
russell-cups at stuart.id.au
Wed Dec 8 18:33:21 PST 2004
This bug has been observed in cups-1.1.20final+rc1 that
comes with Debian, and cups-1.1.22 compiled from source.
Remote printers are occassionally printing multiple
copies of jobs. None of the jobs had the "copies"
option set.
The multiple copies was caused by two things:
1. Made http_wait() did not handle EINTR.
2. The wait in ipp_http_read was too short for connections
that run over the internet.
Note:
While both these bugs need to be fixed, neither completely
solves the original multiple copies problem. To solve
that no data should be printed if there was a read or
other error.
Patch that fixed the problems in cups-1.1.20final+rc1:
diff -Nur cupsys-1.1.20final+rc1.old/cups/http.c cupsys-1.1.20final+rc1/cups/http.c
--- cupsys-1.1.20final+rc1.old/cups/http.c 2004-05-28 04:17:54.000000000 +1000
+++ cupsys-1.1.20final+rc1/cups/http.c 2004-12-09 11:59:53.000000000 +1000
@@ -2000,6 +2000,9 @@
* 'http_wait()' - Wait for data available on a connection.
*/
+#define MSEC_2_TV(tv, msec) (tv.tv_sec = msec / 1000, tv.tv_usec = msec % 1000 * 1000)
+#define TV_2_MSEC(tv) (tv.tv_sec * 1000 + tv.tv_usec / 1000)
+
static int /* O - 1 if data is available, 0 otherwise */
http_wait(http_t *http, /* I - HTTP data */
int msec) /* I - Milliseconds to wait */
@@ -2008,8 +2011,11 @@
struct rlimit limit; /* Runtime limit */
#endif /* !WIN32 */
struct timeval timeout; /* Timeout */
+ struct timeval start; /* When we started waiting */
+ struct timeval now; /* The time now */
int nfds; /* Result from select() */
int set_size; /* Size of select set */
+ int delay; /* Time remaining in milli seconds */
DEBUG_printf(("http_wait(http=%p, msec=%d)\n", http, msec));
@@ -2069,19 +2075,32 @@
return (0);
}
- FD_SET(http->fd, http->input_set);
- if (msec >= 0)
- {
- timeout.tv_sec = msec / 1000;
- timeout.tv_usec = (msec % 1000) * 1000;
+ gettimeofday(&start, 0);
+ now = start;
- nfds = select(http->fd + 1, http->input_set, NULL, NULL, &timeout);
- }
- else
- nfds = select(http->fd + 1, http->input_set, NULL, NULL, NULL);
+ for (;;) {
+
+ FD_SET(http->fd, http->input_set);
+
+ delay = msec - (TV_2_MSEC(now) - TV_2_MSEC(start));
+
+ if (delay >= 0)
+ {
+ MSEC_2_TV(timeout, delay);
+ nfds = select(http->fd + 1, http->input_set, NULL, NULL, &timeout);
+ }
+ else
+ nfds = select(http->fd + 1, http->input_set, NULL, NULL, NULL);
+
+ FD_CLR(http->fd, http->input_set);
+
+ if (nfds >= 0 || errno != EINTR)
+ break;
+
+ gettimeofday(&now, 0);
+ }
- FD_CLR(http->fd, http->input_set);
return (nfds > 0);
}
diff -Nur cupsys-1.1.20final+rc1.old/cups/ipp.c cupsys-1.1.20final+rc1/cups/ipp.c
--- cupsys-1.1.20final+rc1.old/cups/ipp.c 2004-02-26 06:14:51.000000000 +1000
+++ cupsys-1.1.20final+rc1/cups/ipp.c 2004-12-09 11:59:53.000000000 +1000
@@ -2501,7 +2501,12 @@
* Wait up to 1 second for more data on non-blocking sockets...
*/
+ /*
+ * 1 second is far too short for a connection that runs over
+ * the internet. 2 minutes is a more reasonable value.
if (!httpWait(http, 1000))
+ */
+ if (!httpWait(http, 2 * 60 * 1000))
{
/*
* Signal no data...
More information about the cups
mailing list