Hi, Martin Thanks a lot for that blindingly fast turnaround!
Problems remain; I've attached an enhanced version of my tester that will show them up. On Linux 2.4 my tester's fullscreen read() returns a count of 15, and I suspect it should in Linux 2.6 as well. As to /dev/3270/tub, believe me, devfs was the furthest thing from my mind. Here's what I was talking about. Consider the device /dev/tty. It exists to provide a path for the application to the current controlling tty. What would the application have to do (absent stdout/stderr) to access its controlling terminal if there was no /dev/tty device? It wouldn't be easy, right? Similarly, /dev/3270/tub needs to exist to provide a path for the application to the fullscreen, when the controlling tty is in fact a line-mode 3270 (and ENODEV otherwise). Notice that the permissions of /dev/tty are crw-rw-rw and those of /dev/3270/tub are crw-rw-rw as well. For /dev/tty notice the logic in drivers/char/tty_io.c:tty_open(), right at retry_open:, where a test is made for major 5, minor 0 (the maj/min of /dev/tty) and the device at current->signal->tty is used. That's what /dev/3270/tub wants as well, only of course to use the corresponding full-screen major number 228 with the minor number of the current->signal->tty device. In 2.4 I reserved minor number 0 strictly for /dev/3270/tub, analogous to /dev/tty, and I ensured that 227,N and 228,N referred to the same physical device. That is, there was no 227,0 device: the console would probably come in at 227,1. My test program should work with no operands when invoked from a logged-on 3270: in that case, it opens /dev/3270/tub. This hardly begins to address the issue you very rightly brought up, how to make /dev/3270/tty0987 and /dev/3270/tub0987 for a new device, and I'll try plowing into that. Dick Hitt ---------------------------------------------------------------------- For LINUX-390 subscribe / signoff / archive access instructions, send email to [EMAIL PROTECTED] with the message: INFO LINUX-390 or visit http://www.marist.edu/htbin/wlvindex?LINUX-390
#include <errno.h> #include <fcntl.h> /* extracted from /usr/src/linux/drivers/s390/char/tubio.h --- */ #define TUB(x) (('3'<<8)|(x)) #define TUBICMD TUB(3) #define TUBOCMD TUB(4) #define TC_EWRITE 0x05 #define TC_READMOD 0x06 /* "Hello. world" in EBCDIC */ char Hello[] = { 0x40, /* Write Control Character (WCC) */ 0x11, 0x40, 0x40, /* Set Buffer Address (SBA) */ 0xc8, 0x85, 0x93, 0x93, 0x96, 0x6b, /* H e l l o , */ 0x40, 0xe6, 0x96, 0x99, 0x93, 0x84 }; /* w o r l d */ main(int argc, char *argv[]) { int fd, rc, i; unsigned char buf[4096]; char *tub = "/dev/3270/tub"; if (argc >= 2) tub = argv[1]; if ((fd = open(tub, O_RDWR)) == -1) { printf("open(%s) failed with errno %d (%s)\n", tub, errno, strerror(errno)); exit(1); } if ((rc = ioctl(fd, TUBOCMD, TC_EWRITE))) { printf("ioctl(%d, %d, %d) failed with errno %d (%s)\n", fd, TUBOCMD, TC_EWRITE, errno, strerror(errno)); exit(1); } if ((rc = ioctl(fd, TUBICMD, TC_READMOD))) { printf("ioctl(%d, %d, %d) failed with errno %d (%s)\n", fd, TUBICMD, TC_READMOD, errno, strerror(errno)); exit(1); } if ((rc = write(fd, Hello, sizeof Hello)) != sizeof Hello) { printf("write(%d, ..., %d) returned %d, expected %d\n", fd, sizeof Hello, rc, sizeof Hello); exit(1); } memset(buf, 0xff, sizeof buf); if ((rc = read(fd, buf, sizeof buf)) < 0) { printf("read(%d, ..., %d) failed with errno %d (%s)\n", fd, sizeof buf, errno, strerror(errno)); exit(1); } for (i = 0; i < sizeof buf; i++) { if (buf[i] == 0xff) break; } if (rc != i) { printf("read(%d, ..., %d) returned %d but only %d bytes" " of buffer were altered\n", fd, sizeof buf, rc, i); exit(1); } printf("read() completed: filled %d bytes of the %d-byte buffer\n", rc, sizeof buf); printf("AID=0x%.2x Cursor=0x%.4x\n", buf[0], buf[1] * 256 + buf[2]); if (buf[0] == 0x7d) printf("ENTER key pressed\n"); else if (buf[0] == 0xf1) printf("PF1 key pressed\n"); /* etc */ return 0; }