/* rmtfcn */ #ifdef DOCUMENTATION title rmtfcn prototype task for remote functions index rmtfcn prototype task for remote functions synopsis ins rmtfcn/task=rmtfcn description Remote functions allow executing a function call on a remote node. Existing tasks that need to modify some portion of a remote system (ie. a resident common) can use this technique with the least effect on an existing program. The file contains a prototype of a remote function task. It assumes that a task on a remote node will connect to it, send, and optionally receive, one or more packets. Status from the desired function should be returned via a network send. When the function exits, this task will disconnect and exit. bugs #endif #include #include #include #define IE_DAO 0363 /* transfer rejected */ #define IE_REJ 0250 /* transfer rejected */ #define IE_DSQ 0246 /* disk quota exceed, tried to put too much */ #define IE_EOF 0366 /* end of file */ extern int $$nerr; static NIOV *np; static char buf[132]; int $$nargs = 1; main() { int netmsg(); int len; int *ip; freopen("NL:", "w", stdout); /* prevents flushing cr to CO on exit */ if(!opn_net(netmsg)) { tmsg('F', "open net failed nerr %d\n", $$nerr); exits(4); } wtse(10); /* wait for attach from other task */ while ((len = get_net(buf, sizeof buf, np)) != NULL) { dsar(); /* let code finish */ /**** function specific code goes here *****/ user_routine(buf, len); enar(); /* let asts in */ } finish(1); } netmsg(code, acp) char code[4]; /* message type code */ struct a_conblk *acp; /* pointer to received message */ { switch (code[1]) { case NT_CON: { accept(acp); setf(10); break; } case NT_INT: { tmsg('M', "interrupt message\n"); break; } case NT_DSC: { rclos(0); /* tmsg('D', "NT_DSC exit\n"); */ finish(4); } case NT_ABT: { rclos(0); /* tmsg('D', "NT_ABT exit\n"); */ finish(4); } case NT_ABO: { rclos(0); /* tmsg('D', "NT_ABO exit\n"); */ finish(4); } default: { tmsg('W', "unexpected msg %d msglen %d lun %d\n", code[1], code[2], code[3]); } } return(1); } accept(ap) struct a_conblk *ap; /* pointer to received message */ { NIOV *acc_net(); if ((np = acc_net(ap)) == NULL) { tmsg('E', "accnt failed, err %o\n", $$nerr); return(0); } } finish(stat) /* close everything and exit with status = stat */ int stat; { dsc_net(np); cls_net(); /* tmsg('D', "standard exit\n"); */ exits(stat); }