diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 14:43:48 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2006-11-26 14:43:48 +0000 |
commit | 022ad3d01558dbc1a59aefd36cd80afbf034d415 (patch) | |
tree | 7809beb94b49355c5b5d9d9abe4c1ccea5669463 /app/xfs/os | |
parent | 5a94fa48c7f977f6ae8745a7bb15a8be696be655 (diff) |
Importing from X.Org indiviual releases
Diffstat (limited to 'app/xfs/os')
-rw-r--r-- | app/xfs/os/access.c | 145 | ||||
-rw-r--r-- | app/xfs/os/config.c | 669 | ||||
-rw-r--r-- | app/xfs/os/config.h | 69 | ||||
-rw-r--r-- | app/xfs/os/configstr.h | 62 | ||||
-rw-r--r-- | app/xfs/os/connection.c | 567 | ||||
-rw-r--r-- | app/xfs/os/daemon.c | 138 | ||||
-rw-r--r-- | app/xfs/os/error.c | 210 | ||||
-rw-r--r-- | app/xfs/os/io.c | 706 | ||||
-rw-r--r-- | app/xfs/os/osdep.h | 134 | ||||
-rw-r--r-- | app/xfs/os/osglue.c | 384 | ||||
-rw-r--r-- | app/xfs/os/osinit.c | 64 | ||||
-rw-r--r-- | app/xfs/os/utils.c | 575 | ||||
-rw-r--r-- | app/xfs/os/waitfor.c | 231 | ||||
-rw-r--r-- | app/xfs/os/xfstrans.c | 33 |
14 files changed, 3987 insertions, 0 deletions
diff --git a/app/xfs/os/access.c b/app/xfs/os/access.c new file mode 100644 index 000000000..c50072848 --- /dev/null +++ b/app/xfs/os/access.c @@ -0,0 +1,145 @@ +/* $Xorg: access.c,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */ +/* + +Copyright 1990, 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, or Digital + * not be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, + * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/programs/xfs/os/access.c,v 3.7tsi Exp $ */ + +#include <X11/Xos.h> +#ifndef Lynx +#include <sys/param.h> +#include <sys/socket.h> +#else +#include <socket.h> +#endif +#include <netdb.h> +#include <netinet/in.h> +#include "clientstr.h" +#include "misc.h" +#include "site.h" +#include "accstr.h" +#include "osdep.h" +#include "osstruct.h" +#include "accstr.h" + +long MaxClients = DEFAULT_CLIENT_LIMIT; + +void +AccessSetConnectionLimit(int num) +{ + num++; /* take serverClient into account */ + if (num > MAXSOCKS) { + ErrorF("Client limit of %d too high; using default of %d\n", + num, DEFAULT_CLIENT_LIMIT); + return; + } + MaxClients = num; +} + +#ifdef NOTDEF +/* + * XXX + * + * needs massive amounts of OS-dependent work (big surprise) + * needs IPv6 support as well + */ +int +GetHostAddress(HostAddress *addr) +{ + char hname[64]; + struct hostent *hp; + + addr->addr_len = sizeof(struct in_addr); + addr->address = (pointer) fsalloc(addr->addr_len); + if (!addr->address) + return FSBadAlloc; + addr->type = HOST_AF_INET; + gethostname(hname, sizeof(hname)); + hp = gethostbyname(hname); + if (hp) { + memmove( (char *) addr->address, (char *) hp->h_addr, addr->addr_len); + } else { + fsfree((char *) addr->address); + return FSBadName; + } + return FSSuccess; +} +#endif + +/* ARGSUSED */ +int +CheckClientAuthorization( + ClientPtr client, + AuthPtr client_auth, + int *accept, + int *index, + int *size, + char **auth_data) +{ + OsCommPtr oc; + int i; + + /* now that it's connected, zero the connect time + so it doesn't get killed */ + oc = (OsCommPtr)client->osPrivate; + oc->conn_time = 0; + + *size = 0; + *accept = AuthSuccess; + + client->auth_generation++; + +#define AUTH1_NAME "hp-hostname-1" +#define AUTH2_NAME "hp-printername-1" + for (i = 0; i < *index; i++) + if ((client_auth[i].namelen == sizeof(AUTH1_NAME) && + !strcmp(client_auth[i].name, AUTH1_NAME)) || + (client_auth[i].namelen == sizeof(AUTH2_NAME) && + !strcmp(client_auth[i].name, AUTH2_NAME))) break; + if (i == *index) + i = 0; + else + i++; + *index = i; + return FSSuccess; +} diff --git a/app/xfs/os/config.c b/app/xfs/os/config.c new file mode 100644 index 000000000..e5dbc4801 --- /dev/null +++ b/app/xfs/os/config.c @@ -0,0 +1,669 @@ +/* $Xorg: config.c,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */ +/* +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, + * or Digital not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Network Computing Devices, or Digital + * make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $NCDXorg: @(#)config.c,v 4.6 1991/07/09 14:08:09 lemke Exp $ + * + */ +/* $XFree86: xc/programs/xfs/os/config.c,v 3.15 2002/05/31 18:46:12 dawes Exp $ */ + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <X11/Xtrans/Xtrans.h> +#include <X11/Xos.h> +#include "misc.h" +#include "configstr.h" +#include "osdep.h" +#include "globals.h" +#include "access.h" +#include "difsutils.h" +#ifdef FONTCACHE +#include <X11/extensions/fontcacheP.h> +#endif +#include <X11/fonts/fontutil.h> +#include "difs.h" + +extern int portFromCmdline; + +static char *font_catalogue = NULL; + +static char *config_set_int(ConfigOptionPtr parm, char *val); +static char *config_set_bool(ConfigOptionPtr parm, char *val); +static char *config_set_catalogue(ConfigOptionPtr parm, char *val); +static char *config_set_glyph_caching_mode(ConfigOptionPtr parm, char *val); +static char *config_set_list(ConfigOptionPtr parm, char *val); +static char *config_set_file(ConfigOptionPtr parm, char *val); +static char *config_set_resolutions(ConfigOptionPtr parm, char *val); +static char *config_set_ignored_transports(ConfigOptionPtr parm, char *val); +static char *config_set_snf_format(ConfigOptionPtr parm, char *val); + +/* these need to be in lower case and alphabetical order so a + * binary search lookup can be used + */ +static ConfigOptionRec config_options[] = { + {"alternate-servers", config_set_list}, +#ifdef FONTCACHE + {"cache-balance", config_set_int}, + {"cache-hi-mark", config_set_int}, + {"cache-low-mark", config_set_int}, +#endif + {"catalogue", config_set_catalogue}, + {"client-limit", config_set_int}, + {"clone-self", config_set_bool}, + {"default-point-size", config_set_int}, + {"default-resolutions", config_set_resolutions}, + {"deferglyphs", config_set_glyph_caching_mode}, + {"error-file", config_set_file}, + {"no-listen", config_set_ignored_transports}, + {"port", config_set_int}, + {"server-number", config_set_int}, + {"snf-format", config_set_snf_format}, + {"trusted-clients", config_set_list}, + {"use-syslog", config_set_bool}, + {(char *) 0, 0}, +}; + +char *ConfigErrors[] = { + "", + "CONFIG: insufficient memory to load configuration file \"%s\"\n", + "CONFIG: can't open configuration file \"%s\"\n", + "CONFIG: error reading configuration file \"%s\"\n", + "CONFIG: bad value \"%s\" for parameter \"%s\"\n", + "CONFIG: unknown parameter \"%s\"\n", + "CONFIG: missing '=' after parameter \"%s\"\n", + "CONFIG: value out of range for parameter \"%s\"\n", + "CONFIG: syntax error near parameter \"%s\"\n", + "CONFIG: missing value for parameter \"%s\"\n", + "CONFIG: extra value for parameter \"%s\"\n", +}; + +#define iseol(c) ((c) == '\n' || (c) == '\r' || (c) == '\f') +#define skip_whitespace(c) while(isspace(*(c)) || *(c) == ',') (c)++; +#define skip_val(c) while(!isspace(*(c)) && *(c) != ',' && *(c) != '\0')\ + (c) ++; +#define skip_list_val(c) while(!isspace(*(c)) && *(c) != '\0')\ + (c) ++; +#define blank_comment(c) while (!iseol(*(c)) && *(c) != '\0') \ + *(c)++= ' '; + +static char * +next_assign(char *c) +{ + int nesting = 0; + + while (*c != '\0') { + if (*c == '(') + nesting++; + else if (*c == ')') + nesting--; + else if (*c == '=' && nesting == 0) + return c; + c++; + } + return (char *) 0; +} + +static void +strip_comments(char *data) +{ + char *c; + + c = data; + while ((c = strchr(c, '#')) != NULL) { + if (c == data || *(c - 1) != '\\') { + blank_comment(c); + } else { + c++; + } + } +} + +static ConfigOptionPtr +match_param_name(char *name) +{ + int pos, + rc, + low, + high; + + low = 0; + high = sizeof(config_options) / sizeof(ConfigOptionRec) - 2; + pos = high >> 1; + + while (low <= high) { + rc = strcmp(name, config_options[pos].parm_name); + if (rc == 0) { + return &config_options[pos]; + } else if (rc < 0) { + high = pos - 1; + } else { + low = pos + 1; + } + pos = ((high + low) >> 1); + } + return 0; +} + +static int +parse_config(char *data) +{ + char *c, + *val = NULL, + *next_eq, + *consumed, + *p; + char param_name[64]; + Bool equals_missing; + ConfigOptionPtr param; + + c = data; + skip_whitespace(c); + + while (*c != '\0') { + equals_missing = FALSE; + + /* get parm name in lower case */ + p = c; + while (isalnum(*c) || *c == '-') { + if (isupper(*c)) + *c = tolower(*c); + c++; + } + memmove( param_name, p, min(sizeof(param_name), (int) (c - p))); + param_name[(int) (c - p)] = '\0'; + + /* check for junk */ + if (!isspace(*c) && *c != '=') { + ErrorF(ConfigErrors[CONFIG_ERR_SYNTAX], param_name); + /* eat garbage */ + while (!isspace(*c) && *c != '=' && *c != '\0') + c++; + } + skip_whitespace(c); + if (*c != '=') { + ErrorF(ConfigErrors[CONFIG_ERR_NOEQUALS], param_name); + equals_missing = TRUE; + } else { + c++; + } + + skip_whitespace(c); + + /* find next assignment to guess where the value ends */ + if ((next_eq = next_assign(c)) != NULL) { + /* back up over whitespace */ + for (val = next_eq - 1; val >= c && + (isspace(*val) || *val == ','); + val--); + + /* back over parm name */ + for (; val >= c && (isalnum(*val) || *val == '-'); val--); + + if (val <= c) { + /* no value, ignore */ + ErrorF(ConfigErrors[CONFIG_ERR_NOVALUE], param_name); + continue; + } + *val = '\0'; + } else if (*c == '\0') { + /* no value, ignore */ + ErrorF(ConfigErrors[CONFIG_ERR_NOVALUE], param_name); + continue; + } + /* match parm name */ + if (equals_missing) { + equals_missing = FALSE; + } else if ((param = match_param_name(param_name)) == NULL) { + ErrorF(ConfigErrors[CONFIG_ERR_UNKNOWN], param_name); + } else { + consumed = (param->set_func) (param, c); + + skip_whitespace(consumed); + if (*consumed != '\0') { + ErrorF(ConfigErrors[CONFIG_ERR_EXTRAVALUE], + param_name); + } + } + + if (next_eq != NULL) + c = val + 1; + else /* last setting */ + break; + } + return FSSuccess; +} + +/* + * handles anything that should be set once the file is parsed + */ +void +SetConfigValues(void) +{ + int err, + num; + + err = SetFontCatalogue(font_catalogue, &num); + if (err != FSSuccess) { + FatalError("element #%d (starting at 0) of font path is bad or has a bad font:\n\"%s\"\n", + num, font_catalogue); + } + InitErrors(); + fsfree((char *) font_catalogue); + font_catalogue = NULL; +} + +#ifdef __UNIXOS2__ +char *__XFSRedirRoot(char *fname) +{ + static char redirname[300]; /* enough for long filenames */ + char *root; + + /* if name does not start with /, assume it is not root-based */ + if (fname==0 || !(fname[0]=='/' || fname[0]=='\\')) + return fname; + + root = (char*)getenv("X11ROOT"); + if (root==0 || + (fname[1]==':' && isalpha(fname[0])) || + ((strlen(fname)+strlen(root)+2) > 300)) + return fname; + sprintf(redirname,"%s%s",root,fname); + return redirname; +} +#endif + +int +ReadConfigFile(char *filename) +{ + FILE *fp; + int ret; + int len; + char *data; + + data = (char *) fsalloc(CONFIG_MAX_FILESIZE); + if (!data) { + ErrorF(ConfigErrors[CONFIG_ERR_MEMORY], filename); + return FSBadAlloc; + } +#ifdef __UNIXOS2__ + filename = __XFSRedirRoot(filename); +#endif + if ((fp = fopen(filename, "r")) == NULL) { + fsfree(data); + ErrorF(ConfigErrors[CONFIG_ERR_OPEN], filename); + return FSBadName; + } + ret = fread(data, sizeof(char), CONFIG_MAX_FILESIZE, fp); + if (ret <= 0) { + fsfree(data); + (void) fclose(fp); + ErrorF(ConfigErrors[CONFIG_ERR_READ], filename); + return FSBadName; + } + len = ftell(fp); + len = min(len, CONFIG_MAX_FILESIZE); + data[len] = '\0'; /* NULL terminate the data */ + + (void) fclose(fp); + + strip_comments(data); + ret = parse_config(data); + + fsfree(data); + + return ret; +} + +struct nameVal { + char *name; + int val; +}; + +static char * +config_parse_nameVal ( + char *c, + int *ret, + int *pval, + struct nameVal *name_val) +{ + char *start, + t; + int i, + len; + + start = c; + skip_val(c); + t = *c; + *c = '\0'; + len = c - start; + + for (i = 0; name_val[i].name; i++) { + if (!strncmpnocase(start, name_val[i].name, len)) { + *pval = name_val[i].val; + *ret = 0; + *c = t; + return c; + } + } + ErrorF(ConfigErrors[CONFIG_ERR_VALUE], start); + *c = t; + *ret = -1; + return c; +} + +static char * +config_parse_bool ( + char *c, + int *ret, + Bool *pval) +{ + static struct nameVal bool_val[] = { + { "yes", TRUE }, + { "on", TRUE }, + { "1", TRUE }, + { "true", TRUE }, + { "no", FALSE }, + { "off", FALSE }, + { "0", FALSE }, + { "false", FALSE }, + { (char *) 0, 0 }, + }; + return config_parse_nameVal (c, ret, pval, bool_val); +} + +static char * +config_parse_int( + char *c, + int *ret, + int *pval) +{ + char *start, + t; + + start = c; + while (*c != '\0' && !isspace(*c) && *c != ',') { + if (!isdigit(*c)) { /* error */ + skip_val(c); + t = *c; + *c = '\0'; + ErrorF(ConfigErrors[CONFIG_ERR_VALUE], start); + *ret = -1; + *c = t; + return c; + } + c++; + } + t = *c; + *c = '\0'; + *ret = 0; + *pval = atoi(start); + *c = t; + return c; +} + + +/* config option sets */ +/* these have to know how to do the real work and tweak the proper things */ +static char * +config_set_int( + ConfigOptionPtr parm, + char *val) +{ + int ival, + ret; + + val = config_parse_int(val, &ret, &ival); + if (ret == -1) + return val; + + /* now do individual attribute checks */ + if (!strcmp(parm->parm_name, "port") && !portFromCmdline) { + ListenPort = ival; + } else if (!strcmp(parm->parm_name, "client-limit")) { + AccessSetConnectionLimit(ival); + } else if (!strcmp(parm->parm_name, "default-point-size")) { + SetDefaultPointSize(ival); + } +#ifdef FONTCACHE + else if (!strcmp(parm->parm_name, "cache-balance")) { + cacheSettings.balance = ival; + } else if (!strcmp(parm->parm_name, "cache-hi-mark")) { + cacheSettings.himark = ival * 1024; + } else if (!strcmp(parm->parm_name, "cache-low-mark")) { + cacheSettings.lowmark = ival * 1024; + } +#endif + return val; +} + +static char * +config_set_bool( + ConfigOptionPtr parm, + char *val) +{ + int + ret; + Bool bval; + + val = config_parse_bool(val, &ret, &bval); + if (ret == -1) + return val; + + /* now do individual attribute checks */ + if (!strcmp(parm->parm_name, "use-syslog")) { + UseSyslog = bval; + } else if (!strcmp(parm->parm_name, "clone-self")) { + CloneSelf = bval; + } + return val; +} + +static char * +config_set_file( + ConfigOptionPtr parm, + char *val) +{ + char *start = val, + t; + + skip_val(val); + t = *val; + *val = '\0'; + if (!strcmp(parm->parm_name, "error-file")) { +#ifndef __UNIXOS2__ + memmove( ErrorFile, start, val - start + 1); +#else + strcpy( ErrorFile, __XFSRedirRoot(start)); +#endif + } + *val = t; + return val; +} + +static char * +config_set_catalogue( + ConfigOptionPtr parm, + char *val) +{ + char *b; + + if (!strcmp(parm->parm_name, "catalogue")) { + /* stash it for later */ + fsfree((char *) font_catalogue); /* dump any previous one */ + b = font_catalogue = (char *) fsalloc(strlen(val) + 1); + if (!font_catalogue) + FatalError("insufficent memory for font catalogue\n"); + while (*val) { /* remove all the gunk */ + if (!isspace(*val)) { + *b++ = *val; + } + val++; + } + *b = '\0'; + } + return val; +} + +static char * +config_set_list( + ConfigOptionPtr parm, + char *val) +{ + char *start = val, + t; + + skip_list_val(val); + t = *val; + *val = '\0'; + if (!strcmp(parm->parm_name, "alternate-servers")) { + SetAlternateServers(start); + } + *val = t; + return val; +} + +static char * +config_set_ignored_transports( + ConfigOptionPtr parm, + char *val) +{ + char *start = val, + t; + + skip_list_val(val); + t = *val; + *val = '\0'; + _FontTransNoListen(start); + *val = t; + return val; +} + +static char * +config_set_glyph_caching_mode( + ConfigOptionPtr parm, + char *val) +{ + char *start = val, + t; + + skip_list_val(val); + t = *val; + *val = '\0'; + if (!strcmp(parm->parm_name, "deferglyphs")) { + ParseGlyphCachingMode(start); + } + *val = t; + return val; +} + +static char * +config_set_resolutions( + ConfigOptionPtr parm, + char *val) +{ + char *start = val, + t; + int err; + + skip_list_val(val); + t = *val; + *val = '\0'; + if (!strcmp(parm->parm_name, "default-resolutions")) { + err = SetDefaultResolutions(start); + if (err != FSSuccess) { + FatalError("bogus resolution list \"%s\"\n", start); + } + } + *val = t; + return val; +} + + +static char * +config_parse_endian( + char *c, + int *ret, + int *pval) +{ + static struct nameVal endian_val[] = { + { "lsb", LSBFirst }, + { "little", LSBFirst }, + { "lsbfirst", LSBFirst }, + { "msb", MSBFirst }, + { "big", MSBFirst }, + { "msbfirst", MSBFirst }, + { (char *) 0, 0 }, + }; + return config_parse_nameVal (c, ret, pval, endian_val); +} + +/* ARGSUSED */ +static char * +config_set_snf_format ( + ConfigOptionPtr parm, + char *val) +{ + int bit, byte, glyph, scan; + int ret; + + val = config_parse_endian (val, &ret, &bit); + if (ret == -1) + return val; + skip_whitespace (val); + val = config_parse_endian (val, &ret, &byte); + if (ret == -1) + return val; + skip_whitespace (val); + val = config_parse_int (val, &ret, &glyph); + if (ret == -1) + return val; + skip_whitespace (val); + val = config_parse_int (val, &ret, &scan); + if (ret == -1) + return val; + SnfSetFormat (bit, byte, glyph, scan); + return val; +} diff --git a/app/xfs/os/config.h b/app/xfs/os/config.h new file mode 100644 index 000000000..ba6db45cb --- /dev/null +++ b/app/xfs/os/config.h @@ -0,0 +1,69 @@ +/* $Xorg: config.h,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */ +/* +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, + * or Digital not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Network Computing Devices, or Digital + * make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * @(#)config.h 4.1 91/05/02 + * + */ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +/* max size in bytes of config file */ +#define CONFIG_MAX_FILESIZE 32767 + +/* error codes */ +/* these should be in the same order as the error strings in config.c */ +#define CONFIG_ERR_MEMORY 1 +#define CONFIG_ERR_OPEN 2 +#define CONFIG_ERR_READ 3 +#define CONFIG_ERR_VALUE 4 +#define CONFIG_ERR_UNKNOWN 5 +#define CONFIG_ERR_NOEQUALS 6 +#define CONFIG_ERR_RANGE 7 +#define CONFIG_ERR_SYNTAX 8 +#define CONFIG_ERR_NOVALUE 9 +#define CONFIG_ERR_EXTRAVALUE 10 +#endif /* _CONFIG_H_ */ diff --git a/app/xfs/os/configstr.h b/app/xfs/os/configstr.h new file mode 100644 index 000000000..9c1a8afa1 --- /dev/null +++ b/app/xfs/os/configstr.h @@ -0,0 +1,62 @@ +/* $Xorg: configstr.h,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */ +/* +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, + * or Digital not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Network Computing Devices, or Digital + * make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, DIGITAL OR MIT BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * @(#)configstr.h 4.1 91/05/02 + * + */ +/* $XFree86: xc/programs/xfs/os/configstr.h,v 1.4 2001/01/17 23:45:32 dawes Exp $ */ +#ifndef _CONFIGSTR_H_ +#define _CONFIGSTR_H_ +#include "config.h" + +typedef struct _config_options ConfigOptionRec, *ConfigOptionPtr; + +struct _config_options { + char *parm_name; + char *(*set_func) (ConfigOptionPtr, char *); +}; + +#endif /* _CONFIGSTR_H_ */ diff --git a/app/xfs/os/connection.c b/app/xfs/os/connection.c new file mode 100644 index 000000000..2035312c7 --- /dev/null +++ b/app/xfs/os/connection.c @@ -0,0 +1,567 @@ +/* $Xorg: connection.c,v 1.5 2001/02/09 02:05:44 xorgcvs Exp $ */ +/* + * handles connections + */ +/* + +Copyright 1990, 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, or Digital + * not be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, + * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, or Digital + * not be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, + * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/programs/xfs/os/connection.c,v 3.25tsi Exp $ */ + +#include <stdlib.h> +#include <X11/Xtrans/Xtrans.h> +#include <stdlib.h> +#include "misc.h" +#include <stdio.h> +#include <errno.h> +#include <X11/Xos.h> +#ifndef Lynx +#include <sys/param.h> +#include <sys/socket.h> +#ifndef __UNIXOS2__ +#include <sys/uio.h> +#endif +#else +#include <socket.h> +#include <uio.h> +#endif +#include <signal.h> + +#include <X11/fonts/FS.h> +#include <X11/fonts/FSproto.h> +#include "clientstr.h" +#include "X11/Xpoll.h" +#include "osdep.h" +#include "globals.h" +#include "osstruct.h" +#include "servermd.h" +#include "dispatch.h" +#include "fsevents.h" + +#ifdef __UNIXOS2__ +#define _NFILE OPEN_MAX +#define select(n,r,w,x,t) os2PseudoSelect(n,r,w,x,t) +#endif + + +int ListenPort = DEFAULT_FS_PORT; /* port to listen on */ +int lastfdesc; + +fd_set WellKnownConnections; +fd_set AllSockets; +fd_set AllClients; +fd_set LastSelectMask; +fd_set ClientsWithInput; +fd_set ClientsWriteBlocked; +fd_set OutputPending; +long OutputBufferSize = BUFSIZE; + +Bool NewOutputPending; +Bool AnyClientsWriteBlocked; + +int ConnectionTranslation[MAXSOCKS]; + +XtransConnInfo *ListenTransConns = NULL; +int *ListenTransFds = NULL; +int ListenTransCount; + + +static void error_conn_max(XtransConnInfo trans_conn); +static void close_fd(OsCommPtr oc); + + +static XtransConnInfo +lookup_trans_conn (int fd) +{ + if (ListenTransFds) + { + int i; + for (i = 0; i < ListenTransCount; i++) + if (ListenTransFds[i] == fd) + return ListenTransConns[i]; + } + + return (NULL); +} + +void +StopListening(void) +{ + int i; + + for (i = 0; i < ListenTransCount; i++) + { + FD_CLR (ListenTransFds[i], &AllSockets); + _FontTransCloseForCloning (ListenTransConns[i]); + } + + free ((char *) ListenTransFds); + free ((char *) ListenTransConns); + + ListenTransFds = NULL; + ListenTransConns = NULL; +} + +/* + * creates the sockets for listening to clients + * + * only called when server first started + */ +void +CreateSockets(int old_listen_count, OldListenRec *old_listen) +{ + int i; + + FD_ZERO(&AllSockets); + FD_ZERO(&AllClients); + FD_ZERO(&LastSelectMask); + FD_ZERO(&ClientsWithInput); + FD_ZERO(&WellKnownConnections); + + for (i = 0; i < MAXSOCKS; i++) + ConnectionTranslation[i] = 0; + +#ifdef XNO_SYSCONF /* should only be on FreeBSD 1.x and NetBSD 0.x */ +#undef _SC_OPEN_MAX +#endif +#ifdef _SC_OPEN_MAX + lastfdesc = sysconf(_SC_OPEN_MAX) - 1; +#else +#if defined(hpux) || defined(__UNIXOS2__) + lastfdesc = _NFILE - 1; +#else + lastfdesc = getdtablesize() - 1; +#endif /* hpux */ +#endif + + if (lastfdesc > MAXSOCKS) { + lastfdesc = MAXSOCKS; + } + + if (old_listen_count > 0) { + + /* + * The font server cloned itself. Re-use previously opened + * transports for listening. + */ + + ListenTransConns = (XtransConnInfo *) malloc ( + old_listen_count * sizeof (XtransConnInfo)); + + ListenTransFds = (int *) malloc (old_listen_count * sizeof (int)); + + ListenTransCount = 0; + + for (i = 0; i < old_listen_count; i++) + { + char portnum[10]; + + if (old_listen[i].portnum != ListenPort) + continue; /* this should never happen */ + else + sprintf (portnum, "%d", old_listen[i].portnum); + + if ((ListenTransConns[ListenTransCount] = + _FontTransReopenCOTSServer (old_listen[i].trans_id, + old_listen[i].fd, portnum)) != NULL) + { + ListenTransFds[ListenTransCount] = old_listen[i].fd; + FD_SET (old_listen[i].fd, &WellKnownConnections); + + NoticeF("reusing existing file descriptor %d\n", + old_listen[i].fd); + + ListenTransCount++; + } + } + } else { + char port[20]; + int partial; + + sprintf (port, "%d", ListenPort); + + if ((_FontTransMakeAllCOTSServerListeners (port, &partial, + &ListenTransCount, &ListenTransConns) >= 0) && + (ListenTransCount >= 1)) + { + ListenTransFds = (int *) malloc (ListenTransCount * sizeof (int)); + + for (i = 0; i < ListenTransCount; i++) + { + int fd = _FontTransGetConnectionNumber (ListenTransConns[i]); + + ListenTransFds[i] = fd; + FD_SET (fd, &WellKnownConnections); + } + } + } + + if (! XFD_ANYSET(&WellKnownConnections)) + FatalError("cannot establish any listening sockets\n"); + + /* set up all the signal handlers */ + signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, AutoResetServer); + signal(SIGINT, GiveUp); + signal(SIGTERM, GiveUp); + signal(SIGUSR1, ServerReconfig); + signal(SIGUSR2, ServerCacheFlush); + signal(SIGCHLD, CleanupChild); + + XFD_COPYSET (&WellKnownConnections, &AllSockets); +} + +/* + * called when server cycles + */ +void +ResetSockets(void) +{ +} + +void +CloseSockets(void) +{ + int i; + + for (i = 0; i < ListenTransCount; i++) + _FontTransClose (ListenTransConns[i]); +} + +/* + * accepts new connections + */ +void +MakeNewConnections(void) +{ + fd_mask readyconnections; + int curconn; + int newconn; + long connect_time; + int i; + ClientPtr client; + OsCommPtr oc; + fd_set tmask; + + XFD_ANDSET (&tmask, &LastSelectMask, &WellKnownConnections); + readyconnections = tmask.fds_bits[0]; + if (!readyconnections) + return; + connect_time = GetTimeInMillis(); + + /* kill off stragglers */ + for (i = MINCLIENT; i < currentMaxClients; i++) { + if ((client = clients[i]) != NullClient) { + oc = (OsCommPtr) client->osPrivate; + if ((oc && (oc->conn_time != 0) && + (connect_time - oc->conn_time) >= TimeOutValue) || + ((client->noClientException != FSSuccess) && + (client->clientGone != CLIENT_GONE))) + CloseDownClient(client); + } + } + + while (readyconnections) { + XtransConnInfo trans_conn, new_trans_conn; + int status; + + curconn = ffs(readyconnections) - 1; + readyconnections &= ~(1 << curconn); + + if ((trans_conn = lookup_trans_conn (curconn)) == NULL) + continue; + + if ((new_trans_conn = _FontTransAccept (trans_conn, &status)) == NULL) + continue; + + newconn = _FontTransGetConnectionNumber (new_trans_conn); + + _FontTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1); + + oc = (OsCommPtr) fsalloc(sizeof(OsCommRec)); + if (!oc) { + fsfree(oc); + error_conn_max(new_trans_conn); + _FontTransClose(new_trans_conn); + continue; + } + FD_SET(newconn, &AllClients); + FD_SET(newconn, &AllSockets); + oc->fd = newconn; + oc->trans_conn = new_trans_conn; + oc->input = (ConnectionInputPtr) NULL; + oc->output = (ConnectionOutputPtr) NULL; + oc->conn_time = connect_time; + + if ((newconn < lastfdesc) && + (client = NextAvailableClient((pointer) oc))) { + ConnectionTranslation[newconn] = client->index; + } else { + error_conn_max(new_trans_conn); + close_fd(oc); + } + } +} + +#define NOROOM "maximum number of clients reached" + +static void +error_conn_max(XtransConnInfo trans_conn) +{ + int fd = _FontTransGetConnectionNumber (trans_conn); + fsConnSetup conn; + char pad[3]; + char byteOrder = 0; + int whichbyte = 1; + struct timeval waittime; + fd_set mask; + + + waittime.tv_usec = BOTIMEOUT / MILLI_PER_SECOND; + waittime.tv_usec = (BOTIMEOUT % MILLI_PER_SECOND) * + (1000000 / MILLI_PER_SECOND); + FD_ZERO(&mask); + FD_SET(fd, &mask); + (void) Select(fd + 1, &mask, NULL, NULL, &waittime); + /* try to read the byteorder of the connection */ + (void) _FontTransRead(trans_conn, &byteOrder, 1); + if ((byteOrder == 'l') || (byteOrder == 'B')) { + int num_alts; + AlternateServerPtr altservers, + as; + int i, + altlen = 0; + + num_alts = ListAlternateServers(&altservers); + conn.status = AuthDenied; + conn.major_version = FS_PROTOCOL; + conn.minor_version = FS_PROTOCOL_MINOR; + conn.num_alternates = num_alts; + for (i = 0, as = altservers; i < num_alts; i++, as++) { + altlen += (2 + as->namelen + 3) >> 2; + } + conn.alternate_len = altlen; + /* blow off the auth info */ + conn.auth_index = 0; + conn.auth_len = 0; + + if (((*(char *) &whichbyte) && (byteOrder == 'B')) || + (!(*(char *) &whichbyte) && (byteOrder == 'l'))) { + conn.status = lswaps(conn.status); + conn.major_version = lswaps(conn.major_version); + conn.minor_version = lswaps(conn.minor_version); + conn.alternate_len = lswaps(conn.alternate_len); + } + (void) _FontTransWrite(trans_conn, + (char *) &conn, SIZEOF(fsConnSetup)); + /* dump alternates */ + for (i = 0, as = altservers; i < num_alts; i++, as++) { + (void) _FontTransWrite(trans_conn, + (char *) as, 2); /* XXX */ + (void) _FontTransWrite(trans_conn, + (char *) as->name, as->namelen); + altlen = 2 + as->namelen; + /* pad it */ + if (altlen & 3) + (void) _FontTransWrite(trans_conn, + (char *) pad, ((4 - (altlen & 3)) & 3)); + } + } +} + +static void +close_fd(OsCommPtr oc) +{ + int fd = oc->fd; + + if (oc->trans_conn) + _FontTransClose(oc->trans_conn); + FreeOsBuffers(oc); + FD_CLR(fd, &AllSockets); + FD_CLR(fd, &AllClients); + FD_CLR(fd, &ClientsWithInput); + FD_CLR(fd, &ClientsWriteBlocked); + if (!XFD_ANYSET(&ClientsWriteBlocked)) + AnyClientsWriteBlocked = FALSE; + FD_CLR(fd, &OutputPending); + fsfree(oc); +} + +void +CheckConnections(void) +{ + fd_set mask; + fd_set tmask; + int curclient; + int i; + struct timeval notime; + int r; + + notime.tv_sec = 0; + notime.tv_usec = 0; + + XFD_COPYSET(&AllClients, &mask); + for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) { + while (mask.fds_bits[i]) { + curclient = ffs(mask.fds_bits[i]) - 1 + (i << 5); + FD_ZERO(&tmask); + FD_SET(curclient, &tmask); + r = Select(curclient + 1, &tmask, NULL, NULL, ¬ime); + if (r < 0) + CloseDownClient(clients[ConnectionTranslation[curclient]]); + FD_CLR(curclient, &mask); + } + } +} + +void +CloseDownConnection(ClientPtr client) +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + + if (oc->output && oc->output->count) + FlushClient(client, oc, (char *) NULL, 0, 0); + ConnectionTranslation[oc->fd] = 0; + close_fd(oc); + client->osPrivate = (pointer) NULL; +} + + +/**************** + * IgnoreClient + * Removes one client from input masks. + * Must have cooresponding call to AttendClient. + ****************/ + +static fd_set IgnoredClientsWithInput; + +void +IgnoreClient(ClientPtr client) +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + int connection = oc->fd; + + if (FD_ISSET(connection, &ClientsWithInput)) + FD_SET(connection, &IgnoredClientsWithInput); + else + FD_CLR(connection, &IgnoredClientsWithInput); + FD_CLR(connection, &ClientsWithInput); + FD_CLR(connection, &AllSockets); + FD_CLR(connection, &AllClients); + FD_CLR(connection, &LastSelectMask); + isItTimeToYield = TRUE; +} + +/**************** + * AttendClient + * Adds one client back into the input masks. + ****************/ + +void +AttendClient(ClientPtr client) +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + int connection = oc->fd; + + FD_SET(connection, &AllClients); + FD_SET(connection, &AllSockets); + FD_SET(connection, &LastSelectMask); + if (FD_ISSET(connection, &IgnoredClientsWithInput)) + FD_SET(connection, &ClientsWithInput); +} + +/* + * figure out which clients need to be toasted + */ +void +ReapAnyOldClients(void) +{ + int i; + long cur_time = GetTimeInMillis(); + ClientPtr client; + +#ifdef DEBUG + fprintf(stderr, "looking for clients to reap\n"); +#endif + + for (i = MINCLIENT; i < currentMaxClients; i++) { + client = clients[i]; + if (client) { + if ((cur_time - client->last_request_time) >= ReapClientTime) { + if (client->clientGone == CLIENT_AGED) { + client->clientGone = CLIENT_TIMED_OUT; + +#ifdef DEBUG + fprintf(stderr, "reaping client #%d\n", i); +#endif + + CloseDownClient(client); + } else { + client->clientGone = CLIENT_AGED; + SendKeepAliveEvent(client); + } + } + } + } +} diff --git a/app/xfs/os/daemon.c b/app/xfs/os/daemon.c new file mode 100644 index 000000000..2b23de328 --- /dev/null +++ b/app/xfs/os/daemon.c @@ -0,0 +1,138 @@ +/* + +Copyright (c) 1988 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ +/* $XFree86: xc/programs/xfs/os/daemon.c,v 1.12 2002/10/20 21:42:50 tsi Exp $ */ + +#include <X11/Xos.h> +#include <sys/types.h> +#include <errno.h> +#include <stdlib.h> + +#if defined(USG) +# include <termios.h> +#else +# include <sys/ioctl.h> +#endif +#ifdef hpux +# include <sys/ptyio.h> +#endif + +#ifdef X_NOT_POSIX +# define Pid_t int +#else +# define Pid_t pid_t +#endif + +#include "os.h" + +#if defined(__GLIBC__) || defined(CSRG_BASED) +#define HAS_DAEMON +#endif + +#ifndef X_NOT_POSIX +#define HAS_SETSID +#endif + +#ifndef HAS_SETSID + +#define setsid() MySetsid() + +static Pid_t +MySetsid(void) +{ +#if defined(TIOCNOTTY) || defined(TCCLRCTTY) || defined(TIOCTTY) + int fd; +#endif + int stat; + + fd = open("/dev/tty", O_RDWR); + if (fd >= 0) { +#if defined(USG) && defined(TCCLRCTTY) + int zero = 0; + (void) ioctl (fd, TCCLRCTTY, &zero); +#elif (defined(SYSV) || defined(SVR4)) && defined(TIOCTTY) + int zero = 0; + (void) ioctl (i, TIOCTTY, &zero); +#elif defined(TIOCNOTTY) + (void) ioctl (i, TIOCNOTTY, (char *) 0); /* detach, BSD style */ +#endif + close(fd); + } + +#if defined(SYSV) || defined(__QNXNTO__) + return setpgrp(); +#else + return setpgid(0, getpid()); +#endif +} + +#endif /* !HAS_SETSID */ + + +/* detach */ +void +BecomeDaemon () +{ + /* If our C library has the daemon() function, just use it. */ +#ifdef HAS_DAEMON + daemon (0, 0); +#else + + switch (fork()) { + case -1: + /* error */ + FatalError("daemon fork failed, %s\n", strerror(errno)); + break; + case 0: + /* child */ + break; + default: + /* parent */ + exit(0); + } + + if (setsid() == -1) + FatalError("setting session id for daemon failed: %s\n", + strerror(errno)); + + chdir("/"); + + close (0); + close (1); + close (2); + + /* + * Set up the standard file descriptors. + */ + (void) open ("/dev/null", O_RDWR); + (void) dup2 (0, 1); + (void) dup2 (0, 2); + +#endif /* HAS_DAEMON */ +} diff --git a/app/xfs/os/error.c b/app/xfs/os/error.c new file mode 100644 index 000000000..8c72a657c --- /dev/null +++ b/app/xfs/os/error.c @@ -0,0 +1,210 @@ +/* $Xorg: error.c,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */ +/* + * error message handling + */ +/* +Copyright 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * Copyright 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, or Digital + * not be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES, DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETWORK COMPUTING DEVICES, + * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: error.c,v 1.11 2002/10/15 01:45:03 dawes Exp $ */ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <X11/Xos.h> + +#ifndef X_NOT_POSIX +#ifdef _POSIX_SOURCE +#include <limits.h> +#else +#define _POSIX_SOURCE +#include <limits.h> +#undef _POSIX_SOURCE +#endif +#endif +#ifndef PATH_MAX +#include <sys/param.h> +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif +#endif + +#ifdef USE_SYSLOG +#include <syslog.h> +#endif + +#include <errno.h> + +#include "misc.h" + +extern char *progname; + +Bool UseSyslog; +#ifdef USE_SYSLOG +Bool log_open = FALSE; +#endif +char ErrorFile[PATH_MAX]; +static char CurrentErrorFile[PATH_MAX]; + +static void +abort_server(void) +{ + fflush(stderr); + +#ifdef SABER + saber_stop(); +#else + _exit(1); +#endif +} + +void +InitErrors(void) +{ + int i; + +#ifdef USE_SYSLOG + if (UseSyslog && !log_open) { + openlog("xfs", LOG_PID, LOG_DAEMON); + log_open = TRUE; + return; + } +#endif + + if (ErrorFile[0] && strcmp(CurrentErrorFile, ErrorFile) != 0) { + i = creat(ErrorFile, 0666); + if (i != -1) { + dup2(i, 2); + close(i); + } else { + ErrorF("can't open error file \"%s\"\n", ErrorFile); + } + strncpy(CurrentErrorFile, ErrorFile, sizeof CurrentErrorFile); + } +} + +void +CloseErrors(void) +{ +#ifdef USE_SYSLOG + if (UseSyslog) { + closelog(); + log_open = FALSE; + return; + } +#endif +} + +void +Error(char *str) +{ +#ifdef USE_SYSLOG + if (UseSyslog) { + syslog(LOG_ERR, "%s: %s", str, strerror(errno)); + return; + } +#endif + perror(str); +} + +/* + * used for informational messages + */ +void +NoticeF(char *f, ...) +{ + /* XXX should Notices just be ignored if not using syslog? */ + va_list args; + va_start(args, f); +#ifdef USE_SYSLOG + if (UseSyslog) { + vsyslog(LOG_NOTICE, f, args); + return; + } +#else + fprintf(stderr, "%s notice: ", progname); + vfprintf(stderr, f, args); +#endif /* USE_SYSLOG */ + va_end(args); +} + +/* + * used for non-fatal error messages + */ +void +ErrorF(char * f, ...) +{ + va_list args; + va_start(args, f); +#ifdef USE_SYSLOG + if (UseSyslog) { + vsyslog(LOG_WARNING, f, args); + return; + } +#else + fprintf(stderr, "%s error: ", progname); + vfprintf(stderr, f, args); +#endif + va_end(args); +} + +void +FatalError(char * f, ...) +{ + va_list args; + va_start(args, f); +#ifdef USE_SYSLOG + if (UseSyslog) { + vsyslog(LOG_ERR, f, args); + return; + } +#else + fprintf(stderr, "%s fatal error: ", progname); + vfprintf(stderr, f, args); +#endif + va_end(args); + abort_server(); + /* NOTREACHED */ +} diff --git a/app/xfs/os/io.c b/app/xfs/os/io.c new file mode 100644 index 000000000..a5603e24f --- /dev/null +++ b/app/xfs/os/io.c @@ -0,0 +1,706 @@ +/* $Xorg: io.c,v 1.5 2001/02/09 02:05:44 xorgcvs Exp $ */ +/* + * i/o functions + */ +/* + +Copyright 1990, 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, or Digital + * not be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, + * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/programs/xfs/os/io.c,v 3.18 2001/12/14 20:01:41 dawes Exp $ */ + +#include <X11/Xtrans/Xtrans.h> +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#ifndef Lynx +#include <sys/param.h> +#ifndef __UNIXOS2__ +#include <sys/uio.h> +#endif +#else +#include <uio.h> +#endif + +#include <X11/fonts/FSproto.h> +#include "clientstr.h" +#include "X11/Xpoll.h" +#include "osdep.h" +#include "globals.h" +#include "dispatch.h" + + +/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX + * systems are broken and return EWOULDBLOCK when they should return EAGAIN + */ + +#if defined(EAGAIN) && defined(EWOULDBLOCK) +#define ETEST(err) (err == EAGAIN || err == EWOULDBLOCK) +#else + +#ifdef EAGAIN +#define ETEST(err) (err == EAGAIN) +#else +#define ETEST(err) (err == EWOULDBLOCK) +#endif + +#endif + + +extern fd_set ClientsWithInput; +extern fd_set ClientsWriteBlocked; +extern fd_set OutputPending; + +extern long OutputBufferSize; + +extern int ConnectionTranslation[]; + +extern Bool AnyClientsWriteBlocked; +extern Bool NewOutputPending; + +static int timesThisConnection = 0; +static ConnectionInputPtr FreeInputs = (ConnectionInputPtr) NULL; +static ConnectionOutputPtr FreeOutputs = (ConnectionOutputPtr) NULL; +static OsCommPtr AvailableInput = (OsCommPtr) NULL; + +static ConnectionInputPtr AllocateInputBuffer(void); +static ConnectionOutputPtr AllocateOutputBuffer(void); + + +#define MAX_TIMES_PER 10 + +#define yield_control() \ + { isItTimeToYield = TRUE; \ + timesThisConnection = 0; } + +#define yield_control_no_input() \ + { yield_control(); \ + FD_CLR(fd, &ClientsWithInput); } + +#define yield_control_death() \ + { timesThisConnection = 0; } + +#define request_length(req, client) \ + ((int)((client)->swapped ? lswaps((req)->length) : (req)->length) << 2) + +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; + +#ifdef WORD64 + /* need 8-byte alignment */ + if ((oci->bufptr - oci->buffer) & 7 && gotnow > 0) + { + memmove( oci->buffer, oci->bufptr, gotnow); + oci->bufptr = oci->buffer; + oci->bufcnt = gotnow; + } +#endif + + 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; +} + +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; +} + +void +ResetCurrentRequest(ClientPtr client) +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + ConnectionInputPtr oci = oc->input; + int fd = oc->fd; + fsReq *request; + int gotnow; + + if (AvailableInput == oc) + AvailableInput = (OsCommPtr) NULL; + oci->lenLastReq = 0; + request = (fsReq *) oci->bufptr; + gotnow = oci->bufcnt + oci->buffer - oci->bufptr; + if ((gotnow >= SIZEOF(fsReq)) && + (gotnow >= request_length(request, client))) { + FD_SET(fd, &ClientsWithInput); + yield_control(); + } else { + yield_control_no_input(); + } +} + +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) + _FontTransClose(oc->trans_conn); + oc->trans_conn = NULL; + MarkClientException(client); + oco->count = 0; + return -1; + } + } + + /* everything was flushed */ + oco->count = 0; + + /* clear the write block if it was set */ + if (AnyClientsWriteBlocked) { + FD_CLR(fd, &ClientsWriteBlocked); + if (!XFD_ANYSET(&ClientsWriteBlocked)) + AnyClientsWriteBlocked = FALSE; + } + if (oco->size > BUFWATERMARK) { + fsfree(oco->buf); + fsfree(oco); + } else { + oco->next = FreeOutputs; + FreeOutputs = oco; + } + oc->output = (ConnectionOutputPtr) NULL; + + return extraCount; +} + +void +FlushAllOutput(void) +{ + int index, base; + fd_mask mask; + OsCommPtr oc; + ClientPtr client; + + if (!NewOutputPending) + return; + + NewOutputPending = FALSE; + + for (base = 0; base < howmany(XFD_SETSIZE, NFDBITS); base++) { + mask = OutputPending.fds_bits[base]; + OutputPending.fds_bits[base] = 0; + while (mask) { + index = ffs(mask) - 1; + mask &= ~lowbit(mask); + if ((index = ConnectionTranslation[(base << 5) + index]) == 0) + continue; + client = clients[index]; + if (client->clientGone == CLIENT_GONE) + continue; + oc = (OsCommPtr) client->osPrivate; + if (FD_ISSET(oc->fd, &ClientsWithInput)) { + FD_SET(oc->fd, &OutputPending); + NewOutputPending = TRUE; + } else { + (void) FlushClient(client, oc, (char *) NULL, 0, 0); + } + } + } +} + +/* + * returns number of bytes written + */ +static int +write_to_client_internal(ClientPtr client, int count, char *buf, int padBytes) +{ + OsCommPtr oc = (OsCommPtr) client->osPrivate; + ConnectionOutputPtr oco = oc->output; + + if (!count) + return 0; + + if (!oco) { + if ((oco = FreeOutputs) != (ConnectionOutputPtr) 0) { + FreeOutputs = oco->next; + } else if (!(oco = AllocateOutputBuffer())) { + _FontTransClose(oc->trans_conn); + oc->trans_conn = NULL; + MarkClientException(client); + return -1; + } + oc->output = oco; + } + if (oco->count + count + padBytes > oco->size) { + FD_CLR(oc->fd, &OutputPending); + NewOutputPending = FALSE; + return FlushClient(client, oc, buf, count, padBytes); + } + NewOutputPending = TRUE; + FD_SET(oc->fd, &OutputPending); + memmove( (char *) oco->buf + oco->count, buf, count); + oco->count += count + padBytes; + + return count; +} + +void +WriteToClientUnpadded(ClientPtr client, int count, char *buf) +{ + write_to_client_internal(client, count, buf, 0); +} + +static int padlength[4] = {0, 3, 2, 1}; + +void +WriteToClient(ClientPtr client, int count, char *buf) +{ + int flag = 0; + if (NULL == buf) { + flag = -1; + buf = (char *)fsalloc(count); memset(buf, 0, count); + } + write_to_client_internal(client, count, buf, padlength[count & 3]); + if (flag) + fsfree(buf); +} + +static ConnectionInputPtr +AllocateInputBuffer(void) +{ + register ConnectionInputPtr oci; + + oci = (ConnectionInputPtr) fsalloc(sizeof(ConnectionInput)); + if (!oci) + return (ConnectionInputPtr) NULL; + oci->buffer = (char *) fsalloc(BUFSIZE); + if (!oci->buffer) { + fsfree(oci); + return (ConnectionInputPtr) NULL; + } + oci->next = 0; + oci->size = BUFSIZE; + oci->bufptr = oci->buffer; + oci->bufcnt = 0; + oci->lenLastReq = 0; + return oci; +} + +static ConnectionOutputPtr +AllocateOutputBuffer(void) +{ + register ConnectionOutputPtr oco; + + oco = (ConnectionOutputPtr) fsalloc(sizeof(ConnectionOutput)); + if (!oco) + return (ConnectionOutputPtr) NULL; + oco->buf = (unsigned char *) fsalloc(BUFSIZE); + if (!oco->buf) { + fsfree(oco); + return (ConnectionOutputPtr) NULL; + } + oco->size = BUFSIZE; + oco->count = 0; + return oco; +} + + +void +FreeOsBuffers(OsCommPtr oc) +{ + register ConnectionInputPtr oci; + register ConnectionOutputPtr oco; + + if (AvailableInput == oc) + AvailableInput = (OsCommPtr) NULL; + if ((oci = oc->input) != (ConnectionInputPtr) 0) { + if (FreeInputs) { + fsfree(oci->buffer); + fsfree(oci); + } else { + FreeInputs = oci; + oci->next = (ConnectionInputPtr) NULL; + oci->bufptr = oci->buffer; + oci->bufcnt = 0; + oci->lenLastReq = 0; + } + } + if ((oco = oc->output) != (ConnectionOutputPtr) 0) { + if (FreeOutputs) { + fsfree(oco->buf); + fsfree(oco); + } else { + FreeOutputs = oco; + oco->next = (ConnectionOutputPtr) NULL; + oco->count = 0; + } + } +} + +void +ResetOsBuffers(void) +{ + register ConnectionInputPtr oci; + register ConnectionOutputPtr oco; + + while ((oci = FreeInputs) != (ConnectionInputPtr) 0) { + FreeInputs = oci->next; + fsfree(oci->buffer); + fsfree(oci); + } + while ((oco = FreeOutputs) != (ConnectionOutputPtr) 0) { + FreeOutputs = oco->next; + fsfree(oco->buf); + fsfree(oco); + } +} diff --git a/app/xfs/os/osdep.h b/app/xfs/os/osdep.h new file mode 100644 index 000000000..4b07b283e --- /dev/null +++ b/app/xfs/os/osdep.h @@ -0,0 +1,134 @@ +/* $Xorg: osdep.h,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */ +/* +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, + * or Digital not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Network Computing Devices, or Digital + * make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * @(#)osdep.h 4.1 5/2/91 + * + */ +/* $XFree86: xc/programs/xfs/os/osdep.h,v 3.11 2001/12/14 20:01:41 dawes Exp $ */ + +#ifndef _OSDEP_H_ +#define _OSDEP_H_ + +#define BOTIMEOUT 200 /* in milliseconds */ +#define BUFSIZE 4096 +#define BUFWATERMARK 8192 +#define MAXBUFSIZE (1 << 15) + +#ifndef sgi /* SGI defines OPEN_MAX in a useless way */ +#ifndef X_NOT_POSIX +#ifdef _POSIX_SOURCE +#include <limits.h> +#else +#define _POSIX_SOURCE +#include <limits.h> +#undef _POSIX_SOURCE +#endif +#endif +#endif + +#ifndef OPEN_MAX +#if defined(__UNIXOS2__) || defined(__QNX__) +#define OPEN_MAX 256 +#else +#ifdef SVR4 +#define OPEN_MAX 128 +#else +#include <sys/param.h> +#ifdef __GNU__ +#define OPEN_MAX (sysconf(_SC_OPEN_MAX)) +#endif /*__GNU__*/ +#ifndef OPEN_MAX +#ifdef SCO325 +#define OPEN_MAX (sysconf(_SC_OPEN_MAX)) +#else +#if defined(NOFILE) && !defined(NOFILES_MAX) +#define OPEN_MAX NOFILE +#else +#define OPEN_MAX NOFILES_MAX +#endif +#endif +#endif +#endif +#endif +#endif + +#if defined(__GNU__) || defined(SCO325) +#define MAXSOCKS 128 +#else /*__GNU__*/ +#if OPEN_MAX <= 128 /* 128 is value of MAXCLIENTS */ +#define MAXSOCKS (OPEN_MAX - 1) +#else +#define MAXSOCKS 128 +#endif +#endif /*__GNU__*/ + +#include <stddef.h> + +typedef struct _connectionInput { + struct _connectionInput *next; + char *buffer; /* contains current client input */ + char *bufptr; /* pointer to current start of data */ + int bufcnt; /* count of bytes in buffer */ + int lenLastReq; + int size; +} ConnectionInput, *ConnectionInputPtr; + +typedef struct _connectionOutput { + struct _connectionOutput *next; + int size; + unsigned char *buf; + int count; +} ConnectionOutput, *ConnectionOutputPtr; + +typedef struct _osComm { + int fd; + ConnectionInputPtr input; + ConnectionOutputPtr output; + long conn_time; /* timestamp if not established, else 0 */ + struct _XtransConnInfo *trans_conn; /* transport connection object */ +} OsCommRec, *OsCommPtr; + +#endif /* _OSDEP_H_ */ diff --git a/app/xfs/os/osglue.c b/app/xfs/os/osglue.c new file mode 100644 index 000000000..e1e9ef239 --- /dev/null +++ b/app/xfs/os/osglue.c @@ -0,0 +1,384 @@ +/* $Xorg: osglue.c,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */ +/* +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, + * or Digital not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Network Computing Devices, or Digital + * make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $NCDXorg: @(#)osglue.c,v 4.6 1991/07/09 14:07:30 lemke Exp $ + * + */ +/* $XFree86: xc/programs/xfs/os/osglue.c,v 3.18 2002/10/15 01:45:03 dawes Exp $ */ + +/* + * this is miscellaneous OS specific stuff. + * + * Catalogue support, alternate servers, and cloneing + */ + +#include <X11/Xtrans/Xtrans.h> +#include "osstruct.h" +#include <stdio.h> +#include <stdlib.h> +#define XK_LATIN1 +#include <X11/keysymdef.h> +#ifdef __UNIXOS2__ +#define _NFILE 256 +#endif + +Bool drone_server = FALSE; +extern char *progname; +extern char *configfilename; + +static int num_alts; +static AlternateServerPtr alt_servers = (AlternateServerPtr) 0; + +extern XtransConnInfo *ListenTransConns; +extern int *ListenTransFds; +extern int ListenTransCount; + +/* + * XXX + * + * Catalogue support is absolutely minimal. Some guts are here, but + * we don't actually do anything with them so the only one exported is + * 'all'. Be warned that other parts of the server may incorrectly + * assume the catalogue list is global, and will therefore need fixing. + * + */ + +static char *catalogue_name = "all"; + +static Bool /* stolen from R4 Match() */ +pattern_match(char *pat, int plen, char *string) +{ + register int i, + l; + int j, + m, + res; + register char cp, + cs; + int head, + tail; + + head = 0; + tail = plen; + + res = -1; + for (i = 0; i < head; i++) { + cp = pat[i]; + if (cp == XK_question) { + if (!string[i]) + return res; + res = 0; + } else if (cp != string[i]) + return res; + } + if (head == plen) + return (string[head] ? res : 1); + l = head; + while (++i < tail) { + /* we just skipped an asterisk */ + j = i; + m = l; + while ((cp = pat[i]) != XK_asterisk) { + if (!(cs = string[l])) + return 0; + if ((cp != cs) && (cp != XK_question)) { + m++; + cp = pat[j]; + if (cp == XK_asterisk) { + if (!string[m]) + return 0; + } else { + while ((cs = string[m]) != cp) { + if (!cs) + return 0; + m++; + } + } + l = m; + i = j; + } + l++; + i++; + } + } + m = strlen(&string[l]); + j = plen - tail; + if (m < j) + return 0; + l = (l + m) - j; + while ((cp = pat[i])) { + if ((cp != string[l]) && (cp != XK_question)) + return 0; + l++; + i++; + } + return 1; +} + +int +ListCatalogues(char *pattern, int patlen, int maxnames, + char **catalogues, int *len) +{ + int count = 0; + char *catlist = NULL; + int size = 0; + + if (maxnames) { + if (pattern_match(pattern, patlen, catalogue_name)) { + size = strlen(catalogue_name); + catlist = (char *) fsalloc(size + 1); + if (!catlist) + goto bail; + *catlist = size; + memmove( &catlist[1], catalogue_name, size); + size++; /* for length */ + count++; + } + } +bail: + *len = size; + *catalogues = catlist; + return count; +} + +/* + * check if catalogue list is valid + */ + +int +ValidateCatalogues(int *num, char *cats) +{ + char *c = cats; + int i, + len; + + for (i = 0; i < *num; i++) { + len = *c++; + if (strncmp(c, catalogue_name, len)) { + *num = i; /* return bad entry index */ + return FSBadName; + } + c += len; + } + return FSSuccess; +} + +int +SetAlternateServers(char *list) +{ + char *t, + *st; + AlternateServerPtr alts, + a; + int num, + i; + + t = list; + num = 1; + while (*t) { + if (*t == ',') + num++; + t++; + } + + a = alts = (AlternateServerPtr) fsalloc(sizeof(AlternateServerRec) * num); + if (!alts) + return FSBadAlloc; + + st = t = list; + a->namelen = 0; + while (*t) { + if (*t == ',') { + a->name = (char *) fsalloc(a->namelen); + if (!a->name) { + /* XXX -- leak */ + return FSBadAlloc; + } + memmove( a->name, st, a->namelen); + a->subset = FALSE; /* XXX */ + a++; + t++; + st = t; + a->namelen = 0; + } else { + a->namelen++; + t++; + } + } + a->name = (char *) fsalloc(a->namelen); + if (!a->name) { + /* XXX -- leak */ + return FSBadAlloc; + } + memmove( a->name, st, a->namelen); + a->subset = FALSE; /* XXX */ + + for (i = 0; i < num_alts; i++) { + fsfree((char *) alt_servers[i].name); + } + fsfree((char *) alt_servers); + num_alts = num; + alt_servers = alts; + return FSSuccess; +} + +int +ListAlternateServers(AlternateServerPtr *svrs) +{ + *svrs = alt_servers; + return num_alts; +} + +/* + * here's some fun stuff. in order to cleanly handle becoming overloaded, + * this allows us to clone ourselves. the parent keeps the Listen + * socket open, and sends it to itself. the child stops listening, + * and becomes a drone, hanging out till it loses all its clients. + */ + +int +CloneMyself(void) +{ + int child; + char old_listen_arg[256]; + char *arg_ptr = old_listen_arg; + int i, j; + int lastfdesc; + char portnum[20]; + + assert(!drone_server); /* a drone shouldn't hit this */ + + if (!CloneSelf) + return -1; + +#ifdef __UNIXOS2__ + NoticeF("cloning of font server not supported under OS/2!\n"); + return(-1); +#endif + + old_listen_arg[0] = '\0'; + +#ifdef XNO_SYSCONF /* should only be on FreeBSD 1.x and NetBSD 0.x */ +#undef _SC_OPEN_MAX +#endif +#ifdef _SC_OPEN_MAX + lastfdesc = sysconf(_SC_OPEN_MAX) - 1; +#else +#if defined(hpux) || defined(__UNIXOS2__) + lastfdesc = _NFILE - 1; +#else + lastfdesc = getdtablesize() - 1; +#endif /* hpux */ +#endif + + NoticeF("attempting clone...\n"); + chdir("/"); + child = fork(); + if (child == -1) { + /* failed to fork */ + ErrorF("clone failed to fork()\n"); + return -1; + } + /* + * Note: they still share the same process group, and killing the parent + * will take out all the kids as well. this is considered a feature (at + * least until i'm convinced otherwise) + */ + if (child == 0) { + StopListening(); + NoticeF("clone: child becoming drone\n"); + drone_server = TRUE; + return 1; + } else { /* parent */ + NoticeF("clone: parent revitalizing as %s\n", progname); + CloseErrors(); + /* XXX should we close stdio as well? */ + for (i = 3; i < lastfdesc; i++) + { + for (j = 0; j < ListenTransCount; j++) + if (ListenTransFds[j] == i) + break; + + if (j >= ListenTransCount) + (void) close(i); + } + + for (i = 0; i < ListenTransCount; i++) + { + int trans_id, fd; + char *port; + + if (!_FontTransGetReopenInfo (ListenTransConns[i], + &trans_id, &fd, &port)) + continue; + + sprintf (arg_ptr, "%d/%d/%s", trans_id, fd, port); + arg_ptr += strlen (arg_ptr); + free (port); + + if (i < ListenTransCount - 1) + { + strcat (arg_ptr, ","); + arg_ptr++; + } + } + + sprintf (portnum, "%d", ListenPort); + if (*old_listen_arg != '\0') + execlp(progname, progname, + "-ls", old_listen_arg, + "-cf", configfilename, + "-port", portnum, + (void *)NULL); + + InitErrors(); /* reopen errors, since we don't want to lose + * this */ + Error("clone failed"); + FatalError("failed to clone self\n"); + } + /* NOTREACHED */ + return 0; +} diff --git a/app/xfs/os/osinit.c b/app/xfs/os/osinit.c new file mode 100644 index 000000000..a12bb002d --- /dev/null +++ b/app/xfs/os/osinit.c @@ -0,0 +1,64 @@ +/* $Xorg: osinit.c,v 1.4 2001/02/09 02:05:45 xorgcvs Exp $ */ +/* + * os init code + */ +/* +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, + * or Digital not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Network Computing Devices, or Digital + * make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * @(#)osinit.c 4.3 5/7/91 + * + */ +/* $XFree86: xc/programs/xfs/os/osinit.c,v 1.4 2001/01/17 23:45:33 dawes Exp $ */ + +#include "os.h" + +extern long LastReapTime; + +void +OsInit(void) +{ + LastReapTime = GetTimeInMillis(); + OsInitAllocator (); +} diff --git a/app/xfs/os/utils.c b/app/xfs/os/utils.c new file mode 100644 index 000000000..fcc1c2a06 --- /dev/null +++ b/app/xfs/os/utils.c @@ -0,0 +1,575 @@ +/* $Xorg: utils.c,v 1.4 2001/02/09 02:05:45 xorgcvs Exp $ */ +/* + * misc os utilities + */ +/* + +Copyright 1990, 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, or Digital + * not be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, + * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/programs/xfs/os/utils.c,v 3.20 2002/10/15 01:45:03 dawes Exp $ */ + +#include <stdio.h> +#include <X11/Xos.h> +#include <stdlib.h> +#include "misc.h" +#include "globals.h" +#include <signal.h> +#ifdef MEMBUG +#include <util/memleak/memleak.h> +#endif +#include <sys/wait.h> +#include <unistd.h> +#include <pwd.h> +#include <grp.h> +#include <errno.h> +#include <sys/types.h> +#include <errno.h> +#include <string.h> + +#ifndef X_NOT_POSIX +#ifdef _POSIX_SOURCE +#include <limits.h> +#else +#define _POSIX_SOURCE +#include <limits.h> +#undef _POSIX_SOURCE +#endif +#endif /* X_NOT_POSIX */ +#ifndef PATH_MAX +#include <sys/param.h> +#ifndef PATH_MAX +#ifdef MAXPATHLEN +#define PATH_MAX MAXPATHLEN +#else +#define PATH_MAX 1024 +#endif +#endif +#endif /* PATH_MAX */ + +#if defined(X_NOT_POSIX) && (defined(SYSV) || defined(SVR4)) +#define SIGNALS_RESET_WHEN_CAUGHT +#endif + +#include <stdlib.h> + +extern char *configfilename; +static Bool dropPriv = FALSE; /* whether or not to drop root privileges */ +#ifdef DEFAULT_DAEMON +static Bool becomeDaemon = TRUE; /* whether to become a daemon or not */ +#else +static Bool becomeDaemon = FALSE; /* whether to become a daemon or not */ +#endif +static const char *userId = NULL; +char *progname; +Bool CloneSelf; +Bool portFromCmdline = FALSE; + +OldListenRec *OldListen = NULL; +int OldListenCount = 0; + +#ifdef STDERR_FILENO +# define WRITES write(STDERR_FILENO, s, strlen(s)) +#else +# define WRITES write(fileno(stderr), s, strlen(s)) +#endif + +static char *pidFile = XFSPIDDIR "/xfs.pid"; +static int pidFd; +static FILE *pidFilePtr; +static int StorePid (void); + +/* ARGSUSED */ +SIGVAL +AutoResetServer(int n) +{ + int olderrno = errno; + +#ifdef DEBUG + WRITES("got a reset signal\n"); +#endif + + dispatchException |= DE_RESET; + isItTimeToYield = TRUE; + +#ifdef SIGNALS_RESET_WHEN_CAUGHT + signal(SIGHUP, AutoResetServer); +#endif + errno = olderrno; +} + +/* ARGSUSED */ +SIGVAL +GiveUp(int n) +{ + int olderrno = errno; +#ifdef DEBUG + WRITES("got a TERM signal\n"); +#endif + + dispatchException |= DE_TERMINATE; + isItTimeToYield = TRUE; + errno = olderrno; +} + +/* ARGSUSED */ +SIGVAL +ServerReconfig(int n) +{ + int olderrno = errno; + +#ifdef DEBUG + WRITES("got a re-config signal\n"); +#endif + + dispatchException |= DE_RECONFIG; + isItTimeToYield = TRUE; + +#ifdef SIGNALS_RESET_WHEN_CAUGHT + signal(SIGUSR1, ServerReconfig); +#endif + errno = olderrno; +} + +/* ARGSUSED */ +SIGVAL +ServerCacheFlush(int n) +{ + int olderrno = errno; + +#ifdef DEBUG + WRITES("got a flush signal\n"); +#endif + + dispatchException |= DE_FLUSH; + isItTimeToYield = TRUE; + +#ifdef SIGNALS_RESET_WHEN_CAUGHT + signal(SIGUSR2, ServerCacheFlush); +#endif + errno = olderrno; +} + +/* ARGSUSED */ +SIGVAL +CleanupChild(int n) +{ + int olderrno = errno; + +#ifdef DEBUG + WRITES("got a child signal\n"); +#endif + + wait(NULL); + +#ifdef SIGNALS_RESET_WHEN_CAUGHT + signal(SIGCHLD, CleanupChild); +#endif + errno = olderrno; +} + +long +GetTimeInMillis(void) +{ + struct timeval tp; + + X_GETTIMEOFDAY(&tp); + return ((tp.tv_sec * 1000) + (tp.tv_usec / 1000)); +} + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [-config config_file] [-port tcp_port] [-droppriv] [-daemon] [-nodaemon] [-user user_name] [-ls listen_socket]\n", + progname); + exit(1); +} + +void +OsInitAllocator (void) +{ +#ifdef MEMBUG + CheckMemory (); +#endif +} + + +/* + * The '-ls' option is used for cloning the font server. + * + * We expect a single string of the form... + * + * transport_id/fd/portnum[,transport_id/fd/portnum]... + * + * [] denotes optional and ... denotes repitition. + * + * The string must be _exactly_ in the above format. + */ + +void +ProcessLSoption (char *str) +{ + char *ptr = str; + char *slash; + char number[20]; + int count = 0; + int len, i; + + while (*ptr != '\0') + { + if (*ptr == ',') + count++; + ptr++; + } + + OldListenCount = count + 1; + OldListen = (OldListenRec *) malloc ( + OldListenCount * sizeof (OldListenRec)); + if (OldListen == NULL) { + fprintf(stderr, "ProcessLSoption: malloc error\n"); + exit(1); + } + ptr = str; + + for (i = 0; i < OldListenCount; i++) + { + slash = (char *) strchr (ptr, '/'); + if (slash == NULL) { + usage(); + } + len = slash - ptr; + strncpy (number, ptr, len); + number[len] = '\0'; + OldListen[i].trans_id = atoi (number); + + ptr = slash + 1; + + slash = (char *) strchr (ptr, '/'); + if (slash == NULL) { + usage(); + } + len = slash - ptr; + strncpy (number, ptr, len); + number[len] = '\0'; + OldListen[i].fd = atoi (number); + + ptr = slash + 1; + + if (i == OldListenCount - 1) + OldListen[i].portnum = atoi (ptr); + else + { + char *comma = (char *) strchr (ptr, ','); + if (comma == NULL) { + usage(); + } + len = comma - ptr; + strncpy (number, ptr, len); + number[len] = '\0'; + OldListen[i].portnum = atoi (number); + + ptr = comma + 1; + } + } +} + + + +/* ARGSUSED */ +void +ProcessCmdLine(int argc, char **argv) +{ + int i; + + progname = argv[0]; + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-port")) { + if (argv[i + 1]) { + ListenPort = atoi(argv[++i]); + portFromCmdline = TRUE; + } else + usage(); + } else if (!strcmp(argv[i], "-ls")) { + if (argv[i + 1]) + ProcessLSoption (argv[++i]); + else + usage(); + } else if (!strcmp(argv[i], "-droppriv")) { + dropPriv = TRUE; + } else if (!strcmp(argv[i], "-daemon")) { + becomeDaemon = TRUE; + } else if (!strcmp(argv[i], "-nodaemon")) { + becomeDaemon = FALSE; + } else if (!strcmp(argv[i], "-user")) { + if (argv[i + 1]) + userId = argv[++i]; + else + usage(); + } else if (!strcmp(argv[i], "-cf") || !strcmp(argv[i], "-config")) { + if (argv[i + 1]) + configfilename = argv[++i]; + else + usage(); + } +#ifdef MEMBUG + else if ( strcmp( argv[i], "-alloc") == 0) + { + extern unsigned long MemoryFail; + if(++i < argc) + MemoryFail = atoi(argv[i]); + else + usage (); + } +#endif + else + usage(); + } +} + + +#ifndef SPECIAL_MALLOC + +unsigned long Must_have_memory; + +#ifdef MEMBUG +#define MEM_FAIL_SCALE 100000 +unsigned long MemoryFail; + +#endif + +/* FSalloc -- FS's internal memory allocator. Why does it return unsigned + * int * instead of the more common char *? Well, if you read K&R you'll + * see they say that alloc must return a pointer "suitable for conversion" + * to whatever type you really want. In a full-blown generic allocator + * there's no way to solve the alignment problems without potentially + * wasting lots of space. But we have a more limited problem. We know + * we're only ever returning pointers to structures which will have to + * be long word aligned. So we are making a stronger guarantee. It might + * have made sense to make FSalloc return char * to conform with people's + * expectations of malloc, but this makes lint happier. + */ + +pointer +FSalloc (unsigned long amount) +{ + register pointer ptr; + + if ((long)amount < 0) + return 0; + if (amount == 0) + amount++; + /* aligned extra on long word boundary */ + amount = (amount + 3) & ~3; +#ifdef MEMBUG + if (!Must_have_memory && MemoryFail && + ((random() % MEM_FAIL_SCALE) < MemoryFail)) + return 0; + if (ptr = (pointer)fmalloc(amount)) + return ptr; +#else + if ((ptr = (pointer)malloc(amount)) != 0) + return ptr; +#endif + if (Must_have_memory) + FatalError("out of memory\n"); + return 0; +} + +/***************** + * FScalloc + *****************/ + +pointer +FScalloc (unsigned long amount) +{ + pointer ret; + + ret = FSalloc (amount); + if (ret) + bzero ((char *) ret, (int) amount); + return ret; +} + +/***************** + * FSrealloc + *****************/ + +pointer +FSrealloc (pointer ptr, unsigned long amount) +{ +#ifdef MEMBUG + if (!Must_have_memory && MemoryFail && + ((random() % MEM_FAIL_SCALE) < MemoryFail)) + return 0; + ptr = (pointer)frealloc((char *) ptr, amount); + if (ptr) + return ptr; +#else + if ((long)amount <= 0) + { + if (ptr && !amount) + free(ptr); + return 0; + } + amount = (amount + 3) & ~3; + if (ptr) + ptr = (pointer)realloc((char *)ptr, amount); + else + ptr = (pointer)malloc(amount); + if (ptr) + return ptr; +#endif + if (Must_have_memory) + FatalError("out of memory\n"); + return 0; +} + +/***************** + * FSfree + * calls free + *****************/ + +void +FSfree(pointer ptr) +{ +#ifdef MEMBUG + if (ptr) + ffree((char *)ptr); +#else + if (ptr) + free((char *)ptr); +#endif +} + +#endif /* SPECIAL_MALLOC */ + + +void +SetUserId(void) +{ + /* become xfs user (or other specified on command line) if possible */ + if ((geteuid() == 0) && (dropPriv || userId)) { + const char *user; + struct passwd *pwent; + + if (!userId) + user = "xfs"; + else + user = userId; + pwent = getpwnam(user); + if (pwent) { + if (setgid(pwent->pw_gid)) { + FatalError("fatal: couldn't set groupid to xfs user's group\n"); + } +#ifndef QNX4 +#ifndef __CYGWIN__ + if (setgroups(0, NULL)) { + FatalError("fatal: couldn't drop supplementary groups\n"); + } +#endif + if (initgroups(user, pwent->pw_gid)) { + FatalError("fatal: couldn't init supplementary groups\n"); + } +#endif /* QNX4 */ + if (setuid(pwent->pw_uid)) { + FatalError("fatal: couldn't set userid to %s user\n", user); + } + } + } else if (dropPriv || userId) { + FatalError("fatal: -droppriv or -user flag specified, but xfs not run as root\n"); + } +} + + +void +SetDaemonState(void) +{ + int oldpid; + + if (becomeDaemon) { + BecomeDaemon(); + if ((oldpid = StorePid ())) { + if (oldpid == -1) + ErrorF ("error opening process-id file %s\n", pidFile); + else + ErrorF ("process-id file %s indicates another xfs is " + "running (pid %d); exiting\n", pidFile, oldpid); + exit(1); + } + } +} + + +static int +StorePid (void) +{ + int oldpid; + + if (pidFile[0] != '\0') { + pidFd = open (pidFile, O_RDWR); + if (pidFd == -1 && errno == ENOENT) + pidFd = open (pidFile, O_RDWR|O_CREAT, 0666); + if (pidFd == -1 || !(pidFilePtr = fdopen (pidFd, "r+"))) + { + ErrorF ("cannot open process-id file %s: %s\n", pidFile, + strerror (errno)); + return -1; + } + if (fscanf (pidFilePtr, "%d\n", &oldpid) != 1) + oldpid = -1; + if (fseek (pidFilePtr, 0L, SEEK_SET) == -1) + { + ErrorF ("cannot seek process-id file %s: %s\n", pidFile, + strerror (errno)); + return -1; + } + if (fprintf (pidFilePtr, "%5ld\n", (long) getpid ()) != 6) + { + ErrorF ("cannot write to process-id file %s: %s\n", pidFile, + strerror (errno)); + return -1; + } + (void) fflush (pidFilePtr); + (void) fclose (pidFilePtr); + } + return 0; +} diff --git a/app/xfs/os/waitfor.c b/app/xfs/os/waitfor.c new file mode 100644 index 000000000..09e30c87c --- /dev/null +++ b/app/xfs/os/waitfor.c @@ -0,0 +1,231 @@ +/* $Xorg: waitfor.c,v 1.4 2001/02/09 02:05:45 xorgcvs Exp $ */ +/* + * waits for input + */ +/* +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, + * or Digital not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Network Computing Devices, or Digital + * make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $NCDXorg: @(#)waitfor.c,v 4.5 1991/06/24 11:59:20 lemke Exp $ + * + */ +/* $XFree86: xc/programs/xfs/os/waitfor.c,v 3.15 2001/12/14 20:01:41 dawes Exp $ */ + +#include <X11/Xos.h> /* strings, time, etc */ + +#include <stdio.h> +#include <errno.h> +#if !defined(Lynx) +#include <sys/param.h> +#endif + +#include "clientstr.h" +#include "globals.h" +#include "X11/Xpoll.h" +#include "osdep.h" +#include "os.h" + +#ifdef __UNIXOS2__ +#define select(n,r,w,x,t) os2PseudoSelect(n,r,w,x,t) +#endif + +extern WorkQueuePtr workQueue; + + +extern fd_set WellKnownConnections; +extern fd_set LastSelectMask; +extern fd_set WriteMask; +extern fd_set ClientsWithInput; +extern fd_set ClientsWriteBlocked; +extern fd_set AllSockets; +extern fd_set AllClients; +extern fd_set OutputPending; + +extern Bool AnyClientsWriteBlocked; +extern Bool NewOutputPending; + +extern int ConnectionTranslation[]; + +long LastReapTime; + +/* + * wait_for_something + * + * server suspends until + * - data from clients + * - new client connects + * - room to write data to clients + */ + +int +WaitForSomething(int *pClientsReady) +{ + struct timeval *wt, + waittime; + fd_set clientsReadable; + fd_set clientsWriteable; + long curclient; + int selecterr; + long current_time = 0; + long timeout; + int nready, + i; + + while (1) { + /* handle the work Q */ + if (workQueue) + ProcessWorkQueue(); + + if (XFD_ANYSET(&ClientsWithInput)) { + XFD_COPYSET(&ClientsWithInput, &clientsReadable); + break; + } + /* + * deal with KeepAlive timeouts. if this seems to costly, SIGALRM + * could be used, but its more dangerous since some it could catch us + * at an inopportune moment (like inside un-reentrant malloc()). + */ + current_time = GetTimeInMillis(); + timeout = current_time - LastReapTime; + if (timeout > ReapClientTime) { + ReapAnyOldClients(); + LastReapTime = current_time; + timeout = ReapClientTime; + } + timeout = ReapClientTime - timeout; + waittime.tv_sec = timeout / MILLI_PER_SECOND; + waittime.tv_usec = (timeout % MILLI_PER_SECOND) * + (1000000 / MILLI_PER_SECOND); + wt = &waittime; + + XFD_COPYSET(&AllSockets, &LastSelectMask); + + BlockHandler(&wt, (pointer) &LastSelectMask); + if (NewOutputPending) + FlushAllOutput(); + + if (AnyClientsWriteBlocked) { + XFD_COPYSET(&ClientsWriteBlocked, &clientsWriteable); + i = Select(MAXSOCKS, &LastSelectMask, &clientsWriteable, NULL, wt); + } else { + i = Select(MAXSOCKS, &LastSelectMask, NULL, NULL, wt); + } + selecterr = errno; + + WakeupHandler(i, (unsigned long *) &LastSelectMask); + if (i <= 0) { /* error or timeout */ + FD_ZERO(&clientsWriteable); + if (i < 0) { + if (selecterr == EBADF) { /* somebody disconnected */ + CheckConnections(); + } else if (selecterr != EINTR) { + ErrorF("WaitForSomething: select(): errno %d\n", selecterr); + } else { + /* + * must have been broken by a signal. go deal with any + * exception flags + */ + return 0; + } + } else { /* must have timed out */ + ReapAnyOldClients(); + LastReapTime = GetTimeInMillis(); + } + } else { + if (AnyClientsWriteBlocked && XFD_ANYSET(&clientsWriteable)) { + NewOutputPending = TRUE; + XFD_ORSET(&OutputPending, &clientsWriteable, &OutputPending); + XFD_UNSET(&ClientsWriteBlocked, &clientsWriteable); + if (!XFD_ANYSET(&ClientsWriteBlocked)) + AnyClientsWriteBlocked = FALSE; + } + XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients); + if (LastSelectMask.fds_bits[0] & WellKnownConnections.fds_bits[0]) + MakeNewConnections(); + if (XFD_ANYSET(&clientsReadable)) + break; + + } + } + nready = 0; + + if (XFD_ANYSET(&clientsReadable)) { + ClientPtr client; + int conn; + + if (current_time) /* may not have been set */ + current_time = GetTimeInMillis(); + for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) { + while (clientsReadable.fds_bits[i]) { + curclient = ffs(clientsReadable.fds_bits[i]) - 1; + conn = ConnectionTranslation[curclient + (i << 5)]; + clientsReadable.fds_bits[i] &= ~(((fd_mask)1L) << curclient); + client = clients[conn]; + if (!client) + continue; + pClientsReady[nready++] = conn; + client->last_request_time = current_time; + client->clientGone = CLIENT_ALIVE; + } + } + } + return nready; +} + +#if 0 +/* + * This is not always a macro + */ +int +ANYSET(long *src) +{ + int i; + + for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) + if (src[i]) + return (1); + return (0); +} + +#endif diff --git a/app/xfs/os/xfstrans.c b/app/xfs/os/xfstrans.c new file mode 100644 index 000000000..0ee846473 --- /dev/null +++ b/app/xfs/os/xfstrans.c @@ -0,0 +1,33 @@ +/* + * $Id: xfstrans.c,v 1.1 2006/11/26 14:43:47 matthieu Exp $ + * + * Copyright © 2003 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#define FONT_t +#define TRANS_REOPEN +#define TRANS_SERVER + +#include <X11/Xtrans/transport.c> |