/*
- * GDB operations to send and recieve RPC requests and replies.
+ * $Source$
+ * $Author$
+ * $Header$
+ *
+ * Copyright (C) 1987 by the Massachusetts Institute of Technology
+ *
+ * $Log$
+ * Revision 1.5 1987-06-16 17:47:50 wesommer
+ * Clean up memory allocation, indenting.
+ *
*/
-sms_start_call(op, hcon, arg)
- OPERATION op;
- HALF_CONNECTION hcon;
- register struct param *arg;
-{
- /*
- * This should probably be split into several routines.
- * It could also probably be made more efficient (punting most
- * of the argument marshalling stuff by doing I/O directly
- * from the strings. Anyone for a scatter/gather sms_send_data?
- *
- * that would look a lot like the uio stuff in the kernel.. hmm.
- */
-
- /*
- * Marshall the entire data right now..
- * We are sending the version number,
- * total request size, request number,
- * argument count, and then each argument.
- * At least for now, each argument is a string, which is
- * sent as a count of bytes followed by the bytes
- * (including the trailing '\0'), padded
- * to a longword boundary.
- */
-
- sms_size = 4 * sizeof(long);
-
- argl = (int *)malloc(sizeof(int) * arg->argc);
-
- /*
- * For each argument, figure out how much space is needed.
- */
-
- for (i = arg->argc; i; --i) {
- argl[i] = len = strlen(arg->argv[i]) + 1;
- sms_size += sizeof(long) + len;
- sms_size = sizeof(long) * howmany(sms_size, sizeof(long));
- }
-
- arg->flattened = buf = db_alloc(sms_size);
+#ifndef lint
+static char *rcsid_sms_call_c = "$Header$";
+#endif lint
- bzero(arg->flattened, sms_size);
-
- arg->size = sms_size;
-
- /*
- * This is gross. Any better suggestions, anyone?
- * It should work on the RT's, since malloc is guaranteed to
- * return a pointer which is aligned correctly for any data.
- */
+#include "sms_private.h"
- ((long *)buf)[0] = htonl(SMS_VERSION_1);
- ((long *)buf)[1] = htonl(sms_size);
- ((long *)buf)[2] = htonl(arg->procno);
- ((long *)buf)[3] = htonl(arg->argc);
-
- /*
- * bp is a pointer into the point in the buffer to put
- * the next argument.
- */
-
- bp = (char *)(&(long *)buf[4])
- for (i = arg->argc; i; --i) {
- len = argl[i];
- *((long *)bp) = htonl(len);
- bp += sizeof(long);
- bcopy(arg->argv[i], bp, len);
- bp += sizeof(long) * howmany(len, sizeof(long));
- }
- op->fcn.cont = sms_cont_call;
- arg->size = sms_size;
-
- if (gdb_send_data(hcon, arg->flattened, sms_size) == OP_COMPLETE)
- return sms_cont_call(op, hcon, arg);
- else return OP_RUNNING;
-}
-
-/*
- * This doesn't get called until after the actual buffered write completes.
- * In a non-preflattening version of this, this would then queue the
- * write of the next bunch of data.
- */
-
-sms_cont_call(op, hcon, arg)
- OPERATION op;
- HALF_CONNECTION hcon;
- struct params *arg;
+sms_do_call(params, reply)
+ struct sms_params *params;
+ struct sms_params **reply;
{
- op->result = OP_SUCCESS;
- db_free(arg->flattened, arg->size);
- db_free(arg, sizeof(struct params));
- return OP_COMPLETE;
+ CHECK_CONNECTED;
+
+ if (!_sms_send_op)
+ _sms_send_op = create_operation();
+
+ if (!_sms_recv_op)
+ _sms_recv_op = create_operation();
+
+ initialize_operation(_sms_send_op, sms_start_send, (char *)params,
+ (int (*)())NULL);
+ queue_operation(_sms_conn, CON_OUTPUT, _sms_send_op);
+
+ initialize_operation(_sms_recv_op, sms_start_recv, (char *)reply,
+ (int (*)())NULL);
+ queue_operation(_sms_conn, CON_INPUT, _sms_recv_op);
+
+ /* Block until operation done. */
+ complete_operation(_sms_send_op);
+ complete_operation(_sms_recv_op);
+ /* Look at results */
+ if ((OP_STATUS(_sms_send_op) != OP_COMPLETE) ||
+ (OP_STATUS(_sms_recv_op) != OP_COMPLETE)) {
+ sms_disconnect();
+ return SMS_ABORTED;
+ }
+ return 0;
}
-
-
-/* Need routines to decode all that... */
+/*
+ * Local Variables:
+ * mode: c
+ * c-indent-level: 4
+ * c-continued-statement-offset: 4
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * End:
+ */