source: asp3_tinet_ecnl_arm/trunk/ntshell/src/fdtable.c@ 364

Last change on this file since 364 was 364, checked in by coas-nagasima, 5 years ago

TINETとSocket APIなどを更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 19.4 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2017 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id$
36 */
37#include "shellif.h"
38#include <stdint.h>
39#include <kernel.h>
40#include <t_syslog.h>
41#include <t_stdlib.h>
42#include <sil.h>
43#include "syssvc/serial.h"
44#include "syssvc/syslog.h"
45#include "target_syssvc.h"
46#ifndef NTSHELL_NO_SOCKET
47#include <tinet_defs.h>
48#include <tinet_config.h>
49#include <net/net.h>
50#include <net/net_endian.h>
51#include <netinet/in.h>
52#include <netinet/in_itron.h>
53#include <tinet_nic_defs.h>
54#include <tinet_cfg.h>
55#include <netinet/in_var.h>
56#include <net/ethernet.h>
57#include <net/if6_var.h>
58#include <net/net.h>
59#include <net/if_var.h>
60#include <netinet/udp.h>
61#include <netinet/udp_var.h>
62#include <netinet/tcp.h>
63#include <netinet/tcp_var.h>
64#include <net/net_buf.h>
65#endif
66#include "ff.h"
67#include "socket_stub.h"
68#include "kernel_cfg.h"
69#include <string.h>
70
71#define IO_TYPE_FREE 0
72#define IO_TYPE_SIO 1
73#define IO_TYPE_FILE 2
74#define IO_TYPE_DIR 3
75#define IO_TYPE_TCP 4
76#define IO_TYPE_UDP 5
77
78static struct _IO_FILE fd_table[8 * sizeof(FLGPTN)] = {
79 { 0, IO_TYPE_SIO, 0, stdio_close, stdin_read, stdio_write, sio_seek, sio_ioctl },
80 { 1, IO_TYPE_SIO, 0, stdio_close, stdio_read, stdout_write, sio_seek, sio_ioctl },
81 { 2, IO_TYPE_SIO, 0, stdio_close, stdio_read, stderr_write, sio_seek, sio_ioctl },
82};
83#define fd_table_count (sizeof(fd_table) / sizeof(fd_table[0]))
84
85static int new_fd(int type, int id)
86{
87 for (int fd = 3; fd < fd_table_count; fd++) {
88 struct _IO_FILE *fp = &fd_table[fd];
89 if (fp->type != IO_TYPE_FREE)
90 continue;
91
92 memset(fp, 0, sizeof(struct _IO_FILE));
93 fp->fd = fd;
94 fp->type = type;
95 fp->handle = id;
96 return fd;
97 }
98
99 return -ENOMEM;
100}
101
102static struct _IO_FILE *id_to_fd(int type, int id)
103{
104 for (int fd = 3; fd < fd_table_count; fd++) {
105 struct _IO_FILE *fp = &fd_table[fd];
106 if ((fp->type == type) && (fp->handle == id))
107 return fp;
108 }
109
110 return NULL;
111}
112
113static int delete_fd(int type, int id)
114{
115 struct _IO_FILE *fp = id_to_fd(type, id);
116 if (fp == NULL)
117 return -EBADF;
118
119 return delete_fp(fp);
120}
121
122int delete_fp(struct _IO_FILE *fp)
123{
124 free(fp->pfile);
125 fp->pfile = NULL;
126 free(fp->pdir);
127 fp->pdir = NULL;
128 free(fp->psock);
129 fp->psock = NULL;
130 memset(fp, 0, sizeof(struct _IO_FILE));
131
132 return 0;
133}
134
135struct _IO_FILE *fd_to_fp(int fd)
136{
137 if ((fd < 0) || (fd >= fd_table_count))
138 return NULL;
139 return &fd_table[fd];
140}
141
142struct _IO_FILE *new_sio_fd(int sioid)
143{
144 int fd = new_fd(IO_TYPE_SIO, sioid);
145 if ((fd < 0) || (fd >= fd_table_count))
146 return NULL;
147
148 struct _IO_FILE *fp = &fd_table[fd];
149 fp->close = sio_close;
150 fp->read = sio_read;
151 fp->write = sio_write;
152 fp->seek = sio_seek;
153 fp->ioctl = sio_ioctl;
154 fp->writable = 1;
155
156 return fp;
157}
158
159int delete_sio_fd(int sioid)
160{
161 return delete_fd(IO_TYPE_SIO, sioid);
162}
163
164struct _IO_FILE *sioid_to_fd(int sioid)
165{
166 return id_to_fd(IO_TYPE_SIO, sioid);
167}
168
169struct _IO_FILE *new_file_fd(int fileid)
170{
171 int fd = new_fd(IO_TYPE_FILE, fileid);
172 if ((fd < 0) || (fd >= fd_table_count))
173 return NULL;
174
175 struct _IO_FILE *fp = &fd_table[fd];
176 fp->close = file_close;
177 fp->read = file_read;
178 fp->write = file_write;
179 fp->seek = file_seek;
180 fp->ioctl = file_ioctl;
181 fp->writable = 1;
182 fp->pfile = malloc(sizeof(FIL));
183 memset(fp->pfile, 0, sizeof(FIL));
184
185 return fp;
186}
187
188int delete_file_fd(int fileid)
189{
190 return delete_fd(IO_TYPE_FILE, fileid);
191}
192
193struct _IO_FILE *fileid_to_fd(int fileid)
194{
195 return id_to_fd(IO_TYPE_FILE, fileid);
196}
197
198struct _IO_FILE *new_dir_fd(int fileid)
199{
200 int fd = new_fd(IO_TYPE_DIR, fileid);
201 if ((fd < 0) || (fd >= fd_table_count))
202 return NULL;
203
204 struct _IO_FILE *fp = &fd_table[fd];
205 fp->close = dir_close;
206 fp->read = dir_read;
207 fp->write = dir_write;
208 fp->seek = dir_seek;
209 fp->ioctl = dir_ioctl;
210 fp->writable = 0;
211 fp->pdir = malloc(sizeof(struct _IO_DIR));
212 memset(fp->pdir, 0, sizeof(struct _IO_DIR));
213
214 return fp;
215}
216
217int delete_dir_fd(int dirid)
218{
219 return delete_fd(IO_TYPE_DIR, dirid);
220}
221
222struct _IO_FILE *dirid_to_fd(int dirid)
223{
224 return id_to_fd(IO_TYPE_DIR, dirid);
225}
226
227#ifndef NTSHELL_NO_SOCKET
228struct _IO_FILE *new_tcp_fd(int tcpid)
229{
230 int fd = new_fd(IO_TYPE_TCP, tcpid);
231 if ((fd < 0) || (fd >= fd_table_count))
232 return NULL;
233
234 struct _IO_FILE *fp = &fd_table[fd];
235 fp->close = tcp_fd_close;
236 fp->read = tcp_fd_read;
237 fp->write = tcp_fd_write;
238 fp->seek = tcp_fd_seek;
239 fp->ioctl = tcp_fd_ioctl;
240 fp->writable = 0;
241 fp->psock = malloc(sizeof(socket_t));
242 memset(fp->psock, 0, sizeof(socket_t));
243
244 return fp;
245}
246
247int delete_tcp_fd(int tcpid)
248{
249 return delete_fd(IO_TYPE_TCP, tcpid);
250}
251
252struct _IO_FILE *tcpid_to_fd(int tcpid)
253{
254 return id_to_fd(IO_TYPE_TCP, tcpid);
255}
256
257struct _IO_FILE *new_udp_fd(int udpid)
258{
259 int fd = new_fd(IO_TYPE_UDP, udpid);
260 if ((fd < 0) || (fd >= fd_table_count))
261 return NULL;
262
263 struct _IO_FILE *fp = &fd_table[fd];
264 fp->close = udp_fd_close;
265 fp->read = udp_fd_read;
266 fp->write = udp_fd_write;
267 fp->seek = udp_fd_seek;
268 fp->ioctl = udp_fd_ioctl;
269 fp->writable = 1;
270 fp->psock = malloc(sizeof(socket_t));
271 memset(fp->psock, 0, sizeof(socket_t));
272
273 return fp;
274}
275
276int delete_udp_fd(int udpid)
277{
278 return delete_fd(IO_TYPE_UDP, udpid);
279}
280
281struct _IO_FILE *udpid_to_fd(int udpid)
282{
283 return id_to_fd(IO_TYPE_UDP, udpid);
284}
285
286#endif
287
288void memor(void *dst, void *src, size_t len)
289{
290 uint8_t *d = (uint8_t *)dst;
291 uint8_t *s = (uint8_t *)src;
292 uint8_t *e = &s[len];
293
294 while (s < e) {
295 *d++ |= *s++;
296 }
297}
298
299struct fd_events {
300 int count;
301 fd_set readfds;
302 fd_set writefds;
303 fd_set errorfds;
304};
305
306ER shell_get_evts(struct fd_events *evts, TMO tmout);
307
308#define TMO_MAX INT_MAX
309
310int shell_select(int n, fd_set *__restrict rfds, fd_set *__restrict wfds, fd_set *__restrict efds, struct timeval *__restrict tv)
311{
312 ER ret;
313 TMO tmout = TMO_FEVR;
314 struct fd_events evts;
315
316 if (tv != NULL) {
317 if (tv->tv_sec < (TMO_MAX / 1000000))
318 tmout = tv->tv_sec * 1000000 + tv->tv_usec;
319 else
320 tmout = TMO_MAX;
321 }
322
323 if (rfds != NULL)
324 memcpy(&evts.readfds, rfds, sizeof(fd_set));
325 else
326 memset(&evts.readfds, 0, sizeof(fd_set));
327 if (wfds != NULL)
328 memcpy(&evts.writefds, wfds, sizeof(fd_set));
329 else
330 memset(&evts.writefds, 0, sizeof(fd_set));
331 if (efds != NULL)
332 memcpy(&evts.errorfds, efds, sizeof(fd_set));
333 else
334 memset(&evts.errorfds, 0, sizeof(fd_set));
335 evts.count = 0;
336
337 ret = shell_get_evts(&evts, tmout);
338 if (rfds != NULL)
339 memset(rfds, 0, sizeof(fd_set));
340 if (wfds != NULL)
341 memset(wfds, 0, sizeof(fd_set));
342 if (efds != NULL)
343 memset(efds, 0, sizeof(fd_set));
344 if (ret == E_OK) {
345 if (rfds != NULL)
346 memor(rfds, &evts.readfds, sizeof(fd_set));
347 if (wfds != NULL)
348 memor(wfds, &evts.writefds, sizeof(fd_set));
349 if (efds != NULL)
350 memor(efds, &evts.errorfds, sizeof(fd_set));
351 return evts.count;
352 }
353 if (ret == E_TMOUT) {
354 return 0;
355 }
356
357 return -EBADF;
358}
359
360int shell_poll(struct pollfd *fds, nfds_t nfds, int timeout)
361{
362 ER ret;
363 TMO tmout;
364 struct fd_events evts;
365
366 if(timeout < 0)
367 tmout = TMO_FEVR;
368 else if (timeout < (TMO_MAX / 1000))
369 tmout = timeout * 1000;
370 else
371 tmout = TMO_MAX;
372
373 memset(&evts, 0, sizeof(evts));
374
375 for (int i = 0; i < nfds; i++) {
376 struct pollfd *pfd = &fds[i];
377 int fd = pfd->fd;
378 if ((fd < 0) || (fd >= fd_table_count))
379 continue;
380
381 if (pfd->events & POLLIN)
382 FD_SET(fd, &evts.readfds);
383 if (pfd->events & POLLOUT)
384 FD_SET(fd, &evts.writefds);
385 if (pfd->events & POLLERR)
386 FD_SET(fd, &evts.errorfds);
387 pfd->revents = 0;
388 }
389
390 ret = shell_get_evts(&evts, tmout);
391 if (ret == E_OK) {
392 int result = 0;
393 for (int i = 0; i < nfds; i++) {
394 struct pollfd *pfd = &fds[i];
395 int fd = pfd->fd;
396 if ((fd < 0) || (fd >= fd_table_count))
397 continue;
398
399 if (FD_ISSET(fd, &evts.readfds))
400 pfd->revents |= POLLIN;
401 if (FD_ISSET(fd, &evts.writefds))
402 pfd->revents |= POLLOUT;
403 if (FD_ISSET(fd, &evts.errorfds))
404 pfd->revents |= POLLERR;
405 if (pfd->revents != 0)
406 result++;
407 }
408 return result;
409 }
410 if (ret == E_TMOUT) {
411 return 0;
412 }
413
414 return -EBADF;
415}
416
417/* TODO:コールバック化したい */
418void stdio_update_evts()
419{
420 int fd = STDIN_FILENO;
421 struct _IO_FILE *fp = &fd_table[fd];
422 T_SERIAL_RPOR rpor;
423 FLGPTN flgptn = 0;
424
425 ER ret = serial_ref_por(SIO_PORTID, &rpor);
426 if (ret != E_OK)
427 return;
428
429 if (rpor.reacnt != 0) {
430 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
431
432 FD_SET(fd, (fd_set *)&flgptn);
433 }
434 if (rpor.wricnt != 0) {
435 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
436
437 FD_SET(fd, (fd_set *)&flgptn);
438 }
439
440 if (flgptn != 0) {
441 set_flg(FLG_SELECT_WAIT, flgptn);
442 }
443}
444
445/* TODO:コールバック化したい */
446void stdio_flgptn(FLGPTN *flgptn)
447{
448 int fd = STDIN_FILENO;
449 struct _IO_FILE *fp = &fd_table[fd];
450 T_SERIAL_RPOR rpor;
451 *flgptn = 0;
452
453 ER ret = serial_ref_por(SIO_PORTID, &rpor);
454 if (ret != E_OK)
455 return;
456
457 if (rpor.reacnt != 0) {
458 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
459
460 FD_SET(fd, (fd_set *)flgptn);
461 }
462 if (rpor.wricnt != 0) {
463 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
464
465 FD_SET(fd, (fd_set *)flgptn);
466 }
467}
468
469#ifndef NTSHELL_NO_SOCKET
470
471ER socket_tcp_callback(ID cepid, FN fncd, void *p_parblk)
472{
473 struct _IO_FILE *fp = tcpid_to_fd(cepid);
474 FLGPTN flgptn = 0;
475 ER ret;
476 int len;
477
478 if (fp == NULL)
479 return E_PAR;
480
481 int fd = fp->fd;
482 FD_SET(fd, (fd_set *)&flgptn);
483
484 switch (fncd) {
485 case TFN_TCP_RCV_BUF:
486 len = *(int *)p_parblk;
487 if (len <= 0)
488 return E_OK;
489
490 ret = wai_sem(SEM_FILEDESC);
491 if (ret < 0) {
492 syslog(LOG_ERROR, "wai_sem => %d", ret);
493 }
494 fp->psock->len += len;
495 ret = sig_sem(SEM_FILEDESC);
496 if (ret < 0) {
497 syslog(LOG_ERROR, "sig_sem => %d", ret);
498 }
499
500 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
501
502 set_flg(FLG_SELECT_WAIT, flgptn);
503 return E_OK;
504
505 case TFN_TCP_RCV_DAT:
506 len = *(int *)p_parblk;
507 if (len <= 0)
508 return E_OK;
509
510 ret = wai_sem(SEM_FILEDESC);
511 if (ret < 0) {
512 syslog(LOG_ERROR, "wai_sem => %d", ret);
513 }
514 fp->psock->len += len;
515 ret = sig_sem(SEM_FILEDESC);
516 if (ret < 0) {
517 syslog(LOG_ERROR, "sig_sem => %d", ret);
518 }
519
520 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
521
522 set_flg(FLG_SELECT_WAIT, flgptn);
523 return E_OK;
524
525 case TFN_TCP_SND_DAT:
526 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
527
528 set_flg(FLG_SELECT_WAIT, flgptn);
529 return E_OK;
530
531 case TFN_TCP_CAN_CEP:
532 if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
533
534 set_flg(FLG_SELECT_WAIT, flgptn);
535 return E_OK;
536
537 case TFN_TCP_DEL_REP:
538 delete_tcp_rep(cepid);
539 return E_OK;
540
541 case TFN_TCP_DEL_CEP:
542 delete_tcp_fd(cepid);
543 return E_OK;
544
545 default:
546 return E_OK;
547 }
548}
549
550ER socket_udp_callback(ID cepid, FN fncd, void *p_parblk)
551{
552 struct _IO_FILE *fp = udpid_to_fd(cepid);
553 FLGPTN flgptn = 0;
554 int len;
555
556 if (fp == NULL)
557 return E_PAR;
558
559 int fd = fp->fd;
560 FD_SET(fd, (fd_set *)&flgptn);
561
562 switch (fncd) {
563 case TEV_UDP_RCV_DAT:
564 {
565 T_UDP_RCV_DAT_PARA *udppara = (T_UDP_RCV_DAT_PARA *)p_parblk;
566 len = udppara->len;
567 if (len <= 0)
568 return E_OK;
569
570 ER ret = wai_sem(SEM_FILEDESC);
571 if (ret < 0) {
572 syslog(LOG_ERROR, "wai_sem => %d", ret);
573 }
574 fp->psock->len = len;
575 if (fp->psock->input != NULL) {
576 ret = rel_net_buf(fp->psock->input);
577 if (ret < 0) {
578 syslog(LOG_ERROR, "rel_net_buf => %d", ret);
579 }
580 }
581 fp->psock->input = udppara->input;
582 fp->psock->buf = GET_UDP_SDU(udppara->input, udppara->off);
583 memset(&fp->psock->raddr4, 0, sizeof(fp->psock->raddr4));
584 fp->psock->raddr4.sin_family = AF_INET;
585 fp->psock->raddr4.sin_port = htons(udppara->rep4.portno);
586 fp->psock->raddr4.sin_addr.s_addr = htonl(udppara->rep4.ipaddr);
587 udppara->input->flags |= NB_FLG_NOREL_IFOUT;
588 ret = sig_sem(SEM_FILEDESC);
589 if (ret < 0) {
590 syslog(LOG_ERROR, "sig_sem => %d", ret);
591 }
592
593 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
594
595 set_flg(FLG_SELECT_WAIT, flgptn);
596 return E_OK;
597 }
598 case TFN_UDP_CRE_CEP:
599 return E_OK;
600
601 case TFN_UDP_RCV_DAT:
602 len = *(int *)p_parblk;
603 if (len <= 0)
604 return E_OK;
605
606 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
607
608 set_flg(FLG_SELECT_WAIT, flgptn);
609 return E_OK;
610
611 case TFN_UDP_SND_DAT:
612 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
613
614 set_flg(FLG_SELECT_WAIT, flgptn);
615 return E_OK;
616
617 case TFN_UDP_CAN_CEP:
618 if (fp->errorevt_w == fp->errorevt_r) fp->errorevt_w++;
619
620 set_flg(FLG_SELECT_WAIT, flgptn);
621 return E_OK;
622
623 case TFN_UDP_DEL_CEP:
624 delete_udp_fd(cepid);
625 return E_OK;
626
627 default:
628 return E_OK;
629 }
630}
631
632#endif
633
634ER shell_get_evts(struct fd_events *evts, TMO tmout)
635{
636 int count = 0;
637 SYSTIM prev, now;
638
639 get_tim(&prev);
640
641 for (;;) {
642 ER ret;
643 FLGPTN waitptn, flgptn, readfds = 0, writefds = 0;
644 struct _IO_FILE *fp = NULL;
645
646 stdio_update_evts();
647
648#ifndef NTSHELL_NO_SOCKET
649 waitptn = *((FLGPTN *)&evts->errorfds);
650#else
651 waitptn = *((FLGPTN *)&evts->readfds) | *((FLGPTN *)&evts->errorfds);
652#endif
653 for (int fd = 0; fd < fd_table_count; fd++) {
654 fp = &fd_table[fd];
655
656#ifndef NTSHELL_NO_SOCKET
657 if (FD_ISSET(fd, &evts->readfds)) {
658 if ((fp->type == IO_TYPE_TCP) && (fp->psock->cepid != 0)) {
659 if (fp->psock->len == 0) {
660 ret = tcp_rcv_buf(fp->psock->cepid, &fp->psock->input, TMO_NBLK);
661 if ((ret != E_WBLK) && (ret != E_OBJ) && (ret < 0)) {
662 syslog(LOG_ERROR, "tcp_rcv_buf => %d", ret);
663 //return ret;
664 }
665 if (ret > 0) {
666 ret = wai_sem(SEM_FILEDESC);
667 if (ret < 0) {
668 syslog(LOG_ERROR, "wai_sem => %d", ret);
669 }
670 fp->psock->len += ret;
671 ret = sig_sem(SEM_FILEDESC);
672 if (ret < 0) {
673 syslog(LOG_ERROR, "sig_sem => %d", ret);
674 }
675 }
676 }
677 else ret = 1;
678 if (ret > 0) {
679 FD_SET(fd, (fd_set *)&readfds);
680 count++;
681 if (fp->readevt_w == fp->readevt_r) fp->readevt_r--;
682 }
683 }
684 else if ((fp->type == IO_TYPE_UDP) && (fp->psock->cepid != 0)) {
685 if (fp->psock->input != NULL) {
686 FD_SET(fd, (fd_set *)&readfds);
687 count++;
688 if (fp->readevt_w == fp->readevt_r) fp->readevt_r--;
689 }
690 }
691 else {
692 FD_SET(fd, (fd_set *)&waitptn);
693 }
694 }
695#endif
696 if (FD_ISSET(fd, &evts->writefds)) {
697 if (fp->writeevt_w == fp->writeevt_r) {
698 FD_SET(fd, (fd_set *)&writefds);
699 count++;
700 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_r--;
701 }
702 else {
703 FD_SET(fd, (fd_set *)&waitptn);
704 }
705 }
706 }
707 memset(evts, 0, sizeof(*evts));
708
709 if (waitptn == 0) {
710 memcpy(&evts->readfds, &readfds, sizeof(evts->readfds));
711 memcpy(&evts->writefds, &writefds, sizeof(evts->writefds));
712 evts->count = count;
713 return E_OK;
714 }
715 else if ((readfds | writefds) != 0) {
716 set_flg(FLG_SELECT_WAIT, (readfds | writefds));
717 }
718
719 /* イベント待ち */
720 flgptn = 0;
721 ret = twai_flg(FLG_SELECT_WAIT, waitptn, TWF_ORW, &flgptn, tmout);
722 if (ret != E_OK) {
723 if (ret != E_TMOUT) {
724 syslog(LOG_ERROR, "twai_flg => %d", ret);
725 return ret;
726 }
727
728 stdio_flgptn(&flgptn);
729
730 if (flgptn == 0)
731 return E_TMOUT;
732 }
733 flgptn &= waitptn;
734
735 /* 受け取ったフラグのみクリア */
736 ret = clr_flg(FLG_SELECT_WAIT, ~flgptn);
737 if (ret != E_OK) {
738 syslog(LOG_ERROR, "clr_flg => %d", ret);
739 }
740
741 count = 0;
742 for (int fd = 0; fd < fd_table_count; fd++) {
743 if (!FD_ISSET(fd, (fd_set *)&waitptn))
744 continue;
745
746 fp = &fd_table[fd];
747
748 if (fp->readevt_w != fp->readevt_r) {
749 fp->readevt_r++;
750 FD_SET(fd, &evts->readfds);
751 count++;
752 }
753 if (fp->writeevt_w != fp->writeevt_r) {
754 fp->writeevt_r++;
755 fp->writable = 1;
756 }
757 if (fp->writable) {
758 FD_SET(fd, &evts->writefds);
759 count++;
760 }
761 if (fp->errorevt_w != fp->errorevt_r) {
762 fp->errorevt_r++;
763 FD_SET(fd, &evts->errorfds);
764 count++;
765 }
766 }
767
768 if (count > 0)
769 break;
770
771 get_tim(&now);
772
773 SYSTIM elapse = now - prev;
774 if (elapse > tmout)
775 return E_TMOUT;
776
777 prev = now;
778 tmout -= elapse;
779 }
780
781 evts->count = count;
782
783 return E_OK;
784}
785
786void clean_fd()
787{
788 struct _IO_FILE *fp = NULL;
789 for (int fd = 3; fd < fd_table_count; fd++) {
790 fp = &fd_table[fd];
791 if ((fp->type == 0) || (fp->fd == 0))
792 continue;
793
794 fp->close(fp);
795
796 delete_fp(fp);
797 }
798}
799
800int shell_ioctl(int fd, int request, void *arg)
801{
802 struct _IO_FILE *fp = fd_to_fp(fd);
803 if (fp == NULL)
804 return -EBADF;
805
806 return fp->ioctl(fp, request, arg);
807}
808
809#ifdef NTSHELL_NO_SOCKET
810
811int shell_socket(int family, int type, int protocol)
812{
813 return -ENOMEM;
814}
815
816int shell_bind(int fd, const struct sockaddr *addr, socklen_t len)
817{
818 return -ENOMEM;
819}
820
821int shell_listen(int fd, int backlog)
822{
823 return -ENOMEM;
824}
825
826int shell_connect(int fd, const struct sockaddr *addr, socklen_t len)
827{
828 return -ENOMEM;
829}
830
831int shell_accept(int fd, struct sockaddr *__restrict addr, socklen_t *__restrict len)
832{
833 return -ENOMEM;
834}
835
836ssize_t shell_sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
837{
838 return -ENOMEM;
839}
840
841ssize_t shell_sendmsg(int fd, const struct msghdr *msg, int flags)
842{
843 return -ENOMEM;
844}
845
846ssize_t shell_recvfrom(int fd, void *__restrict buf, size_t len, int flags, struct sockaddr *__restrict addr, socklen_t *__restrict alen)
847{
848 return -ENOMEM;
849}
850
851ssize_t shell_recvmsg(int fd, struct msghdr *msg, int flags)
852{
853 return -ENOMEM;
854}
855
856int shell_shutdown(int fd, int how)
857{
858 return -ENOMEM;
859}
860
861int shell_getsockopt(int fd, int level, int optname, void *optval, socklen_t *__restrict optlen)
862{
863 return -ENOMEM;
864}
865
866int shell_setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
867{
868 return -ENOMEM;
869}
870
871int shell_getpeername(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
872{
873 return -ENOMEM;
874}
875
876int shell_getsockname(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
877{
878 return -ENOMEM;
879}
880#endif
Note: See TracBrowser for help on using the repository browser.