| 113 | } |
| 114 | |
| 115 | void xs_serial_constructor(xsMachine *the) |
| 116 | { |
| 117 | xsSerial s = NULL; |
| 118 | xsIntegerValue baud; |
| 119 | xsStringValue device; |
| 120 | struct termios tio; |
| 121 | struct termios2 tio2; |
| 122 | GError *error = NULL; |
| 123 | xsVars(1); |
| 124 | xsTry { |
| 125 | s = calloc(1, sizeof(xsSerialRecord)); |
| 126 | xsElseThrow(s != NULL); |
| 127 | s->the = the; |
| 128 | s->obj = xsThis; |
| 129 | s->onError = xsGet(xsArg(0), xsID_onError); |
| 130 | s->hasOnError = xsTest(s->onError); |
| 131 | s->onReadable = xsGet(xsArg(0), xsID_onReadable); |
| 132 | s->hasOnReadable = xsTest(s->onReadable); |
| 133 | s->onWritable = xsGet(xsArg(0), xsID_onWritable); |
| 134 | s->hasOnWritable = xsTest(s->onWritable); |
| 135 | if (xsHas(xsArg(0), xsID_format)) { |
| 136 | xsVar(0) = xsGet(xsArg(0), xsID_format); |
| 137 | xs_serial_format_set_aux(the, s, xsToString(xsVar(0))); |
| 138 | } |
| 139 | else |
| 140 | s->bufferFormat = 1; |
| 141 | if (xsHas(xsArg(0), xsID_target)) { |
| 142 | xsVar(0) = xsGet(xsArg(0), xsID_target); |
| 143 | xsSet(xsThis, xsID_target, xsVar(0)); |
| 144 | } |
| 145 | xsVar(0) = xsGet(xsArg(0), xsID_baud); |
| 146 | baud = xsToInteger(xsVar(0)); |
| 147 | xsVar(0) = xsGet(xsArg(0), xsID_device); |
| 148 | device = xsToString(xsVar(0)); |
| 149 | |
| 150 | s->fd = open(device, O_RDWR | O_NOCTTY | O_NONBLOCK); |
| 151 | xsElseThrow(s->fd != -1); |
| 152 | c_memset(&tio, 0, sizeof(tio)); |
| 153 | tio.c_cflag = CS8 | CLOCAL | CREAD; |
| 154 | tio.c_iflag = IGNPAR; |
| 155 | tio.c_cc[VMIN] = 1; |
| 156 | xsElseThrow(tcsetattr(s->fd, TCSANOW, &tio) == 0); |
| 157 | xsElseThrow(ioctl(s->fd, TCGETS2, &tio2) == 0); |
| 158 | tio2.c_cflag &= ~CBAUD; |
| 159 | tio2.c_cflag |= BOTHER; |
| 160 | tio2.c_ispeed = baud; |
| 161 | tio2.c_ospeed = baud; |
| 162 | xsElseThrow(ioctl(s->fd, TCSETS2, &tio2) == 0); |
| 163 | |
| 164 | s->channel = g_io_channel_unix_new(s->fd); |
| 165 | xsElseThrow(s->channel != NULL); |
| 166 | xsElseThrow(g_io_channel_set_encoding(s->channel, NULL, &error) == G_IO_STATUS_NORMAL); |
| 167 | s->source = g_io_add_watch(s->channel, G_IO_IN | G_IO_ERR, xs_serial_read_callback, s); |
| 168 | xsElseThrow(s->source != 0); |
| 169 | if (s->hasOnWritable) |
| 170 | s->writeSource = g_io_add_watch(s->channel, G_IO_OUT, xs_serial_write_callback, s); |
| 171 | } |
| 172 | xsCatch { |
nothing calls this directly
no test coverage detected