RESTYPE CreateNewResourceType(DeleteType deleteFunc) { RESTYPE next = lastResourceType + 1; DeleteType *funcs; if (next & lastResourceClass) return 0; funcs = (DeleteType *) fsrealloc(DeleteFuncs, (next + 1) * sizeof(DeleteType)); if (!funcs) return 0; lastResourceType = next; DeleteFuncs = funcs; DeleteFuncs[next] = deleteFunc; return next; }
Bool AddExtensionAlias(char *alias, ExtensionEntry *ext) { char *name; char **aliases; aliases = (char **) fsrealloc(ext->aliases, (ext->num_aliases + 1) * sizeof(char *)); if (!aliases) return FALSE; ext->aliases = aliases; name = (char *) fsalloc(strlen(alias) + 1); if (!name) return FALSE; strcpy(name, alias); ext->aliases[ext->num_aliases++] = name; return TRUE; }
int FlushClient( ClientPtr client, OsCommPtr oc, char *extraBuf, int extraCount, int padsize) { ConnectionOutputPtr oco = oc->output; int fd = oc->fd; struct iovec iov[3]; char padBuffer[3]; long written; long notWritten; long todo; if (!oco) return 0; written = 0; notWritten = oco->count + extraCount + padsize; todo = notWritten; while (notWritten) { long before = written; long remain = todo; int i = 0; long len; /*- * You could be very general here and have "in" and "out" iovecs and * write a loop without using a macro, but what the heck. This * translates to: * * how much of this piece is new? * if more new then we are trying this time, clamp * if nothing new * then bump down amount already written, for next piece * else put new stuff in iovec, will need all of next piece * * Note that todo had better be at least 1 or else we'll end up * writing 0 iovecs. */ #define InsertIOV(pointer, length) \ len = (length) - before; \ if (len > remain) \ len = remain; \ if (len <= 0) { \ before = (-len); \ } else { \ iov[i].iov_len = len; \ iov[i].iov_base = (pointer) + before; \ i++; \ remain -= len; \ before = 0; \ } InsertIOV((char *) oco->buf, oco->count); InsertIOV(extraBuf, extraCount); InsertIOV(padBuffer, padsize); errno = 0; if (oc->trans_conn && (len = _FontTransWritev(oc->trans_conn, iov, i)) >= 0) { written += len; notWritten -= len; todo = notWritten; } else if (ETEST(errno) #ifdef SUNSYSV /* check for another brain-damaged OS bug */ || (errno == 0) #endif #ifdef EMSGSIZE /* check for another brain-damaged OS bug */ || ((errno == EMSGSIZE) && (todo == 1)) #endif ) { FD_SET(fd, &ClientsWriteBlocked); AnyClientsWriteBlocked = TRUE; if (written < oco->count) { if (written > 0) { oco->count -= written; memmove( (char *) oco->buf, (char *) oco->buf + written, oco->count); written = 0; } } else { written -= oco->count; oco->count = 0; } /* grow buffer if necessary */ if (notWritten > oco->size) { unsigned char *obuf; obuf = (unsigned char *) fsrealloc(oco->buf, notWritten + OutputBufferSize); if (!obuf) { if (oc->trans_conn) _FontTransClose(oc->trans_conn); oc->trans_conn = NULL; MarkClientException(client); oco->count = 0; return -1; } oco->size = notWritten + OutputBufferSize; oco->buf = obuf; } if ((len = extraCount - written) > 0) { memmove( (char *) oco->buf + oco->count, extraBuf + written, len); } oco->count = notWritten; return extraCount; } #ifdef EMSGSIZE /* check for another brain-damaged OS bug */ else if (errno == EMSGSIZE) { todo >>= 1; } #endif else { if (oc->trans_conn)
Bool InsertFakeRequest(ClientPtr client, char *data, int count) { OsCommPtr oc = (OsCommPtr) client->osPrivate; ConnectionInputPtr oci = oc->input; int fd = oc->fd; fsReq *request; int gotnow, moveup; if (AvailableInput) { if (AvailableInput != oc) { register ConnectionInputPtr aci = AvailableInput->input; if (aci->size > BUFWATERMARK) { fsfree(aci->buffer); fsfree(aci); } else { aci->next = FreeInputs; FreeInputs = aci; } AvailableInput->input = (ConnectionInputPtr) NULL; } AvailableInput = (OsCommPtr) NULL; } if (!oci) { if ((oci = FreeInputs) != (ConnectionInputPtr) 0) FreeInputs = oci->next; else if (!(oci = AllocateInputBuffer())) return FALSE; oc->input = oci; } oci->bufptr += oci->lenLastReq; oci->lenLastReq = 0; gotnow = oci->bufcnt + oci->buffer - oci->bufptr; if ((gotnow + count) > oci->size) { char *ibuf; ibuf = (char *) fsrealloc(oci->buffer, gotnow + count); if (!ibuf) return FALSE; oci->size = gotnow + count; oci->buffer = ibuf; oci->bufptr = ibuf + oci->bufcnt - gotnow; } moveup = count - (oci->bufptr - oci->buffer); if (moveup > 0) { if (gotnow > 0) memmove( oci->bufptr + moveup, oci->bufptr, gotnow); oci->bufptr += moveup; oci->bufcnt += moveup; } memmove( oci->bufptr - count, data, count); oci->bufptr -= count; request = (fsReq *) oci->bufptr; gotnow += count; if ((gotnow >= SIZEOF(fsReq)) && (gotnow >= request_length(request, client))) FD_SET(fd, &ClientsWithInput); else yield_control_no_input(); return TRUE; }
int ReadRequest(ClientPtr client) { OsCommPtr oc; ConnectionInputPtr oci; fsReq *request; int fd, result, gotnow, needed = 0; if (client == NULL) return -1; oc = (OsCommPtr) client->osPrivate; if (oc == NULL) return -1; oci = oc->input; fd = oc->fd; if (oci != NULL && fd < 0) return -1; if (AvailableInput) { if (AvailableInput != oc) { ConnectionInputPtr aci = AvailableInput->input; if (aci->size > BUFWATERMARK) { fsfree(aci->buffer); fsfree(aci); } else { aci->next = FreeInputs; FreeInputs = aci; } AvailableInput->input = (ConnectionInputPtr) NULL; } AvailableInput = (OsCommPtr) NULL; } if (!oci) { if ((oci = FreeInputs ) != (ConnectionInputPtr) 0) { FreeInputs = oci->next; } else if (!(oci = AllocateInputBuffer())) { yield_control_death(); return -1; } oc->input = oci; } oci->bufptr += oci->lenLastReq; gotnow = oci->bufcnt + oci->buffer - oci->bufptr; request = (fsReq *) oci->bufptr; /* not enough for a request */ if ((gotnow < SIZEOF(fsReq)) || (gotnow < (needed = request_length(request, client)))) { oci->lenLastReq = 0; if ((gotnow < SIZEOF(fsReq)) || needed == 0) needed = SIZEOF(fsReq); else if (needed > MAXBUFSIZE) { yield_control_death(); return -1; } /* see if we need to shift up a partial request so the rest can fit */ if ((gotnow == 0) || ((oci->bufptr - oci->buffer + needed) > oci->size)) { if ((gotnow > 0) && (oci->bufptr != oci->buffer)) memmove( oci->buffer, oci->bufptr, gotnow); /* grow buffer if necessary */ if (needed > oci->size) { char *ibuf; ibuf = (char *) fsrealloc(oci->buffer, needed); if (!ibuf) { yield_control_death(); return -1; } oci->size = needed; oci->buffer = ibuf; } oci->bufptr = oci->buffer; oci->bufcnt = gotnow; } /* fill 'er up */ if (oc->trans_conn == NULL) { yield_control_death(); return -1; } result = _FontTransRead(oc->trans_conn, oci->buffer + oci->bufcnt, oci->size - oci->bufcnt); if (result <= 0) { #if !(defined(SVR4) && defined(i386) && !defined(sun)) if ((result < 0) && ETEST(errno)) { yield_control_no_input(); return 0; } else #endif { yield_control_death(); return -1; } } oci->bufcnt += result; gotnow += result; /* free up space after huge requests */ if ((oci->size > BUFWATERMARK) && (oci->bufcnt < BUFSIZE) && (needed < BUFSIZE)) { char *ibuf; ibuf = (char *) fsrealloc(oci->buffer, BUFSIZE); if (ibuf) { oci->size = BUFSIZE; oci->buffer = ibuf; oci->bufptr = ibuf + oci->bufcnt - gotnow; } } request = (fsReq *) oci->bufptr; if ((gotnow < SIZEOF(fsReq)) || (gotnow < (needed = request_length(request, client)))) { yield_control_no_input(); return 0; } } if (needed == 0) needed = SIZEOF(fsReq); oci->lenLastReq = needed; /* * Check to see if client has at least one whole request in the buffer. If * there is only a partial request, treat like buffer is empty so that * select() will be called again and other clients can get into the queue. */ if (gotnow >= needed + SIZEOF(fsReq)) { request = (fsReq *) (oci->bufptr + needed); if (gotnow >= needed + request_length(request, client)) FD_SET(fd, &ClientsWithInput); else yield_control_no_input(); } else { if (gotnow == needed) AvailableInput = oc; yield_control_no_input(); } if (++timesThisConnection >= MAX_TIMES_PER) yield_control(); client->requestBuffer = (pointer) oci->bufptr; return needed; }
ExtensionEntry * AddExtension( char *name, int num_events, int num_errors, int (*main_proc) (ClientPtr), int (*smain_proc) (ClientPtr), void (*closedown_proc) (struct _ExtensionEntry *), unsigned short (*minorop_proc) (ClientPtr)) { int i; ExtensionEntry *ext, **newexts; if (!main_proc || !smain_proc || !closedown_proc || !minorop_proc) return ((ExtensionEntry *) 0); if ((lastEvent + num_events > LAST_EVENT) || (unsigned) (lastError + num_errors > LAST_ERROR)) return ((ExtensionEntry *) 0); ext = (ExtensionEntry *) fsalloc(sizeof(ExtensionEntry)); if (!ext) return ((ExtensionEntry *) 0); ext->name = (char *) fsalloc(strlen(name) + 1); ext->num_aliases = 0; ext->aliases = (char **) NULL; if (!ext->name) { fsfree(ext); return ((ExtensionEntry *) 0); } strcpy(ext->name, name); i = NumExtensions; newexts = (ExtensionEntry **) fsrealloc(extensions, (i + 1) * sizeof(ExtensionEntry *)); if (!newexts) { fsfree(ext->name); fsfree(ext); return ((ExtensionEntry *) 0); } NumExtensions++; extensions = newexts; extensions[i] = ext; ext->index = i; ext->base = i + EXTENSION_BASE; ext->CloseDown = closedown_proc; ext->MinorOpcode = minorop_proc; ProcVector[i + EXTENSION_BASE] = main_proc; SwappedProcVector[i + EXTENSION_BASE] = smain_proc; if (num_events) { ext->eventBase = lastEvent; ext->eventLast = lastEvent + num_events; lastEvent += num_events; } else { ext->eventBase = 0; ext->eventLast = 0; } if (num_errors) { ext->errorBase = lastError; ext->errorLast = lastError + num_errors; lastError += num_errors; } else { ext->errorBase = 0; ext->errorLast = 0; } return ext; }