Index: runloop.c =================================================================== --- runloop.c (revision 5719) +++ runloop.c (working copy) @@ -53,6 +53,7 @@ total_bytes, /* Total bytes written */ bytes; /* Bytes written */ int paperout; /* "Paper out" status */ + int offline; /* "Off-line" status */ char print_buffer[8192], /* Print data buffer */ *print_ptr, /* Pointer into print data buffer */ bc_buffer[1024]; /* Back-channel data buffer */ @@ -61,6 +62,9 @@ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + fprintf(stderr, "DEBUG: backendRunLoop(print_fd=%d, device_fd=%d, use_bc=%d)\n", + print_fd, device_fd, use_bc); + /* * If we are printing data from a print driver on stdin, ignore SIGTERM * so that the driver can finish out any page data, e.g. to eject the @@ -93,7 +97,7 @@ * Now loop until we are out of data from print_fd... */ - for (print_bytes = 0, print_ptr = print_buffer, paperout = 0, total_bytes = 0;;) + for (print_bytes = 0, print_ptr = print_buffer, offline = 0, paperout = 0, total_bytes = 0;;) { /* * Use select() to determine whether we have data to copy around... @@ -106,12 +110,36 @@ FD_SET(device_fd, &input); FD_ZERO(&output); - if (print_bytes) + if (print_bytes || !use_bc) FD_SET(device_fd, &output); - if (select(nfds, &input, &output, NULL, NULL) < 0) - continue; /* Ignore errors here */ + if (use_bc) + { + if (select(nfds, &input, &output, NULL, NULL) < 0) + { + /* + * Pause printing to clear any pending errors... + */ + if (errno == ENXIO && !offline) + { + fputs("STATE: +offline-error\n", stderr); + fputs("INFO: Printer is currently off-line.\n", stderr); + offline = 1; + } + + sleep(1); + continue; + } + + if (offline) + { + fputs("STATE: -offline-error\n", stderr); + fputs("INFO: Printer is now on-line.\n", stderr); + offline = 0; + } + } + /* * Check if we have back-channel data ready... */ @@ -158,6 +186,9 @@ } print_ptr = print_buffer; + + fprintf(stderr, "DEBUG: Read %d bytes of print data...\n", + (int)print_bytes); } /* @@ -196,7 +227,7 @@ paperout = 0; } - fprintf(stderr, "DEBUG: Wrote %d bytes...\n", (int)bytes); + fprintf(stderr, "DEBUG: Wrote %d bytes of print data...\n", (int)bytes); print_bytes -= bytes; print_ptr += bytes; Index: usb-unix.c =================================================================== --- usb-unix.c (revision 5719) +++ usb-unix.c (working copy) @@ -44,7 +44,7 @@ * Local functions... */ -int open_device(const char *uri); +int open_device(const char *uri, int *use_bc); /* @@ -75,14 +75,6 @@ (void)argv; /* - * Disable backchannel data when printing to Canon USB printers - apparently - * Canon printers will return the IEEE-1284 device ID over and over and over - * when they get a read request... - */ - - use_bc = strcasecmp(hostname, "Canon") != 0; - - /* * Open the USB port device... */ @@ -90,7 +82,15 @@ do { - if ((device_fd = open_device(uri)) == -1) + /* + * Disable backchannel data when printing to Canon USB printers - apparently + * Canon printers will return the IEEE-1284 device ID over and over and over + * when they get a read request... + */ + + use_bc = strcasecmp(hostname, "Canon") != 0; + + if ((device_fd = open_device(uri, &use_bc)) == -1) { if (getenv("CLASS") != NULL) { @@ -195,7 +195,7 @@ lseek(print_fd, 0, SEEK_SET); } - tbytes = backendRunLoop(print_fd, device_fd, 1); + tbytes = backendRunLoop(print_fd, device_fd, use_bc); if (print_fd != 0 && tbytes >= 0) fprintf(stderr, "INFO: Sent print file, " CUPS_LLFMT " bytes...\n", @@ -277,7 +277,7 @@ { sprintf(device, "/dev/usb/printer%d", i); - if ((fd = open(device, O_RDWR | O_EXCL)) >= 0) + if ((fd = open(device, O_WRONLY | O_EXCL)) >= 0) { if (!backendGetDeviceID(fd, device_id, sizeof(device_id), make_model, sizeof(make_model), @@ -314,8 +314,12 @@ */ int /* O - File descriptor or -1 on error */ -open_device(const char *uri) /* I - Device URI */ +open_device(const char *uri, /* I - Device URI */ + int *use_bc) /* O - Set to 0 for unidirectional */ { + int fd; /* File descriptor */ + + /* * The generic implementation just treats the URI as a device filename... * Specific operating systems may also support using the device serial @@ -340,7 +344,6 @@ int i; /* Looping var */ int busy; /* Are any ports busy? */ - int fd; /* File descriptor */ char format[255], /* Format for device filename */ device[255], /* Device filename */ device_id[1024], /* Device ID string */ @@ -446,7 +449,6 @@ int i; /* Looping var */ int busy; /* Are any ports busy? */ - int fd; /* File descriptor */ char device[255], /* Device filename */ device_id[1024], /* Device ID string */ make_model[1024], /* Make and model */ @@ -463,7 +465,7 @@ { sprintf(device, "/dev/usb/printer%d", i); - if ((fd = open(device, O_RDWR | O_EXCL)) >= 0) + if ((fd = open(device, O_WRONLY | O_EXCL)) >= 0) backendGetDeviceID(fd, device_id, sizeof(device_id), make_model, sizeof(make_model), "usb", device_uri, sizeof(device_uri)); @@ -481,8 +483,18 @@ } if (!strcmp(uri, device_uri)) - return (fd); /* Yes, return this file descriptor... */ + { + /* + * Yes, return this file descriptor... + */ + fputs("DEBUG: Setting use_bc to 0!\n", stderr); + + *use_bc = 0; + + return (fd); + } + /* * This wasn't the one... */ @@ -514,7 +526,15 @@ return (-1); } #else - return (open(uri + 4, O_RDWR | O_EXCL)); + { + if ((fd = open(uri + 4, O_RDWR | O_EXCL)) < 0) + { + fd = open(uri + 4, O_WRONLY | O_EXCL); + *use_bc = 0; + } + + return (fd); + } #endif /* __linux */ else {