*
*/
+/* To get ptsname grantpt and unlockpt definitions from stdlib.h */
+#define _GNU_SOURCE
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* maximum rx buffer len: extended CAN frame with timestamp */
#define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r")+1)
+#define DEVICE_NAME_PTMX "/dev/ptmx"
#define DEBUG
int ptr;
struct can_frame frame;
int tmp, i;
+ static int rxoffset = 0; /* points to the end of an received incomplete SLCAN message */
+
+ nbytes = read(pty, &buf[rxoffset], sizeof(buf)-rxoffset-1);
+ if (nbytes <= 0) {
+ /* nbytes == 0 : no error but pty decriptor has been closed */
+ if (nbytes < 0)
+ perror("read pty");
- nbytes = read(pty, &buf, sizeof(buf)-1);
- if (nbytes < 0) {
- perror("read pty");
return 1;
}
+ /* reset incomplete message offset */
+ nbytes += rxoffset;
+ rxoffset = 0;
+
rx_restart:
/* remove trailing '\r' characters to be robust against some apps */
while (buf[0] == '\r' && nbytes > 0) {
if (!nbytes)
return 0;
+ /* check if we can detect a complete SLCAN message including '\r' */
+ for (tmp = 0; tmp < nbytes; tmp++) {
+ if (buf[tmp] == '\r')
+ break;
+ }
+
+ /* no '\r' found in the message buffer? */
+ if (tmp == nbytes) {
+ /* save incomplete message */
+ rxoffset = nbytes;
+
+ /* leave here and read from pty again */
+ return 0;
+ }
+
cmd = buf[0];
buf[nbytes] = 0;
fprintf(stderr, "Usage: %s <pty> <can interface>\n", argv[0]);
fprintf(stderr, "e.g. '%s /dev/ptyc0 can0' creates"
" /dev/ttyc0 for the slcan application\n", argv[0]);
+ fprintf(stderr, "e.g. for pseudo-terminal '%s %s can0' creates"
+ " /dev/pts/N\n", argv[0], DEVICE_NAME_PTMX);
fprintf(stderr, "\n");
return 1;
}
ECHONL | ECHOPRT | ECHOKE | ICRNL);
tcsetattr(p, TCSANOW, &topts);
+ /* Support for the Unix 98 pseudo-terminal interface /dev/ptmx /dev/pts/N */
+ if (strcmp(argv[1], DEVICE_NAME_PTMX) == 0) {
+
+ char *name_pts = NULL; /* slave pseudo-terminal device name */
+
+ if (grantpt(p) < 0) {
+ perror("grantpt");
+ return 1;
+ }
+
+ if (unlockpt(p) < 0) {
+ perror("unlockpt");
+ return 1;
+ }
+
+ name_pts = ptsname(p);
+ if (name_pts == NULL) {
+ perror("ptsname");
+ return 1;
+ }
+ printf("open: %s: slave pseudo-terminal is %s\n", argv[1], name_pts);
+ }
+
/* open socket */
s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (s < 0) {