1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
/* File rw.c
*
* Due to some problems with the 2.6 kernels, I had to find a way in
* order to make reading and writing from/to the device file /dev/lp0 and
* /dev/usb/lp0 working in the same way.
* With the 2.6 kernel, the read() call will no more be interrupted by
* an alarm timer. Read on /dev/lp0 is a blocking call, read on
* /dev/usb/lp0 will never block.
* Both device has different behaviour and the kernel people seem not to
* be able to understood the problem and fix it.
*
* Solution: If we open the device file with the O_NDELAY flag set,
* both interface will return immediatly with the value -1 and errno set
* to EAGAIN if nothing is to be read.
*
* Writing may be working for now without changes.
*/
#ifndef MACOS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/poll.h>
#include <signal.h>
int inFromFile = 0;
/* the two following functions are for testing. If we got a log
* from ttink (status or id), we can check what happen and if the
* results are as expected.
*/
/**********************************************
* Read the next line beginning with Recv:
*********************************************/
ssize_t readLine(int fd, unsigned char *buf, size_t sz)
{
int i = 0;
buf[0] = 0;
while( read(fd, buf+i, 1) > 0 )
{
buf[i+1] = 0;
if ( buf[i] == '\n' )
{
buf[i] = 0;
if ( strncmp(buf, "Recv:",5) == 0 )
{
return i;
}
else
{
i = 0;
buf[0] = 0;
continue;
}
}
i++;
if ( i >= sz )
break;
}
return -1;
}
/**********************************************
* convert the hex value to binary and copy to
* the output buffer *buf
*********************************************/
ssize_t convertBuf(unsigned char *buf, int sz, char *buffer)
{
int i = 0;
buffer += 5; /* skip Recv: */
while(*buffer && sz > 1)
{
buf[i] = (unsigned char)strtol(buffer, &buffer, 16)&0xff;
i++;
sz--;
}
buf[i] = '\0';
return i;
}
/***********************************************
* Low level read function. The device is in
* NON_BLOCK mode.
**********************************************/
ssize_t devRead(int fd, unsigned char *buf, size_t sz, int to)
{
int rd = 0;
to /= 10;
errno = 0;
if ( !inFromFile )
{
/* Normal way */
while(to > 0 && rd != -1 )
{
/* wait a little bit */
poll(NULL, 0, 10);
to--;
rd = read(fd, buf, sz);
if ( rd > 0 )
{
return rd;
}
}
}
else
{
/* Read from a file (test)
* read a line, if the line begin with Recv:
* put the code into the buffer
*/
char buffer[8092];
if ( readLine(fd, buffer, sizeof(buffer)) >= 0 )
{
rd = convertBuf(buf, sz, buffer);
return rd;
}
}
/* at this point we are probably interrupted */
if ( rd == 0 )
{
errno = EINTR;
}
return -1;
}
/***********************************************
* Low level write function. The device is in
* NON_BLOCK mode.
**********************************************/
ssize_t devWrite(int fd, unsigned char *buf, size_t sz, int to)
{
int wr = 0;
to /= 10;
errno = 0;
/* if we are readinf from a file don't write to it
* leave the function with OK
*/
if (inFromFile )
{
return sz;
}
while(to > 0 && wr != -1 )
{
/* wait a little bit */
poll(NULL, 0, 10);
to--;
wr = write(fd, buf, sz);
if ( wr > 0 )
{
return wr;
}
}
/* at this point we are probably interrupted */
if ( wr == 0 )
{
errno = EINTR;
}
return -1;
}
#endif
|