/* mig_put_reply_port(_buf_start->Head.msgh_local_port); */ #if 0 if (_buf_start->RetCode != KERN_SUCCESS) fprintf(stderr,"Return error code: %x\n", _buf_start->RetCode); #endif return mr; } #if 0 /* the send is handled by a direct call to mach_msg now */ mach_msg_return_t flick_mach3mig_send(void *buf_current, mach_msg_option_t msg_options, mach_msg_timeout_t timeout) { register mig_reply_header_t *_buf_start = _global_buf_start; register void *_buf_current = buf_current; mach_msg_return_t mr; _buf_start->Head.msgh_local_port = MACH_PORT_NULL; #if 0 printf("Send:\n"); print_message(_buf_start, _buf_start->Head.msgh_size); #endif mr = mach_msg(&_buf_start->Head, MACH_SEND_MSG|msg_options, _buf_start->Head.msgh_size, 0, MACH_PORT_NULL, timeout, MACH_PORT_NULL); if (mr != MACH_MSG_SUCCESS) { while (mr == MACH_SEND_INTERRUPTED) { /* Retry both the send and the receive. */ mr = mach_msg_trap(&_buf_start->Head, MACH_SEND_MSG, _buf_start->Head.msgh_size, 0, MACH_PORT_NULL, 0, 0); } if (mr != MACH_MSG_SUCCESS) { #if 0 if ((mr == MACH_SEND_INVALID_REPLY) || (mr == MACH_SEND_INVALID_MEMORY) || (mr == MACH_SEND_INVALID_RIGHT) || (mr == MACH_SEND_INVALID_TYPE) || (mr == MACH_SEND_MSG_TOO_SMALL) || (mr == MACH_RCV_INVALID_NAME)) mig_dealloc_reply_port(_buf_start->Head.msgh_local_port); else mig_put_reply_port(_buf_start->Head.msgh_local_port); #endif return mr; } } #if 0 if (_buf_start->RetCode != KERN_SUCCESS) fprintf(stderr,"Return error code: %x\n", _buf_start->RetCode); #endif return mr; }
/* Routine send_message */ mig_external kern_return_t Cache_send_message ( mach_port_t send_port, string_t message ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t messageType; string_t message; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; auto const mach_msg_type_t messageType = { /* msgt_name = */ MACH_MSG_TYPE_STRING_C, /* msgt_size = */ 8, /* msgt_number = */ 1024, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->messageType = messageType; (void) mig_strncpy(InP->message, message, 1024); InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); /* msgh_size passed as argument */ InP->Head.msgh_request_port = send_port; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 4066; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, 1052, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 4166) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck if ((OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || (OutP->Head.msgh_size != 32)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ return OutP->RetCode; }
mach_msg_return_t flick_mach3mig_rpc(mach_msg_option_t msg_options, mach_msg_timeout_t timeout) { register mig_reply_header_t *_buf_start = _global_buf_start; mach_msg_return_t mr; int buf_size = ((int)_buf_end - (int)_buf_start); /* * Consider the following cases: * 1) Errors in pseudo-receive (eg, MACH_SEND_INTERRUPTED * plus special bits). * 2) Use of MACH_SEND_INTERRUPT/MACH_RCV_INTERRUPT options. * 3) RPC calls with interruptions in one/both halves. * 4) Exception reply messages that are bigger * than the expected non-exception reply message. * * We refrain from passing the option bits that we implement * to the kernel. This prevents their presence from inhibiting * the kernel's fast paths (when it checks the option value). */ #if 0 printf("RPC-SND:\n"); print_message(_buf_start, _buf_start->Head.msgh_size); #endif mr = mach_msg(&_buf_start->Head, MACH_SEND_MSG | MACH_RCV_MSG | MACH_RCV_LARGE | msg_options, _buf_start->Head.msgh_size, buf_size, _buf_start->Head.msgh_local_port, timeout, MACH_PORT_NULL); if (mr != MACH_MSG_SUCCESS) { while (mr == MACH_SEND_INTERRUPTED) { /* Retry both the send and the receive. */ mr = mach_msg_trap(&_buf_start->Head, (MACH_SEND_MSG | MACH_RCV_MSG | MACH_RCV_LARGE | msg_options), _buf_start->Head.msgh_size, buf_size, _buf_start->Head.msgh_local_port, timeout, MACH_PORT_NULL); } while ((mr == MACH_RCV_INTERRUPTED) || (mr == MACH_RCV_TOO_LARGE)) { if (mr == MACH_RCV_TOO_LARGE) { /* Oops, message too large - grow the buffer. */ buf_size = _buf_start->Head.msgh_size; if (!(_buf_start = (mig_reply_header_t *) nonposix_realloc(_buf_start, buf_size))) { mig_dealloc_reply_port(/*_buf_start->Head.msgh_local_port*/); return FLICK_NO_MEMORY; } #if 0 __buffer = _buf_start; __buflen = buf_size; #endif } /* Retry the receive only (the request message has already been sent successfully). */ mr = mach_msg_trap(&_buf_start->Head, MACH_RCV_MSG|MACH_RCV_LARGE|msg_options, 0, buf_size, _buf_start->Head.msgh_local_port, timeout, MACH_PORT_NULL); } if (mr != MACH_MSG_SUCCESS) { #if 0 if ((mr == MACH_SEND_INVALID_REPLY) || (mr == MACH_SEND_INVALID_MEMORY) || (mr == MACH_SEND_INVALID_RIGHT) || (mr == MACH_SEND_INVALID_TYPE) || (mr == MACH_SEND_MSG_TOO_SMALL) || (mr == MACH_RCV_INVALID_NAME)) mig_dealloc_reply_port(_buf_start->Head.msgh_local_port); else mig_put_reply_port(_buf_start->Head.msgh_local_port); #endif return mr; } } #if 0 printf("RPC-RCV: (%d, 0x%08x)\n", mr, mr); print_message(_buf_start, _buf_start->Head.msgh_size); scanf("%d",&mr); #endif /* Stash the reply port again for future use. */ /* mig_put_reply_port(_buf_start->Head.msgh_local_port); */ #if 0 if (_buf_start->RetCode != KERN_SUCCESS) fprintf(stderr,"Return error code: %x\n", _buf_start->RetCode); #endif return mr; }