]> andersk Git - moira.git/blobdiff - lib/mr_call.c
Initial revision
[moira.git] / lib / mr_call.c
diff --git a/lib/mr_call.c b/lib/mr_call.c
new file mode 100644 (file)
index 0000000..8bd9fd5
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * GDB operations to send and recieve RPC requests and replies.
+ */
+
+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);
+
+       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.
+        */
+
+       ((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;
+{
+       op->result = OP_SUCCESS;
+       db_free(arg->flattened, arg->size);
+       db_free(arg, sizeof(struct params));
+       return OP_COMPLETE;
+}
+
+
+/* Need routines to decode all that... */
This page took 0.037679 seconds and 4 git commands to generate.