|
1 #ifndef __SYMBIAN32__ |
|
2 // clone.c - start a forked instance of the current shell on a new terminal |
|
3 // |
|
4 // © Portions Copyright (c) Symbian Software Ltd 2007. All rights reserved. |
|
5 // |
|
6 /* |
|
7 * This file is part of zsh, the Z shell. |
|
8 * |
|
9 * Copyright (c) 1997 Zoltán Hidvégi |
|
10 * All rights reserved. |
|
11 * |
|
12 * Permission is hereby granted, without written agreement and without |
|
13 * license or royalty fees, to use, copy, modify, and distribute this |
|
14 * software and to distribute modified versions of this software for any |
|
15 * purpose, provided that the above copyright notice and the following |
|
16 * two paragraphs appear in all copies of this software. |
|
17 * |
|
18 * In no event shall Zoltán Hidvégi or the Zsh Development Group be liable |
|
19 * to any party for direct, indirect, special, incidental, or consequential |
|
20 * damages arising out of the use of this software and its documentation, |
|
21 * even if Zoltán Hidvégi and the Zsh Development Group have been advised of |
|
22 * the possibility of such damage. |
|
23 * |
|
24 * Zoltán Hidvégi and the Zsh Development Group specifically disclaim any |
|
25 * warranties, including, but not limited to, the implied warranties of |
|
26 * merchantability and fitness for a particular purpose. The software |
|
27 * provided hereunder is on an "as is" basis, and Zoltán Hidvégi and the |
|
28 * Zsh Development Group have no obligation to provide maintenance, |
|
29 * support, updates, enhancements, or modifications. |
|
30 * |
|
31 */ |
|
32 |
|
33 /* |
|
34 * The clone builtin can be used to start a forked instance of the current |
|
35 * shell on a new terminal. The only argument to the builtin is the name |
|
36 * of the new terminal. In the new shell the PID, PPID and TTY parameters |
|
37 * are changed appropriately. $! is set to zero in the new instance of the |
|
38 * shell and to the pid of the new instance in the original shell. |
|
39 * |
|
40 */ |
|
41 #include "clone.mdh" |
|
42 #include "clone.pro" |
|
43 |
|
44 #ifdef __SYMBIAN32__ |
|
45 #ifdef __WINSCW__ |
|
46 #pragma warn_unusedarg off |
|
47 #endif//__WINSCW__ |
|
48 #endif//__SYMBIAN32__ |
|
49 |
|
50 /**/ |
|
51 static int |
|
52 bin_clone(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) |
|
53 { |
|
54 int ttyfd, pid, cttyfd; |
|
55 |
|
56 unmetafy(*args, NULL); |
|
57 ttyfd = open(*args, O_RDWR|O_NOCTTY); |
|
58 if (ttyfd < 0) { |
|
59 zwarnnam(nam, "%s: %e", *args, errno); |
|
60 return 1; |
|
61 } |
|
62 pid = fork(); |
|
63 if (!pid) { |
|
64 clearjobtab(0); |
|
65 ppid = getppid(); |
|
66 mypid = getpid(); |
|
67 #ifdef HAVE_SETSID |
|
68 if (setsid() != mypid) |
|
69 zwarnnam(nam, "failed to create new session: %e", NULL, errno); |
|
70 #elif defined(TIOCNOTTY) |
|
71 if (ioctl(SHTTY, TIOCNOTTY, 0)) |
|
72 zwarnnam(*args, "%e", NULL, errno); |
|
73 setpgrp(0L, mypid); |
|
74 #endif |
|
75 dup2(ttyfd,0); |
|
76 dup2(ttyfd,1); |
|
77 dup2(ttyfd,2); |
|
78 if (ttyfd > 2) |
|
79 close(ttyfd); |
|
80 closem(0); |
|
81 close(coprocin); |
|
82 close(coprocout); |
|
83 /* Acquire a controlling terminal */ |
|
84 cttyfd = open(*args, O_RDWR); |
|
85 if (cttyfd == -1) |
|
86 zwarnnam(nam, "%e", NULL, errno); |
|
87 else { |
|
88 #ifdef TIOCSCTTY |
|
89 ioctl(cttyfd, TIOCSCTTY, 0); |
|
90 #endif |
|
91 close(cttyfd); |
|
92 } |
|
93 /* check if we acquired the tty successfully */ |
|
94 cttyfd = open("/dev/tty", O_RDWR); |
|
95 if (cttyfd == -1) |
|
96 zwarnnam(nam, "could not make %s my controlling tty, job control " |
|
97 "disabled", *args, 0); |
|
98 else |
|
99 close(cttyfd); |
|
100 |
|
101 /* Clear mygrp so that acquire_pgrp() gets the new process group. |
|
102 * (acquire_pgrp() is called from init_io()) */ |
|
103 mypgrp = 0; |
|
104 init_io(); |
|
105 setsparam("TTY", ztrdup(ttystrname)); |
|
106 } |
|
107 close(ttyfd); |
|
108 if (pid < 0) { |
|
109 zerrnam(nam, "fork failed: %e", NULL, errno); |
|
110 return 1; |
|
111 } |
|
112 lastpid = pid; |
|
113 return 0; |
|
114 } |
|
115 |
|
116 static struct builtin bintab[] = { |
|
117 BUILTIN("clone", 0, bin_clone, 1, 1, 0, NULL, NULL), |
|
118 }; |
|
119 |
|
120 /**/ |
|
121 int |
|
122 setup_(UNUSED(Module m)) |
|
123 { |
|
124 return 0; |
|
125 } |
|
126 |
|
127 /**/ |
|
128 int |
|
129 boot_(Module m) |
|
130 { |
|
131 return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); |
|
132 } |
|
133 |
|
134 /**/ |
|
135 int |
|
136 cleanup_(Module m) |
|
137 { |
|
138 deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab)); |
|
139 return 0; |
|
140 } |
|
141 |
|
142 /**/ |
|
143 int |
|
144 finish_(UNUSED(Module m)) |
|
145 { |
|
146 return 0; |
|
147 } |
|
148 |
|
149 #endif //__SYMBIAN32__ |
|
150 |