* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. All rights reserved.
* Copyright 2010, JΓ©rΓ΄me Duval, korli@users.berlios.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <pty.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
int
openpty(int* _master, int* _slave, char* name, struct termios* termAttrs,
struct winsize* windowSize)
{
int master = posix_openpt(O_RDWR);
if (master < 0)
return -1;
int slave;
const char *ttyName;
if (grantpt(master) != 0 || unlockpt(master) != 0
|| (ttyName = ptsname(master)) == NULL
|| (slave = open(ttyName, O_RDWR | O_NOCTTY)) < 0) {
close(master);
return -1;
}
if ((termAttrs != NULL && tcsetattr(master, TCSANOW, termAttrs) != 0)
|| (windowSize != NULL
&& ioctl(master, TIOCSWINSZ, windowSize, sizeof(winsize)) != 0)) {
close(slave);
close(master);
return -1;
}
*_master = master;
*_slave = slave;
if (name != NULL)
strcpy(name, ttyName);
return 0;
}
int
login_tty(int fd)
{
setsid();
if (ioctl(fd, TIOCSCTTY, NULL) != 0)
return -1;
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
close(fd);
return 0;
}
pid_t
forkpty(int* _master, char* name, struct termios* termAttrs,
struct winsize* windowSize)
{
int master, slave;
if (openpty(&master, &slave, name, termAttrs, windowSize) != 0)
return -1;
int pid = fork();
if (pid < 0) {
close(master);
close(slave);
return -1;
}
if (pid == 0) {
close(master);
return login_tty(slave);
}
close (slave);
*_master = master;
return pid;
}