예제 #1
0
파일: sim_slirp.c 프로젝트: ST3ALth/simh
int sim_slirp_send (SLIRP *slirp, const char *msg, size_t len, int flags)
{
struct slirp_write_request *request;
int wake_needed = 0;

/* Get a buffer */
pthread_mutex_lock (&slirp->write_buffer_lock);
if (NULL != (request = slirp->write_buffers))
    slirp->write_buffers = request->next;
pthread_mutex_unlock (&slirp->write_buffer_lock);
if (NULL == request)
    request = (struct slirp_write_request *)g_malloc(sizeof(*request));

/* Copy buffer contents */
request->len = len;
memcpy(request->msg, msg, len);

/* Insert buffer at the end of the write list (to make sure that */
/* packets make it to the wire in the order they were presented here) */
pthread_mutex_lock (&slirp->write_buffer_lock);
request->next = NULL;
if (slirp->write_requests) {
    struct slirp_write_request *last_request = slirp->write_requests;

    while (last_request->next) {
        last_request = last_request->next;
        }
    last_request->next = request;
    }
else {
    slirp->write_requests = request;
    wake_needed = 1;
    }
pthread_mutex_unlock (&slirp->write_buffer_lock);

if (wake_needed)
    sim_write_sock (slirp->db_chime, msg, 0);
return len;
}
예제 #2
0
/* cannot use sim_check_conn to check whether read will return an error */
static t_stat net_svc(UNIT *uptr) {
    int32 i, j, k, r;
    SOCKET s;
    static char svcBuffer[BUFFER_LENGTH];
    if (net_unit.flags & UNIT_ATT) { /* cannot remove due to following else */
        sim_activate(&net_unit, net_unit.wait);             /* continue poll */
        if (net_unit.flags & UNIT_SERVER) {
            for (i = 1; i <= MAX_CONNECTIONS; i++)
                if (serviceDescriptor[i].ioSocket == 0) {
                    s = sim_accept_conn(serviceDescriptor[1].masterSocket, NULL);
                    if (s != INVALID_SOCKET) {
                        serviceDescriptor[i].ioSocket = s;
                        sim_debug(ACCEPT_MSG, &net_dev, "NET: " ADDRESS_FORMAT " Accepted connection %i with socket %i.\n", PCX, i, s);
                    }
                }
        }
        else if (serviceDescriptor[0].ioSocket == 0) {
            serviceDescriptor[0].ioSocket = sim_connect_sock(net_unit.filename, "localhost", "3000");
            if (serviceDescriptor[0].ioSocket == INVALID_SOCKET)
                return SCPE_IOERR;
            printf("\rWaiting for server ... Type g<return> (possibly twice) when ready" NLP);
            return SCPE_STOP;
        }
        for (i = 0; i <= MAX_CONNECTIONS; i++)
            if (serviceDescriptor[i].ioSocket) {
                if (serviceDescriptor[i].inputSize < BUFFER_LENGTH) { /* there is space left in inputBuffer */
                    r = sim_read_sock(serviceDescriptor[i].ioSocket, svcBuffer,
                        BUFFER_LENGTH - serviceDescriptor[i].inputSize);
                    if (r == -1) {
                        sim_debug(DROP_MSG, &net_dev, "NET: " ADDRESS_FORMAT " Drop connection %i with socket %i.\n", PCX, i, serviceDescriptor[i].ioSocket);
                        sim_close_sock(serviceDescriptor[i].ioSocket, FALSE);
                        serviceDescriptor[i].ioSocket = 0;
                        serviceDescriptor_reset(i);
                        continue;
                    }
                    else {
                        for (j = 0; j < r; j++) {
                            serviceDescriptor[i].inputBuffer[serviceDescriptor[i].inputPosWrite++] = svcBuffer[j];
                            if (serviceDescriptor[i].inputPosWrite == BUFFER_LENGTH)
                                serviceDescriptor[i].inputPosWrite = 0;
                        }
                        serviceDescriptor[i].inputSize += r;
                    }
                }
                if (serviceDescriptor[i].outputSize > 0) { /* there is something to write in outputBuffer */
                    k = serviceDescriptor[i].outputPosRead;
                    for (j = 0; j < serviceDescriptor[i].outputSize; j++) {
                        svcBuffer[j] = serviceDescriptor[i].outputBuffer[k++];
                        if (k == BUFFER_LENGTH)
                            k = 0;
                    }
                    r = sim_write_sock(serviceDescriptor[i].ioSocket, svcBuffer, serviceDescriptor[i].outputSize);
                    if (r >= 0) {
                        serviceDescriptor[i].outputSize -= r;
                        serviceDescriptor[i].outputPosRead += r;
                        if (serviceDescriptor[i].outputPosRead >= BUFFER_LENGTH)
                            serviceDescriptor[i].outputPosRead -= BUFFER_LENGTH;
                    }
                    else
                        printf("write %i" NLP, r);
                }
            }
    }
    return SCPE_OK;
}