1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-03 21:30:29 +02:00

2001-11-21 Stefan Jahn <stefan@lkcc.org>

* win32-socket.c (getservent, setservent, endservent,
        getprotoent, setprotoent, endprotoent): New functions.
        Appropriate replacements for M$-Windows.

        * numbers.c (SIZE_MAX, PTRDIFF_MAX, PTRDIFF_MIN): Reintroduced
        these definitions for GUILE_DEBUG.

        * net_db.c: Include "win32-socket.h" if compiling with a native
        M$-Windows compiler.  Include some pieces of code (protoent and
        servent interface) protected by HAVE_* macros when using a
        native M$-Windows compiler.
This commit is contained in:
Stefan Jahn 2001-11-21 07:59:53 +00:00
parent 351982f656
commit 6063dc1ddd
5 changed files with 289 additions and 4 deletions

View file

@ -1,3 +1,17 @@
2001-11-21 Stefan Jahn <stefan@lkcc.org>
* win32-socket.c (getservent, setservent, endservent,
getprotoent, setprotoent, endprotoent): New functions.
Appropriate replacements for M$-Windows.
* numbers.c (SIZE_MAX, PTRDIFF_MAX, PTRDIFF_MIN): Reintroduced
these definitions for GUILE_DEBUG.
* net_db.c: Include "win32-socket.h" if compiling with a native
M$-Windows compiler. Include some pieces of code (protoent and
servent interface) protected by HAVE_* macros when using a
native M$-Windows compiler.
2001-11-20 Marius Vollmer <mvo@zagadka.ping.de> 2001-11-20 Marius Vollmer <mvo@zagadka.ping.de>
* modules.c (scm_c_export): Do nothing when the first argument is * modules.c (scm_c_export): Do nothing when the first argument is

View file

