* 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:
parent
ba51713c8f
commit
1590c69933
@ -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.
|
||||
*/
|
||||
#ifndef _BSD_PTY_H_
|
||||
@ -13,6 +13,9 @@ __BEGIN_DECLS
|
||||
|
||||
extern int openpty(int* master, int* slave, char* name,
|
||||
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
|
||||
|
||||
|
@ -180,6 +180,7 @@ struct termios {
|
||||
#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 TIOCSPGRP (TCGETA + 16) /* Sets the process group ID ('pgid' in BeOS) */
|
||||
#define TIOCSCTTY (TCGETA + 17) /* Become controlling TTY */
|
||||
|
||||
/* Event codes. Returned from TCWAITEVENT */
|
||||
#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;
|
||||
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
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@ -31,6 +32,8 @@ openpty(int* _master, int* _slave, char* name, struct termios* termAttrs,
|
||||
if (termAttrs != NULL && tcsetattr(master, TCSANOW, termAttrs) != 0
|
||||
|| windowSize != NULL
|
||||
&& 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(master);
|
||||
}
|
||||
@ -43,3 +46,47 @@ openpty(int* _master, int* _slave, char* name, struct termios* termAttrs,
|
||||
|
||||
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;
|
||||
}
|
||||
|
7
src/tests/libs/bsd/Jamfile
Normal file
7
src/tests/libs/bsd/Jamfile
Normal file
@ -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 ;
|
||||
|
||||
|
47
src/tests/libs/bsd/forkpty.c
Normal file
47
src/tests/libs/bsd/forkpty.c
Normal file
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user