hybridgroup-serialport 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ gem 'rake-compiler', '>= 0.4.1'
5
+ require "rake/extensiontask"
6
+
7
+ begin
8
+ require 'jeweler'
9
+ Jeweler::Tasks.new do |gemspec|
10
+ gemspec.name = "hybridgroup-serialport"
11
+ gemspec.summary = "Library for using RS-232 serial ports."
12
+ gemspec.description = "Ruby/SerialPort is a Ruby library that provides a class for using RS-232 serial ports."
13
+ gemspec.email = "serialport@hybridgroup.com"
14
+ gemspec.homepage = 'http://github.com/hybridgroup/ruby-serialport/'
15
+ gemspec.authors = ['Guillaume Pierronnet', 'Alan Stern', 'Daniel E. Shipton', 'Tobin Richard', 'Hector Parra', 'Ryan C. Payne']
16
+ gemspec.has_rdoc = true
17
+ gemspec.extensions << 'ext/native/extconf.rb'
18
+ gemspec.version = "1.2.0"
19
+ gemspec.files = [
20
+ "CHANGELOG",
21
+ "CHECKLIST",
22
+ "LICENSE",
23
+ "MANIFEST",
24
+ "README",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "ext/native/extconf.rb",
28
+ "ext/native/posix_serialport_impl.c",
29
+ "ext/native/serialport.c",
30
+ "ext/native/serialport.h",
31
+ "ext/native/win_serialport_impl.c",
32
+ "lib/serialport.rb",
33
+ "hybridgroup-serialport.gemspec",
34
+ "test/miniterm.rb",
35
+ "test/set_readtimeout.rb"
36
+ ]
37
+
38
+ Rake::ExtensionTask.new "serialport", gemspec do |ext|
39
+ #ext.lib_dir = File.join(*['lib', ENV['FAT_DIR']].compact)
40
+ ext.ext_dir = "ext/native"
41
+ end
42
+ end
43
+ Jeweler::GemcutterTasks.new
44
+ rescue LoadError
45
+ puts "Jeweler not available. Install it with: sudo gem install jeweler -s http://gemcutter.org"
46
+ end
47
+
48
+ task :clean do
49
+ rm_rf(Dir['doc'], :verbose => true)
50
+ rm_rf(Dir['pkg'], :verbose => true)
51
+ end
52
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.2.0
@@ -0,0 +1,13 @@
1
+ require 'mkmf'
2
+
3
+ printf("checking for OS... ")
4
+ STDOUT.flush
5
+ os = /-([a-z]+)/.match(RUBY_PLATFORM)[1]
6
+ puts(os)
7
+ $CFLAGS += " -DOS_#{os.upcase}"
8
+
9
+ if !(os == 'mswin' or os == 'bccwin' or os == 'mingw')
10
+ exit(1) if not have_header("termios.h") or not have_header("unistd.h")
11
+ end
12
+
13
+ create_makefile('serialport')
@@ -0,0 +1,733 @@
1
+ /* Ruby/SerialPort
2
+ * Guillaume Pierronnet <moumar@netcourrier.com>
3
+ * Alan Stern <stern@rowland.harvard.edu>
4
+ * Daniel E. Shipton <dshipton@redshiptechnologies.com>
5
+ * Ryan C. Payne <rpayne-oss@bullittsystems.com>
6
+ *
7
+ * This code is hereby licensed for public consumption under either the
8
+ * GNU GPL v2 or greater.
9
+ *
10
+ * You should have received a copy of the GNU General Public License
11
+ * along with this program; if not, write to the Free Software
12
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
13
+ *
14
+ * For documentation on serial programming, see the excellent:
15
+ * "Serial Programming Guide for POSIX Operating Systems"
16
+ * written Michael R. Sweet.
17
+ * http://www.easysw.com/~mike/serial/
18
+ */
19
+
20
+ #include "serialport.h"
21
+
22
+ /* Check if we are on a posix compliant system. */
23
+ #if !defined(OS_MSWIN) && !defined(OS_BCCWIN) && !defined(OS_MINGW)
24
+
25
+ #include <stdio.h> /* Standard input/output definitions */
26
+ #include <unistd.h> /* UNIX standard function definitions */
27
+ #include <fcntl.h> /* File control definitions */
28
+ #include <errno.h> /* Error number definitions */
29
+ #include <termios.h> /* POSIX terminal control definitions */
30
+ #include <sys/ioctl.h>
31
+
32
+ #ifdef CRTSCTS
33
+ #define HAVE_FLOWCONTROL_HARD 1
34
+ #else
35
+ #undef HAVE_FLOWCONTROL_HARD
36
+ #endif
37
+
38
+ /* on mac os x, not all baud rates are defined in termios.h but
39
+ they are mapped to the numeric value anyway, so we define them here */
40
+ #ifdef __APPLE__
41
+ #ifndef B460800
42
+ #define B460800 460800
43
+ #endif
44
+ #ifndef B500000
45
+ #define B500000 500000
46
+ #endif
47
+ #ifndef B576000
48
+ #define B576000 576000
49
+ #endif
50
+ #ifndef B921600
51
+ #define B921600 921600
52
+ #endif
53
+ #ifndef B1000000
54
+ #define B1000000 1000000
55
+ #endif
56
+ #endif
57
+
58
+ static char sTcgetattr[] = "tcgetattr";
59
+ static char sTcsetattr[] = "tcsetattr";
60
+ static char sIoctl[] = "ioctl";
61
+
62
+
63
+ int get_fd_helper(obj)
64
+ VALUE obj;
65
+ {
66
+ #ifdef HAVE_RUBY_IO_H
67
+ rb_io_t *fptr;
68
+ #else
69
+ OpenFile *fptr;
70
+ #endif
71
+ GetOpenFile(obj, fptr);
72
+ #ifdef HAVE_RUBY_IO_H
73
+ return (fptr->fd);
74
+ #else
75
+ return (fileno(fptr->f));
76
+ #endif
77
+ }
78
+
79
+ VALUE sp_create_impl(class, _port)
80
+ VALUE class, _port;
81
+ {
82
+ #ifdef HAVE_RUBY_IO_H
83
+ rb_io_t *fp;
84
+ #else
85
+ OpenFile *fp;
86
+ #endif
87
+
88
+ int fd;
89
+ int num_port;
90
+ char *port;
91
+ char *ports[] = {
92
+ #if defined(OS_LINUX) || defined(OS_CYGWIN)
93
+ "/dev/ttyS0", "/dev/ttyS1", "/dev/ttyS2", "/dev/ttyS3",
94
+ "/dev/ttyS4", "/dev/ttyS5", "/dev/ttyS6", "/dev/ttyS7"
95
+ #elif defined(OS_FREEBSD) || defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_DARWIN)
96
+ "/dev/cuaa0", "/dev/cuaa1", "/dev/cuaa2", "/dev/cuaa3",
97
+ "/dev/cuaa4", "/dev/cuaa5", "/dev/cuaa6", "/dev/cuaa7"
98
+ #elif defined(OS_SOLARIS)
99
+ "/dev/ttya", "/dev/ttyb", "/dev/ttyc", "/dev/ttyd",
100
+ "/dev/ttye", "/dev/ttyf", "/dev/ttyg", "/dev/ttyh"
101
+ #elif defined(OS_AIX)
102
+ "/dev/tty0", "/dev/tty1", "/dev/tty2", "/dev/tty3",
103
+ "/dev/tty4", "/dev/tty5", "/dev/tty6", "/dev/tty7"
104
+ #elif defined(OS_IRIX)
105
+ "/dev/ttyf1", "/dev/ttyf2", "/dev/ttyf3", "/dev/ttyf4",
106
+ "/dev/ttyf5", "/dev/ttyf6", "/dev/ttyf7", "/dev/ttyf8"
107
+ #endif
108
+ };
109
+ struct termios params;
110
+
111
+ NEWOBJ(sp, struct RFile);
112
+ rb_secure(4);
113
+ OBJSETUP(sp, class, T_FILE);
114
+ MakeOpenFile((VALUE) sp, fp);
115
+
116
+ switch(TYPE(_port))
117
+ {
118
+ case T_FIXNUM:
119
+ num_port = FIX2INT(_port);
120
+ if (num_port < 0 || num_port > sizeof(ports) / sizeof(ports[0]))
121
+ {
122
+ rb_raise(rb_eArgError, "illegal port number");
123
+ }
124
+ port = ports[num_port];
125
+ break;
126
+
127
+ case T_STRING:
128
+ Check_SafeStr(_port);
129
+ port = RSTRING_PTR(_port);
130
+ break;
131
+
132
+ default:
133
+ rb_raise(rb_eTypeError, "wrong argument type");
134
+ break;
135
+ }
136
+
137
+ fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
138
+ if (fd == -1)
139
+ {
140
+ rb_sys_fail(port);
141
+ }
142
+
143
+ if (!isatty(fd))
144
+ {
145
+ close(fd);
146
+ rb_raise(rb_eArgError, "not a serial port");
147
+ }
148
+
149
+ /* enable blocking read */
150
+ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NONBLOCK);
151
+
152
+ if (tcgetattr(fd, &params) == -1)
153
+ {
154
+ close(fd);
155
+ rb_sys_fail(sTcgetattr);
156
+ }
157
+
158
+ params.c_oflag = 0;
159
+ params.c_lflag = 0;
160
+ params.c_iflag &= (IXON | IXOFF | IXANY);
161
+ params.c_cflag |= CLOCAL | CREAD;
162
+ params.c_cflag &= ~HUPCL;
163
+
164
+ if (tcsetattr(fd, TCSANOW, &params) == -1)
165
+ {
166
+ close(fd);
167
+ rb_sys_fail(sTcsetattr);
168
+ }
169
+
170
+ #ifdef HAVE_RUBY_IO_H
171
+ fp->fd = fd;
172
+ #else
173
+ fp->f = rb_fdopen(fd, "r+");
174
+ #endif
175
+ fp->mode = FMODE_READWRITE | FMODE_SYNC;
176
+
177
+ return (VALUE) sp;
178
+ }
179
+
180
+ VALUE sp_set_modem_params_impl(argc, argv, self)
181
+ int argc;
182
+ VALUE *argv, self;
183
+ {
184
+ int fd;
185
+ struct termios params;
186
+ VALUE _data_rate, _data_bits, _parity, _stop_bits;
187
+ int use_hash = 0;
188
+ int data_rate, data_bits;
189
+ _data_rate = _data_bits = _parity = _stop_bits = Qnil;
190
+
191
+ if (argc == 0)
192
+ {
193
+ return self;
194
+ }
195
+
196
+ if (argc == 1 && T_HASH == TYPE(argv[0]))
197
+ {
198
+ use_hash = 1;
199
+ _data_rate = rb_hash_aref(argv[0], sBaud);
200
+ _data_bits = rb_hash_aref(argv[0], sDataBits);
201
+ _stop_bits = rb_hash_aref(argv[0], sStopBits);
202
+ _parity = rb_hash_aref(argv[0], sParity);
203
+ }
204
+
205
+ fd = get_fd_helper(self);
206
+ if (tcgetattr(fd, &params) == -1)
207
+ {
208
+ rb_sys_fail(sTcgetattr);
209
+ }
210
+
211
+ if (!use_hash)
212
+ {
213
+ _data_rate = argv[0];
214
+ }
215
+
216
+ if (NIL_P(_data_rate))
217
+ {
218
+ goto SkipDataRate;
219
+ }
220
+ Check_Type(_data_rate, T_FIXNUM);
221
+
222
+ switch(FIX2INT(_data_rate))
223
+ {
224
+ case 50: data_rate = B50; break;
225
+ case 75: data_rate = B75; break;
226
+ case 110: data_rate = B110; break;
227
+ case 134: data_rate = B134; break;
228
+ case 150: data_rate = B150; break;
229
+ case 200: data_rate = B200; break;
230
+ case 300: data_rate = B300; break;
231
+ case 600: data_rate = B600; break;
232
+ case 1200: data_rate = B1200; break;
233
+ case 1800: data_rate = B1800; break;
234
+ case 2400: data_rate = B2400; break;
235
+ case 4800: data_rate = B4800; break;
236
+ case 9600: data_rate = B9600; break;
237
+ case 19200: data_rate = B19200; break;
238
+ case 38400: data_rate = B38400; break;
239
+ #ifdef B57600
240
+ case 57600: data_rate = B57600; break;
241
+ #endif
242
+ #ifdef B76800
243
+ case 76800: data_rate = B76800; break;
244
+ #endif
245
+ #ifdef B115200
246
+ case 115200: data_rate = B115200; break;
247
+ #endif
248
+ #ifdef B230400
249
+ case 230400: data_rate = B230400; break;
250
+ #endif
251
+ #ifdef B460800
252
+ case 460800: data_rate = B460800; break;
253
+ #endif
254
+ #ifdef B500000
255
+ case 500000: data_rate = B500000; break;
256
+ #endif
257
+ #ifdef B576000
258
+ case 576000: data_rate = B576000; break;
259
+ #endif
260
+ #ifdef B921600
261
+ case 921600: data_rate = B921600; break;
262
+ #endif
263
+ #ifdef B1000000
264
+ case 1000000: data_rate = B1000000; break;
265
+ #endif
266
+
267
+ default:
268
+ rb_raise(rb_eArgError, "unknown baud rate");
269
+ break;
270
+ }
271
+ cfsetispeed(&params, data_rate);
272
+ cfsetospeed(&params, data_rate);
273
+
274
+ SkipDataRate:
275
+
276
+ if (!use_hash)
277
+ {
278
+ _data_bits = (argc >= 2 ? argv[1] : INT2FIX(8));
279
+ }
280
+
281
+ if (NIL_P(_data_bits))
282
+ {
283
+ goto SkipDataBits;
284
+ }
285
+ Check_Type(_data_bits, T_FIXNUM);
286
+
287
+ switch(FIX2INT(_data_bits))
288
+ {
289
+ case 5:
290
+ data_bits = CS5;
291
+ break;
292
+ case 6:
293
+ data_bits = CS6;
294
+ break;
295
+ case 7:
296
+ data_bits = CS7;
297
+ break;
298
+ case 8:
299
+ data_bits = CS8;
300
+ break;
301
+ default:
302
+ rb_raise(rb_eArgError, "unknown character size");
303
+ break;
304
+ }
305
+ params.c_cflag &= ~CSIZE;
306
+ params.c_cflag |= data_bits;
307
+
308
+ SkipDataBits:
309
+
310
+ if (!use_hash)
311
+ {
312
+ _stop_bits = (argc >= 3 ? argv[2] : INT2FIX(1));
313
+ }
314
+
315
+ if (NIL_P(_stop_bits))
316
+ {
317
+ goto SkipStopBits;
318
+ }
319
+
320
+ Check_Type(_stop_bits, T_FIXNUM);
321
+
322
+ switch(FIX2INT(_stop_bits))
323
+ {
324
+ case 1:
325
+ params.c_cflag &= ~CSTOPB;
326
+ break;
327
+ case 2:
328
+ params.c_cflag |= CSTOPB;
329
+ break;
330
+ default:
331
+ rb_raise(rb_eArgError, "unknown number of stop bits");
332
+ break;
333
+ }
334
+
335
+ SkipStopBits:
336
+
337
+ if (!use_hash)
338
+ {
339
+ _parity = (argc >= 4 ? argv[3] : ((params.c_cflag & CSIZE) == CS8 ?
340
+ INT2FIX(NONE) : INT2FIX(EVEN)));
341
+ }
342
+
343
+ if (NIL_P(_parity))
344
+ {
345
+ goto SkipParity;
346
+ }
347
+
348
+ Check_Type(_parity, T_FIXNUM);
349
+
350
+ switch(FIX2INT(_parity))
351
+ {
352
+ case EVEN:
353
+ params.c_cflag |= PARENB;
354
+ params.c_cflag &= ~PARODD;
355
+ break;
356
+
357
+ case ODD:
358
+ params.c_cflag |= PARENB;
359
+ params.c_cflag |= PARODD;
360
+ break;
361
+
362
+ case NONE:
363
+ params.c_cflag &= ~PARENB;
364
+ break;
365
+
366
+ default:
367
+ rb_raise(rb_eArgError, "unknown parity");
368
+ break;
369
+ }
370
+
371
+ SkipParity:
372
+
373
+ if (tcsetattr(fd, TCSANOW, &params) == -1)
374
+ {
375
+ rb_sys_fail(sTcsetattr);
376
+ }
377
+ return argv[0];
378
+ }
379
+
380
+ void get_modem_params_impl(self, mp)
381
+ VALUE self;
382
+ struct modem_params *mp;
383
+ {
384
+ int fd;
385
+ struct termios params;
386
+
387
+ fd = get_fd_helper(self);
388
+ if (tcgetattr(fd, &params) == -1)
389
+ {
390
+ rb_sys_fail(sTcgetattr);
391
+ }
392
+
393
+ switch (cfgetospeed(&params))
394
+ {
395
+ case B50: mp->data_rate = 50; break;
396
+ case B75: mp->data_rate = 75; break;
397
+ case B110: mp->data_rate = 110; break;
398
+ case B134: mp->data_rate = 134; break;
399
+ case B150: mp->data_rate = 150; break;
400
+ case B200: mp->data_rate = 200; break;
401
+ case B300: mp->data_rate = 300; break;
402
+ case B600: mp->data_rate = 600; break;
403
+ case B1200: mp->data_rate = 1200; break;
404
+ case B1800: mp->data_rate = 1800; break;
405
+ case B2400: mp->data_rate = 2400; break;
406
+ case B4800: mp->data_rate = 4800; break;
407
+ case B9600: mp->data_rate = 9600; break;
408
+ case B19200: mp->data_rate = 19200; break;
409
+ case B38400: mp->data_rate = 38400; break;
410
+ #ifdef B57600
411
+ case B57600: mp->data_rate = 57600; break;
412
+ #endif
413
+ #ifdef B76800
414
+ case B76800: mp->data_rate = 76800; break;
415
+ #endif
416
+ #ifdef B115200
417
+ case B115200: mp->data_rate = 115200; break;
418
+ #endif
419
+ #ifdef B230400
420
+ case B230400: mp->data_rate = 230400; break;
421
+ #endif
422
+ #ifdef B460800
423
+ case B460800: mp->data_rate = 460800; break;
424
+ #endif
425
+ #ifdef B500000
426
+ case B500000: mp->data_rate = 500000; break;
427
+ #endif
428
+ #ifdef B576000
429
+ case B576000: mp->data_rate = 576000; break;
430
+ #endif
431
+ #ifdef B921600
432
+ case B921600: mp->data_rate = 921600; break;
433
+ #endif
434
+ #ifdef B1000000
435
+ case B1000000: mp->data_rate = 1000000; break;
436
+ #endif
437
+ }
438
+
439
+ switch(params.c_cflag & CSIZE)
440
+ {
441
+ case CS5:
442
+ mp->data_bits = 5;
443
+ break;
444
+ case CS6:
445
+ mp->data_bits = 6;
446
+ break;
447
+ case CS7:
448
+ mp->data_bits = 7;
449
+ break;
450
+ case CS8:
451
+ mp->data_bits = 8;
452
+ break;
453
+ default:
454
+ mp->data_bits = 0;
455
+ break;
456
+ }
457
+
458
+ mp->stop_bits = (params.c_cflag & CSTOPB ? 2 : 1);
459
+
460
+ if (!(params.c_cflag & PARENB))
461
+ {
462
+ mp->parity = NONE;
463
+ }
464
+ else if (params.c_cflag & PARODD)
465
+ {
466
+ mp->parity = ODD;
467
+ }
468
+ else
469
+ {
470
+ mp->parity = EVEN;
471
+ }
472
+ }
473
+
474
+ VALUE sp_set_flow_control_impl(self, val)
475
+ VALUE self, val;
476
+ {
477
+ int fd;
478
+ int flowc;
479
+ struct termios params;
480
+
481
+ Check_Type(val, T_FIXNUM);
482
+
483
+ fd = get_fd_helper(self);
484
+ if (tcgetattr(fd, &params) == -1)
485
+ {
486
+ rb_sys_fail(sTcgetattr);
487
+ }
488
+
489
+ flowc = FIX2INT(val);
490
+ if (flowc & HARD)
491
+ {
492
+ #ifdef HAVE_FLOWCONTROL_HARD
493
+ params.c_cflag |= CRTSCTS;
494
+ }
495
+ else
496
+ {
497
+ params.c_cflag &= ~CRTSCTS;
498
+ }
499
+ #else
500
+ rb_raise(rb_eIOError, "Hardware flow control not supported");
501
+ }
502
+ #endif
503
+
504
+ if (flowc & SOFT)
505
+ {
506
+ params.c_iflag |= (IXON | IXOFF | IXANY);
507
+ }
508
+ else
509
+ {
510
+ params.c_iflag &= ~(IXON | IXOFF | IXANY);
511
+ }
512
+
513
+ if (tcsetattr(fd, TCSANOW, &params) == -1)
514
+ {
515
+ rb_sys_fail(sTcsetattr);
516
+ }
517
+
518
+ return val;
519
+ }
520
+
521
+ VALUE sp_get_flow_control_impl(self)
522
+ VALUE self;
523
+ {
524
+ int ret;
525
+ int fd;
526
+ struct termios params;
527
+
528
+ fd = get_fd_helper(self);
529
+ if (tcgetattr(fd, &params) == -1)
530
+ {
531
+ rb_sys_fail(sTcgetattr);
532
+ }
533
+
534
+ ret = 0;
535
+
536
+ #ifdef HAVE_FLOWCONTROL_HARD
537
+ if (params.c_cflag & CRTSCTS)
538
+ {
539
+ ret += HARD;
540
+ }
541
+ #endif
542
+
543
+ if (params.c_iflag & (IXON | IXOFF | IXANY))
544
+ {
545
+ ret += SOFT;
546
+ }
547
+
548
+ return INT2FIX(ret);
549
+ }
550
+
551
+ VALUE sp_set_read_timeout_impl(self, val)
552
+ VALUE self, val;
553
+ {
554
+ int timeout;
555
+ int fd;
556
+ struct termios params;
557
+
558
+ Check_Type(val, T_FIXNUM);
559
+ timeout = FIX2INT(val);
560
+
561
+ fd = get_fd_helper(self);
562
+ if (tcgetattr(fd, &params) == -1)
563
+ {
564
+ rb_sys_fail(sTcgetattr);
565
+ }
566
+
567
+ if (timeout < 0)
568
+ {
569
+ params.c_cc[VTIME] = 0;
570
+ params.c_cc[VMIN] = 0;
571
+ }
572
+ else if (timeout == 0)
573
+ {
574
+ params.c_cc[VTIME] = 0;
575
+ params.c_cc[VMIN] = 1;
576
+ }
577
+ else
578
+ {
579
+ params.c_cc[VTIME] = (timeout + 50) / 100;
580
+ params.c_cc[VMIN] = 0;
581
+ }
582
+
583
+ if (tcsetattr(fd, TCSANOW, &params) == -1)
584
+ {
585
+ rb_sys_fail(sTcsetattr);
586
+ }
587
+
588
+ return val;
589
+ }
590
+
591
+ VALUE sp_get_read_timeout_impl(self)
592
+ VALUE self;
593
+ {
594
+ int fd;
595
+ struct termios params;
596
+
597
+ fd = get_fd_helper(self);
598
+ if (tcgetattr(fd, &params) == -1)
599
+ {
600
+ rb_sys_fail(sTcgetattr);
601
+ }
602
+
603
+ if (params.c_cc[VTIME] == 0 && params.c_cc[VMIN] == 0)
604
+ {
605
+ return INT2FIX(-1);
606
+ }
607
+
608
+ return INT2FIX(params.c_cc[VTIME] * 100);
609
+ }
610
+
611
+ VALUE sp_set_write_timeout_impl(self, val)
612
+ VALUE self, val;
613
+ {
614
+ rb_notimplement();
615
+ return self;
616
+ }
617
+
618
+ VALUE sp_get_write_timeout_impl(self)
619
+ VALUE self;
620
+ {
621
+ rb_notimplement();
622
+ return self;
623
+ }
624
+
625
+ VALUE sp_break_impl(self, time)
626
+ VALUE self, time;
627
+ {
628
+ int fd;
629
+
630
+ Check_Type(time, T_FIXNUM);
631
+
632
+ fd = get_fd_helper(self);
633
+
634
+ if (tcsendbreak(fd, FIX2INT(time) / 3) == -1)
635
+ {
636
+ rb_sys_fail("tcsendbreak");
637
+ }
638
+
639
+ return Qnil;
640
+ }
641
+
642
+ void get_line_signals_helper_impl(obj, ls)
643
+ VALUE obj;
644
+ struct line_signals *ls;
645
+ {
646
+ int fd, status;
647
+
648
+ fd = get_fd_helper(obj);
649
+
650
+ if (ioctl(fd, TIOCMGET, &status) == -1)
651
+ {
652
+ rb_sys_fail(sIoctl);
653
+ }
654
+
655
+ ls->rts = (status & TIOCM_RTS ? 1 : 0);
656
+ ls->dtr = (status & TIOCM_DTR ? 1 : 0);
657
+ ls->cts = (status & TIOCM_CTS ? 1 : 0);
658
+ ls->dsr = (status & TIOCM_DSR ? 1 : 0);
659
+ ls->dcd = (status & TIOCM_CD ? 1 : 0);
660
+ ls->ri = (status & TIOCM_RI ? 1 : 0);
661
+ }
662
+
663
+ VALUE set_signal_impl(obj, val, sig)
664
+ VALUE obj,val;
665
+ int sig;
666
+ {
667
+ int status;
668
+ int fd;
669
+ int set;
670
+
671
+ Check_Type(val, T_FIXNUM);
672
+ fd = get_fd_helper(obj);
673
+
674
+ if (ioctl(fd, TIOCMGET, &status) == -1)
675
+ {
676
+ rb_sys_fail(sIoctl);
677
+ }
678
+
679
+ set = FIX2INT(val);
680
+
681
+ if (set == 0)
682
+ {
683
+ status &= ~sig;
684
+ }
685
+ else if (set == 1)
686
+ {
687
+ status |= sig;
688
+ }
689
+ else
690
+ {
691
+ rb_raise(rb_eArgError, "invalid value");
692
+ }
693
+
694
+ if (ioctl(fd, TIOCMSET, &status) == -1)
695
+ {
696
+ rb_sys_fail(sIoctl);
697
+ }
698
+
699
+ return val;
700
+ }
701
+
702
+ VALUE sp_set_rts_impl(self, val)
703
+ VALUE self, val;
704
+ {
705
+ return set_signal_impl(self, val, TIOCM_RTS);
706
+ }
707
+
708
+ VALUE sp_set_dtr_impl(self, val)
709
+ VALUE self, val;
710
+ {
711
+ return set_signal_impl(self, val, TIOCM_DTR);
712
+ }
713
+
714
+ VALUE sp_get_rts_impl(self)
715
+ VALUE self;
716
+ {
717
+ struct line_signals ls;
718
+
719
+ get_line_signals_helper_impl(self, &ls);
720
+ return INT2FIX(ls.rts);
721
+ }
722
+
723
+ VALUE sp_get_dtr_impl(self)
724
+ VALUE self;
725
+ {
726
+ struct line_signals ls;
727
+
728
+ get_line_signals_helper_impl(self, &ls);
729
+
730
+ return INT2FIX(ls.dtr);
731
+ }
732
+
733
+ #endif /* !defined(OS_MSWIN) && !defined(OS_BCCWIN) && !defined(OS_MINGW) */