/* * sgs_connection_logout() */ int sgs_connection_logout(sgs_connection_impl *connection, int force) { if (force) { conn_closed(connection); } else { if (connection->state == SGS_CONNECTION_IMPL_DISCONNECTED) { errno = ENOTCONN; return -1; } connection->expecting_disconnect = 1; if (connection->in_redirect) return 0; sgs_session_impl_logout(connection->session); } return 0; }
PRIVATE void compile_main(FILE *conni, FILE *conno) { REPL_DATA rd = allocmem(sizeof(repl_data)); VMstate vms; rd->h1 = rd->h2 = NULL; protect(&rd->h1); protect(&rd->h2); rd->vmregs = (VMREGS) newvector(NUM_VMREGS); /* dodgy casting :-) */ vms.r = rd->vmregs; protect((OBJ *)(&rd->vmregs)); init_vm(&vms); vms.c.vm_state = VM_STATE_NOQUOTA; while (vms.c.vm_state != VM_STATE_DYING) { ScanInst si; char buf[16384]; rd->h1 = (OBJ) newbvector(0); while (1) { char *result; result = fgets(buf, 256, conni); if (result == NULL) break; while (1) { int l = strlen(buf); if (buf[l-1] == '\r' || buf[l-1] == '\n') buf[l-1] = '\0'; else break; } strcat(buf, "\n"); if (!strcmp(buf, ".\n")) break; rd->h2 = (OBJ) newstring(buf); rd->h1 = (OBJ) bvector_concat((BVECTOR) rd->h1, (BVECTOR) rd->h2); } gc_reach_safepoint(); rd->h2 = (OBJ) newstringconn((BVECTOR) rd->h1); fill_scaninst(&si, (OVECTOR) rd->h2); while (!conn_closed((OVECTOR) rd->h2)) { rd->h1 = (OBJ) parse(&vms, &si); gc_reach_safepoint(); if (rd->h1 == NULL) { sprintf(buf, "-->! the compiler returned NULL.\n"); } else { vms.c.vm_state = VM_STATE_NOQUOTA; ATPUT((OVECTOR) rd->h1, ME_OWNER, (OBJ) vms.r->vm_uid); vms.r->vm_effuid = vms.r->vm_uid; { OVECTOR c = newovector_noinit(CL_MAXSLOTINDEX, T_CLOSURE); ATPUT(c, CL_SELF, NULL); ATPUT(c, CL_METHOD, rd->h1); rd->h1 = (OBJ) c; } apply_closure(&vms, (OVECTOR) rd->h1, newvector_noinit(1)); while (!run_vm(&vms)) ; rd->h1 = (OBJ) newvector(2); ATPUT((VECTOR) rd->h1, 0, NULL); ATPUT((VECTOR) rd->h1, 1, vms.r->vm_acc); rd->h1 = lookup_prim(0x00001, NULL)(&vms, (VECTOR) rd->h1); rd->h1 = (OBJ) bvector_concat((BVECTOR) rd->h1, newbvector(1)); /* terminates C-string */ gc_reach_safepoint(); sprintf(buf, "--> %s\n", ((BVECTOR) rd->h1)->vec); } fputs(buf, conno); } } unprotect((OBJ *)(&rd->vmregs)); unprotect(&rd->h2); unprotect(&rd->h1); freemem(rd); }
/* * sgs_connection_do_work() */ int sgs_connection_do_work(sgs_connection_impl *connection) { fd_set readset, writeset, exceptset; struct timeval timeout_tv; int result; sgs_socket_t sockfd; socklen_t optlen; if (connection->state == SGS_CONNECTION_IMPL_DISCONNECTED) { /** Error: should not call do_io() when disconnected. */ errno = ENOTCONN; return -1; } sockfd = connection->socket_fd; FD_ZERO(&readset); FD_ZERO(&writeset); FD_ZERO(&exceptset); FD_SET(sockfd, &readset); FD_SET(sockfd, &writeset); FD_SET(sockfd, &exceptset); timeout_tv.tv_sec = 0; timeout_tv.tv_usec = 0; result = select(sockfd + 1, &readset, &writeset, &exceptset, &timeout_tv); if (result <= 0) { return result; /** -1 or 0 */ } if (FD_ISSET(sockfd, &exceptset)) { optlen = sizeof(errno); /* SO_ERROR should return an int */ if (sgs_socket_getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &errno, &optlen) == -1) { return -1; } conn_closed(connection); return -1; } if (FD_ISSET(sockfd, &readset)) { /** Read stuff off the socket and write it to the in-buffer. */ result = sgs_impl_read_from_fd(connection->inbuf, sockfd); if (result == -1) { return -1; } /* Return value of 0 may or may not mean that EOF was read. */ if ((result == 0) && (sgs_buffer_remaining(connection->inbuf) > 0)) { conn_closed(connection); /** The server closed the socket. */ return 0; } /** Try to pull out messages from the inbuf and process them. */ if (consume_data(connection) == -1) return -1; } if (FD_ISSET(sockfd, &writeset)) { /** If we are waiting for connect() to complete, its done now. */ if (connection->state == SGS_CONNECTION_IMPL_CONNECTING) { connection->state = SGS_CONNECTION_IMPL_CONNECTED; } /** Read stuff out of the out-buffer and write it to the socket. */ result = sgs_impl_write_to_fd(connection->outbuf, sockfd); if (result == -1) { return -1; } } /** If there is room in inbuf, then register interest in socket reads. */ if (connection->state == SGS_CONNECTION_IMPL_CONNECTED) { if (sgs_buffer_remaining(connection->inbuf) > 0){ if (connection->input_enabled == 0){ connection->ctx->reg_fd_cb(connection, sockfd, POLLIN); connection->input_enabled = 1; } } else if (connection->input_enabled == 1){ connection->ctx->unreg_fd_cb(connection, sockfd, POLLIN); connection->input_enabled = 0; } /** If there is data in outbuf, then register interest in socket writes. */ if (sgs_buffer_size(connection->outbuf) > 0) { if (connection->output_enabled == 0) { connection->ctx->reg_fd_cb(connection, sockfd, POLLOUT); connection->output_enabled = 1; } } else if (connection->output_enabled == 1){ connection->ctx->unreg_fd_cb(connection, sockfd, POLLOUT); connection->output_enabled = 0; } } return 0; }