File: rw.c

package info (click to toggle)
mtink 1.0.16-10
  • links: PTS
  • area: main
  • in suites: buster
  • size: 3,808 kB
  • sloc: ansic: 19,264; sh: 1,008; python: 626; xml: 444; makefile: 76
file content (177 lines) | stat: -rw-r--r-- 3,897 bytes parent folder | download | duplicates (4)
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