Page MenuHomeFreeBSD
Authored By
vova_fbsd.ru
Tue, Oct 13, 10:14 PM
Size
2 KB
Referenced Files
None
Subscribers
None

ctty-last-close-repro.c

/* SPDX-License-Identifier: BSD-2-Clause */
/* Tests Linux semantics; native FreeBSD may intentionally fail this test.
* cc -O2 -Wall -Wextra -Werror ctty-last-close-repro.c -o ctty-last-close-repro
*/
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static void setup_error(const char *what)
{
perror(what);
_exit(2);
}
int main(void)
{
int master, status;
pid_t child;
char slave_name[256];
setbuf(stdout, NULL);
master = posix_openpt(O_RDWR | O_NOCTTY);
if (master < 0) setup_error("posix_openpt");
if (grantpt(master) < 0 || unlockpt(master) < 0)
setup_error("grantpt/unlockpt");
char *name = ptsname(master);
if (name == NULL) setup_error("ptsname");
if (strlen(name) >= sizeof(slave_name)) {
fprintf(stderr, "slave path too long\n");
return 2;
}
strcpy(slave_name, name);
child = fork();
if (child < 0) setup_error("fork");
if (child == 0) {
/* Parent keeps the master open until this process exits. */
close(master);
if (setsid() < 0) setup_error("setsid");
int slave = open(slave_name, O_RDWR | O_NOCTTY);
if (slave < 0) setup_error("open slave");
if (ioctl(slave, TIOCSCTTY, 0) < 0) setup_error("TIOCSCTTY");
int tty = open("/dev/tty", O_RDWR | O_NOCTTY);
if (tty < 0) setup_error("open /dev/tty before last close");
printf("before last close: /dev/tty works\n");
if (close(tty) < 0) setup_error("close /dev/tty");
/* No dup or stdio descriptors refer to this new slave. */
if (close(slave) < 0) setup_error("close last slave");
tty = open("/dev/tty", O_RDWR | O_NOCTTY);
if (tty < 0) {
int saved = errno;
printf("FAIL: /dev/tty after last slave close: errno=%d (%s)\n",
saved, strerror(saved));
_exit(1);
}
printf("PASS: /dev/tty still opens after last slave close\n");
close(tty);
_exit(0);
}
while (waitpid(child, &status, 0) < 0) {
if (errno != EINTR) setup_error("waitpid");
}
close(master);
if (!WIFEXITED(status)) {
fprintf(stderr, "child terminated by signal %d\n", WTERMSIG(status));
return 2;
}
return WEXITSTATUS(status);
}

File Metadata

Mime Type
text/x-c
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40821688
Default Alt Text
ctty-last-close-repro.c (2 KB)

Event Timeline