1 /* Copyright (C) 2001, 2006 Free Software Foundation, Inc.
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "libguile/__scm.h"
26 #include "libguile/modules.h"
27 #include "libguile/numbers.h"
40 #include "win32-socket.h"
42 /* Winsock API error description structure. The error description is
43 necessary because there is no error list available. */
46 int error
; /* Error code. */
47 char *str
; /* Error description. */
48 int replace
; /* Possible error code replacement. */
49 char *replace_str
; /* Replacement symbol. */
50 char *correct_str
; /* Original symbol. */
54 #define FILE_ETC_SERVICES "services"
55 #define ENVIRON_ETC_SERVICES "SERVICES"
56 #define FILE_ETC_NETWORKS "networks"
57 #define ENVIRON_ETC_NETWORKS "NETWORKS"
58 #define FILE_ETC_PROTOCOLS "protocol"
59 #define ENVIRON_ETC_PROTOCOLS "PROTOCOLS"
60 #define MAX_NAMLEN 256
63 /* Internal structure for a thread's M$-Windows servent interface. */
66 FILE *fd
; /* Current file. */
67 char file
[PATH_MAX
]; /* File name. */
68 struct servent ent
; /* Return value. */
69 char name
[MAX_NAMLEN
]; /* Service name. */
70 char proto
[MAX_NAMLEN
]; /* Protocol name. */
71 char alias
[MAX_ALIASES
][MAX_NAMLEN
]; /* All aliases. */
72 char *aliases
[MAX_ALIASES
]; /* Alias pointers. */
73 int port
; /* Network port. */
77 static scm_i_servent_t scm_i_servent
;
79 /* Internal structure for a thread's M$-Windows protoent interface. */
82 FILE *fd
; /* Current file. */
83 char file
[PATH_MAX
]; /* File name. */
84 struct protoent ent
; /* Return value. */
85 char name
[MAX_NAMLEN
]; /* Protocol name. */
86 char alias
[MAX_ALIASES
][MAX_NAMLEN
]; /* All aliases. */
87 char *aliases
[MAX_ALIASES
]; /* Alias pointers. */
88 int proto
; /* Protocol number. */
92 static scm_i_protoent_t scm_i_protoent
;
94 /* Define replacement symbols for most of the WSA* error codes. */
96 # define EWOULDBLOCK WSAEWOULDBLOCK
99 # define EINPROGRESS WSAEINPROGRESS
102 # define EALREADY WSAEALREADY
105 # define EDESTADDRREQ WSAEDESTADDRREQ
108 # define EMSGSIZE WSAEMSGSIZE
111 # define EPROTOTYPE WSAEPROTOTYPE
114 # define ENOTSOCK WSAENOTSOCK
117 # define ENOPROTOOPT WSAENOPROTOOPT
119 #ifndef EPROTONOSUPPORT
120 # define EPROTONOSUPPORT WSAEPROTONOSUPPORT
122 #ifndef ESOCKTNOSUPPORT
123 # define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
126 # define EOPNOTSUPP WSAEOPNOTSUPP
129 # define EPFNOSUPPORT WSAEPFNOSUPPORT
132 # define EAFNOSUPPORT WSAEAFNOSUPPORT
135 # define EADDRINUSE WSAEADDRINUSE
137 #ifndef EADDRNOTAVAIL
138 # define EADDRNOTAVAIL WSAEADDRNOTAVAIL
141 # define ENETDOWN WSAENETDOWN
144 # define ENETUNREACH WSAENETUNREACH
147 # define ENETRESET WSAENETRESET
150 # define ECONNABORTED WSAECONNABORTED
153 # define ECONNRESET WSAECONNRESET
156 # define ENOBUFS WSAENOBUFS
159 # define EISCONN WSAEISCONN
162 # define ENOTCONN WSAENOTCONN
165 # define ESHUTDOWN WSAESHUTDOWN
168 # define ETOOMANYREFS WSAETOOMANYREFS
171 # define ETIMEDOUT WSAETIMEDOUT
174 # define ECONNREFUSED WSAECONNREFUSED
177 # define ELOOP WSAELOOP
180 # define EHOSTDOWN WSAEHOSTDOWN
183 # define EHOSTUNREACH WSAEHOSTUNREACH
186 # define EPROCLIM WSAEPROCLIM
189 # define EUSERS WSAEUSERS
192 # define EDQUOT WSAEDQUOT
195 # define ESTALE WSAESTALE
198 # define EREMOTE WSAEREMOTE
201 /* List of error structures. */
202 static socket_error_t socket_errno
[] = {
203 /* 000 */ { 0, NULL
, 0, NULL
, NULL
},
204 /* 001 */ { 0, NULL
, 0, NULL
, NULL
},
205 /* 002 */ { 0, NULL
, 0, NULL
, NULL
},
206 /* 003 */ { 0, NULL
, 0, NULL
, NULL
},
207 /* 004 */ { WSAEINTR
, "Interrupted function call", EINTR
, NULL
, "WSAEINTR" },
208 /* 005 */ { 0, NULL
, 0, NULL
, NULL
},
209 /* 006 */ { 0, NULL
, 0, NULL
, NULL
},
210 /* 007 */ { 0, NULL
, 0, NULL
, NULL
},
211 /* 008 */ { 0, NULL
, 0, NULL
, NULL
},
212 /* 009 */ { WSAEBADF
, "Bad file number", EBADF
, NULL
, "WSAEBADF" },
213 /* 010 */ { 0, NULL
, 0, NULL
, NULL
},
214 /* 011 */ { 0, NULL
, 0, NULL
, NULL
},
215 /* 012 */ { 0, NULL
, 0, NULL
, NULL
},
216 /* 013 */ { WSAEACCES
, "Permission denied", EACCES
, NULL
, "WSAEACCES" },
217 /* 014 */ { WSAEFAULT
, "Bad address", EFAULT
, NULL
, "WSAEFAULT" },
218 /* 015 */ { 0, NULL
, 0, NULL
, NULL
},
219 /* 016 */ { 0, NULL
, 0, NULL
, NULL
},
220 /* 017 */ { 0, NULL
, 0, NULL
, NULL
},
221 /* 018 */ { 0, NULL
, 0, NULL
, NULL
},
222 /* 019 */ { 0, NULL
, 0, NULL
, NULL
},
223 /* 020 */ { 0, NULL
, 0, NULL
, NULL
},
224 /* 021 */ { 0, NULL
, 0, NULL
, NULL
},
225 /* 022 */ { WSAEINVAL
, "Invalid argument", EINVAL
, NULL
, "WSAEINVAL" },
226 /* 023 */ { 0, NULL
, 0, NULL
, NULL
},
227 /* 024 */ { WSAEMFILE
, "Too many open files", EMFILE
, NULL
, "WSAEMFILE" },
228 /* 025 */ { 0, NULL
, 0, NULL
, NULL
},
229 /* 026 */ { 0, NULL
, 0, NULL
, NULL
},
230 /* 027 */ { 0, NULL
, 0, NULL
, NULL
},
231 /* 028 */ { 0, NULL
, 0, NULL
, NULL
},
232 /* 029 */ { 0, NULL
, 0, NULL
, NULL
},
233 /* 030 */ { 0, NULL
, 0, NULL
, NULL
},
234 /* 031 */ { 0, NULL
, 0, NULL
, NULL
},
235 /* 032 */ { 0, NULL
, 0, NULL
, NULL
},
236 /* 033 */ { 0, NULL
, 0, NULL
, NULL
},
237 /* 034 */ { 0, NULL
, 0, NULL
, NULL
},
238 /* 035 */ { WSAEWOULDBLOCK
, "Resource temporarily unavailable",
239 EWOULDBLOCK
, "EWOULDBLOCK", "WSAEWOULDBLOCK" },
240 /* 036 */ { WSAEINPROGRESS
, "Operation now in progress",
241 EINPROGRESS
, "EINPROGRESS", "WSAEINPROGRESS" },
242 /* 037 */ { WSAEALREADY
, "Operation already in progress",
243 EALREADY
, "EALREADY", "WSAEALREADY" },
244 /* 038 */ { WSAENOTSOCK
, "Socket operation on non-socket",
245 ENOTSOCK
, "ENOTSOCK", "WSAENOTSOCK"},
246 /* 039 */ { WSAEDESTADDRREQ
, "Destination address required",
247 EDESTADDRREQ
, "EDESTADDRREQ", "WSAEDESTADDRREQ" },
248 /* 040 */ { WSAEMSGSIZE
, "Message too long",
249 EMSGSIZE
, "EMSGSIZE", "WSAEMSGSIZE" },
250 /* 041 */ { WSAEPROTOTYPE
, "Protocol wrong type for socket",
251 EPROTOTYPE
, "EPROTOTYPE", "WSAEPROTOTYPE" },
252 /* 042 */ { WSAENOPROTOOPT
, "Bad protocol option",
253 ENOPROTOOPT
, "ENOPROTOOPT", "WSAENOPROTOOPT" },
254 /* 043 */ { WSAEPROTONOSUPPORT
, "Protocol not supported",
255 EPROTONOSUPPORT
, "EPROTONOSUPPORT", "WSAEPROTONOSUPPORT" },
256 /* 044 */ { WSAESOCKTNOSUPPORT
, "Socket type not supported",
257 ESOCKTNOSUPPORT
, "ESOCKTNOSUPPORT", "WSAESOCKTNOSUPPORT" },
258 /* 045 */ { WSAEOPNOTSUPP
, "Operation not supported",
259 EOPNOTSUPP
, "EOPNOTSUPP", "WSAEOPNOTSUPP" },
260 /* 046 */ { WSAEPFNOSUPPORT
, "Protocol family not supported",
261 EPFNOSUPPORT
, "EPFNOSUPPORT", "WSAEPFNOSUPPORT" },
262 /* 047 */ { WSAEAFNOSUPPORT
,
263 "Address family not supported by protocol family",
264 EAFNOSUPPORT
, "EAFNOSUPPORT", "WSAEAFNOSUPPORT" },
265 /* 048 */ { WSAEADDRINUSE
, "Address already in use",
266 EADDRINUSE
, "EADDRINUSE", "WSAEADDRINUSE" },
267 /* 049 */ { WSAEADDRNOTAVAIL
, "Cannot assign requested address",
268 EADDRNOTAVAIL
, "EADDRNOTAVAIL", "WSAEADDRNOTAVAIL" },
269 /* 050 */ { WSAENETDOWN
, "Network is down",
270 ENETDOWN
, "ENETDOWN", "WSAENETDOWN" },
271 /* 051 */ { WSAENETUNREACH
, "Network is unreachable",
272 ENETUNREACH
, "ENETUNREACH", "WSAENETUNREACH" },
273 /* 052 */ { WSAENETRESET
, "Network dropped connection on reset",
274 ENETRESET
, "ENETRESET", "WSAENETRESET" },
275 /* 053 */ { WSAECONNABORTED
, "Software caused connection abort",
276 ECONNABORTED
, "ECONNABORTED", "WSAECONNABORTED" },
277 /* 054 */ { WSAECONNRESET
, "Connection reset by peer",
278 ECONNRESET
, "ECONNRESET", "WSAECONNRESET" },
279 /* 055 */ { WSAENOBUFS
, "No buffer space available",
280 ENOBUFS
, "ENOBUFS", "WSAENOBUFS" },
281 /* 056 */ { WSAEISCONN
, "Socket is already connected",
282 EISCONN
, "EISCONN", "WSAEISCONN" },
283 /* 057 */ { WSAENOTCONN
, "Socket is not connected",
284 ENOTCONN
, "ENOTCONN", "WSAENOTCONN" },
285 /* 058 */ { WSAESHUTDOWN
, "Cannot send after socket shutdown",
286 ESHUTDOWN
, "ESHUTDOWN", "WSAESHUTDOWN" },
287 /* 059 */ { WSAETOOMANYREFS
, "Too many references; can't splice",
288 ETOOMANYREFS
, "ETOOMANYREFS", "WSAETOOMANYREFS" },
289 /* 060 */ { WSAETIMEDOUT
, "Connection timed out",
290 ETIMEDOUT
, "ETIMEDOUT", "WSAETIMEDOUT" },
291 /* 061 */ { WSAECONNREFUSED
, "Connection refused",
292 ECONNREFUSED
, "ECONNREFUSED", "WSAECONNREFUSED" },
293 /* 062 */ { WSAELOOP
, "Too many levels of symbolic links",
294 ELOOP
, "ELOOP", "WSAELOOP" },
295 /* 063 */ { WSAENAMETOOLONG
, "File name too long",
296 ENAMETOOLONG
, NULL
, "WSAENAMETOOLONG" },
297 /* 064 */ { WSAEHOSTDOWN
, "Host is down",
298 EHOSTDOWN
, "EHOSTDOWN", "WSAEHOSTDOWN" },
299 /* 065 */ { WSAEHOSTUNREACH
, "No route to host",
300 EHOSTUNREACH
, "EHOSTUNREACH", "WSAEHOSTUNREACH" },
301 /* 066 */ { WSAENOTEMPTY
, "Directory not empty",
302 ENOTEMPTY
, NULL
, "WSAENOTEMPTY" },
303 /* 067 */ { WSAEPROCLIM
, "Too many processes",
304 EPROCLIM
, "EPROCLIM", "WSAEPROCLIM" },
305 /* 068 */ { WSAEUSERS
, "Too many users",
306 EUSERS
, "EUSERS", "WSAEUSERS" },
307 /* 069 */ { WSAEDQUOT
, "Disc quota exceeded",
308 EDQUOT
, "EDQUOT", "WSAEDQUOT" },
309 /* 070 */ { WSAESTALE
, "Stale NFS file handle",
310 ESTALE
, "ESTALE", "WSAESTALE" },
311 /* 071 */ { WSAEREMOTE
, "Too many levels of remote in path",
312 EREMOTE
, "EREMOTE", "WSAEREMOTE" },
313 /* 072 */ { 0, NULL
, 0, NULL
, NULL
},
314 /* 073 */ { 0, NULL
, 0, NULL
, NULL
},
315 /* 074 */ { 0, NULL
, 0, NULL
, NULL
},
316 /* 075 */ { 0, NULL
, 0, NULL
, NULL
},
317 /* 076 */ { 0, NULL
, 0, NULL
, NULL
},
318 /* 077 */ { 0, NULL
, 0, NULL
, NULL
},
319 /* 078 */ { 0, NULL
, 0, NULL
, NULL
},
320 /* 079 */ { 0, NULL
, 0, NULL
, NULL
},
321 /* 080 */ { 0, NULL
, 0, NULL
, NULL
},
322 /* 081 */ { 0, NULL
, 0, NULL
, NULL
},
323 /* 082 */ { 0, NULL
, 0, NULL
, NULL
},
324 /* 083 */ { 0, NULL
, 0, NULL
, NULL
},
325 /* 084 */ { 0, NULL
, 0, NULL
, NULL
},
326 /* 085 */ { 0, NULL
, 0, NULL
, NULL
},
327 /* 086 */ { 0, NULL
, 0, NULL
, NULL
},
328 /* 087 */ { 0, NULL
, 0, NULL
, NULL
},
329 /* 088 */ { 0, NULL
, 0, NULL
, NULL
},
330 /* 089 */ { 0, NULL
, 0, NULL
, NULL
},
331 /* 090 */ { 0, NULL
, 0, NULL
, NULL
},
332 /* 091 */ { WSASYSNOTREADY
, "Network subsystem is unavailable",
333 0, NULL
, "WSASYSNOTREADY" },
334 /* 092 */ { WSAVERNOTSUPPORTED
, "WINSOCK.DLL version out of range",
335 0, NULL
, "WSAVERNOTSUPPORTED" },
336 /* 093 */ { WSANOTINITIALISED
, "Successful WSAStartup not yet performed",
337 0, NULL
, "WSANOTINITIALISED" },
338 /* 094 */ { 0, NULL
, 0, NULL
, NULL
},
339 /* 095 */ { 0, NULL
, 0, NULL
, NULL
},
340 /* 096 */ { 0, NULL
, 0, NULL
, NULL
},
341 /* 097 */ { 0, NULL
, 0, NULL
, NULL
},
342 /* 098 */ { 0, NULL
, 0, NULL
, NULL
},
343 /* 099 */ { 0, NULL
, 0, NULL
, NULL
},
344 /* 100 */ { 0, NULL
, 0, NULL
, NULL
},
345 /* 101 */ { WSAEDISCON
, "Graceful shutdown in progress",
346 0, NULL
, "WSAEDISCON" },
347 /* 102 */ { WSAENOMORE
, "No more services",
348 0, NULL
, "WSAENOMORE" },
349 /* 103 */ { WSAECANCELLED
, "Service lookup cancelled",
350 0, NULL
, "WSAECANCELLED" },
351 /* 104 */ { WSAEINVALIDPROCTABLE
, "Invalid procedure call table",
352 0, NULL
, "WSAEINVALIDPROCTABLE" },
353 /* 105 */ { WSAEINVALIDPROVIDER
, "Invalid service provider",
354 0, NULL
, "WSAEINVALIDPROVIDER" },
355 /* 106 */ { WSAEPROVIDERFAILEDINIT
, "Service provider failure",
356 0, NULL
, "WSAEPROVIDERFAILEDINIT" },
357 /* 107 */ { WSASYSCALLFAILURE
, "System call failed",
358 0, NULL
, "WSASYSCALLFAILURE" },
359 /* 108 */ { WSASERVICE_NOT_FOUND
, "No such service",
360 0, NULL
, "WSASERVICE_NOT_FOUND" },
361 /* 109 */ { WSATYPE_NOT_FOUND
, "Class not found",
362 0, NULL
, "WSATYPE_NOT_FOUND" },
363 /* 110 */ { WSA_E_NO_MORE
, "No more services",
364 0, NULL
, "WSA_E_NO_MORE" },
365 /* 111 */ { WSA_E_CANCELLED
, "Service lookup cancelled",
366 0, NULL
, "WSA_E_CANCELLED" },
367 /* 112 */ { WSAEREFUSED
, "Database query refused",
368 0, NULL
, "WSAEREFUSED" },
369 /* end */ { -1, NULL
, -1, NULL
, NULL
}
372 /* Extended list of error structures. */
373 static socket_error_t socket_h_errno
[] = {
374 /* 000 */ { 0, NULL
, 0, NULL
, NULL
},
375 /* 001 */ { WSAHOST_NOT_FOUND
, "Host not found",
376 HOST_NOT_FOUND
, "HOST_NOT_FOUND", "WSAHOST_NOT_FOUND" },
377 /* 002 */ { WSATRY_AGAIN
, "Non-authoritative host not found",
378 TRY_AGAIN
, "TRY_AGAIN", "WSATRY_AGAIN" },
379 /* 003 */ { WSANO_RECOVERY
, "This is a non-recoverable error",
380 NO_RECOVERY
, "NO_RECOVERY", "WSANO_RECOVERY" },
381 /* 004 */ { WSANO_DATA
, "Valid name, no data record of requested type",
382 NO_DATA
, "NO_DATA", "WSANO_DATA" },
383 /* 005 */ { WSANO_ADDRESS
, "No address, look for MX record",
384 NO_ADDRESS
, "NO_ADDRESS", "WSANO_ADDRESS" },
385 /* end */ { -1, NULL
, -1, NULL
, NULL
}
388 /* Returns the result of @code{WSAGetLastError()}. */
390 scm_i_socket_errno (void)
392 return WSAGetLastError ();
395 /* Returns a valid error message for Winsock-API error codes obtained via
396 @code{WSAGetLastError()} or NULL otherwise. */
398 scm_i_socket_strerror (int error
)
400 if (error
>= WSABASEERR
&& error
<= (WSABASEERR
+ 112))
401 return socket_errno
[error
- WSABASEERR
].str
;
402 else if (error
>= (WSABASEERR
+ 1000) && error
<= (WSABASEERR
+ 1005))
403 return socket_h_errno
[error
- (WSABASEERR
+ 1000)].str
;
407 /* Constructs a valid filename for the given file @var{file} in the M$-Windows
408 directory. This is usually the default location for the network files. */
410 scm_i_socket_filename (char *file
)
412 static char dir
[PATH_MAX
];
415 len
= GetWindowsDirectory (dir
, len
);
416 if (dir
[len
- 1] != '\\')
422 /* Removes comments and white spaces at end of line and returns a pointer
423 to the end of the line. */
425 scm_i_socket_uncomment (char *line
)
429 if ((end
= strchr (line
, '#')) != NULL
)
433 end
= line
+ strlen (line
) - 1;
434 while (end
> line
&& (*end
== '\r' || *end
== '\n'))
437 while (end
> line
&& isspace (*end
))
443 /* The getservent() function reads the next line from the file `/etc/services'
444 and returns a structure servent containing the broken out fields from the
445 line. The `/etc/services' file is opened if necessary. */
449 char line
[MAX_NAMLEN
], *end
, *p
;
450 int done
= 0, i
, n
, a
;
451 struct servent
*e
= NULL
;
453 /* Ensure a open file. */
454 if (scm_i_servent
.fd
== NULL
|| feof (scm_i_servent
.fd
))
457 if (scm_i_servent
.fd
== NULL
)
464 if (fgets (line
, MAX_NAMLEN
, scm_i_servent
.fd
) != NULL
)
466 end
= scm_i_socket_uncomment (line
);
469 if ((i
= sscanf (line
, "%s %d/%s%n",
472 scm_i_servent
.proto
, &n
)) != 3)
475 /* Scan the remaining aliases. */
477 for (a
= 0; a
< MAX_ALIASES
&& p
< end
&& i
!= -1 && n
> 1;
479 i
= sscanf (p
, "%s%n", scm_i_servent
.alias
[a
], &n
);
481 /* Prepare the return value. */
482 e
= &scm_i_servent
.ent
;
483 e
->s_name
= scm_i_servent
.name
;
484 e
->s_port
= htons (scm_i_servent
.port
);
485 e
->s_proto
= scm_i_servent
.proto
;
486 e
->s_aliases
= scm_i_servent
.aliases
;
487 scm_i_servent
.aliases
[a
] = NULL
;
489 scm_i_servent
.aliases
[a
] = scm_i_servent
.alias
[a
];
495 return done
? e
: NULL
;
498 /* The setservent() function opens and rewinds the `/etc/services' file.
499 This file can be set from outside with an environment variable specifying
502 setservent (int stayopen
)
507 if ((file
= getenv (ENVIRON_ETC_SERVICES
)) != NULL
)
508 strcpy (scm_i_servent
.file
, file
);
509 else if ((file
= scm_i_socket_filename (FILE_ETC_SERVICES
)) != NULL
)
510 strcpy (scm_i_servent
.file
, file
);
511 scm_i_servent
.fd
= fopen (scm_i_servent
.file
, "rt");
514 /* The endservent() function closes the `/etc/services' file. */
518 if (scm_i_servent
.fd
!= NULL
)
520 fclose (scm_i_servent
.fd
);
521 scm_i_servent
.fd
= NULL
;
525 /* The getprotoent() function reads the next line from the file
526 `/etc/protocols' and returns a structure protoent containing the broken
527 out fields from the line. The `/etc/protocols' file is opened if
532 char line
[MAX_NAMLEN
], *end
, *p
;
533 int done
= 0, i
, n
, a
;
534 struct protoent
*e
= NULL
;
536 /* Ensure a open file. */
537 if (scm_i_protoent
.fd
== NULL
|| feof (scm_i_protoent
.fd
))
540 if (scm_i_protoent
.fd
== NULL
)
547 if (fgets (line
, MAX_NAMLEN
, scm_i_protoent
.fd
) != NULL
)
549 end
= scm_i_socket_uncomment (line
);
552 if ((i
= sscanf (line
, "%s %d%n",
554 &scm_i_protoent
.proto
, &n
)) != 2)
557 /* Scan the remaining aliases. */
559 for (a
= 0; a
< MAX_ALIASES
&& p
< end
&& i
!= -1 && n
> 1;
561 i
= sscanf (p
, "%s%n", scm_i_protoent
.alias
[a
], &n
);
563 /* Prepare the return value. */
564 e
= &scm_i_protoent
.ent
;
565 e
->p_name
= scm_i_protoent
.name
;
566 e
->p_proto
= scm_i_protoent
.proto
;
567 e
->p_aliases
= scm_i_protoent
.aliases
;
568 scm_i_protoent
.aliases
[a
] = NULL
;
570 scm_i_protoent
.aliases
[a
] = scm_i_protoent
.alias
[a
];
576 return done
? e
: NULL
;
579 /* The setprotoent() function opens and rewinds the `/etc/protocols' file.
580 As in setservent() the user can modify the location of the file using
581 an environment variable. */
583 setprotoent (int stayopen
)
588 if ((file
= getenv (ENVIRON_ETC_PROTOCOLS
)) != NULL
)
589 strcpy (scm_i_protoent
.file
, file
);
590 else if ((file
= scm_i_socket_filename (FILE_ETC_PROTOCOLS
)) != NULL
)
591 strcpy (scm_i_protoent
.file
, file
);
592 scm_i_protoent
.fd
= fopen (scm_i_protoent
.file
, "rt");
595 /* The endprotoent() function closes `/etc/protocols'. */
599 if (scm_i_protoent
.fd
!= NULL
)
601 fclose (scm_i_protoent
.fd
);
602 scm_i_protoent
.fd
= NULL
;
606 /* Define both the original and replacement error symbol is possible. Thus
607 the user is able to check symbolic errors after unsuccessful networking
610 scm_socket_symbols_Win32 (socket_error_t
* e
)
612 while (e
->error
!= -1)
617 scm_c_define (e
->correct_str
, scm_from_int (e
->error
));
618 if (e
->replace
&& e
->replace_str
)
619 scm_c_define (e
->replace_str
, scm_from_int (e
->replace
));
625 /* Initialize Winsock API under M$-Windows. */
627 scm_i_init_socket_Win32 (void)
629 scm_socket_symbols_Win32 (socket_errno
);
630 scm_socket_symbols_Win32 (socket_h_errno
);