/* ** Name: CS_cp_mbx_create - mailbox creation and initialization ** ** Description: ** This subroutine is called from CSinitiate(). ** ** It does the following: ** a) establishes a mailbox, with the name II_CPRES_xx_pid, where ** xx is the (optional) installation code, and pid is the ** process ID in hex. ** b) queues a read on the mailbox, with completion routine set to ** CS_cp_mbx_complete ** c) deletes the mailbox, so it'll go away when the process dies. ** ** Inputs: ** num_sessions - Number of sessions for the process. ** ** Outputs: ** sys_err - reason for error ** ** Returns: ** OK, !OK ** ** Side Effects: ** Sets cpres_mbx_chan to the mailbox's channel ** Defines the system-wide logical name II_CPRES_xx_pid ** ** History: ** Summer, 1992 (bryanp) ** Working on the new portable logging and locking system. ** 08-Nov-2007 (jonj) ** Use of "num_sessions" is totally bogus. CS_cp_mbx_create() is called ** before the startup parms are determined from config.dat (where we'd ** find "connect_limit"), so SCD hard-codes num_sessions = 32, resulting ** in CS_CP_MIN_MSGS == 5 always being used, which is way too small. ** Instead, default to the (configurable) VMS sysgen parameter ** DEFMBXBUFQUO. ** Also, create mailbox as read-only. Writers will assign write-only ** channels. */ STATUS CS_cp_mbx_create(i4 num_sessions, CL_ERR_DESC *sys_err) { struct dsc$descriptor_s name_desc; i4 vms_status; char mbx_name[100]; char *inst_id; PID pid; CL_CLEAR_ERR(sys_err); /* ** Build the mailbox logical name: */ PCpid(&pid); NMgtAt("II_INSTALLATION", &inst_id); if (inst_id && *inst_id) STprintf(mbx_name, "II_CPRES_%s_%x", inst_id, (i4)pid); else STprintf(mbx_name, "II_CPRES_%x", (i4)pid); name_desc.dsc$a_pointer = mbx_name; name_desc.dsc$w_length = STlength(mbx_name); name_desc.dsc$b_dtype = DSC$K_DTYPE_T; name_desc.dsc$b_class = DSC$K_CLASS_S; vms_status = sys$crembx( 1, /* Mailbox is "permanent" */ &cpres_mbx_chan, /* where to put channel */ (i4)sizeof(CS_CP_WAKEUP_MSG), /* maximum message size */ 0, /* buffer quota (DEFMBXBUFQUO) */ 0, /* prot mask = all priv */ PSL$C_USER, /* acmode */ &name_desc, /* logical name descriptor */ CMB$M_READONLY, /* flags */ 0); /* nullarg */ if ( vms_status != SS$_NORMAL ) { sys_err->error = vms_status; if (vms_status == SS$_NOPRIV) return (E_CS00F8_CSMBXCRE_NOPRIV); else return (E_CS00F7_CSMBXCRE_ERROR); } /* Hang a read */ cpres_q_read_io(); /* Mark for deletion, so it disappears when we exit. */ sys$delmbx(cpres_mbx_chan); cpres_channels_sem = 0; cpres_num_channels_assigned = 0; return (OK); }
NamedEventImpl::NamedEventImpl(const std::string& name): _name(name) { struct dsc$descriptor_s mbxDesc; mbxDesc.dsc$w_length = _name.length(); mbxDesc.dsc$b_dtype = DSC$K_DTYPE_T; mbxDesc.dsc$b_class = DSC$K_CLASS_S; mbxDesc.dsc$a_pointer = _name.c_str(); if (sys$crembx(0, &_mbxChan, 0, 0, 0, 0, &mbxDesc, 0, 0) != 1) throw SystemException("cannot create named event", _name); }
int job_control(void *unused) { int sts; struct _pcb *tsk = ctl$gl_pcb; strcpy(tsk->pcb$t_lname, "JOB_CONTROL"); sts=exe$crembx(1,&mailbox_channel,512,512,0,0,0,0); sys$ar_jobctlmb=ctl$gl_ccbbase[mailbox_channel].ccb$l_ucb; do_mbx_read(); sys$hiber(); printk("job control should not get past sys$hiber\n"); }
/* **++ ** ROUTINE: sp_open ** ** FUNCTIONAL DESCRIPTION: ** ** Spawns a subprocess, possibly passing it an initial command. ** ** RETURNS: cond_value, longword (unsigned), write only, by value ** ** PROTOTYPE: ** ** sp_open(SPHANDLE *ctxpp, struct dsc$descriptor *inicmd, ** unsigned int (*rcvast)(void *), void *rcvastprm); ** ** IMPLICIT INPUTS: None. ** ** IMPLICIT OUTPUTS: None. ** ** COMPLETION CODES: ** SS$_NORMAL: Normal successful completion. ** ** SIDE EFFECTS: None. ** **-- */ unsigned int sp_open (SPHANDLE *ctxpp, void *inicmd, unsigned int (*rcvast)(void *), void *rcvastprm) { SPHANDLE ctx; unsigned int dvi_devnam = DVI$_DEVNAM, dvi_devbufsiz = DVI$_DEVBUFSIZ; unsigned int spawn_flags = CLI$M_NOWAIT|CLI$M_NOKEYPAD; unsigned int status; struct dsc$descriptor inbox, outbox; status = lib$get_vm(&spb_size, &ctx); if (!OK(status)) return status; /* ** Assign the SPHANDLE address for the caller immediately to avoid timing issues with ** WRTATTN AST that passes the ctx as rcvastprm (which sp_once does). */ *ctxpp = ctx; ctx->sendque.head = ctx->sendque.tail = &ctx->sendque; ctx->ok_to_send = 0; /* ** Create the mailboxes we'll be using for I/O with the subprocess */ status = sys$crembx(0, &ctx->inchn, 1024, 1024, 0xff00, 0, 0, 0); if (!OK(status)) { lib$free_vm(&spb_size, &ctx); return status; } status = sys$crembx(0, &ctx->outchn, 1024, 1024, 0xff00, 0, 0, 0); if (!OK(status)) { sys$dassgn(ctx->inchn); lib$free_vm(&spb_size, &ctx); return status; } /* ** Now that they're created, let's find out what they're called so we ** can tell LIB$SPAWN */ INIT_DYNDESC(inbox); INIT_DYNDESC(outbox); lib$getdvi(&dvi_devnam, &ctx->inchn, 0, 0, &inbox); lib$getdvi(&dvi_devnam, &ctx->outchn, 0, 0, &outbox); lib$getdvi(&dvi_devbufsiz, &ctx->outchn, 0, &ctx->bufsiz); /* ** Create the output buffer for the subprocess. */ status = lib$get_vm(&ctx->bufsiz, &ctx->bufptr); if (!OK(status)) { sys$dassgn(ctx->outchn); sys$dassgn(ctx->inchn); str$free1_dx(&inbox); str$free1_dx(&outbox); lib$free_vm(&spb_size, &ctx); return status; } /* ** Set the "receive AST" routine to be invoked by SP_WRTATTN_AST */ ctx->rcvast = rcvast; ctx->astprm = rcvastprm; sys$qiow(0, ctx->outchn, IO$_SETMODE|IO$M_WRTATTN, 0, 0, 0, sp_wrtattn_ast, ctx, 0, 0, 0, 0); sys$qiow(0, ctx->inchn, IO$_SETMODE|IO$M_READATTN, 0, 0, 0, sp_readattn_ast, ctx, 0, 0, 0, 0); /* ** Get us a termination event flag */ status = lib$get_ef(&ctx->termefn); if (OK(status)) lib$get_ef(&ctx->inefn); if (OK(status)) lib$get_ef(&ctx->outefn); if (!OK(status)) { sys$dassgn(ctx->outchn); sys$dassgn(ctx->inchn); str$free1_dx(&inbox); str$free1_dx(&outbox); lib$free_vm(&ctx->bufsiz, &ctx->bufptr); lib$free_vm(&spb_size, &ctx); return status; } /* ** Now create the subprocess */ status = lib$spawn(inicmd, &inbox, &outbox, &spawn_flags, 0, &ctx->pid, 0, &ctx->termefn); if (!OK(status)) { lib$free_ef(&ctx->termefn); lib$free_ef(&ctx->outefn); lib$free_ef(&ctx->inefn); sys$dassgn(ctx->outchn); sys$dassgn(ctx->inchn); str$free1_dx(&inbox); str$free1_dx(&outbox); lib$free_vm(&ctx->bufsiz, &ctx->bufptr); lib$free_vm(&spb_size, &ctx); return status; } /* ** Set up the exit handler, if we haven't done so already */ status = sys$setast(0); if (!exh_declared) { sys$dclexh(&exhblk); exh_declared = 1; } if (status == SS$_WASSET) sys$setast(1); /* ** Save the SPB in our private queue */ queue_insert(ctx, spque.tail); /* ** Clean up and return */ str$free1_dx(&inbox); str$free1_dx(&outbox); return SS$_NORMAL; } /* sp_open */
void cce_dbdump(void) { uint4 channel, status, flags, pid, real_size, req_size, size, addrs[2], sec_addrs[2]; int i, j, k, l; gds_file_id file; m_iosb stat_blk; sgmnt_data *sd; unsigned char mbuff[512], *c, *cptr, *ctop; $DESCRIPTOR(d_sec,mbuff); static readonly $DESCRIPTOR(d_cmd,"install lis/glo"); static readonly $DESCRIPTOR(d_mnam,"CCE$DBDUMPMBX"); static readonly $DESCRIPTOR(d_pnam,"CCE$DBDUMPPRC"); char filename[]="SYS$LOGIN:CCE_DBDUMP.DMP", buff[RECORD_SIZE], id_lab[]=" FILE ID:"; struct FAB fab; struct RAB rab; error_def(ERR_CCEDBDUMP); error_def(ERR_CCEDBNODUMP); util_out_open(0); status = sys$crembx(0, &channel, 512, 0, 0, PSL$C_USER, &d_mnam); if (status != SS$_NORMAL) sys$exit(status); flags = CLI$M_NOWAIT | CLI$M_NOLOGNAM; status = lib$spawn(&d_cmd, 0, &d_mnam, &flags, &d_pnam, &pid); if (status != SS$_NORMAL) { if (status == SS$_DUPLNAM) { util_out_print("Spawned process CCE$DBDUMPPRC already exists, cannot continue rundown",TRUE); } sys$exit(status); } /* the following guess at the dump file size is modeled on the calculation for a section */ size = DIVIDE_ROUND_UP((SIZEOF(sgmnt_data) + (WC_MAX_BUFFS + getprime(WC_MAX_BUFFS) + 1) * SIZEOF(bt_rec) + (DEF_LOCK_SIZE / OS_PAGELET_SIZE) + (WC_MAX_BUFFS + getprime(WC_MAX_BUFFS)) * SIZEOF(cache_rec) + SIZEOF(cache_que_heads)), OS_PAGELET_SIZE); size += EXTRA_SPACE; fab = cc$rms_fab; fab.fab$b_fac = FAB$M_PUT; fab.fab$l_fop = FAB$M_CBT | FAB$M_MXV | FAB$M_TEF; fab.fab$l_fna = filename; fab.fab$b_fns = SIZEOF(filename); fab.fab$b_rfm = FAB$C_FIX; fab.fab$w_mrs = RECORD_SIZE; fab.fab$w_deq = size; fab.fab$l_alq = size; switch (status = sys$create(&fab)) { case RMS$_NORMAL: case RMS$_CREATED: case RMS$_SUPERSEDE: case RMS$_FILEPURGED: break; default: util_out_print("Error: Cannot create dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna); sys$exit(status); } rab = cc$rms_rab; rab.rab$l_fab = &fab; status = sys$connect(&rab); if (status != RMS$_NORMAL) { util_out_print("Error: Cannot connect to dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna); sys$exit(status); } rab.rab$w_rsz = SIZEOF(buff); for (; ;) { status = sys$qiow (0, channel,IO$_READVBLK ,&stat_blk, 0, 0, mbuff, 512,0,0,0,0); if (status != SS$_NORMAL) { sys$exit(status); break; } if (stat_blk.status == SS$_ENDOFFILE) break; if (stat_blk.status != SS$_NORMAL) { sys$exit(stat_blk.status); break; } if (!memcmp("GT$S",mbuff,4)) { for ( c = mbuff; *c > 32 ; c++) ; d_sec.dsc$w_length = c - mbuff; flags = SEC$M_GBL | SEC$M_WRT | SEC$M_SYSGBL | SEC$M_PAGFIL | SEC$M_DZRO | SEC$M_PERM; addrs[0] = addrs[1] = 0; fid_from_sec(&d_sec,&file); real_size = cce_sec_size(&file); if (real_size == 0) real_size = size; real_size += 1; assert(OS_PAGE_SIZE % OS_PAGELET_SIZE == 0); /* Request enough pagelets to ensure enough contiguous pages to contain desired number of pagelets. */ req_size = ROUND_UP(real_size, OS_PAGE_SIZE); lib$get_vm_page(&req_size, &addrs[0]); /* addrs will hold addresses of start and end of contiguous block of pagelets for use by $deltva. */ assert((addrs[0] + (req_size * OS_PAGELET_SIZE) - 1) == addrs[1]); /* $get_vm_page returns pagelets; we must align to integral page boundary. */ /* sec_addrs will contain the starting and ending addresses of the mapped section. */ sec_addrs[0] = ROUND_UP(addrs[0], OS_PAGE_SIZE); /* align to first integral page boundary */ sec_addrs[1] = addrs[0] + (real_size * OS_PAGELET_SIZE); sec_addrs[1] = ROUND_UP(addrs[1], OS_PAGE_SIZE) - 1; /* A(last byte of last page) */ status = init_sec(sec_addrs, &d_sec, 0, real_size, flags); if (status & 1) { sd = sec_addrs[0]; memset(buff, 0, RECORD_SIZE); memcpy(buff, d_sec.dsc$a_pointer, d_sec.dsc$w_length); cptr = &buff[0] + d_sec.dsc$w_length; memcpy(cptr,id_lab,SIZEOF(id_lab)); cptr += SIZEOF(id_lab); memcpy(cptr,&file,SIZEOF(file)); rab.rab$l_rbf = buff; status = sys$put(&rab); if (status != RMS$_NORMAL) { util_out_print("Error writing to dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna); util_out_print("Status code is !UL.",TRUE,status); break; } for (c = sd, i = 0; (real_size + EXTRA_SPACE) >= i; c += RECORD_SIZE, i += (RECORD_SIZE / DISK_BLOCK_SIZE)) { rab.rab$l_rbf = c; status = sys$put(&rab); if (status != RMS$_NORMAL) { util_out_print("Error writing to dump file !AD.",TRUE,fab.fab$b_fns,fab.fab$l_fna); util_out_print("Status code is !UL.",TRUE,status); break; } } lib$signal(ERR_CCEDBDUMP,2,d_sec.dsc$w_length,d_sec.dsc$a_pointer); }else { lib$signal(ERR_CCEDBNODUMP,2,d_sec.dsc$w_length,d_sec.dsc$a_pointer,status,0); } gtm_deltva(&addrs[0],0,0); lib$free_vm_page(&real_size,&addrs[0]); } } sys$exit(SS$_NORMAL); }
rlMailbox::rlMailbox(const char *mbxname) { #ifdef RLUNIX FILE *fp; key_t key; status = OK; buffer = NULL; buffer_size = 0; name = new char[strlen(mbxname)+1]; strcpy(name,mbxname); // create file fp = fopen(name,"r"); if(fp == NULL) { fp = fopen(name,"w"); if(fp == NULL) { int ret; char buf[1024]; sprintf(buf,"could not write mailbox=%s\n",mbxname); ret = ::write(1,buf,strlen(buf)); if(ret < 0) exit(-1); sprintf(buf,"you have to run this program as root !!!\n"); ret = ::write(1,buf,strlen(buf)); if(ret < 0) exit(-1); exit(-1); } fchmod(fileno(fp),0x0fff); if(fp == NULL) { status=COULD_NOT_CREATE_MAILBOX; return; } } fclose(fp); // getkey // old stuff, without suggestions from Stefan Lievens // key = ftok(name, 'R'); key = ftok(name, 'b'); if(key == ((key_t) (-1))) { status=COULD_NOT_GET_KEY; return; } // get chanid // old stuff, without suggestions from Stefan Lievens // chanid = msgget(key,IPC_CREAT); chanid = msgget(key, 0600 | IPC_CREAT); if(chanid == -1) { status=COULD_NOT_GET_CHAN_ID; return; } #endif #ifdef __VMS long ret; short chan_id; struct dsc$descriptor_s dmbxname; chanid = -1; status = OK; name = new char[strlen(mbxname)+1]; strcpy(name,mbxname); dmbxname.dsc$w_length = strlen(name); dmbxname.dsc$a_pointer = name; dmbxname.dsc$b_dtype = DSC$K_DTYPE_T; dmbxname.dsc$b_class = DSC$K_CLASS_S; ret = sys$crembx((char)1, // 0 temp 1 permanence flag &chan_id, // i/o channel MAX_MAILBOX, // max msg length MAX_MAILBOX*4, // max buffer size (long)0, (long)0, &dmbxname); // mailbox name if(ret == SS$_NORMAL) { chanid = chan_id; return; } else { status = COULD_NOT_CREATE_MAILBOX; return; } #endif #ifdef RLWIN32 chanid = -1; status = OK; name = new char[strlen(mbxname)+1]; strcpy(name,mbxname); #endif }
} break; } default: break; } } /* ** create mailbox for passing commands to the new process. ** Get the device name of the mailbox to to be used as input ** stream for new process. */ status = sys$crembx( 0, &chan, 0, 0, 0, PSL$C_USER, NULL ); if ( !(status & 1) ) { log_errmsg( "SYS$CREMBX(1) failed", status, 1 ); return ( status ); } dviitem = DVI$_DEVNAM; $DESCFILL( input, sizeof( inbuf ), inbuf ); status = lib$getdvi( &dviitem, &chan, NULL, NULL, &input, &input ); if ( !(status & 1) ) { log_errmsg( "LIB$GETDVI(1) failed", status, 1 ); return ( status ); }
main(){ struct _iosb myiosb; char mybuf1[MBXBUFSIZ]="test1"; char mybuf2[MBXBUFSIZ]="test2"; char mybuf3[MBXBUFSIZ]="test3"; char * out1="hello"; char * out2="world"; char * out3="hi"; void *p1, mbxast(); char mbuffer[MBXBUFSIZ]; unsigned short mbxchan1, mbxchan2, mbxchan3, mbxiosb; unsigned int status, outlen; unsigned int mbuflen=MBXBUFSIZ, bufquo=MBXBUFQUO, promsk=0; $DESCRIPTOR(mblognam1,"MAILBOX1"); $DESCRIPTOR(mblognam2,"MAILBOX2"); $DESCRIPTOR(mblognam3,"MAILBOX3"); printf("this was originally in 1: %s\n",mybuf1); printf("this was originally in 2: %s\n",mybuf2); printf("this was originally in 3: %s\n",mybuf3); status = sys$crembx(0,&mbxchan1,mbuflen,bufquo,promsk,0,&mblognam1,0); printf("status %x mbxchan %x \n", status,mbxchan1); if ((status&1)==0) signal(status); status = sys$crembx(0,&mbxchan2,mbuflen,bufquo,promsk,0,&mblognam2,0); printf("status %x mbxchan %x \n", status,mbxchan2); if ((status&1)==0) signal(status); status = sys$crembx(0,&mbxchan3,mbuflen,bufquo,promsk,0,&mblognam3,0); printf("status %x mbxchan %x \n", status,mbxchan3); if ((status&1)==0) signal(status); printf("before qio %x\n",time(0)); status=sys$qio(0,mbxchan1,IO$_READVBLK,0,0,0,mybuf1,512,0,0,0,0); printf("after qio %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("before qiow %x\n",time(0)); status=sys$qio(0,mbxchan1,IO$_WRITEVBLK,0,0,0,out1,strlen(out1),0,0,0,0); printf("after qiow %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("before qiow %x\n",time(0)); status=sys$qio(0,mbxchan1,IO$_WRITEVBLK,0,0,0,out2,strlen(out2),0,0,0,0); printf("after qiow %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("this was read from 1: %s\n",mybuf1); printf("Pausing...\n"); sleep(2); printf("before qio %x\n",time(0)); status=sys$qio(0,mbxchan2,IO$_READVBLK|IO$M_STREAM,0,0,0,mybuf2,512,0,0,0,0); printf("after qio %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("before qiow %x\n",time(0)); status=sys$qio(0,mbxchan2,IO$_WRITEVBLK,0,0,0,out1,strlen(out1),0,0,0,0); printf("after qiow %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("before qiow %x\n",time(0)); status=sys$qio(0,mbxchan2,IO$_WRITEVBLK,0,0,0,out2,strlen(out2),0,0,0,0); printf("after qiow %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("this was read from 2: %s\n",mybuf2); printf("Pausing...\n"); sleep(2); printf("before qio %x\n",time(0)); printf("before qiow %x\n",time(0)); status=sys$qio(0,mbxchan3,IO$_WRITEVBLK,0,0,0,out1,strlen(out1),0,0,0,0); printf("after qiow %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("before qiow %x\n",time(0)); status=sys$qio(0,mbxchan3,IO$_WRITEVBLK,0,0,0,out2,strlen(out2),0,0,0,0); printf("after qiow %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); status=sys$qiow(0,mbxchan3,IO$_READVBLK|IO$M_STREAM,0,0,0,mybuf3,512,0,0,0,0); printf("after qio %x\n",time(0)); printf("status %x done %x \n", status,done); if ((status&1)==0) signal(status); printf("this was read from 3: %s\n",mybuf3); sleep(2); { struct item_list_3 { short buflen, item_code; void *bufaddr; void *retlenaddr; } itmlist[2]; char buf[50]; int retlen; itmlist[0].item_code=LNM$_STRING; itmlist[0].bufaddr=buf; itmlist[0].buflen=50; itmlist[0].retlenaddr=&retlen; itmlist[1].item_code=0; itmlist[1].buflen=0; itmlist[1].bufaddr=0; $DESCRIPTOR(tab,"LNM$TEMPORARY_MAILBOX"); status = sys$trnlnm(0, &tab, &mblognam1, 0, itmlist); if ((status&1)==0) signal(status); printf("mailbox1 translates to %s\n",buf); } return SS$_NORMAL; }