|
@ -1,4 +1,4 @@ |
|
|
/* $OpenBSD: pty.c,v 1.20 2016/08/30 14:44:45 guenther Exp $ */ |
|
|
|
|
|
|
|
|
/* $OpenBSD: pty.c,v 1.21 2017/04/20 17:48:30 nicm Exp $ */ |
|
|
|
|
|
|
|
|
/*- |
|
|
/*- |
|
|
* Copyright (c) 1990, 1993 |
|
|
* Copyright (c) 1990, 1993 |
|
@ -43,25 +43,42 @@ |
|
|
|
|
|
|
|
|
#include "util.h" |
|
|
#include "util.h" |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
|
getptmfd(void) |
|
|
|
|
|
{ |
|
|
|
|
|
return (open(PATH_PTMDEV, O_RDWR|O_CLOEXEC)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
int |
|
|
int |
|
|
openpty(int *amaster, int *aslave, char *name, struct termios *termp, |
|
|
openpty(int *amaster, int *aslave, char *name, struct termios *termp, |
|
|
struct winsize *winp) |
|
|
struct winsize *winp) |
|
|
{ |
|
|
{ |
|
|
int master, slave, fd; |
|
|
|
|
|
|
|
|
int ptmfd; |
|
|
|
|
|
|
|
|
|
|
|
if ((ptmfd = getptmfd()) == -1) |
|
|
|
|
|
return (-1); |
|
|
|
|
|
if (fdopenpty(ptmfd, amaster, aslave, name, termp, winp) == -1) { |
|
|
|
|
|
close(ptmfd); |
|
|
|
|
|
return (-1); |
|
|
|
|
|
} |
|
|
|
|
|
close(ptmfd); |
|
|
|
|
|
return (0); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
|
fdopenpty(int ptmfd, int *amaster, int *aslave, char *name, |
|
|
|
|
|
struct termios *termp, struct winsize *winp) |
|
|
|
|
|
{ |
|
|
|
|
|
int master, slave; |
|
|
struct ptmget ptm; |
|
|
struct ptmget ptm; |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
* Use /dev/ptm and the PTMGET ioctl to get a properly set up and |
|
|
* Use /dev/ptm and the PTMGET ioctl to get a properly set up and |
|
|
* owned pty/tty pair. |
|
|
* owned pty/tty pair. |
|
|
*/ |
|
|
*/ |
|
|
fd = open(PATH_PTMDEV, O_RDWR|O_CLOEXEC); |
|
|
|
|
|
if (fd == -1) |
|
|
|
|
|
|
|
|
if (ioctl(ptmfd, PTMGET, &ptm) == -1) |
|
|
return (-1); |
|
|
return (-1); |
|
|
if ((ioctl(fd, PTMGET, &ptm) == -1)) { |
|
|
|
|
|
close(fd); |
|
|
|
|
|
return (-1); |
|
|
|
|
|
} |
|
|
|
|
|
close(fd); |
|
|
|
|
|
|
|
|
|
|
|
master = ptm.cfd; |
|
|
master = ptm.cfd; |
|
|
slave = ptm.sfd; |
|
|
slave = ptm.sfd; |
|
|
if (name) { |
|
|
if (name) { |
|
@ -81,11 +98,28 @@ openpty(int *amaster, int *aslave, char *name, struct termios *termp, |
|
|
|
|
|
|
|
|
pid_t |
|
|
pid_t |
|
|
forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp) |
|
|
forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp) |
|
|
|
|
|
{ |
|
|
|
|
|
int ptmfd; |
|
|
|
|
|
pid_t pid; |
|
|
|
|
|
|
|
|
|
|
|
if ((ptmfd = getptmfd()) == -1) |
|
|
|
|
|
return (-1); |
|
|
|
|
|
if ((pid = fdforkpty(ptmfd, amaster, name, termp, winp)) == -1) { |
|
|
|
|
|
close(ptmfd); |
|
|
|
|
|
return (-1); |
|
|
|
|
|
} |
|
|
|
|
|
close(ptmfd); |
|
|
|
|
|
return (pid); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pid_t |
|
|
|
|
|
fdforkpty(int ptmfd, int *amaster, char *name, struct termios *termp, |
|
|
|
|
|
struct winsize *winp) |
|
|
{ |
|
|
{ |
|
|
int master, slave; |
|
|
int master, slave; |
|
|
pid_t pid; |
|
|
pid_t pid; |
|
|
|
|
|
|
|
|
if (openpty(&master, &slave, name, termp, winp) == -1) |
|
|
|
|
|
|
|
|
if (fdopenpty(ptmfd, &master, &slave, name, termp, winp) == -1) |
|
|
return (-1); |
|
|
return (-1); |
|
|
switch (pid = fork()) { |
|
|
switch (pid = fork()) { |
|
|
case -1: |
|
|
case -1: |
|
|