source: EcnlProtoTool/trunk/ntshell/src/stdio_stub.c@ 441

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

NTShellタスクを更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 17.1 KB
Line 
1/*
2 * TOPPERS PROJECT Home Network Working Group Software
3 *
4 * Copyright (C) 2017-2019 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#include "fdtable.h"
47#include "kernel_cfg.h"
48#include <string.h>
49#include <errno.h>
50#include "util/ntstdio.h"
51#include "hal/serial_api.h"
52#include "target_rename.h"
53#include "target_kernel_impl.h"
54#include "syssvc/siofd.h"
55
56#ifdef _DEBUG
57static const char THIS_FILE[] = __FILE__;
58#endif
59
60int shell_errno;
61
62extern bool_t sio_isr_snd(ID siopid);
63extern bool_t sio_isr_rcv(ID siopid, char c);
64
65static unsigned char stdio_xi(struct ntstdio_t *handle);
66static void stdio_xo(struct ntstdio_t *handle, unsigned char c);
67static void stdio_serial_irq_handler(uint32_t id, SerialIrq event);
68
69static int stdio_close(struct SHELL_FILE *fp);
70static size_t stdio_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
71static size_t stdio_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
72static void stdio_delete(struct SHELL_FILE *fp);
73
74static unsigned char sio_xi(struct ntstdio_t *handle);
75static void sio_xo(struct ntstdio_t *handle, unsigned char c);
76static void sio_serial_irq_handler(uint32_t id, SerialIrq event);
77
78static int sio_close(struct SHELL_FILE *fp);
79static size_t sio_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
80static size_t sio_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
81static off_t sio_seek(struct SHELL_FILE *fp, off_t ofs, int org);
82static int sio_ioctl(struct SHELL_FILE *fp, int req, void *arg);
83static bool_t sio_readable(struct SHELL_FILE *fp);
84static bool_t sio_writable(struct SHELL_FILE *fp);
85static void sio_delete(struct SHELL_FILE *fp);
86
87IO_TYPE IO_TYPE_STDIN = { stdio_close, sio_read, stdio_write, sio_seek, sio_ioctl, sio_readable, sio_writable, stdio_delete };
88IO_TYPE IO_TYPE_STDOUT = { stdio_close, stdio_read, sio_write, sio_seek, sio_ioctl, sio_readable, sio_writable, stdio_delete };
89IO_TYPE IO_TYPE_STDERR = { stdio_close, stdio_read, sio_write, sio_seek, sio_ioctl, sio_readable, sio_writable, stdio_delete };
90IO_TYPE IO_TYPE_SIO = { sio_close, sio_read, sio_write, sio_seek, sio_ioctl, sio_readable, sio_writable, sio_delete };
91
92#define STDIO_UART_BUF_SZ 256
93
94typedef struct stdio_sio_t {
95 serial_t serial;
96 ntstdio_t ntstdio;
97 struct SHELL_FILE *fp;
98 unsigned char tx_buf[STDIO_UART_BUF_SZ];
99 int tx_pos_w;
100 int tx_pos_r;
101 unsigned char rx_buf[STDIO_UART_BUF_SZ];
102 int rx_pos_w;
103 int rx_pos_r;
104} stdio_sio_t;
105
106stdio_sio_t stdio_sio;
107ntstdio_t *ntstdio = &stdio_sio.ntstdio;
108
109void sys_init(intptr_t exinf)
110{
111 serial_t *serial = &stdio_sio.serial;
112 ntstdio_t *ntstdio = &stdio_sio.ntstdio;
113
114 serial_init(serial, STDIO_UART_TX, STDIO_UART_RX);
115 serial_baud(serial, UART_BAUDRATE);
116 serial_format(serial, 8, ParityNone, 1);
117
118 ntstdio_init(ntstdio, NTSTDIO_OPTION_LINE_ECHO | NTSTDIO_OPTION_CANON | NTSTDIO_OPTION_LF_CRLF | NTSTDIO_OPTION_LF_CR, stdio_xi, stdio_xo);
119 ntstdio->exinf = (void *)&stdio_sio;
120
121 struct SHELL_FILE *fp;
122
123 fp = fd_to_fp(STDIN_FILENO);
124 fp->handle = SIO_PORTID;
125 fp->exinf = (void *)ntstdio;
126
127 fp = fd_to_fp(STDOUT_FILENO);
128 fp->handle = SIO_PORTID;
129 fp->exinf = (void *)ntstdio;
130
131 fp = fd_to_fp(STDERR_FILENO);
132 fp->handle = SIO_PORTID;
133 fp->exinf = (void *)ntstdio;
134
135 serial_irq_handler(&stdio_sio.serial, stdio_serial_irq_handler, 0);
136
137 serial_irq_set(serial, RxIrq, true);
138}
139
140void stdio_open(ID portid)
141{
142 struct SHELL_FILE *fp;
143
144 serial_ctl_por(portid, IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
145
146 fp = fd_to_fp(STDIN_FILENO);
147 fp->handle = portid;
148
149 fp = fd_to_fp(STDOUT_FILENO);
150 fp->handle = portid;
151
152 fp = fd_to_fp(STDERR_FILENO);
153 fp->handle = portid;
154}
155
156int stdio_close(struct SHELL_FILE *fp)
157{
158 return -EPERM;
159}
160
161size_t stdio_read(struct SHELL_FILE *fp, unsigned char *data, size_t len)
162{
163 return -EPERM;
164}
165
166size_t stdio_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len)
167{
168 return -EPERM;
169}
170
171void stdio_delete(struct SHELL_FILE *fp)
172{
173}
174
175int sio_close(struct SHELL_FILE *fp)
176{
177 return -EPERM;
178}
179
180size_t sio_read(struct SHELL_FILE *fp, unsigned char *data, size_t len)
181{
182 int i = 0;
183 while (i < len) {
184 int c = ntstdio_getc((struct ntstdio_t *)fp->exinf);
185 data[i++] = c;
186 if ((c == EOF) || (c == '\n'))
187 break;
188 }
189 return i;
190}
191
192size_t sio_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len)
193{
194 for (int i = 0; i < len; i++) {
195 ntstdio_putc((struct ntstdio_t *)fp->exinf, data[i]);
196 }
197 return len;
198}
199
200off_t sio_seek(struct SHELL_FILE *fp, off_t ofs, int org)
201{
202 return -EPERM;
203}
204
205int sio_tcgetattr(struct SHELL_FILE *fp, struct termios *termios)
206{
207 ntstdio_t *ntstdio = (ntstdio_t *)fp->exinf;
208
209 memset(termios, 0, sizeof(*termios));
210
211 if (ntstdio->option & NTSTDIO_OPTION_LINE_ECHO) {
212 termios->c_lflag |= ECHO;
213 }
214 else {
215 termios->c_lflag &= ~ECHO;
216 }
217 if (ntstdio->option & NTSTDIO_OPTION_CANON) {
218 termios->c_lflag |= ICANON;
219 }
220 else {
221 termios->c_lflag &= ~ICANON;
222 }
223 if (ntstdio->option & NTSTDIO_OPTION_LF_CR) {
224 termios->c_iflag |= INLCR;
225 }
226 else {
227 termios->c_iflag &= ~INLCR;
228 }
229 if (ntstdio->option & NTSTDIO_OPTION_LF_CRLF) {
230 termios->c_oflag |= ONLCR;
231 }
232 else {
233 termios->c_oflag &= ~ONLCR;
234 }
235
236 return 0;
237}
238
239int sio_tcsetattr(struct SHELL_FILE *fp, int optional_actions, const struct termios *termios)
240{
241 ntstdio_t *ntstdio = (ntstdio_t *)fp->exinf;
242
243 if (optional_actions == TCSANOW) {
244 if (termios->c_lflag & ECHO) {
245 ntstdio->option |= NTSTDIO_OPTION_LINE_ECHO;
246 }
247 else {
248 ntstdio->option &= ~NTSTDIO_OPTION_LINE_ECHO;
249 }
250 if (termios->c_lflag & ICANON) {
251 ntstdio->option |= NTSTDIO_OPTION_CANON;
252 }
253 else {
254 ntstdio->option &= ~NTSTDIO_OPTION_CANON;
255 }
256 if (termios->c_iflag & INLCR) {
257 ntstdio->option |= NTSTDIO_OPTION_LF_CR;
258 }
259 else {
260 ntstdio->option &= ~NTSTDIO_OPTION_LF_CR;
261 }
262 if (termios->c_oflag & ONLCR) {
263 ntstdio->option |= NTSTDIO_OPTION_LF_CRLF;
264 }
265 else {
266 ntstdio->option &= ~NTSTDIO_OPTION_LF_CRLF;
267 }
268 return 0;
269 }
270
271 //shell_abort();
272 return 0;
273}
274
275int sio_ioctl(struct SHELL_FILE *fp, int request, void *arg)
276{
277 switch (request) {
278 case TIOCGWINSZ:
279 return 0;
280 case TCGETS:
281 return sio_tcgetattr(fp, (struct termios *)arg);
282 case TCSETS + TCSANOW:
283 case TCSETS + TCSADRAIN:
284 case TCSETS + TCSAFLUSH:
285 return sio_tcsetattr(fp, request - TCSETS, (const struct termios *)arg);
286 }
287
288 return -EINVAL;
289}
290
291bool_t sio_readable(struct SHELL_FILE *fp)
292{
293 struct ntstdio_t *ntstdio = (struct ntstdio_t *)fp->exinf;
294 stdio_sio_t *uart = (stdio_sio_t *)ntstdio->exinf;
295
296 return uart->rx_pos_r != uart->rx_pos_w;
297}
298
299bool_t sio_writable(struct SHELL_FILE *fp)
300{
301 if (!fp->writable)
302 return false;
303
304 struct ntstdio_t *ntstdio = (struct ntstdio_t *)fp->exinf;
305 stdio_sio_t *uart = (stdio_sio_t *)ntstdio->exinf;
306
307 int tx_pos_w = uart->tx_pos_w + 1;
308 if (tx_pos_w >= sizeof(uart->tx_buf))
309 tx_pos_w = 0;
310 return uart->tx_pos_r != tx_pos_w;
311}
312
313void sio_delete(struct SHELL_FILE *fp)
314{
315 free((stdio_sio_t *)((struct ntstdio_t *)fp->exinf)->exinf);
316 ((struct ntstdio_t *)fp->exinf)->exinf = NULL;
317 free((struct ntstdio_t *)fp->exinf);
318 fp->exinf = NULL;
319}
320
321static unsigned char ntstdio_xi(struct ntstdio_t *handle, struct SHELL_FILE *fp)
322{
323 stdio_sio_t *uart = (stdio_sio_t *)handle->exinf;
324 ER ret;
325 unsigned char c;
326
327 bool_t lock = sense_lock();
328 if (lock)
329 unl_cpu();
330
331 while (uart->rx_pos_w == uart->rx_pos_r) {
332 FLGPTN flgptn = 0, waitptn = 0;
333 FD_SET(fp->fd, (fd_set *)&waitptn);
334
335 ret = wai_flg(FLG_SELECT_WAIT, waitptn, TWF_ORW, &flgptn);
336 if (ret != E_OK) {
337 if (lock)
338 loc_cpu();
339 syslog(LOG_ERROR, "wai_flg => %d", ret);
340 return 0;
341 }
342
343 ret = clr_flg(FLG_SELECT_WAIT, ~(flgptn & waitptn));
344 if (ret != E_OK) {
345 syslog(LOG_ERROR, "clr_flg => %d", ret);
346 }
347 }
348
349 if (lock)
350 unl_cpu();
351
352 c = uart->rx_buf[uart->rx_pos_r++];
353 if (uart->rx_pos_r >= sizeof(uart->rx_buf))
354 uart->rx_pos_r = 0;
355
356 if ((uart->rx_pos_r == uart->rx_pos_w)
357 && (fp->readevt_w != fp->readevt_r))
358 fp->readevt_r++;
359
360 return c;
361}
362
363void stdio_input(unsigned char c)
364{
365 struct SHELL_FILE *fp = fd_to_fp(STDIN_FILENO);
366 stdio_sio_t *uart = (stdio_sio_t *)((struct ntstdio_t *)fp->exinf)->exinf;
367 serial_t *serial = (serial_t *)&uart->serial;
368 ER ret;
369 FLGPTN flgptn = 0;
370
371 uart->rx_buf[uart->rx_pos_w++] = c;
372 if (uart->rx_pos_w >= sizeof(uart->rx_buf))
373 uart->rx_pos_w = 0;
374
375 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
376
377 FD_SET(STDIN_FILENO, (fd_set *)&flgptn);
378
379 ret = set_flg(FLG_SELECT_WAIT, flgptn);
380 if (ret != E_OK) {
381 syslog(LOG_ERROR, "set_flg => %d", ret);
382 }
383}
384
385static void serial_rx_irq_handler(int fd)
386{
387 struct SHELL_FILE *fp = fd_to_fp(fd);
388 stdio_sio_t *uart = (stdio_sio_t *)((struct ntstdio_t *)fp->exinf)->exinf;
389 serial_t *serial = (serial_t *)&uart->serial;
390
391 if (serial_readable(serial)) {
392 unsigned char c = (unsigned char)serial_getc(serial);
393
394 if (fd != STDIN_FILENO) {
395 ER ret;
396 FLGPTN flgptn = 0;
397
398 uart->rx_buf[uart->rx_pos_w++] = c;
399 if (uart->rx_pos_w >= sizeof(uart->rx_buf))
400 uart->rx_pos_w = 0;
401
402 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
403
404 FD_SET(fd, (fd_set *)&flgptn);
405
406 ret = set_flg(FLG_SELECT_WAIT, flgptn);
407 if (ret != E_OK) {
408 syslog(LOG_ERROR, "set_flg => %d", ret);
409 }
410 }
411 else
412 sio_isr_rcv(fp->handle, c);
413 }
414}
415
416static void ntstdio_xo(struct ntstdio_t *handle, struct SHELL_FILE *fp, unsigned char c)
417{
418 stdio_sio_t *uart = (stdio_sio_t *)handle->exinf;
419 serial_t *serial = (serial_t *)&uart->serial;
420 ER ret;
421
422 // タスクコンテキストでない場合
423 if (sense_context()) {
424 // 送信可能になるまで待ち
425 while (!serial_writable(serial));
426 // 送信する
427 serial_putc(serial, c);
428 return;
429 }
430
431 // 送信バッファが空で
432 if (uart->tx_pos_w == uart->tx_pos_r) {
433 // 送信可能なら
434 if (serial_writable(serial)) {
435 // 送信する
436 serial_putc(serial, c);
437 return;
438 }
439 }
440
441 // 送信バッファに追加する
442 uart->tx_buf[uart->tx_pos_w++] = c;
443 if (uart->tx_pos_w >= sizeof(uart->tx_buf))
444 uart->tx_pos_w = 0;
445
446 // 送信可能になったら割り込みをもらうよう設定
447 serial_irq_set(serial, TxIrq, true);
448
449 bool_t lock = sense_lock();
450 if (lock)
451 unl_cpu();
452
453 // 送信バッファが一杯なら
454 int tx_pos_w = uart->tx_pos_w + 1;
455 if (tx_pos_w >= sizeof(uart->tx_buf))
456 tx_pos_w = 0;
457 while (tx_pos_w == uart->tx_pos_r) {
458 FLGPTN flgptn = 0, waitptn = 0;
459 FD_SET(fp->fd, (fd_set *)&waitptn);
460
461 // 送信完了割り込みまで待つ
462 ret = twai_flg(FLG_SELECT_WAIT, waitptn, TWF_ORW, &flgptn, 1000);
463 if ((ret != E_OK) && (ret != E_TMOUT)) {
464 syslog(LOG_ERROR, "wai_flg => %d", ret);
465 break;
466 }
467
468 ret = clr_flg(FLG_SELECT_WAIT, ~(flgptn & waitptn));
469 if (ret != E_OK) {
470 syslog(LOG_ERROR, "clr_flg => %d", ret);
471 }
472 }
473
474 if (fp->writeevt_w != fp->writeevt_r) fp->writeevt_r++;
475
476 if (lock)
477 loc_cpu();
478}
479
480static void serial_tx_irq_handler(int fd)
481{
482 struct SHELL_FILE *fp = fd_to_fp(fd);
483 stdio_sio_t *uart = (stdio_sio_t *)((struct ntstdio_t *)fp->exinf)->exinf;
484 serial_t *serial = (serial_t *)&uart->serial;
485 ER ret;
486 unsigned char c;
487
488 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
489
490 FLGPTN flgptn = 0;
491 FD_SET(fd, (fd_set *)&flgptn);
492
493 ret = set_flg(FLG_SELECT_WAIT, flgptn);
494 if (ret != E_OK) {
495 syslog(LOG_ERROR, "set_flg => %d", ret);
496 }
497
498 // 送信バッファが空なら
499 if (uart->tx_pos_w == uart->tx_pos_r) {
500 // SIOドライバの送信
501 sio_isr_snd(fp->handle);
502 // やっぱり送信バッファが空なら
503 if (uart->tx_pos_w == uart->tx_pos_r) {
504 // 送信割り込み停止
505 serial_irq_set(serial, TxIrq, false);
506 return;
507 }
508 }
509
510 c = uart->tx_buf[uart->tx_pos_r++];
511 if (uart->tx_pos_r >= sizeof(uart->tx_buf))
512 uart->tx_pos_r = 0;
513
514 // 送信する
515 serial_putc(serial, c);
516}
517
518void stdio_serial_irq_handler(uint32_t id, SerialIrq event)
519{
520 switch (event) {
521 case RxIrq:
522 serial_rx_irq_handler(STDIN_FILENO);
523 break;
524 case TxIrq:
525 serial_tx_irq_handler(STDOUT_FILENO);
526 break;
527 }
528}
529
530void sio_serial_irq_handler(uint32_t id, SerialIrq event)
531{
532 struct SHELL_FILE *fp = fd_to_fp(id);
533 if ((fp == NULL) || (fp->type != &IO_TYPE_SIO))
534 return;
535
536 switch (event) {
537 case RxIrq:
538 serial_rx_irq_handler(id);
539 break;
540 case TxIrq:
541 serial_tx_irq_handler(id);
542 break;
543 }
544}
545
546unsigned char stdio_xi(struct ntstdio_t *handle)
547{
548 return ntstdio_xi(handle, fd_to_fp(STDIN_FILENO));
549}
550
551void stdio_xo(struct ntstdio_t *handle, unsigned char c)
552{
553 ntstdio_xo(handle, fd_to_fp(STDOUT_FILENO), c);
554}
555
556unsigned char sio_xi(struct ntstdio_t *handle)
557{
558 return ntstdio_xi(handle, ((stdio_sio_t *)handle->exinf)->fp);
559}
560
561void sio_xo(struct ntstdio_t *handle, unsigned char c)
562{
563 ntstdio_xo(handle, ((stdio_sio_t *)handle->exinf)->fp, c);
564}
565
566int siofd_open(const char *path, int flags, ...)
567{
568 return -1;
569}
570
571int siofd_close(int fd)
572{
573 struct SHELL_FILE *fp = fd_to_fp(fd);
574 if ((fp == NULL) || (fp->type != &IO_TYPE_SIO)) {
575 shell_errno = EBADF;
576 return -1;
577 }
578
579 shell_errno = sio_close(fp);
580 if (shell_errno != 0)
581 return 1;
582 return 0;
583}
584
585ssize_t siofd_read(int fd, void *data, size_t len)
586{
587 struct SHELL_FILE *fp = fd_to_fp(fd);
588 if ((fp == NULL) || ((fp->type != &IO_TYPE_STDIN) && (fp->type != &IO_TYPE_SIO))) {
589 shell_errno = EBADF;
590 return -1;
591 }
592 char *pos, *end;
593
594 for (pos = (char *)data, end = &pos[len]; pos < end; pos++) {
595 *pos = ntstdio_xi((struct ntstdio_t *)fp->exinf, fp);
596 }
597
598 return pos - (char *)data;
599}
600
601ssize_t siofd_write(int fd, const void *data, size_t len)
602{
603 struct SHELL_FILE *fp = fd_to_fp(fd);
604 if ((fp == NULL) || ((fp->type != &IO_TYPE_STDOUT) && (fp->type != &IO_TYPE_STDERR)
605 && (fp->type != &IO_TYPE_SIO))) {
606 shell_errno = EBADF;
607 return -1;
608 }
609 const char *pos, *end;
610
611 for (pos = (const char *)data, end = &pos[len]; pos < end; pos++) {
612 ntstdio_xo((struct ntstdio_t *)fp->exinf, fp, *pos);
613 }
614
615 return pos - (char *)data;
616}
617
618int siofd_tcsetattr(int fd, int act, const struct termios *tio)
619{
620 struct SHELL_FILE *fp = fd_to_fp(fd);
621 if ((fp == NULL) || ((fp->type != &IO_TYPE_STDIN) && (fp->type != &IO_TYPE_STDOUT)
622 && (fp->type != &IO_TYPE_STDERR) && (fp->type != &IO_TYPE_SIO))) {
623 shell_errno = EBADF;
624 return -1;
625 }
626
627 shell_errno = sio_tcsetattr(fp, act, tio);
628 if (shell_errno != 0)
629 return 1;
630 return 0;
631}
632
633int siofd_tcgetattr(int fd, struct termios *tio)
634{
635 struct SHELL_FILE *fp = fd_to_fp(fd);
636 if ((fp == NULL) || ((fp->type != &IO_TYPE_STDIN) && (fp->type != &IO_TYPE_STDOUT)
637 && (fp->type != &IO_TYPE_STDERR) && (fp->type != &IO_TYPE_SIO))) {
638 shell_errno = EBADF;
639 return -1;
640 }
641
642 shell_errno = sio_tcgetattr(fp, tio);
643 if (shell_errno != 0)
644 return 1;
645 return 0;
646}
647
648int siofd_fcntl(int fd, int cmd, ...)
649{
650 struct SHELL_FILE *fp = fd_to_fp(fd);
651 if ((fp == NULL) || ((fp->type != &IO_TYPE_STDIN) && (fp->type != &IO_TYPE_STDOUT)
652 && (fp->type != &IO_TYPE_STDERR) && (fp->type != &IO_TYPE_SIO))) {
653 shell_errno = EBADF;
654 return -1;
655 }
656 void *arg;
657 va_list ap;
658 va_start(ap, cmd);
659 arg = va_arg(ap, void *);
660 va_end(ap);
661
662 shell_errno = sio_ioctl(fp, cmd, arg);
663 if (shell_errno != 0)
664 return 1;
665 return 0;
666}
Note: See TracBrowser for help on using the repository browser.