X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=backend%2Frunloop.c;h=0b3f65f7864a55a80304a3b16f24eb6ba348e839;hb=23ef1cac65a36f01e78a88f4d987e6350b441990;hp=13f9c23daed9dc051f352c7cf616957b8396c643;hpb=c7017eccd21da514f345a5c7a41156b1adf7cb35;p=thirdparty%2Fcups.git diff --git a/backend/runloop.c b/backend/runloop.c index 13f9c23da..0b3f65f78 100644 --- a/backend/runloop.c +++ b/backend/runloop.c @@ -1,9 +1,9 @@ /* - * "$Id: runloop.c 7895 2008-09-02 19:19:43Z mike $" + * "$Id: runloop.c 9565 2011-02-23 00:08:08Z mike $" * - * Common run loop APIs for the Common UNIX Printing System (CUPS). + * Common run loop APIs for CUPS backends. * - * Copyright 2007-2009 by Apple Inc. + * Copyright 2007-2012 by Apple Inc. * Copyright 2006-2007 by Easy Software Products, all rights reserved. * * These coded instructions, statements, and computer programs are the @@ -18,6 +18,8 @@ * * backendDrainOutput() - Drain pending print data to the device. * backendRunLoop() - Read and write print and back-channel data. + * backendWaitLoop() - Wait for input from stdin while handling + * side-channel queries. */ /* @@ -90,7 +92,8 @@ backendDrainOutput(int print_fd, /* I - Print file descriptor */ if (errno != EAGAIN || errno != EINTR) { - perror("ERROR: Unable to read print data"); + fprintf(stderr, "DEBUG: Read failed: %s\n", strerror(errno)); + _cupsLangPrintFilter(stderr, "ERROR", _("Unable to read print data.")); return (-1); } @@ -119,8 +122,7 @@ backendDrainOutput(int print_fd, /* I - Print file descriptor */ if (errno != ENOSPC && errno != ENXIO && errno != EAGAIN && errno != EINTR && errno != ENOTTY) { - _cupsLangPrintf(stderr, _("ERROR: Unable to write print data: %s\n"), - strerror(errno)); + _cupsLangPrintError("ERROR", _("Unable to write print data")); return (-1); } } @@ -142,14 +144,13 @@ backendDrainOutput(int print_fd, /* I - Print file descriptor */ ssize_t /* O - Total bytes on success, -1 on error */ backendRunLoop( - int print_fd, /* I - Print file descriptor */ - int device_fd, /* I - Device file descriptor */ - int snmp_fd, /* I - SNMP socket or -1 if none */ - http_addr_t *addr, /* I - Address of device */ - int use_bc, /* I - Use back-channel? */ - int update_state, /* I - Update printer-state-reasons? */ - int (*side_cb)(int, int, int, http_addr_t *, int)) - /* I - Side-channel callback */ + int print_fd, /* I - Print file descriptor */ + int device_fd, /* I - Device file descriptor */ + int snmp_fd, /* I - SNMP socket or -1 if none */ + http_addr_t *addr, /* I - Address of device */ + int use_bc, /* I - Use back-channel? */ + int update_state, /* I - Update printer-state-reasons? */ + _cups_sccb_t side_cb) /* I - Side-channel callback */ { int nfds; /* Maximum file descriptor value + 1 */ fd_set input, /* Input set for reading */ @@ -249,13 +250,14 @@ backendRunLoop( if (errno == ENXIO && offline != 1 && update_state) { fputs("STATE: +offline-report\n", stderr); - _cupsLangPuts(stderr, _("INFO: Printer is currently offline.\n")); + _cupsLangPrintFilter(stderr, "INFO", + _("The printer is not connected.")); offline = 1; } else if (errno == EINTR && total_bytes == 0) { fputs("DEBUG: Received an interrupt before any bytes were " - "written, aborting\n", stderr); + "written, aborting.\n", stderr); return (0); } @@ -299,6 +301,8 @@ backendRunLoop( strerror(errno)); use_bc = 0; } + else if (bc_bytes == 0) + use_bc = 0; } /* @@ -316,7 +320,9 @@ backendRunLoop( if (errno != EAGAIN || errno != EINTR) { - perror("ERROR: Unable to read print data"); + fprintf(stderr, "DEBUG: Read failed: %s\n", strerror(errno)); + _cupsLangPrintFilter(stderr, "ERROR", + _("Unable to read print data.")); return (-1); } @@ -355,7 +361,7 @@ backendRunLoop( if (paperout != 1 && update_state) { fputs("STATE: +media-empty-warning\n", stderr); - _cupsLangPuts(stderr, _("DEBUG: Out of paper\n")); + fputs("DEBUG: Out of paper\n", stderr); paperout = 1; } } @@ -364,14 +370,14 @@ backendRunLoop( if (offline != 1 && update_state) { fputs("STATE: +offline-report\n", stderr); - _cupsLangPuts(stderr, _("INFO: Printer is currently off-line.\n")); + _cupsLangPrintFilter(stderr, "INFO", + _("The printer is not connected.")); offline = 1; } } else if (errno != EAGAIN && errno != EINTR && errno != ENOTTY) { - fprintf(stderr, _("ERROR: Unable to write print data: %s\n"), - strerror(errno)); + _cupsLangPrintError("ERROR", _("Unable to write print data")); return (-1); } } @@ -386,7 +392,8 @@ backendRunLoop( if (offline && update_state) { fputs("STATE: -offline-report\n", stderr); - _cupsLangPuts(stderr, _("INFO: Printer is now online.\n")); + _cupsLangPrintFilter(stderr, "INFO", + _("The printer is now connected.")); offline = 0; } @@ -420,5 +427,117 @@ backendRunLoop( /* - * End of "$Id: runloop.c 7895 2008-09-02 19:19:43Z mike $". + * 'backendWaitLoop()' - Wait for input from stdin while handling side-channel + * queries. + */ + +int /* O - 1 if data is ready, 0 if not */ +backendWaitLoop( + int snmp_fd, /* I - SNMP socket or -1 if none */ + http_addr_t *addr, /* I - Address of device */ + int use_bc, /* I - Use back-channel? */ + _cups_sccb_t side_cb) /* I - Side-channel callback */ +{ + int nfds; /* Number of file descriptors */ + fd_set input; /* Input set for reading */ + time_t curtime = 0, /* Current time */ + snmp_update = 0;/* Last SNMP status update */ + struct timeval timeout; /* Timeout for select() */ + + + fprintf(stderr, "DEBUG: backendWaitLoop(snmp_fd=%d, addr=%p, side_cb=%p)\n", + snmp_fd, addr, side_cb); + + /* + * Now loop until we receive data from stdin... + */ + + if (snmp_fd >= 0) + snmp_update = time(NULL) + 5; + + for (;;) + { + /* + * Use select() to determine whether we have data to copy around... + */ + + FD_ZERO(&input); + FD_SET(0, &input); + if (side_cb) + FD_SET(CUPS_SC_FD, &input); + + if (snmp_fd >= 0) + { + curtime = time(NULL); + timeout.tv_sec = curtime >= snmp_update ? 0 : snmp_update - curtime; + timeout.tv_usec = 0; + + nfds = select(CUPS_SC_FD + 1, &input, NULL, NULL, &timeout); + } + else + nfds = select(CUPS_SC_FD + 1, &input, NULL, NULL, NULL); + + if (nfds < 0) + { + /* + * Pause printing to clear any pending errors... + */ + + if (errno == EINTR) + { + fputs("DEBUG: Received an interrupt before any bytes were " + "written, aborting.\n", stderr); + return (0); + } + + sleep(1); + continue; + } + + /* + * Check for input on stdin... + */ + + if (FD_ISSET(0, &input)) + break; + + /* + * Check if we have a side-channel request ready... + */ + + if (side_cb && FD_ISSET(CUPS_SC_FD, &input)) + { + /* + * Do the side-channel request, then start back over in the select + * loop since it may have read from print_fd... + */ + + if ((*side_cb)(0, -1, snmp_fd, addr, use_bc)) + side_cb = NULL; + continue; + } + + /* + * Do SNMP updates periodically... + */ + + if (snmp_fd >= 0 && curtime >= snmp_update) + { + if (backendSNMPSupplies(snmp_fd, addr, NULL, NULL)) + snmp_fd = -1; + else + snmp_update = curtime + 5; + } + } + + /* + * Return with success... + */ + + return (1); +} + + +/* + * End of "$Id: runloop.c 9565 2011-02-23 00:08:08Z mike $". */