-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathio.c
144 lines (120 loc) · 3.36 KB
/
io.c
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
/*!
* \file io.c
* \brief Functions related to performing I/O.
* \author Henrique Nascimento Gouveia <h.gouveia@icloud.com>
*/
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include "io.h"
/*!
* Read bytes from the given file from the given offset.
*
* \param fd file descriptor.
* \param address address to where store the data read.
* \param bytes return-param initially with the desired number of bytes to read,
* being set to the actual number of bytes read afterwards.
* \param offset return-param initially containing the actual offset before the I/O,
* and, afterwards, being set to represent the actual offset on file.
*
* \return -1 on error while reading the file. 0 on success reading file.
*/
static int do_io_read(int fd, void *address, ssize_t *bytes, off_t *offset)
{
ssize_t bytes_read = 0;
bytes_read = pread(fd, address, *bytes, *offset);
switch (bytes_read)
{
case -1:
switch (errno)
{
case EAGAIN:
/* This is OK. */
break;
defaul:
return -1;
}
break;
default:
*bytes = bytes_read;
*offset += bytes_read;
}
return 0;
}
/*!
* Write bytes into the given file from the given offset.
*
* \param fd file descriptor.
* \param address address to get data to write into the file.
* \param bytes return-param initially with the desired number of bytes to be written,
* being set to the actual number of bytes written afterwards.
* \param offset return-param initially containing the actual offset before the I/O,
* and, afterwards, being set to represent the actual offset on file.
*
* \return -1 on error while writing to file. 0 on success writing to file.
*/
static int do_io_write(int fd, void *address, ssize_t *bytes, off_t *offset)
{
ssize_t bytes_written = 0;
bytes_written = pwrite(fd, address, *bytes, *offset);
switch (bytes_written)
{
case -1:
switch (errno)
{
case EAGAIN:
/* This is OK. */
break;
default:
puts(strerror(errno));
return -1;
}
break;
default:
*bytes = bytes_written;
*offset += bytes_written;
}
return 0;
}
/*!
* Perform I/O to the given file.
*
* \param fd file descriptor.
* \param address address to the buffer.
* \param bytes return-param initially with the desired number of bytes used in this
* operation, being set to the actual number of bytes used afterwards.
* \param offset return-param initially containing the actual offset before the I/O,
* and, afterwards, being set to represent the actual offset on file.
*
* \return -1 on error while performing I/O to file. 0 on success.
*/
int akwbs_do_io(int fd, void *address, ssize_t *bytes, off_t *offset, int io_type)
{
int ret = 0;
if ((address == NULL)
|| (bytes == NULL)
|| (offset == NULL))
return -1;
if (fd == -1)
return -1;
if (*bytes < 0)
return -1;
if (*bytes > BUFSIZ)
*bytes = BUFSIZ;
if (*offset < 0)
return -1;
switch (io_type)
{
case AKWBS_IO_GET_TYPE:
ret = do_io_read(fd, address, bytes, offset);
break;
case AKWBS_IO_PUT_TYPE:
ret = do_io_write(fd, address, bytes, offset);
break;
default:
return -1;
}
return ret;
}