static void serial_process_irp_close(SERIAL_DEVICE* serial, IRP* irp) { SERIAL_TTY* tty; tty = serial->tty; if (tty == NULL) { irp->IoStatus = STATUS_UNSUCCESSFUL; DEBUG_WARN("tty not valid."); } else { DEBUG_SVC("%s(%d) closed.", serial->path, tty->id); TerminateThread(serial->mthread, 0); WaitForSingleObject(serial->mthread, INFINITE); CloseHandle(serial->mthread); serial->mthread = NULL; serial_tty_free(tty); serial->tty = NULL; } Stream_Zero(irp->output, 5); /* Padding(5) */ irp->Complete(irp); }
static void serial_free(DEVICE* device) { SERIAL_DEVICE* serial = (SERIAL_DEVICE*) device; DEBUG_SVC("freeing device"); /* Stop thread */ SetEvent(serial->stopEvent); if(serial->mthread) { TerminateThread(serial->mthread, 0); WaitForSingleObject(serial->mthread, INFINITE); CloseHandle(serial->mthread); } WaitForSingleObject(serial->thread, INFINITE); serial_tty_free(serial->tty); /* Clean up resources */ Stream_Free(serial->device.data, TRUE); Queue_Free(serial->queue); list_free(serial->pending_irps); CloseHandle(serial->stopEvent); CloseHandle(serial->newEvent); CloseHandle(serial->thread); free(serial); }
static void serial_process_irp_close(SERIAL_DEVICE* serial, IRP* irp) { SERIAL_TTY* tty; tty = serial->tty; if (tty == NULL) { irp->IoStatus = STATUS_UNSUCCESSFUL; DEBUG_WARN("tty not valid."); } else { DEBUG_SVC("%s(%d) closed.", serial->path, tty->id); serial_tty_free(tty); serial->tty = NULL; } stream_write_zero(irp->output, 5); /* Padding(5) */ irp->Complete(irp); }
SERIAL_TTY* serial_tty_new(const char* path, UINT32 id) { SERIAL_TTY* tty; tty = (SERIAL_TTY*) malloc(sizeof(SERIAL_TTY)); ZeroMemory(tty, sizeof(SERIAL_TTY)); tty->id = id; tty->fd = open(path, O_RDWR | O_NOCTTY | O_NONBLOCK); if (tty->fd < 0) { perror("open"); DEBUG_WARN("failed to open device %s", path); serial_tty_free(tty); return NULL; } else { DEBUG_SVC("tty fd %d successfully opened", tty->fd); } tty->ptermios = (struct termios*) malloc(sizeof(struct termios)); ZeroMemory(tty->ptermios, sizeof(struct termios)); if (tty->ptermios == NULL) { serial_tty_free(tty); return NULL ; } tty->pold_termios = (struct termios*) malloc(sizeof(struct termios)); ZeroMemory(tty->pold_termios, sizeof(struct termios)); if (tty->pold_termios == NULL) { serial_tty_free(tty); return NULL; } tcgetattr(tty->fd, tty->pold_termios); if (!tty_get_termios(tty)) { DEBUG_WARN("%s access denied", path); fflush(stdout); serial_tty_free(tty); return NULL; } tty->ptermios->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); tty->ptermios->c_iflag = IGNPAR | ICRNL; tty->ptermios->c_oflag &= ~OPOST; tty->ptermios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); tty->ptermios->c_cflag &= ~(CSIZE | PARENB); tty->ptermios->c_cflag |= CLOCAL | CREAD | CS8; tcsetattr(tty->fd, TCSANOW, tty->ptermios); tty->event_txempty = 0; tty->event_cts = 0; tty->event_dsr = 0; tty->event_rlsd = 0; tty->event_pending = 0; /* all read and writes should be non-blocking */ if (fcntl(tty->fd, F_SETFL, O_NONBLOCK) == -1) { DEBUG_WARN("%s fcntl", path); perror("fcntl"); serial_tty_free(tty) ; return NULL; } tty->read_total_timeout_constant = 5; return tty; }