diff --git a/cups-usb-paperout.patch b/cups-usb-paperout.patch index 82123f4..a549e79 100644 --- a/cups-usb-paperout.patch +++ b/cups-usb-paperout.patch @@ -1,182 +1,51 @@ ---- cups-1.2.10/backend/runloop.c.usb-paperout 2006-12-06 20:10:16.000000000 +0000 -+++ cups-1.2.10/backend/runloop.c 2007-07-04 12:12:00.000000000 +0100 -@@ -40,6 +40,14 @@ - #endif /* __hpux */ - +--- cups-1.2.10/backend/usb-unix.c.usb-paperout 2007-06-26 15:11:14.000000000 +0100 ++++ cups-1.2.10/backend/usb-unix.c 2007-06-26 15:16:23.000000000 +0100 +@@ -39,6 +39,11 @@ + #include "ieee1284.c" + #include +#ifdef __linux +#include +#include -+#include -+int linux_usb_paperout_hack = 0; +#endif /* __linux */ + -+ - /* - * 'backendRunLoop()' - Read and write print and back-channel data. - */ -@@ -64,6 +72,9 @@ - #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) - struct sigaction action; /* Actions for POSIX signals */ - #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ -+#ifdef __linux -+ time_t last_write = 0; /* Last time write() succeeded */ -+#endif /* __linux */ - - - fprintf(stderr, "DEBUG: backendRunLoop(print_fd=%d, device_fd=%d, use_bc=%d)\n", -@@ -110,8 +121,6 @@ - FD_ZERO(&input); - if (!print_bytes) - FD_SET(print_fd, &input); -- if (use_bc) -- FD_SET(device_fd, &input); - - FD_ZERO(&output); - if (print_bytes || !use_bc) -@@ -119,7 +128,10 @@ - if (use_bc) - { -- if (select(nfds, &input, &output, NULL, NULL) < 0) -+ struct timeval fives; -+ fives.tv_sec = 5; -+ fives.tv_usec = 0; -+ if (select(nfds, &input, &output, NULL, &fives) < 0) - { - /* - * Pause printing to clear any pending errors... -@@ -141,14 +153,24 @@ - * Check if we have back-channel data ready... - */ - -- if (FD_ISSET(device_fd, &input)) -+ if (use_bc && FD_ISSET(device_fd, &output)) /* finished writing */ - { -- if ((bc_bytes = read(device_fd, bc_buffer, sizeof(bc_buffer))) > 0) -+ struct timeval nowait; -+ fd_set readback; -+ FD_ZERO (&readback); -+ nowait.tv_sec = 0; -+ nowait.tv_usec = 0; -+ FD_SET(device_fd, &readback); -+ if (select (device_fd + 1, &readback, NULL, NULL, &nowait) && -+ FD_ISSET(device_fd, &readback)) - { -- fprintf(stderr, -- "DEBUG: Received " CUPS_LLFMT " bytes of back-channel data!\n", -- CUPS_LLCAST bc_bytes); -- cupsBackChannelWrite(bc_buffer, bc_bytes, 1.0); -+ if ((bc_bytes = read(device_fd, bc_buffer, sizeof(bc_buffer))) > 0) -+ { -+ fprintf(stderr, -+ "DEBUG: Received " CUPS_LLFMT " bytes of back-channel data!\n", -+ CUPS_LLCAST bc_bytes); -+ cupsBackChannelWrite(bc_buffer, bc_bytes, 1.0); -+ } - } - } - -@@ -219,6 +241,10 @@ - offline = 1; - } - } -+ else if (linux_usb_paperout_hack && errno == EAGAIN) -+ { -+ sleep (1); -+ } - else if (errno != EAGAIN && errno != EINTR && errno != ENOTTY) - { - perror("ERROR: Unable to write print data"); -@@ -227,6 +253,9 @@ - } - else - { -+#ifdef __linux -+ last_write = time (NULL); -+#endif /* __linux */ - if (paperout) - { - fputs("STATE: -media-empty-error\n", stderr); -@@ -247,7 +276,42 @@ - total_bytes += bytes; - } - } + /* + * Local functions... +@@ -308,7 +313,19 @@ + if (!strncmp(uri, "usb:/dev/", 9)) + #ifdef __linux + { +- return (open(uri + 4, O_RDWR | O_EXCL)); ++ fd = open(uri + 4, O_RDWR | O_EXCL); + -+#ifdef __linux -+ if (linux_usb_paperout_hack) ++ if (fd != -1) + { -+ time_t now; -+ if (!paperout && -+ ((now = time(NULL)) - last_write) >= 5) -+ { -+ unsigned int status; -+ if (ioctl (device_fd, LPGETSTATUS, &status) == 0 && -+ (status & LP_POUTPA)) -+ { -+ fputs("ERROR: Out of paper!\n", stderr); -+ fputs("STATE: +media-empty-error\n", stderr); -+ paperout = 1; -+ } -+ -+ /* Don't check status for another 5s. */ -+ last_write = now; -+ } ++ /* ++ * Tell the driver to return from write() with errno==ENOSPACE ++ * on paper-out. ++ */ ++ unsigned int t = 1; ++ ioctl (fd, LPABORT, &t); + } -+#endif /* __linux */ -+ } + -+#ifdef __linux -+ if (linux_usb_paperout_hack) -+ { -+ /* Wait for the last write() to finish. */ -+ do -+ { -+ FD_ZERO(&output); -+ FD_SET(device_fd, &output); -+ } while (select(device_fd + 1, NULL, &output, NULL, NULL) < 0 && -+ errno == EINTR); ++ return fd; } -+#endif /* __linux */ - - /* - * Return with success... ---- cups-1.2.10/backend/usb-unix.c.usb-paperout 2007-07-04 12:11:46.000000000 +0100 -+++ cups-1.2.10/backend/usb-unix.c 2007-07-04 12:11:46.000000000 +0100 -@@ -39,6 +39,11 @@ - #include "ieee1284.c" - #include - -+#ifdef __linux -+#include -+#include -+extern int linux_usb_paperout_hack; -+#endif /* __linux */ - - /* - * Local functions... -@@ -70,6 +75,11 @@ - (void)argc; - (void)argv; - -+#ifdef __linux -+ /* Get the runloop to check for USB paper-out condition. */ -+ linux_usb_paperout_hack = 1; -+#endif /* __linux */ + else if (!strncmp(uri, "usb://", 6)) + { +@@ -374,7 +391,14 @@ + if (!strcmp(uri, device_uri)) + { + /* +- * Yes, return this file descriptor... ++ * Yes, tell the driver to return from write() with ++ * errno==ENOSPACE on paper-out. ++ */ ++ unsigned int t = 1; ++ ioctl (fd, LPABORT, &t); + - /* - * Open the USB port device... - */ -@@ -150,6 +160,12 @@ - - tcsetattr(device_fd, TCSANOW, &opts); ++ /* ++ * Return this file descriptor... + */ -+#ifdef __linux -+ /* Put the file descriptor into non-blocking mode so that we -+ * get a chance to detect paper-out. */ -+ fcntl (device_fd, F_SETFL, fcntl (device_fd, F_GETFL) | O_NONBLOCK); -+#endif /* __linux */ -+ - /* - * Finally, send the print file... - */ + fprintf(stderr, "DEBUG: Printer using device file \"%s\"...\n", device); diff --git a/cups.spec b/cups.spec index 57aeacb..6aba017 100644 --- a/cups.spec +++ b/cups.spec @@ -6,7 +6,7 @@ Summary: Common Unix Printing System Name: cups Version: 1.2.12 -Release: 1%{?dist} +Release: 2%{?dist} License: GPL Group: System Environment/Daemons Source: ftp://ftp.easysw.com/pub/cups/%{version}/cups-%{version}-source.tar.bz2 @@ -441,6 +441,10 @@ rm -rf $RPM_BUILD_ROOT %{cups_serverbin}/daemon/cups-lpd %changelog +* Mon Jul 23 2007 Tim Waugh 1:1.2.12-2 +- Use kernel support for USB paper-out detection, when available + (bug #249213). + * Fri Jul 13 2007 Tim Waugh 1:1.2.12-1 - 1.2.12. No longer need adminutil or str2408 patches.