Refactor patty_kiss_tnc_new()
Refactor patty_kiss_tnc_new() into the following initialization methods: * init_sock() * init_device() * init_termios()
This commit is contained in:
parent
ab3679b788
commit
4f2f01ec0a
1 changed files with 115 additions and 84 deletions
199
src/tnc.c
199
src/tnc.c
|
@ -49,6 +49,112 @@ struct _patty_kiss_tnc {
|
|||
offset_o;
|
||||
};
|
||||
|
||||
static int init_sock(patty_kiss_tnc *tnc, patty_kiss_tnc_info *info) {
|
||||
struct sockaddr_un addr;
|
||||
|
||||
if (strlen(info->device) > sizeof(addr.sun_path)) {
|
||||
errno = EOVERFLOW;
|
||||
|
||||
goto error_overflow;
|
||||
}
|
||||
|
||||
if ((tnc->fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
goto error_socket;
|
||||
}
|
||||
|
||||
memset(&addr, '\0', sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, info->device, sizeof(addr.sun_path)-1);
|
||||
|
||||
if (connect(tnc->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
goto error_connect;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_connect:
|
||||
(void)close(tnc->fd);
|
||||
|
||||
error_socket:
|
||||
error_overflow:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int init_termios(patty_kiss_tnc *tnc, patty_kiss_tnc_info *info) {
|
||||
if (tcgetattr(tnc->fd, &tnc->attrs) < 0) {
|
||||
goto error_tcgetattr;
|
||||
}
|
||||
|
||||
memcpy(&tnc->attrs_old, &tnc->attrs, sizeof(tnc->attrs_old));
|
||||
|
||||
cfmakeraw(&tnc->attrs);
|
||||
|
||||
if (info->flags & PATTY_KISS_TNC_BAUD) {
|
||||
cfsetspeed(&tnc->attrs, info->baud);
|
||||
}
|
||||
|
||||
if (info->flags & PATTY_KISS_TNC_FLOW) {
|
||||
switch (info->flow) {
|
||||
case PATTY_KISS_TNC_FLOW_NONE:
|
||||
break;
|
||||
|
||||
case PATTY_KISS_TNC_FLOW_CRTSCTS:
|
||||
tnc->attrs.c_cflag |= CRTSCTS;
|
||||
|
||||
break;
|
||||
|
||||
case PATTY_KISS_TNC_FLOW_XONXOFF:
|
||||
tnc->attrs.c_iflag |= IXON | IXOFF;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tcflush(tnc->fd, TCIOFLUSH) < 0) {
|
||||
goto error_tcflush;
|
||||
}
|
||||
|
||||
if (tcsetattr(tnc->fd, TCSANOW, &tnc->attrs) < 0) {
|
||||
goto error_tcsetattr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_tcsetattr:
|
||||
error_tcflush:
|
||||
error_tcgetattr:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int init_device(patty_kiss_tnc *tnc, patty_kiss_tnc_info *info) {
|
||||
struct stat st;
|
||||
|
||||
if (strcmp(info->device, "/dev/ptmx") == 0) {
|
||||
int ptysub;
|
||||
|
||||
if (openpty(&tnc->fd, &ptysub, NULL, NULL, NULL) < 0) {
|
||||
goto error;
|
||||
}
|
||||
} else if (stat(info->device, &st) < 0) {
|
||||
goto error;
|
||||
} else if ((st.st_mode & S_IFMT) == S_IFSOCK) {
|
||||
if (init_sock(tnc, info) < 0) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
if ((tnc->fd = open(info->device, O_RDWR | O_NOCTTY)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
tnc->opts |= TNC_CLOSE_ON_DESTROY;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
patty_kiss_tnc *patty_kiss_tnc_new(patty_kiss_tnc_info *info) {
|
||||
patty_kiss_tnc *tnc;
|
||||
|
||||
|
@ -61,90 +167,21 @@ patty_kiss_tnc *patty_kiss_tnc_new(patty_kiss_tnc_info *info) {
|
|||
}
|
||||
|
||||
if (info->flags & PATTY_KISS_TNC_DEVICE) {
|
||||
struct stat st;
|
||||
|
||||
if (strcmp(info->device, "/dev/ptmx") == 0) {
|
||||
int ptysub;
|
||||
|
||||
if (openpty(&tnc->fd, &ptysub, NULL, NULL, NULL) < 0) {
|
||||
goto error_open;
|
||||
}
|
||||
} else if (stat(info->device, &st) < 0) {
|
||||
goto error_stat;
|
||||
} else if ((st.st_mode & S_IFMT) == S_IFSOCK) {
|
||||
struct sockaddr_un addr;
|
||||
|
||||
if (strlen(info->device) > sizeof(addr.sun_path)) {
|
||||
errno = EOVERFLOW;
|
||||
|
||||
goto error_overflow;
|
||||
}
|
||||
|
||||
if ((tnc->fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
goto error_socket;
|
||||
}
|
||||
|
||||
memset(&addr, '\0', sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
strncpy(addr.sun_path, info->device, sizeof(addr.sun_path)-1);
|
||||
|
||||
if (connect(tnc->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
goto error_connect;
|
||||
}
|
||||
} else {
|
||||
if ((tnc->fd = open(info->device, O_RDWR | O_NOCTTY)) < 0) {
|
||||
goto error_open;
|
||||
}
|
||||
if (init_device(tnc, info) < 0) {
|
||||
goto error_init_device;
|
||||
}
|
||||
|
||||
tnc->opts |= TNC_CLOSE_ON_DESTROY;
|
||||
} else if (info->flags & PATTY_KISS_TNC_FD) {
|
||||
tnc->fd = info->fd;
|
||||
} else {
|
||||
errno = EINVAL;
|
||||
|
||||
goto error_no_fd;
|
||||
goto error_invalid;
|
||||
}
|
||||
|
||||
if (isatty(tnc->fd) && ptsname(tnc->fd) == NULL) {
|
||||
if (tcgetattr(tnc->fd, &tnc->attrs) < 0) {
|
||||
goto error_tcgetattr;
|
||||
if (isatty(tnc->fd)) {
|
||||
if (init_termios(tnc, info) < 0) {
|
||||
goto error_init_termios;
|
||||
}
|
||||
|
||||
memcpy(&tnc->attrs_old, &tnc->attrs, sizeof(tnc->attrs_old));
|
||||
|
||||
cfmakeraw(&tnc->attrs);
|
||||
|
||||
if (info->flags & PATTY_KISS_TNC_BAUD) {
|
||||
cfsetspeed(&tnc->attrs, info->baud);
|
||||
}
|
||||
|
||||
if (info->flags & PATTY_KISS_TNC_FLOW) {
|
||||
switch (info->flow) {
|
||||
case PATTY_KISS_TNC_FLOW_NONE:
|
||||
break;
|
||||
|
||||
case PATTY_KISS_TNC_FLOW_CRTSCTS:
|
||||
tnc->attrs.c_cflag |= CRTSCTS;
|
||||
|
||||
break;
|
||||
|
||||
case PATTY_KISS_TNC_FLOW_XONXOFF:
|
||||
tnc->attrs.c_iflag |= IXON | IXOFF;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tcflush(tnc->fd, TCIOFLUSH) < 0) {
|
||||
goto error_tcflush;
|
||||
}
|
||||
|
||||
if (tcsetattr(tnc->fd, TCSANOW, &tnc->attrs) < 0) {
|
||||
goto error_tcsetattr;
|
||||
}
|
||||
} else {
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
memset(&tnc->stats, '\0', sizeof(tnc->stats));
|
||||
|
@ -160,19 +197,13 @@ patty_kiss_tnc *patty_kiss_tnc_new(patty_kiss_tnc_info *info) {
|
|||
|
||||
return tnc;
|
||||
|
||||
error_tcflush:
|
||||
error_tcsetattr:
|
||||
error_tcgetattr:
|
||||
error_connect:
|
||||
error_init_termios:
|
||||
if (info->flags & PATTY_KISS_TNC_DEVICE) {
|
||||
(void)close(tnc->fd);
|
||||
}
|
||||
|
||||
error_open:
|
||||
error_no_fd:
|
||||
error_socket:
|
||||
error_overflow:
|
||||
error_stat:
|
||||
error_init_device:
|
||||
error_invalid:
|
||||
free(tnc->buf);
|
||||
|
||||
error_malloc_buf:
|
||||
|
|
Loading…
Add table
Reference in a new issue