#include "backend-private.h"
#ifdef __hpux
# include <sys/time.h>
#else
# include <sys/select.h>
#endif
int
backendDrainOutput(int print_fd,
int device_fd)
{
int nfds;
fd_set input;
ssize_t print_bytes,
bytes;
char print_buffer[8192],
*print_ptr;
struct timeval timeout;
fprintf(stderr, "DEBUG: backendDrainOutput(print_fd=%d, device_fd=%d)\n",
print_fd, device_fd);
nfds = (print_fd > device_fd ? print_fd : device_fd) + 1;
for (;;)
{
FD_ZERO(&input);
FD_SET(print_fd, &input);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
if (select(nfds, &input, NULL, NULL, &timeout) < 0)
return (-1);
if (!FD_ISSET(print_fd, &input))
return (0);
if ((print_bytes = read(print_fd, print_buffer,
sizeof(print_buffer))) < 0)
{
if (errno != EAGAIN || errno != EINTR)
{
perror("ERROR: Unable to read print data");
return (-1);
}
print_bytes = 0;
}
else if (print_bytes == 0)
{
return (0);
}
fprintf(stderr, "DEBUG: Read %d bytes of print data...\n",
(int)print_bytes);
for (print_ptr = print_buffer; print_bytes > 0;)
{
if ((bytes = write(device_fd, print_ptr, print_bytes)) < 0)
{
if (errno != ENOSPC && errno != ENXIO && errno != EAGAIN &&
errno != EINTR && errno != ENOTTY)
{
_cupsLangPrintf(stderr, _("ERROR: Unable to write print data: %s\n"),
strerror(errno));
return (-1);
}
}
else
{
fprintf(stderr, "DEBUG: Wrote %d bytes of print data...\n", (int)bytes);
print_bytes -= bytes;
print_ptr += bytes;
}
}
}
}
ssize_t
backendRunLoop(
int print_fd,
int device_fd,
int use_bc,
void (*side_cb)(int, int, int))
{
int nfds;
fd_set input,
output;
ssize_t print_bytes,
bc_bytes,
total_bytes,
bytes;
int paperout;
int offline;
char print_buffer[8192],
*print_ptr,
bc_buffer[1024];
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action;
#endif
fprintf(stderr,
"DEBUG: backendRunLoop(print_fd=%d, device_fd=%d, use_bc=%d, "
"side_cb=%p)\n",
print_fd, device_fd, use_bc, side_cb);
if (!print_fd)
{
#ifdef HAVE_SIGSET
sigset(SIGTERM, SIG_IGN);
#elif defined(HAVE_SIGACTION)
memset(&action, 0, sizeof(action));
sigemptyset(&action.sa_mask);
action.sa_handler = SIG_IGN;
sigaction(SIGTERM, &action, NULL);
#else
signal(SIGTERM, SIG_IGN);
#endif
}
nfds = (print_fd > device_fd ? print_fd : device_fd) + 1;
for (print_bytes = 0, print_ptr = print_buffer, offline = -1,
paperout = -1, total_bytes = 0;;)
{
FD_ZERO(&input);
if (!print_bytes)
FD_SET(print_fd, &input);
if (use_bc)
FD_SET(device_fd, &input);
if (!print_bytes && side_cb)
FD_SET(CUPS_SC_FD, &input);
FD_ZERO(&output);
if (print_bytes || (!use_bc && !side_cb))
FD_SET(device_fd, &output);
if (use_bc || side_cb)
{
if (select(nfds, &input, &output, NULL, NULL) < 0)
{
if (errno == ENXIO && offline != 1)
{
fputs("STATE: +offline-error\n", stderr);
_cupsLangPuts(stderr, _("INFO: Printer is currently off-line.\n"));
offline = 1;
}
else if (errno == EINTR && total_bytes == 0)
{
fputs("DEBUG: Received an interrupt before any bytes were "
"written, aborting!\n", stderr);
return (0);
}
sleep(1);
continue;
}
}
if (side_cb && FD_ISSET(CUPS_SC_FD, &input))
{
(*side_cb)(print_fd, device_fd, use_bc);
continue;
}
if (FD_ISSET(device_fd, &input))
{
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);
}
}
if (FD_ISSET(print_fd, &input))
{
if ((print_bytes = read(print_fd, print_buffer,
sizeof(print_buffer))) < 0)
{
if (errno != EAGAIN || errno != EINTR)
{
perror("ERROR: Unable to read print data");
return (-1);
}
print_bytes = 0;
}
else if (print_bytes == 0)
{
break;
}
print_ptr = print_buffer;
fprintf(stderr, "DEBUG: Read %d bytes of print data...\n",
(int)print_bytes);
}
if (print_bytes && FD_ISSET(device_fd, &output))
{
if ((bytes = write(device_fd, print_ptr, print_bytes)) < 0)
{
if (errno == ENOSPC)
{
if (paperout != 1)
{
fputs("STATE: +media-empty-error\n", stderr);
_cupsLangPuts(stderr, _("ERROR: Out of paper!\n"));
paperout = 1;
}
}
else if (errno == ENXIO)
{
if (offline != 1)
{
fputs("STATE: +offline-error\n", stderr);
_cupsLangPuts(stderr, _("INFO: Printer is currently off-line.\n"));
offline = 1;
}
}
else if (errno != EAGAIN && errno != EINTR && errno != ENOTTY)
{
fprintf(stderr, _("ERROR: Unable to write print data: %s\n"),
strerror(errno));
return (-1);
}
}
else
{
if (paperout)
{
fputs("STATE: -media-empty-error\n", stderr);
paperout = 0;
}
if (offline)
{
fputs("STATE: -offline-error\n", stderr);
_cupsLangPuts(stderr, _("INFO: Printer is now on-line.\n"));
offline = 0;
}
fprintf(stderr, "DEBUG: Wrote %d bytes of print data...\n", (int)bytes);
print_bytes -= bytes;
print_ptr += bytes;
total_bytes += bytes;
}
}
}
return (total_bytes);
}