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; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 #include "libaltos_private.h"
20 #include "libaltos_posix.h"
23 altos_set_last_posix_error(void)
25 altos_set_last_error(errno, strerror(errno));
28 PUBLIC struct altos_file *
29 altos_open(struct altos_device *device)
31 struct altos_file_posix *file = calloc (sizeof (struct altos_file_posix), 1);
36 altos_set_last_posix_error();
40 // altos_set_last_error(12, "yeah yeah, failed again");
44 file->fd = open(device->path, O_RDWR | O_NOCTTY);
46 altos_set_last_posix_error();
53 file->out_fd = open(device->path, O_RDWR | O_NOCTTY);
54 if (file->out_fd < 0) {
55 altos_set_last_posix_error();
61 ret = tcgetattr(file->fd, &term);
63 altos_set_last_posix_error();
72 cfsetospeed(&term, B9600);
73 cfsetispeed(&term, B9600);
81 ret = tcsetattr(file->fd, TCSAFLUSH, &term);
83 altos_set_last_posix_error();
95 altos_close(struct altos_file *file_common)
97 struct altos_file_posix *file = (struct altos_file_posix *) file_common;
103 write(file->pipe[1], "\r", 1);
113 altos_flush(struct altos_file *file_common)
115 struct altos_file_posix *file = (struct altos_file_posix *) file_common;
117 if (file->file.out_used && 0) {
119 fwrite(file->file.out_data, 1, file->file.out_used, stdout);
122 while (file->file.out_used) {
128 ret = write (file->fd, file->file.out_data, file->file.out_used);
130 ret = write (file->out_fd, file->file.out_data, file->file.out_used);
133 altos_set_last_posix_error();
134 return -altos_last_error.code;
137 memmove(file->file.out_data, file->file.out_data + ret,
138 file->file.out_used - ret);
139 file->file.out_used -= ret;
151 altos_fill(struct altos_file *file_common, int timeout)
153 struct altos_file_posix *file = (struct altos_file_posix *) file_common;
161 while (file->file.in_read == file->file.in_used) {
163 return LIBALTOS_ERROR;
166 fd[0].events = POLLIN|POLLERR|POLLHUP|POLLNVAL;
167 fd[1].fd = file->pipe[0];
168 fd[1].events = POLLIN;
169 ret = poll(fd, 2, timeout);
171 altos_set_last_posix_error();
172 return LIBALTOS_ERROR;
175 return LIBALTOS_TIMEOUT;
177 if (fd[0].revents & (POLLHUP|POLLERR|POLLNVAL))
178 return LIBALTOS_ERROR;
179 if (fd[0].revents & POLLIN)
182 ret = read(file->fd, file->file.in_data, USB_BUF_SIZE);
184 altos_set_last_posix_error();
185 return LIBALTOS_ERROR;
187 file->file.in_read = 0;
188 file->file.in_used = ret;
190 if (ret == 0 && timeout > 0)
191 return LIBALTOS_TIMEOUT;
195 if (file->file.in_used && 0) {
197 fwrite(file->file.in_data, 1, file->file.in_used, stdout);
206 altos_pause_one_second(void)
208 struct timespec delay = { .tv_sec = 1, .tv_nsec = 0 };
209 nanosleep(&delay, NULL);