* added forkpty() and login_tty() to bsd compatibility, a test for forkpty().
* added a TODO questioning the closing master and slave in openpty() when applying window size fails. * added TIOCSCTTY as a TTY ioctl code, the caller become controlling TTY. Review comments are welcome. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36105 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008, Haiku, Inc. All Rights Reserved.
|
* Copyright 2008-2010, Haiku, Inc. All Rights Reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _BSD_PTY_H_
|
#ifndef _BSD_PTY_H_
|
||||||
@@ -13,6 +13,9 @@ __BEGIN_DECLS
|
|||||||
|
|
||||||
extern int openpty(int* master, int* slave, char* name,
|
extern int openpty(int* master, int* slave, char* name,
|
||||||
struct termios* termAttrs, struct winsize* windowSize);
|
struct termios* termAttrs, struct winsize* windowSize);
|
||||||
|
extern int login_pty(int fd);
|
||||||
|
extern pid_t forkpty(int* master, char* name,
|
||||||
|
struct termios* termAttrs, struct winsize* windowSize);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,7 @@ struct termios {
|
|||||||
#define TCVTIME (TCGETA + 14) /* pass in bigtime_t, old value saved */
|
#define TCVTIME (TCGETA + 14) /* pass in bigtime_t, old value saved */
|
||||||
#define TIOCGPGRP (TCGETA + 15) /* Gets the process group ID of the TTY device */
|
#define TIOCGPGRP (TCGETA + 15) /* Gets the process group ID of the TTY device */
|
||||||
#define TIOCSPGRP (TCGETA + 16) /* Sets the process group ID ('pgid' in BeOS) */
|
#define TIOCSPGRP (TCGETA + 16) /* Sets the process group ID ('pgid' in BeOS) */
|
||||||
|
#define TIOCSCTTY (TCGETA + 17) /* Become controlling TTY */
|
||||||
|
|
||||||
/* Event codes. Returned from TCWAITEVENT */
|
/* Event codes. Returned from TCWAITEVENT */
|
||||||
#define EV_RING 0x0001
|
#define EV_RING 0x0001
|
||||||
|
|||||||
@@ -1652,6 +1652,24 @@ tty_ioctl(tty_cookie* cookie, uint32 op, void* buffer, size_t length)
|
|||||||
tty->settings->pgrp_id = groupID;
|
tty->settings->pgrp_id = groupID;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// become controlling TTY
|
||||||
|
case TIOCSCTTY:
|
||||||
|
{
|
||||||
|
TRACE(("tty: become controlling tty\n"));
|
||||||
|
pid_t processID = getpid();
|
||||||
|
pid_t sessionID = getsid(processID);
|
||||||
|
// Only session leaders can become controlling tty
|
||||||
|
if (processID != sessionID)
|
||||||
|
return B_NOT_ALLOWED;
|
||||||
|
// Check if already controlling tty
|
||||||
|
if (team_get_controlling_tty() == tty->index)
|
||||||
|
return B_OK;
|
||||||
|
tty->settings->session_id = sessionID;
|
||||||
|
tty->settings->pgrp_id = sessionID;
|
||||||
|
team_set_controlling_tty(tty->index);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// get and set window size
|
// get and set window size
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. All rights reserved.
|
* 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.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -31,6 +32,8 @@ openpty(int* _master, int* _slave, char* name, struct termios* termAttrs,
|
|||||||
if (termAttrs != NULL && tcsetattr(master, TCSANOW, termAttrs) != 0
|
if (termAttrs != NULL && tcsetattr(master, TCSANOW, termAttrs) != 0
|
||||||
|| windowSize != NULL
|
|| windowSize != NULL
|
||||||
&& ioctl(master, TIOCSWINSZ, windowSize, sizeof(winsize)) != 0) {
|
&& ioctl(master, TIOCSWINSZ, windowSize, sizeof(winsize)) != 0) {
|
||||||
|
// TODO we should either close master and slaves and return -1
|
||||||
|
// or we do nothing!
|
||||||
close(slave);
|
close(slave);
|
||||||
close(master);
|
close(master);
|
||||||
}
|
}
|
||||||
@@ -43,3 +46,47 @@ openpty(int* _master, int* _slave, char* name, struct termios* termAttrs,
|
|||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
// child
|
||||||
|
if (pid == 0) {
|
||||||
|
close(master);
|
||||||
|
return login_tty(slave);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parent
|
||||||
|
close (slave);
|
||||||
|
*_master = master;
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
SubDir HAIKU_TOP src tests libs bsd ;
|
||||||
|
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
|
||||||
|
|
||||||
|
SimpleTest forkpty_test : forkpty.c : libbsd.so ;
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/* from http://jwz.livejournal.com/817438.html */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pty.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_fork(void)
|
||||||
|
{
|
||||||
|
int fd = -1;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if ((pid = forkpty(&fd, NULL, NULL, NULL)) < 0)
|
||||||
|
perror("forkpty");
|
||||||
|
else if (!pid)
|
||||||
|
{
|
||||||
|
printf ("0123456789\n");
|
||||||
|
|
||||||
|
/* #### Uncommenting this makes it work! */
|
||||||
|
/* sleep(20); */
|
||||||
|
|
||||||
|
exit (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
char s[1024];
|
||||||
|
int n;
|
||||||
|
int fd = do_fork();
|
||||||
|
|
||||||
|
/* On 10.4, this prints the whole 10 character line, 1 char per second.
|
||||||
|
On 10.5, it prints 1 character and stops.
|
||||||
|
*/
|
||||||
|
do {
|
||||||
|
n = read (fd, s, 1);
|
||||||
|
if (n > 0) fprintf (stderr, "%c", *s);
|
||||||
|
sleep (1);
|
||||||
|
} while (n > 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user