--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/rad/mod/xport_pipe/mod_pipe.c Fri May 18 11:08:12 2012 -0400
@@ -0,0 +1,159 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <bsm/adt_event.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <ucred.h>
+
+#include <rad/adr_stream.h>
+#include "rad_object.h"
+#include "rad_modapi.h"
+#include "rad_modapi_xport.h"
+#include "rad_connection.h"
+#include "rad_xport.h"
+
+#include "api_pipe.h"
+
+static rad_moderr_t
+pipe_listen(rad_thread_t *arg)
+{
+ int fdin;
+ data_t *data = rad_thread_arg(arg);
+ data_t *exitprop = struct_get(data, "exit");
+ rad_subject_t *subject;
+ rad_moderr_t result = rm_ok;
+ ucred_t *uc = ucred_get(P_MYID);
+
+ adr_stream_t *stream;
+ data_t *fdprop = struct_get(data, "fd");
+ if (fdprop) {
+ fdin = data_to_integer(fdprop);
+ stream = adr_stream_create_fd(fdin);
+ } else {
+ fdin = STDIN_FILENO;
+ stream = adr_stream_create_fds(fdin, STDOUT_FILENO);
+ }
+ if (stream == NULL) {
+ rad_log(RL_ERROR, "failed to allocate connection");
+ goto done;
+ }
+
+ if (uc == NULL ||
+ (subject = rad_subject_create_ucred(uc, B_FALSE, NULL)) == NULL) {
+ rad_log(RL_ERROR, "failed to allocate connection");
+ adr_stream_close(stream);
+ adr_stream_free(stream);
+ result = rm_system;
+ goto done;
+ }
+
+ rad_protocol_t *proto = rad_proto_find("rad");
+ if (proto == NULL) {
+ rad_log(RL_ERROR, "unable to find protocol \"rad\"");
+ rad_subject_unref(subject);
+ adr_stream_close(stream);
+ adr_stream_free(stream);
+ result = rm_config;
+ goto done;
+ }
+
+ radmod_connection_t *conn = rad_conn_create_fd(fdin, B_FALSE);
+ if (conn == NULL) {
+ rad_log(RL_WARN, "failed to allocate connection");
+ rad_subject_unref(subject);
+ adr_stream_close(stream);
+ adr_stream_free(stream);
+ result = rm_system;
+ goto done;
+ }
+ conn->rm_conn_xport = stream;
+ conn->rm_conn_proto_ops = proto;
+
+ if (!rad_conn_setsubject(conn, subject)) {
+ rad_log(RL_WARN, "failed to set connection subject");
+ rad_conn_close(conn);
+ rad_conn_free(conn);
+ result = rm_system;
+ goto done;
+ }
+ rad_thread_ack(arg, rm_ok);
+ rad_proto_handle(conn);
+ rad_conn_free(conn);
+
+done:
+ if (exitprop != NULL) {
+ assert(data_basetype(exitprop) == dt_boolean);
+ if (data_to_boolean(exitprop)) {
+ rad_log(result == rm_ok ? RL_DEBUG : RL_WARN,
+ "exit triggered by pipe connector");
+ exit(0);
+ }
+ }
+ return (result);
+}
+
+static boolean_t running = B_FALSE;
+
+static rad_moderr_t
+stdin_starter(data_t *data)
+{
+ rad_moderr_t result;
+
+ if (running) {
+ /* Until we permit configuring the fd */
+ rad_log(RL_ERROR,
+ "Only one stdin transport may be running at a time.\n");
+ return (rm_config);
+ }
+
+ result = rad_thread_create(pipe_listen, data);
+ if (result == rm_ok)
+ running = B_TRUE;
+ return (result);
+}
+
+static rad_moderr_t
+pipe_starter(data_t *data)
+{
+ return (rad_thread_create(pipe_listen, data));
+}
+
+static rad_modinfo_t modinfo = { "xport_pipe", "stdin/pipe transport" };
+
+int
+_rad_init(void *handle)
+{
+ if (rad_module_register(handle, RAD_MODVERSION, &modinfo) == -1)
+ return (-1);
+
+ rad_xport_register("stdin", &t__stdin, stdin_starter);
+ rad_xport_register("pipe", &t__pipe, pipe_starter);
+ return (0);
+}