1 /*
2 Copyright (C) 2010-2017,2018 John E. Davis
3
4 This file is part of the S-Lang Library.
5
6 The S-Lang Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 The S-Lang Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 USA.
20 */
21 #include <stdio.h>
22 #include <slang.h>
23
24 #include <unistd.h>
25 #include <string.h>
26 #include <termios.h>
27 #include <errno.h>
28
29 SLANG_MODULE(termios);
30
31 static int Termios_Type_Id = 0;
32
check_and_set_errno(int e)33 static int check_and_set_errno (int e)
34 {
35 #ifdef EINTR
36 if (e == EINTR)
37 return 0;
38 #endif
39 (void) SLerrno_set_errno (e);
40 return -1;
41 }
42
do_syscall_0(int (* fun)(int),SLFile_FD_Type * f)43 static int do_syscall_0 (int (*fun)(int), SLFile_FD_Type *f)
44 {
45 int fd;
46 int ret;
47
48 if (-1 == SLfile_get_fd (f, &fd))
49 return -1;
50
51 while ((-1 == (ret = (*fun) (fd)))
52 && (0 == check_and_set_errno (errno)))
53 ;
54
55 return ret;
56 }
57
do_syscall_1(int (* fun)(int,int),SLFile_FD_Type * f,int arg)58 static int do_syscall_1 (int (*fun)(int, int), SLFile_FD_Type *f, int arg)
59 {
60 int fd;
61 int ret;
62
63 if (-1 == SLfile_get_fd (f, &fd))
64 return -1;
65
66 while ((-1 == (ret = (*fun) (fd, arg)))
67 && (0 == check_and_set_errno (errno)))
68 ;
69
70 return ret;
71 }
72
do_syscall_struct_1(int (* fun)(int,void *),SLFile_FD_Type * f,void * v)73 static int do_syscall_struct_1 (int (*fun)(int, void *), SLFile_FD_Type *f, void *v)
74 {
75 int fd;
76 int ret;
77
78 if (-1 == SLfile_get_fd (f, &fd))
79 return -1;
80
81 while ((-1 == (ret = (*fun) (fd, v)))
82 && (0 == check_and_set_errno (errno)))
83 ;
84
85 return ret;
86 }
87
do_syscall_struct_2(int (* fun)(int,int,void *),SLFile_FD_Type * f,int i,void * v)88 static int do_syscall_struct_2 (int (*fun)(int, int, void *), SLFile_FD_Type *f, int i, void *v)
89 {
90 int fd;
91 int ret;
92
93 if (-1 == SLfile_get_fd (f, &fd))
94 return -1;
95
96 while ((-1 == (ret = (*fun) (fd, i, v)))
97 && (0 == check_and_set_errno (errno)))
98 ;
99
100 return ret;
101 }
102
103 #define DO_SYSCALL_0(fun, f) do_syscall_0((int(*)(int))(fun),(f))
104 #define DO_SYSCALL_1(fun, f, i) do_syscall_1((int(*)(int,int))(fun),(f),(i))
105 #define DO_SYSCALL_STRUCT_1(fun, f, s) \
106 do_syscall_struct_1((int(*)(int, void*))(fun), (f), (void*)(s))
107 #define DO_SYSCALL_STRUCT_2(fun, f, i, s) \
108 do_syscall_struct_2((int(*)(int, int, void*))(fun), (f), (i), (void*)(s))
109
tcdrain_intrin(SLFile_FD_Type * f)110 static int tcdrain_intrin (SLFile_FD_Type *f)
111 {
112 return DO_SYSCALL_0 (tcdrain, f);
113 }
114
tcflow_intrin(SLFile_FD_Type * f,int * action)115 static int tcflow_intrin (SLFile_FD_Type *f, int *action)
116 {
117 return DO_SYSCALL_1 (tcflow, f, *action);
118 }
119
tcflush_intrin(SLFile_FD_Type * f,int * action)120 static int tcflush_intrin (SLFile_FD_Type *f, int *action)
121 {
122 return DO_SYSCALL_1 (tcflush, f, *action);
123 }
124
tcgetpgrp_intrin(SLFile_FD_Type * f)125 static int tcgetpgrp_intrin (SLFile_FD_Type *f)
126 {
127 return DO_SYSCALL_0 (tcgetpgrp, f);
128 }
129
tcsetpgrp_intrin(SLFile_FD_Type * f,int * id)130 static int tcsetpgrp_intrin (SLFile_FD_Type *f, int *id)
131 {
132 return DO_SYSCALL_1 (tcgetpgrp, f, *id);
133 }
134
tcsendbreak_intrin(SLFile_FD_Type * f,int * action)135 static int tcsendbreak_intrin (SLFile_FD_Type *f, int *action)
136 {
137 return DO_SYSCALL_1 (tcsendbreak, f, *action);
138 }
139
destroy_termios(SLtype type,VOID_STAR f)140 static void destroy_termios (SLtype type, VOID_STAR f)
141 {
142 (void) type;
143 SLfree ((char *) f);
144 }
145
allocate_termios(struct termios * s)146 static SLang_MMT_Type *allocate_termios (struct termios *s)
147 {
148 struct termios *s1;
149 SLang_MMT_Type *mmt;
150
151 s1 = (struct termios *) SLmalloc (sizeof (struct termios));
152 if (s1 == NULL)
153 return NULL;
154
155 memcpy (s1, s, sizeof (struct termios));
156 if (NULL == (mmt = SLang_create_mmt (Termios_Type_Id, (VOID_STAR) s1)))
157 SLfree ((char *) s1);
158 return mmt;
159 }
160
tcgetattr_intrin(SLFile_FD_Type * f)161 static void tcgetattr_intrin (SLFile_FD_Type *f)
162 {
163 struct termios s;
164 SLang_MMT_Type *mmt;
165
166 if (-1 == DO_SYSCALL_STRUCT_1(tcgetattr,f,&s))
167 {
168 SLang_push_null ();
169 return;
170 }
171
172 mmt = allocate_termios (&s); /* NULL ok */
173 if (-1 == SLang_push_mmt (mmt))
174 SLang_free_mmt (mmt);
175 }
176
tcsetattr_intrin(SLFile_FD_Type * f,int * when,struct termios * s)177 static int tcsetattr_intrin (SLFile_FD_Type *f, int *when, struct termios *s)
178 {
179 return DO_SYSCALL_STRUCT_2(tcsetattr,f,*when,s);
180 }
181
termios_get_oflag(struct termios * s)182 static int termios_get_oflag (struct termios *s)
183 {
184 return s->c_oflag;
185 }
termios_get_iflag(struct termios * s)186 static int termios_get_iflag (struct termios *s)
187 {
188 return s->c_iflag;
189 }
termios_get_cflag(struct termios * s)190 static int termios_get_cflag (struct termios *s)
191 {
192 return s->c_cflag;
193 }
termios_get_lflag(struct termios * s)194 static int termios_get_lflag (struct termios *s)
195 {
196 return s->c_lflag;
197 }
198
termios_get_cc(struct termios * s)199 static void termios_get_cc (struct termios *s)
200 {
201 SLang_Array_Type *at;
202 SLindex_Type dims = NCCS;
203 int i;
204 unsigned char *at_data;
205
206 at = SLang_create_array (SLANG_UCHAR_TYPE, 0, NULL, &dims, 1);
207 if (at == NULL)
208 return;
209 at_data = (unsigned char *) at->data;
210
211 for (i = 0; i < NCCS; i++)
212 at_data[i] = (unsigned char) s->c_cc[i];
213
214 (void) SLang_push_array (at, 1);
215 }
216
termios_set_oflag(struct termios * s,int * flag)217 static void termios_set_oflag (struct termios *s, int *flag)
218 {
219 s->c_oflag = *flag;
220 }
termios_set_iflag(struct termios * s,int * flag)221 static void termios_set_iflag (struct termios *s, int *flag)
222 {
223 s->c_iflag = *flag;
224 }
termios_set_cflag(struct termios * s,int * flag)225 static void termios_set_cflag (struct termios *s, int *flag)
226 {
227 s->c_cflag = *flag;
228 }
termios_set_lflag(struct termios * s,int * flag)229 static void termios_set_lflag (struct termios *s, int *flag)
230 {
231 s->c_lflag = *flag;
232 }
233
termios_set_cc(void)234 static void termios_set_cc (void)
235 {
236 SLang_Array_Type *at;
237 SLang_MMT_Type *mmt;
238 struct termios *s;
239 unsigned char *at_data;
240 int i;
241
242 if (-1 == SLang_pop_array_of_type (&at, SLANG_UCHAR_TYPE))
243 return;
244 if (NULL == (mmt = SLang_pop_mmt (Termios_Type_Id)))
245 goto free_and_return;
246
247 s = (struct termios *) SLang_object_from_mmt (mmt);
248 if (at->num_elements != NCCS)
249 {
250 SLang_verror (SL_TYPE_MISMATCH,
251 "Expecting UChar_Type[%d]", NCCS);
252 goto free_and_return;
253 }
254
255 at_data = (unsigned char *) at->data;
256 for (i = 0; i < NCCS; i++)
257 s->c_cc[i] = at_data[i];
258
259 /* drop */
260
261 free_and_return:
262 SLang_free_array (at);
263 SLang_free_mmt (mmt);
264 }
265
266 typedef struct
267 {
268 unsigned int bspeed;
269 unsigned int speed;
270 }
271 Baudrate_Map_Type;
272
273 Baudrate_Map_Type Baudrate_Map[] =
274 {
275 #ifdef B0
276 {B0, 0},
277 #endif
278 #ifdef B50
279 {B50, 50},
280 #endif
281 #ifdef B75
282 {B75, 75},
283 #endif
284 #ifdef B110
285 {B110, 110},
286 #endif
287 #ifdef B134
288 {B134, 134},
289 #endif
290 #ifdef B150
291 {B150, 150},
292 #endif
293 #ifdef B200
294 {B200, 200},
295 #endif
296 #ifdef B300
297 {B300, 300},
298 #endif
299 #ifdef B600
300 {B600, 600},
301 #endif
302 #ifdef B1200
303 {B1200, 1200},
304 #endif
305 #ifdef B1800
306 {B1800, 1800},
307 #endif
308 #ifdef B2400
309 {B2400, 2400},
310 #endif
311 #ifdef B4800
312 {B4800, 4800},
313 #endif
314 #ifdef B9600
315 {B9600, 9600},
316 #endif
317 #ifdef B19200
318 {B19200, 19200},
319 #endif
320 #ifdef B38400
321 {B38400, 38400},
322 #endif
323 #ifdef B57600
324 {B57600, 57600},
325 #endif
326 #ifdef B115200
327 {B115200, 115200},
328 #endif
329 #ifdef B230400
330 {B230400, 230400},
331 #endif
332 #ifdef B460800
333 {B460800, 460800},
334 #endif
335 #ifdef B500000
336 {B500000, 500000},
337 #endif
338 #ifdef B576000
339 {B576000, 576000},
340 #endif
341 #ifdef B921600
342 {B921600, 921600},
343 #endif
344 #ifdef B1000000
345 {B1000000, 1000000},
346 #endif
347 #ifdef B1152000
348 {B1152000, 1152000},
349 #endif
350 #ifdef B1500000
351 {B1500000, 1500000},
352 #endif
353 #ifdef B2000000
354 {B2000000, 2000000},
355 #endif
356 #ifdef B2500000
357 {B2500000, 2500000},
358 #endif
359 #ifdef B3000000
360 {B3000000, 3000000},
361 #endif
362 #ifdef B3500000
363 {B3500000, 3500000},
364 #endif
365 #ifdef B4000000
366 {B4000000, 4000000},
367 #endif
368 {0, 0}
369 };
370
map_speed_to_bspeed(unsigned int speed,unsigned int * bspeed)371 static int map_speed_to_bspeed (unsigned int speed, unsigned int *bspeed)
372 {
373 Baudrate_Map_Type *b, *bmax;
374
375 b = Baudrate_Map;
376 bmax = Baudrate_Map + (sizeof(Baudrate_Map)/sizeof(Baudrate_Map_Type)-1);
377
378 while (b < bmax)
379 {
380 if (b->speed == speed)
381 {
382 *bspeed = b->bspeed;
383 return 0;
384 }
385 b++;
386 }
387 SLang_verror (SL_InvalidParm_Error, "Invalid or Unsupported baudrate %u", speed);
388 return -1;
389 }
390
map_bspeed_to_speed(unsigned int bspeed,unsigned int * speed)391 static int map_bspeed_to_speed (unsigned int bspeed, unsigned int *speed)
392 {
393 Baudrate_Map_Type *b, *bmax;
394
395 b = Baudrate_Map;
396 bmax = Baudrate_Map + (sizeof(Baudrate_Map)/sizeof(Baudrate_Map_Type)-1);
397
398 while (b < bmax)
399 {
400 if (b->bspeed == bspeed)
401 {
402 *speed = b->speed;
403 return 0;
404 }
405 b++;
406 }
407 SLang_verror (SL_InvalidParm_Error, "Invalid or Unsupported baudrate %u", bspeed);
408 return -1;
409 }
410
cfgetispeed_intrin(struct termios * t)411 static void cfgetispeed_intrin (struct termios *t)
412 {
413 unsigned int speed, bspeed;
414
415 bspeed = cfgetispeed (t);
416 if (0 == map_bspeed_to_speed (bspeed, &speed))
417 (void) SLang_push_uint (speed);
418 }
419
cfgetospeed_intrin(struct termios * t)420 static void cfgetospeed_intrin (struct termios *t)
421 {
422 unsigned int speed, bspeed;
423
424 bspeed = cfgetospeed (t);
425 if (0 == map_bspeed_to_speed (bspeed, &speed))
426 (void) SLang_push_uint (speed);
427 }
428
cfsetispeed_intrin(struct termios * t,unsigned int * speed)429 static int cfsetispeed_intrin (struct termios *t, unsigned int *speed)
430 {
431 unsigned int bspeed;
432
433 if (-1 == map_speed_to_bspeed (*speed, &bspeed))
434 return -1;
435
436 if (-1 == cfsetispeed (t, bspeed))
437 {
438 (void) SLerrno_set_errno (errno);
439 return -1;
440 }
441 return 0;
442 }
443
cfsetospeed_intrin(struct termios * t,unsigned int * speed)444 static int cfsetospeed_intrin (struct termios *t, unsigned int *speed)
445 {
446 unsigned int bspeed;
447
448 if (-1 == map_speed_to_bspeed (*speed, &bspeed))
449 return -1;
450
451 if (-1 == cfsetospeed (t, bspeed))
452 {
453 (void) SLerrno_set_errno (errno);
454 return -1;
455 }
456 return 0;
457 }
458
termios_dereference(SLtype type,VOID_STAR addr)459 static int termios_dereference (SLtype type, VOID_STAR addr)
460 {
461 struct termios *s;
462 SLang_MMT_Type *mmt;
463
464 (void) type;
465 mmt = *(SLang_MMT_Type **) addr;
466 if (NULL == (s = (struct termios *)SLang_object_from_mmt (mmt)))
467 return -1;
468
469 mmt = allocate_termios (s);
470 if (-1 == SLang_push_mmt (mmt))
471 {
472 SLang_free_mmt (mmt);
473 return -1;
474 }
475
476 return 0;
477 }
478
479 #define DUMMY_TERMIOS_TYPE ((unsigned int)-1)
480 #define T DUMMY_TERMIOS_TYPE
481 #define F SLANG_FILE_FD_TYPE
482 #define I SLANG_INT_TYPE
483 #define V SLANG_VOID_TYPE
484 #define U SLANG_UINT_TYPE
485 static SLang_Intrin_Fun_Type Termios_Intrinsics [] =
486 {
487 MAKE_INTRINSIC_1("tcdrain", tcdrain_intrin, I, F),
488 MAKE_INTRINSIC_2("tcflow", tcflow_intrin, I, F, I),
489 MAKE_INTRINSIC_2("tcflush", tcflush_intrin, I, F, I),
490 MAKE_INTRINSIC_1("tcgetpgrp", tcgetpgrp_intrin, I, F),
491 MAKE_INTRINSIC_2("tcsetpgrp", tcsetpgrp_intrin, I, F, I),
492 MAKE_INTRINSIC_2("tcsendbreak", tcsendbreak_intrin, I, F, I),
493 MAKE_INTRINSIC_1("tcgetattr", tcgetattr_intrin, V, F),
494 MAKE_INTRINSIC_3("tcsetattr", tcsetattr_intrin, I, F, I, T),
495 MAKE_INTRINSIC_1("cfgetispeed", cfgetispeed_intrin, V, T),
496 MAKE_INTRINSIC_1("cfgetospeed", cfgetospeed_intrin, V, T),
497 MAKE_INTRINSIC_2("cfsetispeed", cfsetispeed_intrin, I, T, U),
498 MAKE_INTRINSIC_2("cfsetospeed", cfsetospeed_intrin, I, T, U),
499 MAKE_INTRINSIC_1("termios_get_oflag", termios_get_oflag, I, T),
500 MAKE_INTRINSIC_1("termios_get_iflag", termios_get_iflag, I, T),
501 MAKE_INTRINSIC_1("termios_get_cflag", termios_get_cflag, I, T),
502 MAKE_INTRINSIC_1("termios_get_lflag", termios_get_lflag, I, T),
503 MAKE_INTRINSIC_1("termios_get_cc", termios_get_cc, V, T),
504 MAKE_INTRINSIC_2("termios_set_oflag", termios_set_oflag, V, T, I),
505 MAKE_INTRINSIC_2("termios_set_iflag", termios_set_iflag, V, T, I),
506 MAKE_INTRINSIC_2("termios_set_cflag", termios_set_cflag, V, T, I),
507 MAKE_INTRINSIC_2("termios_set_lflag", termios_set_lflag, V, T, I),
508 MAKE_INTRINSIC_0("termios_set_cc", termios_set_cc, V),
509
510 SLANG_END_INTRIN_FUN_TABLE
511 };
512 #undef T
513 #undef I
514 #undef F
515 #undef V
516 #undef U
517
518 static SLang_IConstant_Type Termios_Consts [] =
519 {
520 #ifdef BRKINT
521 MAKE_ICONSTANT("BRKINT", BRKINT),
522 #endif
523 #ifdef CLOCAL
524 MAKE_ICONSTANT("CLOCAL", CLOCAL),
525 #endif
526 #ifdef CREAD
527 MAKE_ICONSTANT("CREAD", CREAD),
528 #endif
529 #ifdef CS5
530 MAKE_ICONSTANT("CS5", CS5),
531 #endif
532 #ifdef CS6
533 MAKE_ICONSTANT("CS6", CS6),
534 #endif
535 #ifdef CS7
536 MAKE_ICONSTANT("CS7", CS7),
537 #endif
538 #ifdef CS8
539 MAKE_ICONSTANT("CS8", CS8),
540 #endif
541 #ifdef CSIZE
542 MAKE_ICONSTANT("CSIZE", CSIZE),
543 #endif
544 #ifdef CSTOPB
545 MAKE_ICONSTANT("CSTOPB", CSTOPB),
546 #endif
547 #ifdef ECHO
548 MAKE_ICONSTANT("ECHO", ECHO),
549 #endif
550 #ifdef ECHOE
551 MAKE_ICONSTANT("ECHOE", ECHOE),
552 #endif
553 #ifdef ECHOK
554 MAKE_ICONSTANT("ECHOK", ECHOK),
555 #endif
556 #ifdef ECHONL
557 MAKE_ICONSTANT("ECHONL", ECHONL),
558 #endif
559 #ifdef HUPCL
560 MAKE_ICONSTANT("HUPCL", HUPCL),
561 #endif
562 #ifdef ICANON
563 MAKE_ICONSTANT("ICANON", ICANON),
564 #endif
565 #ifdef ICRNL
566 MAKE_ICONSTANT("ICRNL", ICRNL),
567 #endif
568 #ifdef IEXTEN
569 MAKE_ICONSTANT("IEXTEN", IEXTEN),
570 #endif
571 #ifdef IGNBRK
572 MAKE_ICONSTANT("IGNBRK", IGNBRK),
573 #endif
574 #ifdef IGNCR
575 MAKE_ICONSTANT("IGNCR", IGNCR),
576 #endif
577 #ifdef IGNPAR
578 MAKE_ICONSTANT("IGNPAR", IGNPAR),
579 #endif
580 #ifdef INLCR
581 MAKE_ICONSTANT("INLCR", INLCR),
582 #endif
583 #ifdef INPCK
584 MAKE_ICONSTANT("INPCK", INPCK),
585 #endif
586 #ifdef ISIG
587 MAKE_ICONSTANT("ISIG", ISIG),
588 #endif
589 #ifdef ISTRIP
590 MAKE_ICONSTANT("ISTRIP", ISTRIP),
591 #endif
592 #ifdef IXOFF
593 MAKE_ICONSTANT("IXOFF", IXOFF),
594 #endif
595 #ifdef IXON
596 MAKE_ICONSTANT("IXON", IXON),
597 #endif
598 #ifdef NOFLSH
599 MAKE_ICONSTANT("NOFLSH", NOFLSH),
600 #endif
601 #ifdef OPOST
602 MAKE_ICONSTANT("OPOST", OPOST),
603 #endif
604 #ifdef PARENB
605 MAKE_ICONSTANT("PARENB", PARENB),
606 #endif
607 #ifdef PARMRK
608 MAKE_ICONSTANT("PARMRK", PARMRK),
609 #endif
610 #ifdef PARODD
611 MAKE_ICONSTANT("PARODD", PARODD),
612 #endif
613 #ifdef TCIFLUSH
614 MAKE_ICONSTANT("TCIFLUSH", TCIFLUSH),
615 #endif
616 #ifdef TCIOFF
617 MAKE_ICONSTANT("TCIOFF", TCIOFF),
618 #endif
619 #ifdef TCIOFLUSH
620 MAKE_ICONSTANT("TCIOFLUSH", TCIOFLUSH),
621 #endif
622 #ifdef TCION
623 MAKE_ICONSTANT("TCION", TCION),
624 #endif
625 #ifdef TCOFLUSH
626 MAKE_ICONSTANT("TCOFLUSH", TCOFLUSH),
627 #endif
628 #ifdef TCOOFF
629 MAKE_ICONSTANT("TCOOFF", TCOOFF),
630 #endif
631 #ifdef TCOON
632 MAKE_ICONSTANT("TCOON", TCOON),
633 #endif
634 #ifdef TCSADRAIN
635 MAKE_ICONSTANT("TCSADRAIN", TCSADRAIN),
636 #endif
637 #ifdef TCSAFLUSH
638 MAKE_ICONSTANT("TCSAFLUSH", TCSAFLUSH),
639 #endif
640 #ifdef TCSANOW
641 MAKE_ICONSTANT("TCSANOW", TCSANOW),
642 #endif
643 #ifdef TOSTOP
644 MAKE_ICONSTANT("TOSTOP", TOSTOP),
645 #endif
646 #ifdef VEOF
647 MAKE_ICONSTANT("VEOF", VEOF),
648 #endif
649 #ifdef VEOL
650 MAKE_ICONSTANT("VEOL", VEOL),
651 #endif
652 #ifdef VERASE
653 MAKE_ICONSTANT("VERASE", VERASE),
654 #endif
655 #ifdef VINTR
656 MAKE_ICONSTANT("VINTR", VINTR),
657 #endif
658 #ifdef VKILL
659 MAKE_ICONSTANT("VKILL", VKILL),
660 #endif
661 #ifdef VMIN
662 MAKE_ICONSTANT("VMIN", VMIN),
663 #endif
664 #ifdef VQUIT
665 MAKE_ICONSTANT("VQUIT", VQUIT),
666 #endif
667 #ifdef VSTART
668 MAKE_ICONSTANT("VSTART", VSTART),
669 #endif
670 #ifdef VSTOP
671 MAKE_ICONSTANT("VSTOP", VSTOP),
672 #endif
673 #ifdef VSUSP
674 MAKE_ICONSTANT("VSUSP", VSUSP),
675 #endif
676 #ifdef VTIME
677 MAKE_ICONSTANT("VTIME", VTIME),
678 #endif
679 #ifdef CRTSCTS /* not POSIX */
680 MAKE_ICONSTANT("CRTSCTS", CRTSCTS),
681 #endif
682 #ifdef IXANY
683 MAKE_ICONSTANT("IXANY", IXANY),
684 #endif
685 #ifdef ultrix /* Ultrix gets _POSIX_VDISABLE wrong! */
686 # define NULL_VALUE -1
687 #else
688 # ifdef _POSIX_VDISABLE
689 # define NULL_VALUE _POSIX_VDISABLE
690 # else
691 # define NULL_VALUE 255
692 # endif
693 #endif
694 MAKE_ICONSTANT("VDISABLE", NULL_VALUE),
695
696 SLANG_END_ICONST_TABLE
697 };
698
register_termios_type(void)699 static int register_termios_type (void)
700 {
701 SLang_Class_Type *cl;
702
703 if (Termios_Type_Id != 0)
704 return 0;
705
706 if (NULL == (cl = SLclass_allocate_class ("Termios_Type")))
707 return -1;
708
709 if (-1 == SLclass_set_destroy_function (cl, destroy_termios))
710 return -1;
711
712 if (-1 == SLclass_set_deref_function (cl, termios_dereference))
713 return -1;
714
715 /* By registering as SLANG_VOID_TYPE, slang will dynamically allocate a
716 * type.
717 */
718 if (-1 == SLclass_register_class (cl, SLANG_VOID_TYPE, sizeof (struct termios), SLANG_CLASS_TYPE_MMT))
719 return -1;
720
721 Termios_Type_Id = SLclass_get_class_id (cl);
722 if (-1 == SLclass_patch_intrin_fun_table1 (Termios_Intrinsics, DUMMY_TERMIOS_TYPE, Termios_Type_Id))
723 return -1;
724
725 return 0;
726 }
727
init_termios_module_ns(char * ns_name)728 int init_termios_module_ns (char *ns_name)
729 {
730 SLang_NameSpace_Type *ns;
731
732 ns = SLns_create_namespace (ns_name);
733 if (ns == NULL)
734 return -1;
735
736 if (-1 == register_termios_type ())
737 return -1;
738
739 if ((-1 == SLns_add_intrin_fun_table (ns, Termios_Intrinsics, "__TERMIOS__"))
740 || (-1 == SLns_add_iconstant_table (ns, Termios_Consts, NULL)))
741 return -1;
742
743 return 0;
744 }
745
746 /* This function is optional */
deinit_termios_module(void)747 void deinit_termios_module (void)
748 {
749 }
750