@ -74,6 +74,10 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#endif #endif
#ifdef __MINGW32__
#include "win32-socket.h"
#endif
#if !defined (HAVE_H_ERRNO) && !defined (__MINGW32__) && !defined (__CYGWIN__) #if !defined (HAVE_H_ERRNO) && !defined (__MINGW32__) && !defined (__CYGWIN__)
/* h_errno not found in netdb.h, maybe this will help. */ /* h_errno not found in netdb.h, maybe this will help. */
extern int h_errno; extern int h_errno;
@ -266,7 +270,7 @@ SCM_DEFINE (scm_getnet, "getnet", 0, 1, 0,
#undef FUNC_NAME #undef FUNC_NAME
#endif #endif
#ifdef HAVE_GETPROTOENT #if defined (HAVE_GETPROTOENT) || defined (__MINGW32__)
SCM_DEFINE (scm_getproto, "getproto", 0, 1, 0, SCM_DEFINE (scm_getproto, "getproto", 0, 1, 0,
(SCM protocol), (SCM protocol),
"@deffnx {Scheme Procedure} getprotobyname name\n" "@deffnx {Scheme Procedure} getprotobyname name\n"
@ -314,7 +318,7 @@ SCM_DEFINE (scm_getproto, "getproto", 0, 1, 0,
#undef FUNC_NAME #undef FUNC_NAME
#endif #endif
#ifdef HAVE_GETSERVENT #if defined (HAVE_GETSERVENT) || defined (__MINGW32__)
static SCM static SCM
scm_return_entry (struct servent *entry) scm_return_entry (struct servent *entry)
{ {
@ -405,7 +409,7 @@ SCM_DEFINE (scm_setnet, "setnet", 0, 1, 0,
#undef FUNC_NAME #undef FUNC_NAME
#endif #endif
#if defined(HAVE_SETPROTOENT) && defined(HAVE_ENDPROTOENT) #if defined (HAVE_SETPROTOENT) && defined (HAVE_ENDPROTOENT) || defined (__MINGW32__)
SCM_DEFINE (scm_setproto, "setproto", 0, 1, 0, SCM_DEFINE (scm_setproto, "setproto", 0, 1, 0,
(SCM stayopen), (SCM stayopen),
"If @var{stayopen} is omitted, this is equivalent to @code{endprotoent}.\n" "If @var{stayopen} is omitted, this is equivalent to @code{endprotoent}.\n"
@ -421,7 +425,7 @@ SCM_DEFINE (scm_setproto, "setproto", 0, 1, 0,
#undef FUNC_NAME #undef FUNC_NAME
#endif #endif
#if defined(HAVE_SETSERVENT) && defined(HAVE_ENDSERVENT) #if defined (HAVE_SETSERVENT) && defined (HAVE_ENDSERVENT) || defined (__MINGW32__)
SCM_DEFINE (scm_setserv, "setserv", 0, 1, 0, SCM_DEFINE (scm_setserv, "setserv", 0, 1, 0,
(SCM stayopen), (SCM stayopen),
"If @var{stayopen} is omitted, this is equivalent to @code{endservent}.\n" "If @var{stayopen} is omitted, this is equivalent to @code{endservent}.\n"

View file

@ -4390,6 +4390,17 @@ scm_i_big2dbl (SCM b)
#ifdef GUILE_DEBUG #ifdef GUILE_DEBUG
#ifndef SIZE_MAX
#define SIZE_MAX ((size_t) (-1))
#endif
#ifndef PTRDIFF_MIN
#define PTRDIFF_MIN \
((ptrdiff_t) ((ptrdiff_t) 1 << (sizeof (ptrdiff_t) * 8 - 1)))
#endif
#ifndef PTRDIFF_MAX
#define PTRDIFF_MAX (~ PTRDIFF_MIN)
#endif
#define CHECK(type, v) \ #define CHECK(type, v) \
do { \ do { \
if ((v) != scm_num2##type (scm_##type##2num (v), 1, "check_sanity")) \ if ((v) != scm_num2##type (scm_##type##2num (v), 1, "check_sanity")) \

View file

@ -46,7 +46,16 @@
#include "libguile/modules.h" #include "libguile/modules.h"
#include "libguile/numbers.h" #include "libguile/numbers.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <limits.h>
#ifndef PATH_MAX
#define PATH_MAX 255
#endif
#include "win32-socket.h" #include "win32-socket.h"
@ -62,6 +71,46 @@ typedef struct
} }
socket_error_t; socket_error_t;
#define FILE_ETC_SERVICES "services"
#define ENVIRON_ETC_SERVICES "SERVICES"
#define FILE_ETC_NETWORKS "networks"
#define ENVIRON_ETC_NETWORKS "NETWORKS"
#define FILE_ETC_PROTOCOLS "protocol"
#define ENVIRON_ETC_PROTOCOLS "PROTOCOLS"
#define MAX_NAMLEN 256
#define MAX_ALIASES 4
/* Internal structure for a thread's M$-Windows servent interface. */
typedef struct
{
FILE *fd; /* Current file. */
char file[PATH_MAX]; /* File name. */
struct servent ent; /* Return value. */
char name[MAX_NAMLEN]; /* Service name. */
char proto[MAX_NAMLEN]; /* Protocol name. */
char alias[MAX_ALIASES][MAX_NAMLEN]; /* All aliases. */
char *aliases[MAX_ALIASES]; /* Alias pointers. */
int port; /* Network port. */
}
scm_i_servent_t;
static scm_i_servent_t scm_i_servent;
/* Internal structure for a thread's M$-Windows protoent interface. */
typedef struct
{
FILE *fd; /* Current file. */
char file[PATH_MAX]; /* File name. */
struct protoent ent; /* Return value. */
char name[MAX_NAMLEN]; /* Protocol name. */
char alias[MAX_ALIASES][MAX_NAMLEN]; /* All aliases. */
char *aliases[MAX_ALIASES]; /* Alias pointers. */
int proto; /* Protocol number. */
}
scm_i_protoent_t;
static scm_i_protoent_t scm_i_protoent;
/* Define replacement symbols for most of the WSA* error codes. */ /* Define replacement symbols for most of the WSA* error codes. */
#ifndef EWOULDBLOCK #ifndef EWOULDBLOCK
# define EWOULDBLOCK WSAEWOULDBLOCK # define EWOULDBLOCK WSAEWOULDBLOCK
@ -375,6 +424,205 @@ scm_i_socket_strerror (int error)
return NULL; return NULL;
} }
/* Constructs a valid filename for the given file @var{file} in the M$-Windows
directory. This is usually the default location for the network files. */
char *
scm_i_socket_filename (char *file)
{
static char dir[PATH_MAX];
int len = PATH_MAX;
len = GetWindowsDirectory (dir, len);
if (dir[len - 1] != '\\')
strcat (dir, "\\");
strcat (dir, file);
return dir;
}
/* Removes comments and white spaces at end of line and returns a pointer
to the end of the line. */
static char *
scm_i_socket_uncomment (char *line)
{
char *end;
if ((end = strchr (line, '#')) != NULL)
*end-- = '\0';
else
{
end = line + strlen (line) - 1;
while (end > line && (*end == '\r' || *end == '\n'))
*end-- = '\0';
}
while (end > line && isspace (*end))
*end-- = '\0';
return end;
}
/* The getservent() function reads the next line from the file `/etc/services'
and returns a structure servent containing the broken out fields from the
line. The `/etc/services' file is opened if necessary. */
struct servent *
getservent (void)
{
char line[MAX_NAMLEN], *end, *p;
int done = 0, i, n, a;
struct servent *e = NULL;
/* Ensure a open file. */
if (scm_i_servent.fd == NULL || feof (scm_i_servent.fd))
{
setservent (1);
if (scm_i_servent.fd == NULL)
return NULL;
}
while (!done)
{
/* Get new line. */
if (fgets (line, MAX_NAMLEN, scm_i_servent.fd) != NULL)
{
end = scm_i_socket_uncomment (line);
/* Scan the line. */
if ((i = sscanf (line, "%s %d/%s%n",
scm_i_servent.name,
&scm_i_servent.port,
scm_i_servent.proto, &n)) != 3)
continue;
/* Scan the remaining aliases. */
p = line + n;
for (a = 0; a < MAX_ALIASES && p < end && i != -1 && n > 1;
a++, p += n)
i = sscanf (p, "%s%n", scm_i_servent.alias[a], &n);
/* Prepare the return value. */
e = &scm_i_servent.ent;
e->s_name = scm_i_servent.name;
e->s_port = htons (scm_i_servent.port);
e->s_proto = scm_i_servent.proto;
e->s_aliases = scm_i_servent.aliases;
scm_i_servent.aliases[a] = NULL;
while (a--)
scm_i_servent.aliases[a] = scm_i_servent.alias[a];
done = 1;
}
else
break;
}
return done ? e : NULL;
}
/* The setservent() function opens and rewinds the `/etc/services' file.
This file can be set from outside with an environment variable specifying
the file name. */
void
setservent (int stayopen)
{
char *file = NULL;
endservent ();
if ((file = getenv (ENVIRON_ETC_SERVICES)) != NULL)
strcpy (scm_i_servent.file, file);
else if ((file = scm_i_socket_filename (FILE_ETC_SERVICES)) != NULL)
strcpy (scm_i_servent.file, file);
scm_i_servent.fd = fopen (scm_i_servent.file, "rt");
}
/* The endservent() function closes the `/etc/services' file. */
void
endservent (void)
{
if (scm_i_servent.fd != NULL)
{
fclose (scm_i_servent.fd);
scm_i_servent.fd = NULL;
}
}
/* The getprotoent() function reads the next line from the file
`/etc/protocols' and returns a structure protoent containing the broken
out fields from the line. The `/etc/protocols' file is opened if
necessary. */
struct protoent *
getprotoent (void)
{
char line[MAX_NAMLEN], *end, *p;
int done = 0, i, n, a;
struct protoent *e = NULL;
/* Ensure a open file. */
if (scm_i_protoent.fd == NULL || feof (scm_i_protoent.fd))
{
setprotoent (1);
if (scm_i_protoent.fd == NULL)
return NULL;
}
while (!done)
{
/* Get new line. */
if (fgets (line, MAX_NAMLEN, scm_i_protoent.fd) != NULL)
{
end = scm_i_socket_uncomment (line);
/* Scan the line. */
if ((i = sscanf (line, "%s %d%n",
scm_i_protoent.name,
&scm_i_protoent.proto, &n)) != 2)
continue;
/* Scan the remaining aliases. */
p = line + n;
for (a = 0; a < MAX_ALIASES && p < end && i != -1 && n > 1;
a++, p += n)
i = sscanf (p, "%s%n", scm_i_protoent.alias[a], &n);
/* Prepare the return value. */
e = &scm_i_protoent.ent;
e->p_name = scm_i_protoent.name;
e->p_proto = scm_i_protoent.proto;
e->p_aliases = scm_i_protoent.aliases;
scm_i_protoent.aliases[a] = NULL;
while (a--)
scm_i_protoent.aliases[a] = scm_i_protoent.alias[a];
done = 1;
}
else
break;
}
return done ? e : NULL;
}
/* The setprotoent() function opens and rewinds the `/etc/protocols' file.
As in setservent() the user can modify the location of the file using
an environment variable. */
void
setprotoent (int stayopen)
{
char *file = NULL;
endprotoent ();
if ((file = getenv (ENVIRON_ETC_PROTOCOLS)) != NULL)
strcpy (scm_i_protoent.file, file);
else if ((file = scm_i_socket_filename (FILE_ETC_PROTOCOLS)) != NULL)
strcpy (scm_i_protoent.file, file);
scm_i_protoent.fd = fopen (scm_i_protoent.file, "rt");
}
/* The endprotoent() function closes `/etc/protocols'. */
void
endprotoent (void)
{
if (scm_i_protoent.fd != NULL)
{
fclose (scm_i_protoent.fd);
scm_i_protoent.fd = NULL;
}
}
/* Define both the original and replacement error symbol is possible. Thus /* Define both the original and replacement error symbol is possible. Thus
the user is able to check symbolic errors after unsuccessful networking the user is able to check symbolic errors after unsuccessful networking
function calls. */ function calls. */

View file

@ -52,5 +52,13 @@
int scm_i_socket_errno (void); int scm_i_socket_errno (void);
char * scm_i_socket_strerror (int error); char * scm_i_socket_strerror (int error);
void scm_i_init_socket_Win32 (void); void scm_i_init_socket_Win32 (void);
char * scm_i_socket_filename (char *file);
struct servent * getservent (void);
void setservent (int stayopen);
void endservent (void);
struct protoent * getprotoent (void);
void setprotoent (int stayopen);
void endprotoent (void);
#endif /* SCM_WIN32_SOCKET_H */ #endif /* SCM_WIN32_SOCKET_H */