1/* 2 * "$Id: backchannel.c 11093 2013-07-03 20:48:42Z msweet $" 3 * 4 * Backchannel functions for CUPS. 5 * 6 * Copyright 2007-2012 by Apple Inc. 7 * Copyright 1997-2007 by Easy Software Products. 8 * 9 * These coded instructions, statements, and computer programs are the 10 * property of Apple Inc. and are protected by Federal copyright 11 * law. Distribution and use rights are outlined in the file "LICENSE.txt" 12 * which should have been included with this file. If this file is 13 * file is missing or damaged, see the license at "http://www.cups.org/". 14 * 15 * This file is subject to the Apple OS-Developed Software exception. 16 * 17 * Contents: 18 * 19 * cupsBackChannelRead() - Read data from the backchannel. 20 * cupsBackChannelWrite() - Write data to the backchannel. 21 * cups_setup() - Setup select() 22 */ 23 24/* 25 * Include necessary headers... 26 */ 27 28#include "cups.h" 29#include <errno.h> 30#ifdef WIN32 31# include <io.h> 32# include <fcntl.h> 33#else 34# include <sys/time.h> 35#endif /* WIN32 */ 36 37 38/* 39 * Local functions... 40 */ 41 42static void cups_setup(fd_set *set, struct timeval *tval, 43 double timeout); 44 45 46/* 47 * 'cupsBackChannelRead()' - Read data from the backchannel. 48 * 49 * Reads up to "bytes" bytes from the backchannel/backend. The "timeout" 50 * parameter controls how many seconds to wait for the data - use 0.0 to 51 * return immediately if there is no data, -1.0 to wait for data indefinitely. 52 * 53 * @since CUPS 1.2/OS X 10.5@ 54 */ 55 56ssize_t /* O - Bytes read or -1 on error */ 57cupsBackChannelRead(char *buffer, /* I - Buffer to read into */ 58 size_t bytes, /* I - Bytes to read */ 59 double timeout) /* I - Timeout in seconds, typically 0.0 to poll */ 60{ 61 fd_set input; /* Input set */ 62 struct timeval tval; /* Timeout value */ 63 int status; /* Select status */ 64 65 66 /* 67 * Wait for input ready. 68 */ 69 70 do 71 { 72 cups_setup(&input, &tval, timeout); 73 74 if (timeout < 0.0) 75 status = select(4, &input, NULL, NULL, NULL); 76 else 77 status = select(4, &input, NULL, NULL, &tval); 78 } 79 while (status < 0 && errno != EINTR && errno != EAGAIN); 80 81 if (status < 0) 82 return (-1); /* Timeout! */ 83 84 /* 85 * Read bytes from the pipe... 86 */ 87 88#ifdef WIN32 89 return ((ssize_t)_read(3, buffer, (unsigned)bytes)); 90#else 91 return (read(3, buffer, bytes)); 92#endif /* WIN32 */ 93} 94 95 96/* 97 * 'cupsBackChannelWrite()' - Write data to the backchannel. 98 * 99 * Writes "bytes" bytes to the backchannel/filter. The "timeout" parameter 100 * controls how many seconds to wait for the data to be written - use 101 * 0.0 to return immediately if the data cannot be written, -1.0 to wait 102 * indefinitely. 103 * 104 * @since CUPS 1.2/OS X 10.5@ 105 */ 106 107ssize_t /* O - Bytes written or -1 on error */ 108cupsBackChannelWrite( 109 const char *buffer, /* I - Buffer to write */ 110 size_t bytes, /* I - Bytes to write */ 111 double timeout) /* I - Timeout in seconds, typically 1.0 */ 112{ 113 fd_set output; /* Output set */ 114 struct timeval tval; /* Timeout value */ 115 int status; /* Select status */ 116 ssize_t count; /* Current bytes */ 117 size_t total; /* Total bytes */ 118 119 120 /* 121 * Write all bytes... 122 */ 123 124 total = 0; 125 126 while (total < bytes) 127 { 128 /* 129 * Wait for write-ready... 130 */ 131 132 do 133 { 134 cups_setup(&output, &tval, timeout); 135 136 if (timeout < 0.0) 137 status = select(4, NULL, &output, NULL, NULL); 138 else 139 status = select(4, NULL, &output, NULL, &tval); 140 } 141 while (status < 0 && errno != EINTR && errno != EAGAIN); 142 143 if (status <= 0) 144 return (-1); /* Timeout! */ 145 146 /* 147 * Write bytes to the pipe... 148 */ 149 150#ifdef WIN32 151 count = (ssize_t)_write(3, buffer, (unsigned)(bytes - total)); 152#else 153 count = write(3, buffer, bytes - total); 154#endif /* WIN32 */ 155 156 if (count < 0) 157 { 158 /* 159 * Write error - abort on fatal errors... 160 */ 161 162 if (errno != EINTR && errno != EAGAIN) 163 return (-1); 164 } 165 else 166 { 167 /* 168 * Write succeeded, update buffer pointer and total count... 169 */ 170 171 buffer += count; 172 total += count; 173 } 174 } 175 176 return ((ssize_t)bytes); 177} 178 179 180/* 181 * 'cups_setup()' - Setup select() 182 */ 183 184static void 185cups_setup(fd_set *set, /* I - Set for select() */ 186 struct timeval *tval, /* I - Timer value */ 187 double timeout) /* I - Timeout in seconds */ 188{ 189 tval->tv_sec = (int)timeout; 190 tval->tv_usec = (int)(1000000.0 * (timeout - tval->tv_sec)); 191 192 FD_ZERO(set); 193 FD_SET(3, set); 194} 195 196 197/* 198 * End of "$Id: backchannel.c 11093 2013-07-03 20:48:42Z msweet $". 199 */ 200