2 The pipe port communication routines for Unix.
3 Contributed by Marc Boucher <marc@CAM.ORG>.
5 Copyright (C) 1993 Ian Lance Taylor
7 This file is part of the Taylor UUCP package.
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 The author of the program may be contacted at ian@airs.com or
24 c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
30 const char pipe_rcsid[] = "$FreeBSD$";
49 /* Local functions. */
51 static void uspipe_free P((struct sconnection *qconn));
52 static boolean fspipe_open P((struct sconnection *qconn, long ibaud,
54 static boolean fspipe_close P((struct sconnection *qconn,
56 struct uuconf_dialer *qdialer,
58 static boolean fspipe_dial P((struct sconnection *qconn, pointer puuconf,
59 const struct uuconf_system *qsys,
61 struct uuconf_dialer *qdialer,
62 enum tdialerfound *ptdialer));
64 /* The command table for standard input ports. */
66 static const struct sconncmds spipecmds =
84 /* Initialize a pipe connection. */
87 fsysdep_pipe_init (qconn)
88 struct sconnection *qconn;
90 struct ssysdep_conn *q;
92 q = (struct ssysdep_conn *) xmalloc (sizeof (struct ssysdep_conn));
103 qconn->psysdep = (pointer) q;
104 qconn->qcmds = &spipecmds;
110 struct sconnection *qconn;
112 xfree (qconn->psysdep);
115 /* Open a pipe port. */
119 fspipe_open (qconn, ibaud, fwait)
120 struct sconnection *qconn;
124 /* We don't do incoming waits on pipes. */
131 /* Close a pipe port. */
135 fspipe_close (qconn, puuconf, qdialer, fsuccess)
136 struct sconnection *qconn;
138 struct uuconf_dialer *qdialer;
141 struct ssysdep_conn *qsysdep;
144 qsysdep = (struct ssysdep_conn *) qconn->psysdep;
147 /* Close our sides of the pipe. */
148 if (qsysdep->ord >= 0 && close (qsysdep->ord) < 0)
150 ulog (LOG_ERROR, "fspipe_close: close read fd: %s", strerror (errno));
153 if (qsysdep->owr != qsysdep->ord
155 && close (qsysdep->owr) < 0)
157 ulog (LOG_ERROR, "fspipe_close: close write fd: %s", strerror (errno));
163 /* Kill dangling child process. */
164 if (qsysdep->ipid >= 0)
166 if (kill (qsysdep->ipid, SIGHUP) == 0)
169 if (kill (qsysdep->ipid, SIGPIPE) == 0)
172 if (kill (qsysdep->ipid, SIGKILL) < 0 && errno == EPERM)
174 ulog (LOG_ERROR, "fspipe_close: Cannot kill child pid %lu: %s",
175 (unsigned long) qsysdep->ipid, strerror (errno));
179 (void) ixswait ((unsigned long) qsysdep->ipid, (const char *) NULL);
185 /* Dial out on a pipe port, so to speak: launch connection program
186 under us. The code alternates q->o between q->ord and q->owr as
187 appropriate. It is always q->ord before any call to fsblock. */
191 fspipe_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialer)
192 struct sconnection *qconn;
194 const struct uuconf_system *qsys;
196 struct uuconf_dialer *qdialer;
197 enum tdialerfound *ptdialer;
199 struct ssysdep_conn *q;
203 q = (struct ssysdep_conn *) qconn->psysdep;
205 *ptdialer = DIALERFOUND_FALSE;
207 pzprog = (const char **) qconn->qport->uuconf_u.uuconf_spipe.uuconf_pzcmd;
211 ulog (LOG_ERROR, "No command for pipe connection");
215 aidescs[0] = SPAWN_WRITE_PIPE;
216 aidescs[1] = SPAWN_READ_PIPE;
217 aidescs[2] = SPAWN_NULL;
219 /* Pass fkeepuid, fkeepenv and fshell as TRUE. This puts the
220 responsibility of security on the connection program. */
221 q->ipid = ixsspawn (pzprog, aidescs, TRUE, TRUE, (const char *) NULL,
222 FALSE, TRUE, (const char *) NULL,
223 (const char *) NULL, (const char *) NULL);
226 ulog (LOG_ERROR, "ixsspawn (%s): %s", pzprog[0], strerror (errno));
234 q->iflags = fcntl (q->ord, F_GETFL, 0);
235 q->iwr_flags = fcntl (q->owr, F_GETFL, 0);
236 if (q->iflags < 0 || q->iwr_flags < 0)
238 ulog (LOG_ERROR, "fspipe_dial: fcntl: %s", strerror (errno));
239 (void) fspipe_close (qconn, puuconf, qdialer, FALSE);
248 /* Marc Boucher's contributed code used an alarm to avoid waiting too
249 long when closing the pipe. However, I believe that it is not
250 possible for the kernel to sleep when closing a pipe; it is only
251 possible when closing a device. Therefore, I have removed the
252 code, but am preserving it in case I am wrong. To reenable it, the
253 two calls to close in fspipe_close should be changed to call
254 fspipe_alarmclose. */
260 #if ! HAVE_SIGACTION && ! HAVE_SIGVEC && ! HAVE_SIGSET
261 (void) signal (isig, usalarm);
264 #if HAVE_RESTARTABLE_SYSCALLS
265 longjmp (sSjmp_buf, 1);
270 fspipe_alarmclose (fd)
276 if (fsysdep_catch ())
278 usysdep_start_catch ();
279 usset_signal (SIGALRM, usalarm, TRUE, (boolean *) NULL);
286 usset_signal (SIGALRM, SIG_IGN, TRUE, (boolean *) NULL);
288 usysdep_end_catch ();