summaryrefslogtreecommitdiff
path: root/lib/forkpty.c
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2010-03-22 02:46:57 +0100
committerBruno Haible <bruno@clisp.org>2010-03-22 02:46:57 +0100
commiteb8d73f9107decfddc7de65c4d3ba55b85850b8e (patch)
treeec7594b158675b98eadc6fe500c3efeac8064f18 /lib/forkpty.c
parente665e401dc9aea001cf3eebff04ec3166943372b (diff)
downloadgnulib-eb8d73f9107decfddc7de65c4d3ba55b85850b8e.tar.gz
forkpty: Provide replacement on AIX, HP-UX, IRIX, Solaris.
Diffstat (limited to 'lib/forkpty.c')
-rw-r--r--lib/forkpty.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/lib/forkpty.c b/lib/forkpty.c
index adbc3d5518..942aa5477a 100644
--- a/lib/forkpty.c
+++ b/lib/forkpty.c
@@ -1,4 +1,4 @@
-/* Fork a child attached to a pseudo-terminal descriptor.
+/* Fork a child process attached to the slave of a pseudo-terminal.
Copyright (C) 2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
@@ -19,7 +19,9 @@
/* Specification. */
#include <pty.h>
-#if HAVE_DECL_FORKPTY
+#if HAVE_FORKPTY
+
+/* Provider a wrapper with the precise POSIX prototype. */
# undef forkpty
int
rpl_forkpty (int *amaster, char *name, struct termios const *termp,
@@ -29,7 +31,43 @@ rpl_forkpty (int *amaster, char *name, struct termios const *termp,
return forkpty (amaster, name, (struct termios *) termp,
(struct winsize *) winp);
}
-#else
-# error forkpty has not been ported to your system; \
- report this to bug-gnulib@gnu.org for help
+
+#else /* AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 10, mingw */
+
+# include <pty.h>
+# include <unistd.h>
+
+extern int login_tty (int slave_fd);
+
+int
+forkpty (int *amaster, char *name,
+ const struct termios *termp, const struct winsize *winp)
+{
+ int master, slave, pid;
+
+ if (openpty (&master, &slave, name, termp, winp) == -1)
+ return -1;
+
+ switch (pid = fork ())
+ {
+ case -1:
+ close (master);
+ close (slave);
+ return -1;
+
+ case 0:
+ /* Child. */
+ close (master);
+ if (login_tty (slave))
+ _exit (1);
+ return 0;
+
+ default:
+ /* Parent. */
+ *amaster = master;
+ close (slave);
+ return pid;
+ }
+}
+
#endif