2 * Copyright © 2016 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
18 #include "libaltos_private.h"
19 #include "libaltos_posix.h"
22 altos_set_last_posix_error(void)
24 altos_set_last_error(errno, strerror(errno));
27 PUBLIC struct altos_file *
28 altos_open(struct altos_device *device)
30 struct altos_file_posix *file = calloc (sizeof (struct altos_file_posix), 1);
35 altos_set_last_posix_error();
39 // altos_set_last_error(12, "yeah yeah, failed again");
43 file->fd = open(device->path, O_RDWR | O_NOCTTY);
45 altos_set_last_posix_error();
52 file->out_fd = open(device->path, O_RDWR | O_NOCTTY);
53 if (file->out_fd < 0) {
54 altos_set_last_posix_error();
60 ret = tcgetattr(file->fd, &term);
62 altos_set_last_posix_error();
71 cfsetospeed(&term, B9600);
72 cfsetispeed(&term, B9600);
80 ret = tcsetattr(file->fd, TCSAFLUSH, &term);
82 altos_set_last_posix_error();
94 altos_close(struct altos_file *file_common)
96 struct altos_file_posix *file = (struct altos_file_posix *) file_common;
102 write(file->pipe[1], "\r", 1);
112 altos_flush(struct altos_file *file_common)
114 struct altos_file_posix *file = (struct altos_file_posix *) file_common;
116 if (file->file.out_used && 0) {
118 fwrite(file->file.out_data, 1, file->file.out_used, stdout);
121 while (file->file.out_used) {
127 ret = write (file->fd, file->file.out_data, file->file.out_used);
129 ret = write (file->out_fd, file->file.out_data, file->file.out_used);
132 altos_set_last_posix_error();
133 return -altos_last_error.code;
136 memmove(file->file.out_data, file->file.out_data + ret,
137 file->file.out_used - ret);
138 file->file.out_used -= ret;
150 altos_fill(struct altos_file *file_common, int timeout)
152 struct altos_file_posix *file = (struct altos_file_posix *) file_common;
160 while (file->file.in_read == file->file.in_used) {
162 return LIBALTOS_ERROR;
165 fd[0].events = POLLIN|POLLERR|POLLHUP|POLLNVAL;
166 fd[1].fd = file->pipe[0];
167 fd[1].events = POLLIN;
168 ret = poll(fd, 2, timeout);
170 altos_set_last_posix_error();
171 return LIBALTOS_ERROR;
174 return LIBALTOS_TIMEOUT;
176 if (fd[0].revents & (POLLHUP|POLLERR|POLLNVAL))
177 return LIBALTOS_ERROR;
178 if (fd[0].revents & POLLIN)
181 ret = read(file->fd, file->file.in_data, USB_BUF_SIZE);
183 altos_set_last_posix_error();
184 return LIBALTOS_ERROR;
186 file->file.in_read = 0;
187 file->file.in_used = ret;
189 if (ret == 0 && timeout > 0)
190 return LIBALTOS_TIMEOUT;
194 if (file->file.in_used && 0) {
196 fwrite(file->file.in_data, 1, file->file.in_used, stdout);