diff --git a/src/encode.c b/src/encode.c
index 72fd2e0f7a3b36d1f6633d0e63a4699d21a27709..99cb9b4c6056ae641f07b30fb8b962976f1ade11 100644
--- a/src/encode.c
+++ b/src/encode.c
@@ -466,41 +466,6 @@ static void encode_type(struct pike_type *t, struct encode_data *data)
   }
 }
 
-static void zap_unfinished_program(struct program *p)
-{
-  int e;
-  debug_malloc_touch(p);
-  if(p->flags & PROGRAM_FIXED) return; /* allow natural zapping */
-  debug_malloc_touch(p);
-  if(p->parent)
-  {
-    free_program(p->parent);
-    p->parent=0;
-  }
-  for(e=0;e<p->num_constants;e++)
-  {
-    free_svalue(& p->constants[e].sval);
-    mark_free_svalue (&p->constants[e].sval);
-  }
-  
-  for(e=0;e<p->num_inherits;e++)
-  {
-    if(p->inherits[e].parent)
-    {
-      free_object(p->inherits[e].parent);
-      p->inherits[e].parent=0;
-    }
-    if(e)
-    {
-      if(p->inherits[e].prog)
-      {
-	free_program(p->inherits[e].prog);
-	p->inherits[e].prog=0;
-      }
-    }
-  }
-}
-
 /* force_encode == 0: Maybe dump the thing later, and only a forward
  * reference here (applies to programs only).
  *
@@ -2054,7 +2019,7 @@ static int my_extract_char(struct decode_data *data)
 
 static DECLSPEC(noreturn) void decode_error (
   struct decode_data *data, struct svalue *decoding, const char *msg, ...)
-  ATTRIBUTE((noreturn));
+    ATTRIBUTE((noinline,noreturn));
 
 static DECLSPEC(noreturn) void decode_error (
   struct decode_data *data, struct svalue *decoding, const char *msg, ...)
@@ -2065,8 +2030,7 @@ static DECLSPEC(noreturn) void decode_error (
   struct object *o = fast_clone_object (decode_error_program);
   struct decode_error_struct *dec =
     (struct decode_error_struct *) (o->storage + decode_error_offset);
-  struct generic_error_struct *gen =
-    (struct generic_error_struct *) get_storage (o, generic_error_program);
+  struct generic_error_struct *gen = get_storage (o, generic_error_program);
 
   ASSERT_THREAD_SWAPPED_IN();
 
@@ -2450,8 +2414,6 @@ static void zap_placeholder(struct object *placeholder)
   free_object(placeholder);
 }
 
-static int init_placeholder(struct object *placeholder);
-
 
 #define SETUP_DECODE_MEMOBJ(TYPE, U, VAR, ALLOCATE,SCOUR) do {		\
   struct svalue *tmpptr;						\
@@ -4164,27 +4126,6 @@ decode_done:;
 #endif
 }
 
-/* Placed after to prevent inlining */
-static int init_placeholder(struct object *placeholder)
-{
-  JMP_BUF rec;
-  /* Initialize the placeholder. */
-  if(SETJMP(rec))
-  {
-    dmalloc_touch_svalue(&throw_value);
-    call_handle_error();
-    zap_placeholder(placeholder);
-    UNSETJMP(rec);
-    return 1;
-  }else{
-    call_pike_initializers(placeholder,0);
-    UNSETJMP(rec);
-    return 0;
-  }
-}
-
-
-
 static struct decode_data *current_decode = NULL;
 
 static void free_decode_data (struct decode_data *data, int delay,
diff --git a/src/modules/_Stdio/#udp.c# b/src/modules/_Stdio/#udp.c#
deleted file mode 100644
index 2c7c9a18774037a7c3ca4343adb63415f61be814..0000000000000000000000000000000000000000
--- a/src/modules/_Stdio/#udp.c#
+++ /dev/null
@@ -1,1543 +0,0 @@
-/*
-|| This file is part of Pike. For copyright information see COPYRIGHT.
-|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING
-|| for more information.
-*/
-
-#define NO_PIKE_SHORTHAND
-#include "global.h"
-
-#include "file_machine.h"
-
-#include "fdlib.h"
-#include "pike_netlib.h"
-#include "interpret.h"
-#include "svalue.h"
-#include "stralloc.h"
-#include "array.h"
-#include "mapping.h"
-#include "object.h"
-#include "backend.h"
-#include "time_stuff.h"
-#include "fd_control.h"
-
-#include "pike_error.h"
-#include "signal_handler.h"
-#include "pike_types.h"
-#include "threads.h"
-#include "bignum.h"
-
-#include "module_support.h"
-#include "builtin_functions.h"
-#include "file.h"
-
-#ifdef HAVE_SYS_TYPE_H
-#include <sys/types.h>
-#endif
-
-#include <sys/stat.h>
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif /* HAVE_SYS_TIME_H */
-
-#ifdef HAVE_POLL
-
-#ifdef HAVE_POLL_H
-#include <poll.h>
-#endif /* HAVE_POLL_H */
-
-#ifdef HAVE_SYS_POLL_H
-#include <sys/poll.h>
-#endif /* HAVE_SYS_POLL_H */
-
-/* Some constants... */
-
-#ifndef POLLRDNORM
-#define POLLRDNORM	POLLIN
-#endif /* !POLLRDNORM */
-
-#ifndef POLLRDBAND
-#define POLLRDBAND	POLLPRI
-#endif /* !POLLRDBAND */
-
-#else /* !HAVE_POLL */
-
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#endif /* HAVE_POLL */
-
-#if ! defined(EWOULDBLOCK) && defined(WSAEWOULDBLOCK)
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#endif
-#if ! defined(EADDRINUSE) && defined(WSAEADDRINUSE)
-#define EADDRINUSE WSAEADDRINUSE
-#endif
-
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-#ifndef ARPA_INET_H
-#include <arpa/inet.h>
-#define ARPA_INET_H
-
-/* Stupid patch to avoid trouble with Linux includes... */
-#ifdef LITTLE_ENDIAN
-#undef LITTLE_ENDIAN
-#endif
-
-#endif
-#endif
-
-#ifdef HAVE_SYS_PROTOSW_H
-#include <sys/protosw.h>
-#endif
-
-#ifdef HAVE_SYS_STREAM_H
-#include <sys/stream.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKETVAR_H
-#include <sys/socketvar.h>
-#endif
-
-/* Fix warning on OSF/1
- *
- * NOERROR is defined by both sys/stream.h (-1), and arpa/nameser.h (0),
- * the latter is included by netdb.h.
- */
-#ifdef NOERROR
-#undef NOERROR
-#endif /* NOERROR */
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-#include "dmalloc.h"
-
-struct udp_storage {
-  struct fd_callback_box box;	/* Must be first. */
-  int my_errno;
-   
-  int inet_flags;
-
-  int type;
-  int protocol;
-
-  struct svalue read_callback;	/* Mapped. */
-};
-
-void zero_udp(struct object *ignored);
-int low_exit_udp(void);
-void exit_udp(struct object *UNUSED(ignored)) {
-  low_exit_udp();
-}
-
-#undef THIS
-#define THIS ((struct udp_storage *)Pike_fp->current_storage)
-#define THISOBJ (Pike_fp->current_object)
-#define FD (THIS->box.fd)
-
-/*! @module Stdio
- */
-
-/*! @class UDP
- */
-
-/*! @decl int(0..1) close()
- *!
- *! Closes an open UDP port.
- *!
- *! @note
- *!   This method was introduced in Pike 7.5.
- */
-static void udp_close(INT32 args)
-{
-  int ret = low_exit_udp();
-  zero_udp(NULL);
-  pop_n_elems(args);
-  push_int( ret==0 );
-}
-
-/*! @decl UDP bind(int|string port, string|void address,@
- *!string|int(0..1) no_reuseaddr)
- *!
- *! Binds a port for receiving or transmitting UDP.
- *!
- *! @param no_reuseaddr
- *! 	If set to @expr{1@}, Pike will not set the @expr{SO_REUSEADDR@} option
- *! 	on the UDP port.
- *!
- *! @note
- *! 	@expr{SO_REUSEADDR@} is never applied when binding a random port
- *!	(@expr{bind(0)@}).
- *!
- *! 	In general, @expr{SO_REUSEADDR@} is not desirable on UDP ports.
- *! 	Unless used for receiving multicast, be sure to never bind a
- *! 	non-random port without setting @expr{no_reuseaddr@} to @expr{1@}.
- *!
- *! @throws
- *!   Throws error when unable to bind port.
- */
-static void udp_bind(INT32 args)
-{
-  PIKE_SOCKADDR addr;
-  int addr_len;
-  int o;
-  int fd,tmp;
-#if !defined(SOL_IP) && defined(HAVE_GETPROTOBYNAME)
-  static int ip_proto_num = -1;
-#endif /* !SOL_IP && HAVE_GETPROTOBYNAME */
-
-  if(args < 1)
-    SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.UDP->bind", 1);
-
-  if(TYPEOF(Pike_sp[-args]) != PIKE_T_INT &&
-     (TYPEOF(Pike_sp[-args]) != PIKE_T_STRING ||
-      Pike_sp[-args].u.string->size_shift))
-    SIMPLE_BAD_ARG_ERROR("Stdio.UDP->bind", 1, "int|string (8bit)");
-
-  if(args > 2 && TYPEOF(Pike_sp[2-args]) != PIKE_T_INT)
-    SIMPLE_BAD_ARG_ERROR("Stdio.UDP->bind", 3, "int(0..1)");
-
-#if 0
-  f_backtrace(0);
-  APPLY_MASTER("handle_error", 1);
-  pop_stack();
-#endif /* 0 */
-
-  if(FD != -1)
-  {
-    fd = FD;
-    change_fd_for_box (&THIS->box, -1);
-    fd_close(fd);
-  }
-
-  THIS->inet_flags &= ~PIKE_INET_FLAG_IPV6;
-
-  addr_len = get_inet_addr(&addr, (args > 1 && TYPEOF(Pike_sp[1-args])==PIKE_T_STRING?
-				   Pike_sp[1-args].u.string->str : NULL),
-			   (TYPEOF(Pike_sp[-args]) == PIKE_T_STRING?
-			    Pike_sp[-args].u.string->str : NULL),
-			   (TYPEOF(Pike_sp[-args]) == PIKE_T_INT?
-			    Pike_sp[-args].u.integer : -1),
-			   THIS->inet_flags);
-  INVALIDATE_CURRENT_TIME();
-
-#ifdef AF_INET6
-  if (SOCKADDR_FAMILY(addr) == AF_INET6) {
-    THIS->inet_flags |= PIKE_INET_FLAG_IPV6;
-  }
-#endif
-
-  fd = fd_socket(SOCKADDR_FAMILY(addr), THIS->type, THIS->protocol);
-  if(fd < 0)
-  {
-    pop_n_elems(args);
-    THIS->my_errno=errno;
-    Pike_error("Stdio.UDP->bind: failed to create socket (%d, %d, %d)\n",
-	       SOCKADDR_FAMILY(addr), THIS->type, THIS->protocol);
-  }
-
-  /* Make sure this fd gets closed on exec. */
-  set_close_on_exec(fd, 1);
-
-  o=1;
-  /* linux kernel commit f24d43c07e208372aa3d3bff419afbf43ba87698 introduces
-   * a behaviour change where you can get used random ports if bound with
-   * SO_REUSEADDR. */
-  if(addr.ipv4.sin_port && (args > 2 ? !Pike_sp[2-args].u.integer : 1)
-     && fd_setsockopt(fd, SOL_SOCKET,SO_REUSEADDR,
-		      (char *)&o, sizeof(int)) < 0)
-  {
-    fd_close(fd);
-    THIS->my_errno=errno;
-    Pike_error("Stdio.UDP->bind: setsockopt SO_REUSEADDR failed\n");
-  }
-
-#if defined(IPV6_V6ONLY) && defined(IPPROTO_IPV6)
-  if (SOCKADDR_FAMILY(addr) == AF_INET6) {
-    /* Attempt to enable dual-stack (ie mapped IPv4 adresses). Needed on WIN32.
-     * cf http://msdn.microsoft.com/en-us/library/windows/desktop/bb513665(v=vs.85).aspx
-     */
-    o = 0;
-    fd_setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&o, sizeof(int));
-  }
-#endif
-
-#ifndef SOL_IP
-#ifdef HAVE_GETPROTOBYNAME
-  if (ip_proto_num == -1) {
-    /* NOTE: getprotobyname(3N) is not MT-safe. */
-    struct protoent *proto = getprotobyname("ip");
-    if (!proto) {
-      /* No entry for IP, assume zero. */
-      ip_proto_num = 0;
-    } else {
-      ip_proto_num = proto->p_proto;
-    }
-  }
-#define SOL_IP ip_proto_num
-#else /* !HAVE_GETPROTOBYNAME */
-#define SOL_IP 0
-#endif /* HAVE_GETPROTOBYNAME */
-#endif /* SOL_IP */
-
-#ifdef IP_HDRINCL
-  /*  From mtr-0.28:net.c: FreeBSD wants this to avoid sending
-      out packets with protocol type RAW to the network. */
-
-  if (THIS->type==SOCK_RAW && THIS->protocol==255 /* raw */)
-     if(fd_setsockopt(fd, SOL_IP, IP_HDRINCL, (char *)&o, sizeof(int)))
-	Pike_error("Stdio.UDP->bind: setsockopt IP_HDRINCL failed\n");
-#endif /* IP_HDRINCL */
-
-  THREADS_ALLOW_UID();
-
-  tmp=fd_bind(fd, (struct sockaddr *)&addr, addr_len)<0;
-
-  THREADS_DISALLOW_UID();
-
-  if(tmp)
-  {
-    fd_close(fd);
-    THIS->my_errno=errno;
-    Pike_error("Stdio.UDP->bind: failed to bind to port %d\n",
-	       (unsigned INT16)Pike_sp[-args].u.integer);
-    return;
-  }
-
-  if(!Pike_fp->current_object->prog)
-  {
-    if (fd >= 0)
-      while (fd_close(fd) && errno == EINTR) {}
-    Pike_error("Object destructed in Stdio.UDP->bind()\n");
-  }
-
-  change_fd_for_box (&THIS->box, fd);
-  pop_n_elems(args);
-  ref_push_object(THISOBJ);
-}
-
-
-/*! @decl UDP set_fd(int fd)
- *!
- *! Use the file descriptor @[fd] for UDP.
- *! @seealso
- *!   @[bind]
- */
-static void udp_set_fd(INT32 args)
-{
-  int fd;
-
-  get_all_args("set_fd", args, "%d", &fd);
-
-  if(FD != -1)
-  {
-    int curfd = FD;
-    change_fd_for_box (&THIS->box, -1);
-    fd_close(curfd);
-  }
-
-  change_fd_for_box (&THIS->box, fd);
-  pop_n_elems(args);
-  ref_push_object(THISOBJ);
-}
-
-/*! @decl int query_fd()
- *!
- *! Gets the file descriptor for this UDP port.
- */
-static void udp_query_fd(INT32 args)
-{
-  pop_n_elems(args);
-  push_int(FD);
-}
-
-
-
-/*! @decl int(0..1) enable_broadcast()
- *!
- *! Set the broadcast flag. 
- *! If enabled then sockets receive packets sent  to  a  broadcast
- *! address  and  they are allowed to send packets to a
- *! broadcast address.
- *!
- *! @returns
- *!  Returns @expr{1@} on success, @expr{0@} (zero) otherwise.
- *!
- *! @note
- *!  This is normally only avalable to root users.
- */
-void udp_enable_broadcast(INT32 args)
-{
-#ifdef SO_BROADCAST
-  int o = 1;
-  pop_n_elems(args);
-  push_int(fd_setsockopt(FD, SOL_SOCKET, SO_BROADCAST, (char *)&o, sizeof(int)));
-  THIS->my_errno=errno;
-#else /* SO_BROADCAST */
-  pop_n_elems(args);
-  push_int(0);
-#endif /* SO_BROADCAST */
-}
-
-/*! @decl int(0..1) enable_multicast(string reply_address)
- *!   Set the local device for a multicast socket.
- *!
- *! @param reply_address
- *!   Local address that should appear in the multicast packets.
- *!
- *! See also the Unix man page for setsocketopt IPPROTO_IP IP_MULTICAST_IF
- *! and IPPROTO_IPV6 IPV6_MULTICAST_IF.
- *!
- *! @note
- *!   This function did not support IPv6 in Pike 7.8.
- */
-void udp_enable_multicast(INT32 args)
-{
-  int result;
-  char *ip;
-  PIKE_SOCKADDR reply;
-
-  get_all_args("enable_multicast", args, "%s", &ip);
-
-  get_inet_addr(&reply, ip, NULL, -1, THIS->inet_flags);
-  INVALIDATE_CURRENT_TIME();
-
-#ifdef AF_INET6
-  if (THIS->inet_flags & PIKE_INET_FLAG_IPV6) {
-    if(SOCKADDR_FAMILY(reply) != AF_INET6)
-      Pike_error("Multicast only supported for IPv6.\n");
-
-    result = fd_setsockopt(FD, IPPROTO_IPV6, IPV6_MULTICAST_IF,
-			   (char *)&reply.ipv6.sin6_addr,
-			   sizeof(reply.ipv6.sin6_addr));
-    pop_n_elems(args);
-    push_int(result);
-    return;
-  }
-#endif
-  if(SOCKADDR_FAMILY(reply) != AF_INET)
-    Pike_error("Multicast only supported for IPv4.\n");
-
-  result = fd_setsockopt(FD, IPPROTO_IP, IP_MULTICAST_IF,
-			 (char *)&reply.ipv4.sin_addr,
-			 sizeof(reply.ipv4.sin_addr));
-  pop_n_elems(args);
-  push_int(result);
-}
-
-/*! @decl int set_multicast_ttl(int ttl)
- *!   Set the time-to-live value of outgoing multicast packets
- *!   for this socket.
- *!
- *! @param ttl
- *!   The number of router hops sent multicast packets should
- *!   survive.
- *!
- *!   It is very important for multicast packets to set the
- *!   smallest TTL possible. The default before calling this
- *!   function is 1 which means that multicast packets don't
- *!   leak from the local network unless the user program
- *!   explicitly requests it.
- *!
- *! See also the Unix man page for setsocketopt IPPROTO_IP IP_MULTICAST_TTL
- *! and IPPROTO_IPV6 IPV6_MULTICAST_HOPS.
- *!
- *! @note
- *!   This function did not support IPv6 in Pike 7.8 and earlier.
- *!
- *! @seealso
- *!   @[add_membership()]
- */
-void udp_set_multicast_ttl(INT32 args)
-{
-  int ttl;
-  get_all_args("set_multicast_ttl", args, "%d", &ttl);
-  pop_n_elems(args);
-#ifdef AF_INET6
-  if (THIS->inet_flags & PIKE_INET_FLAG_IPV6) {
-    push_int( fd_setsockopt(FD, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
-			    (char *)&ttl, sizeof(int)) );
-    return;
-  }
-#endif
-  push_int( fd_setsockopt(FD, IPPROTO_IP, IP_MULTICAST_TTL,
-			  (char *)&ttl, sizeof(int)) );
-}
-
-/*! @decl int add_membership(string group, void|string address)
- *!   Join a multicast group.
- *!
- *! @param group
- *!   @[group] contains the address of the multicast group the
- *!   application wants to join. It must be a valid multicast address.
- *!
- *! @param address
- *!   @[address] is the address of the local interface with which
- *!   the system should join to the multicast group. If not provided
- *!   the system will select an appropriate interface.
- *!
- *! See also the Unix man page for setsocketopt IPPROTO_IP IP_ADD_MEMBERSHIP
- *! and IPPROTO_IPV6 IPV6_JOIN_GROUP.
- *!
- *! @note
- *!   The @[address] parameter is currently not supported for IPv6.
- *!
- *! @note
- *!   This function did not support IPv6 in Pike 7.8 and earlier.
- *!
- *! @seealso
- *!   @[drop_membership()]
- */
-void udp_add_membership(INT32 args)
-{
-  int face=0;
-  char *group;
-  char *address=0;
-  struct ip_mreq sock;
-  PIKE_SOCKADDR addr;
-
-  get_all_args("add_membership", args, "%s.%s%d", &group, &address, &face);
-
-  get_inet_addr(&addr, group, NULL, -1, THIS->inet_flags);
-  INVALIDATE_CURRENT_TIME();
-
-#ifdef AF_INET6
-  if (THIS->inet_flags & PIKE_INET_FLAG_IPV6) {
-    struct ipv6_mreq sock;
-
-    if (address)
-      Pike_error("Interface address is not supported for IPv6.\n");
-
-    /* NB: This sets imr_interface to IN6ADDR_ANY,
-     *     and clears imr_ifindex if it exists.
-     */
-    MEMSET(&sock, 0, sizeof(sock));
-
-    if(SOCKADDR_FAMILY(addr) != AF_INET6)
-      Pike_error("Mixing IPv6 and other multicast is not supported.\n");
-
-    sock.ipv6mr_multiaddr = addr.ipv6.sin6_addr;
-
-    pop_n_elems(args);
-    push_int( fd_setsockopt(FD, IPPROTO_IPV6, IPV6_JOIN_GROUP,
-			    (char *)&sock, sizeof(sock)) );
-    return;
-  }
-#endif /* AF_INET6 */
-
-  /* NB: This sets imr_interface to INADDR_ANY,
-   *     and clears imr_ifindex if it exists.
-   */
-  MEMSET(&sock, 0, sizeof(sock));
-
-  if(SOCKADDR_FAMILY(addr) != AF_INET)
-    Pike_error("Mixing IPv6 and IPv4 multicast is not supported.\n");
-
-  sock.imr_multiaddr = addr.ipv4.sin_addr;
-
-  if (address) {
-    get_inet_addr(&addr, address, NULL, -1, THIS->inet_flags);
-    INVALIDATE_CURRENT_TIME();
-
-    if(SOCKADDR_FAMILY(addr) != AF_INET)
-      Pike_error("Mixing IPv6 and IPv4 multicast is not supported.\n");
-
-    sock.imr_interface = addr.ipv4.sin_addr;
-  }
-
-  pop_n_elems(args);
-  push_int( fd_setsockopt(FD, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-			  (char *)&sock, sizeof(sock)) );
-}
-
-/*! @decl int drop_membership(string group, void|string address)
- *!   Leave a multicast group.
- *!
- *! @param group
- *!   @[group] contains the address of the multicast group the
- *!   application wants to join. It must be a valid multicast address.
- *!
- *! @param address
- *!   @[address] is the address of the local interface with which
- *!   the system should join to the multicast group. If not provided
- *!   the system will select an appropriate interface.
- *!
- *! See also the Unix man page for setsocketopt IPPROTO_IP IP_DROP_MEMBERSHIP
- *! and IPPROTO_IPV6 IPV6_LEAVE_GROUP.
- *!
- *! @note
- *!   The @[address] parameter is currently not supported for IPv6.
- *!
- *! @note
- *!   This function did not support IPv6 in Pike 7.8 and earlier.
- *!
- *! @seealso
- *!   @[add_membership()]
- */
-void udp_drop_membership(INT32 args)
-{
-  int face=0;
-  char *group;
-  char *address=0;
-  struct ip_mreq sock;
-  PIKE_SOCKADDR addr;
-
-  get_all_args("drop_membership", args, "%s.%s%d", &group, &address, &face);
-
-  get_inet_addr(&addr, group, NULL, -1, THIS->inet_flags);
-  INVALIDATE_CURRENT_TIME();
-
-#ifdef AF_INET6
-  if (THIS->inet_flags & PIKE_INET_FLAG_IPV6) {
-    struct ipv6_mreq sock;
-
-    if (address)
-      Pike_error("Interface address is not supported for IPv6.\n");
-
-    /* NB: This sets imr_interface to IN6ADDR_ANY,
-     *     and clears imr_ifindex if it exists.
-     */
-    MEMSET(&sock, 0, sizeof(sock));
-
-    if(SOCKADDR_FAMILY(addr) != AF_INET6)
-      Pike_error("Mixing IPv6 and other multicast is not supported.\n");
-
-    sock.ipv6mr_multiaddr = addr.ipv6.sin6_addr;
-
-    pop_n_elems(args);
-    push_int( fd_setsockopt(FD, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
-			    (char *)&sock, sizeof(sock)) );
-    return;
-  }
-#endif /* AF_INET6 */
-
-  /* NB: This sets imr_interface to INADDR_ANY,
-   *     and clears imr_ifindex if it exists.
-   */
-  MEMSET(&sock, 0, sizeof(sock));
-
-  if(SOCKADDR_FAMILY(addr) != AF_INET)
-    Pike_error("Mixing IPv6 and IPv4 multicast is not supported.\n");
-
-  sock.imr_multiaddr = addr.ipv4.sin_addr;
-
-  if (address) {
-    get_inet_addr(&addr, address, NULL, -1, THIS->inet_flags);
-    INVALIDATE_CURRENT_TIME();
-
-    if(SOCKADDR_FAMILY(addr) != AF_INET)
-      Pike_error("Mixing IPv6 and IPv4 multicast is not supported.\n");
-
-    sock.imr_interface = addr.ipv4.sin_addr;
-  }
-
-  pop_n_elems(args);
-  push_int( fd_setsockopt(FD, IPPROTO_IP, IP_DROP_MEMBERSHIP,
-			  (char *)&sock, sizeof(sock)) );
-}
-
-/*! @decl int(0..1) wait(int|float timeout)
- *!
- *! Check for data and wait max. @[timeout] seconds.
- *!
- *! @returns
- *!  Returns @expr{1@} if data are ready, @expr{0@} (zero) otherwise.
- */
-void udp_wait(INT32 args)
-{
-#ifdef HAVE_POLL
-  struct pollfd pollfds[1];
-  int ms;
-#else /* !HAVE_POLL */
-  fd_set rset;
-  struct timeval tv;
-#endif /* HAVE_POLL */
-  FLOAT_TYPE timeout;
-  int fd = FD;
-  int res;
-  int e;
-
-  get_all_args("wait", args, "%F", &timeout);
-
-  if (timeout < 0.0) {
-    timeout = 0.0;
-  }
-
-  if (fd < 0) {
-    Pike_error("udp->wait(): Port not bound!\n");
-  }
-
-#ifdef HAVE_POLL
-  THREADS_ALLOW();
-
-  pollfds->fd = fd;
-  pollfds->events = POLLIN;
-  pollfds->revents = 0;
-  ms = timeout * 1000;
-
-  do {
-    res = poll(pollfds, 1, ms);
-    e = errno;
-  } while (res < 0 && e == EINTR)
-    
-  THREADS_DISALLOW();
-  if (!res) {
-    /* Timeout */
-  } else if (res < 0) {
-    /* Error */
-    Pike_error("udp->wait(): poll() failed with errno %d\n", e);
-  } else {
-    /* Success? */
-    if (pollfds->revents) {
-      res = 1;
-    } else {
-      res = 0;
-    }
-  }
-#else /* !HAVE_POLL */
-  THREADS_ALLOW();
-
-  FD_ZERO(&rset);
-  FD_SET(fd, &rset);
-  tv.tv_sec = DO_NOT_WARN((int)timeout);
-  tv.tv_usec = DO_NOT_WARN((int)((timeout - ((int)timeout)) * 1000000.0));
-  res = fd_select(fd+1, &rset, NULL, NULL, &tv);
-  e = errno;
-
-  THREADS_DISALLOW();
-  if (!res) {
-    /* Timeout */
-  } else if (res < 0) {
-    /* Error */
-    Pike_error("udp->wait(): select() failed with errno %d\n", e);
-  } else {
-    /* Success? */
-    if (FD_ISSET(fd, &rset)) {
-      res = 1;
-    } else {
-      res = 0;
-    }
-  }
-#endif /* HAVE_POLL */
-
-  pop_n_elems(args);
-
-  push_int(res);
-}
-
-/* NOTE: Some versions of AIX seem to have a
- *         #define events reqevents
- *       in one of the poll headerfiles. This will break
- *       the fd_box event handling.
- */
-#undef events
-
-#define UDP_BUFFSIZE 65536
-
-/*! @decl mapping(string:int|string) read()
- *! @decl mapping(string:int|string) read(int flag)
- *!
- *! Read from the UDP socket.
- *!
- *! Flag @[flag] is a bitfield, 1 for out of band data and 2 for peek
- *!
- *! @returns
- *!  mapping(string:int|string) in the form 
- *!	([
- *!	   "data" : string received data
- *!	   "ip" : string   received from this ip
- *!	   "port" : int    ...and this port
- *!	])
- *!
- *! @seealso
- *!   @[set_read_callback()], @[MSG_OOB], @[MSG_PEEK]
- */
-void udp_read(INT32 args)
-{
-  int flags = 0, res=0, fd, e;
-  PIKE_SOCKADDR from;
-  char buffer[UDP_BUFFSIZE];
-  ACCEPT_SIZE_T fromlen = sizeof(from);
-  
-  if(args)
-  {
-    if(Pike_sp[-args].u.integer & 1) {
-      flags |= MSG_OOB;
-    }
-    if(Pike_sp[-args].u.integer & 2) {
-#ifdef MSG_PEEK
-      flags |= MSG_PEEK;
-#else /* !MSG_PEEK */
-      /* FIXME: What should we do here? */
-#endif /* MSG_PEEK */
-    }
-    if(Pike_sp[-args].u.integer & ~3) {
-      Pike_error("Illegal 'flags' value passed to udp->read([int flags])\n");
-    }
-  }
-  pop_n_elems(args);
-  fd = FD;
-  if (FD < 0)
-    Pike_error("Stdio.UDP->read: not open\n");
-  do {
-    THREADS_ALLOW();
-    res = fd_recvfrom(fd, buffer, UDP_BUFFSIZE, flags,
-		      (struct sockaddr *)&from, &fromlen);
-    e = errno;
-    THREADS_DISALLOW();
-
-    check_threads_etc();
-  } while((res==-1) && (e==EINTR));
-
-  THIS->my_errno=errno=e;
-
-  if(res<0)
-  {
-    switch(e)
-    {
-#ifdef WSAEBADF
-       case WSAEBADF:
-#endif
-       case EBADF:
-	  if (THIS->box.backend)
-	    set_fd_callback_events (&THIS->box, 0, 0);
-	  Pike_error("Socket closed\n");
-#ifdef ESTALE
-       case ESTALE:
-#endif
-       case EIO:
-	  if (THIS->box.backend)
-	    set_fd_callback_events (&THIS->box, 0, 0);
-	  Pike_error("I/O error\n");
-       case ENOMEM:
-#ifdef ENOSR
-       case ENOSR:
-#endif /* ENOSR */
-	  Pike_error("Out of memory\n");
-#ifdef ENOTSOCK
-       case ENOTSOCK:
-	  Pike_fatal("reading from non-socket fd!!!\n");
-#endif
-       case EINVAL:
-	 if (!(flags & MSG_OOB)) {
-	   Pike_error("Socket read failed with EINVAL.\n");
-	 }
-	 /* FALL_THROUGH */
-       case EWOULDBLOCK:
-	  push_int( 0 );
-	  return;
-
-       default:
-	  Pike_error("Socket read failed with errno %d.\n", e);
-    }
-  }
-  /* Now comes the interresting part.
-   * make a nice mapping from this stuff..
-   */
-  push_text("data");
-  push_string( make_shared_binary_string(buffer, res) );
-
-  push_text("ip");
-#ifdef fd_inet_ntop
-  if (!fd_inet_ntop( SOCKADDR_FAMILY(from), SOCKADDR_IN_ADDR(from),
-		     buffer, sizeof(buffer) )) {
-    push_text("UNSUPPORTED");
-  } else {
-    /* NOTE: IPv6-mapped IPv4 addresses may only
-     *       connect to other IPv4 addresses.
-     *
-     * Make the Pike-level code believe it has an actual IPv4 address
-     * when getting a mapped address (::FFFF:a.b.c.d).
-     */
-    if ((!strncmp(buffer, "::FFFF:", 7) || !strncmp(buffer, "::ffff:", 7)) &&
-	!strchr(buffer + 7, ':')) {
-      push_text(buffer+7);
-    } else {
-      push_text(buffer);
-    }
-  }
-#else
-  push_text( inet_ntoa( *SOCKADDR_IN_ADDR(from) ) );
-#endif
-
-  push_text("port");
-  push_int(ntohs(from.ipv4.sin_port));
-  f_aggregate_mapping( 6 );
-
-  if (!(THIS->inet_flags & PIKE_INET_FLAG_NB))
-    INVALIDATE_CURRENT_TIME();
-}
-
-/*! @decl int send(string to, int|string port, string message)
- *! @decl int send(string to, int|string port, string message, int flags)
- *!
- *! Send data to a UDP socket. The recipient address will be @[to]
- *! and port will be @[port].
- *!
- *! Flag @[flag] is a bitfield, 1 for out of band data and
- *! 2 for don't route flag.
- *!
- *! @returns
- *! The number of bytes that were actually written.
- */
-void udp_sendto(INT32 args)
-{
-  int flags = 0, fd, e;
-  ptrdiff_t res = 0;
-  PIKE_SOCKADDR to;
-  int to_len;
-  char *str;
-  ptrdiff_t len;
-
-  if(FD < 0)
-    Pike_error("UDP: not open\n");
-  
-  check_all_args("send", args,
-		 BIT_STRING, BIT_INT|BIT_STRING, BIT_STRING, BIT_INT|BIT_VOID, 0);
-  
-  if(args>3)
-  {
-    if(Pike_sp[3-args].u.integer & 1) {
-      flags |= MSG_OOB;
-    }
-    if(Pike_sp[3-args].u.integer & 2) {
-#ifdef MSG_DONTROUTE
-      flags |= MSG_DONTROUTE;
-#else /* !MSG_DONTROUTE */
-      /* FIXME: What should we do here? */
-#endif /* MSG_DONTROUTE */
-    }
-    if(Pike_sp[3-args].u.integer & ~3) {
-      Pike_error("Illegal 'flags' value passed to "
-		 "Stdio.UDP->send(string to, int|string port, string message, int flags)\n");
-    }
-  }
-
-  to_len = get_inet_addr(&to, Pike_sp[-args].u.string->str,
-			 (TYPEOF(Pike_sp[1-args]) == PIKE_T_STRING?
-			  Pike_sp[1-args].u.string->str : NULL),
-			 (TYPEOF(Pike_sp[1-args]) == PIKE_T_INT?
-			  Pike_sp[1-args].u.integer : -1),
-			 THIS->inet_flags);
-  INVALIDATE_CURRENT_TIME();
-
-  fd = FD;
-  str = Pike_sp[2-args].u.string->str;
-  len = Pike_sp[2-args].u.string->len;
-
-  do {
-    THREADS_ALLOW();
-    res = fd_sendto( fd, str, len, flags, (struct sockaddr *)&to, to_len);
-    e = errno;
-    THREADS_DISALLOW();
-
-    check_threads_etc();
-  } while((res == -1) && e==EINTR);
-  
-  if(res<0)
-  {
-    switch(e)
-    {
-#ifdef EMSGSIZE
-       case EMSGSIZE:
-#endif
-	  Pike_error("Too big message\n");
-       case EBADF:
-	  if (THIS->box.backend)
-	    set_fd_callback_events (&THIS->box, 0, 0);
-	  Pike_error("Socket closed\n");
-       case ENOMEM:
-#ifdef ENOSR
-       case ENOSR:
-#endif /* ENOSR */
-	  Pike_error("Out of memory\n");
-       case EINVAL:
-#ifdef ENOTSOCK
-       case ENOTSOCK:
-	  if (THIS->box.backend)
-	    set_fd_callback_events (&THIS->box, 0, 0);
-	  Pike_error("Not a socket!!!\n");
-#endif
-       case EWOULDBLOCK:
-	  Pike_error("Message would block.\n");
-    }
-  }
-  pop_n_elems(args);
-  push_int64(res);
-  if (!(THIS->inet_flags & PIKE_INET_FLAG_NB))
-    INVALIDATE_CURRENT_TIME();
-}
-
-
-static int got_udp_event (struct fd_callback_box *box, int DEBUGUSED(event))
-{
-  struct udp_storage *u = (struct udp_storage *) box;
-#ifdef PIKE_DEBUG
-  if (event != PIKE_FD_READ)
-    Pike_fatal ("Got unexpected event %d.\n", event);
-#endif
-
-  u->my_errno = errno;		/* Propagate backend setting. */
-
-  check_destructed (&u->read_callback);
-  if (UNSAFE_IS_ZERO (&u->read_callback))
-    set_fd_callback_events (&u->box, 0, 0);
-  else {
-    apply_svalue (&u->read_callback, 0);
-    if (TYPEOF(Pike_sp[-1]) == PIKE_T_INT && Pike_sp[-1].u.integer == -1) {
-      pop_stack();
-      return -1;
-    }
-    pop_stack();
-  }
-  return 0;
-}
-
-void zero_udp(struct object *o)
-{
-  INIT_FD_CALLBACK_BOX(&THIS->box, NULL, o, -1, 0, got_udp_event, 0);
-  THIS->my_errno = 0;
-  THIS->inet_flags = PIKE_INET_FLAG_UDP;
-  THIS->type=SOCK_DGRAM;
-  THIS->protocol=0;
-  /* map_variable handles read_callback. */
-}
-
-int low_exit_udp()
-{
-  int fd = FD;
-  int ret = 0;
-
-  unhook_fd_callback_box(&THIS->box);
-  FD = -1;
-
-  if(fd != -1)
-  {
-    THREADS_ALLOW();
-    ret = fd_close(fd);
-    THREADS_DISALLOW();
-  }
-
-  /* map_variable handles read_callback. */
-
-  return ret;
-}
-
-static void udp_set_read_callback(INT32 args)
-{
-  struct udp_storage *u = THIS;
-  if(args < 1)
-    SIMPLE_TOO_FEW_ARGS_ERROR("Stdio.UDP->set_read_callback", 1);
-  if(args > 1)
-    pop_n_elems(args-1);
-
-  assign_svalue(& u->read_callback, Pike_sp-1);
-  if (UNSAFE_IS_ZERO (Pike_sp - 1)) {
-    if (u->box.backend)
-      set_fd_callback_events (&u->box, 0, 0);
-  }
-  else {
-    if (!u->box.backend)
-      INIT_FD_CALLBACK_BOX (&u->box, default_backend, u->box.ref_obj,
-			    u->box.fd, PIKE_BIT_FD_READ, got_udp_event, 0);
-    else
-      set_fd_callback_events (&u->box, PIKE_BIT_FD_READ, 0);
-  }
-
-  pop_stack();
-  ref_push_object(THISOBJ);
-}
-
-static void udp_set_nonblocking(INT32 args)
-{
-  if (FD < 0) Pike_error("File not open.\n");
-
-  if (args)
-  {
-     udp_set_read_callback(args);
-     pop_stack();
-  }
-  set_nonblocking(FD,1);
-  THIS->inet_flags |= PIKE_INET_FLAG_NB;
-  ref_push_object(THISOBJ);
-}
-
-/*! @decl object set_blocking()
- *!
- *! Sets this object to be blocking.
- */
-static void udp_set_blocking(INT32 args)
-{
-  if (FD < 0) Pike_error("File not open.\n");
-  set_nonblocking(FD,0);
-  THIS->inet_flags &= ~PIKE_INET_FLAG_NB;
-  pop_n_elems(args);
-  ref_push_object(THISOBJ);
-}
-
-/*! @decl int(0..1) connect(string address, int|string port)
- *!
- *!   Establish an UDP connection.
- *!
- *!   This function connects an UDP socket previously created with
- *!   @[Stdio.UDP()] to a remote socket. The @[address] is the IP name or
- *!   number for the remote machine. 
- *!
- *! @returns
- *!   Returns @expr{1@} on success, @expr{0@} (zero) otherwise.
- *!
- *! @note
- *!   If the socket is in nonblocking mode, you have to wait
- *!   for a write or close callback before you know if the connection
- *!   failed or not.
- *!
- *! @seealso
- *!   @[bind()], @[query_address()]
- */
-static void udp_connect(INT32 args)
-{
-  PIKE_SOCKADDR addr;
-  int addr_len;
-  struct pike_string *dest_addr = NULL;
-  struct svalue *dest_port = NULL;
-
-  int tmp;
-
-  get_all_args("UDP.connect", args, "%S%*", &dest_addr, &dest_port);
-
-  if(TYPEOF(*dest_port) != PIKE_T_INT &&
-     (TYPEOF(*dest_port) != PIKE_T_STRING || dest_port->u.string->size_shift))
-    SIMPLE_BAD_ARG_ERROR("UDP.connect", 2, "int|string (8bit)");
-
-  addr_len =  get_inet_addr(&addr, dest_addr->str,
-			    (TYPEOF(*dest_port) == PIKE_T_STRING?
-			     dest_port->u.string->str : NULL),
-			    (TYPEOF(*dest_port) == PIKE_T_INT?
-			     dest_port->u.integer : -1),
-			    THIS->inet_flags);
-  INVALIDATE_CURRENT_TIME();
-
-  if(FD < 0)
-  {
-     FD = fd_socket(SOCKADDR_FAMILY(addr), SOCK_DGRAM, 0);
-     if(FD < 0)
-     {
-	THIS->my_errno=errno;
-	Pike_error("Stdio.UDP->connect: failed to create socket\n");
-     }
-     set_close_on_exec(FD, 1);
-
-#if defined(IPV6_V6ONLY) && defined(IPPROTO_IPV6)
-     if (SOCKADDR_FAMILY(addr) == AF_INET6) {
-       /* Attempt to enable dual-stack (ie mapped IPv4 adresses).
-	* Needed on WIN32.
-	* cf http://msdn.microsoft.com/en-us/library/windows/desktop/bb513665(v=vs.85).aspx
-	*/
-       int o = 0;
-       fd_setsockopt(FD, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&o, sizeof(int));
-     }
-#endif
-  }
-
-  tmp=FD;
-  THREADS_ALLOW();
-  tmp=fd_connect(tmp, (struct sockaddr *)&addr, addr_len);
-  THREADS_DISALLOW();
-
-  if (!(THIS->inet_flags & PIKE_INET_FLAG_NB))
-    INVALIDATE_CURRENT_TIME();
-
-  if(tmp < 0)
-  {
-    THIS->my_errno=errno;
-    Pike_error("Stdio.UDP->connect: failed to connect\n");
-  }else{
-    THIS->my_errno=0;
-    pop_n_elems(args);
-    push_int(1);
-  }
-}
-
-/*! @decl string query_address()
- *! 
- *! Returns the local address of a socket on the form "x.x.x.x port".
- *! If this file is not a socket, not connected or some other error occurs,
- *! zero is returned.
- */
-static void udp_query_address(INT32 args)
-{
-  PIKE_SOCKADDR addr;
-  int i;
-  int fd = FD;
-  char buffer[496];
-  ACCEPT_SIZE_T len;
-
-  if(fd <0)
-    Pike_error("Stdio.UDP->query_address(): Port not bound yet.\n");
-
-  THREADS_ALLOW();
-
-  len=sizeof(addr);
-  i=fd_getsockname(fd,(struct sockaddr *)&addr,&len);
-
-  THREADS_DISALLOW();
-
-  pop_n_elems(args);
-  if(i < 0 || len < (int)sizeof(addr.ipv4))
-  {
-    push_int(0);
-    return;
-  }
-
-#ifdef fd_inet_ntop
-  fd_inet_ntop(SOCKADDR_FAMILY(addr), SOCKADDR_IN_ADDR(addr),
-	       buffer, sizeof(buffer)-20);
-#else
-  q=inet_ntoa(*SOCKADDR_IN_ADDR(addr));
-  strncpy(buffer,q,sizeof(buffer)-20);
-  buffer[sizeof(buffer)-20]=0;
-#endif
-  sprintf(buffer+strlen(buffer)," %d",(int)(ntohs(addr.ipv4.sin_port)));
-
-  /* NOTE: IPv6-mapped IPv4 addresses may only connect to other IPv4 addresses.
-   *
-   * Make the Pike-level code believe it has an actual IPv4 address
-   * when getting a mapped address (::FFFF:a.b.c.d).
-   */
-  if ((!strncmp(buffer, "::FFFF:", 7) || !strncmp(buffer, "::ffff:", 7)) &&
-      !strchr(buffer + 7, ':')) {
-    push_text(buffer+7);
-  } else {
-    push_text(buffer);
-  }
-}
-
-/*! @decl void set_backend (Pike.Backend backend)
- *!
- *! Set the backend used for the read callback.
- *!
- *! @note
- *! The backend keeps a reference to this object as long as there can
- *! be calls to the read callback, but this object does not keep a
- *! reference to the backend.
- *!
- *! @seealso
- *!   @[query_backend]
- */
-static void udp_set_backend (INT32 args)
-{
-  struct udp_storage *u = THIS;
-  struct Backend_struct *backend;
-
-  if (!args)
-    SIMPLE_TOO_FEW_ARGS_ERROR ("Stdio.UDP->set_backend", 1);
-  if (TYPEOF(Pike_sp[-args]) != PIKE_T_OBJECT)
-    SIMPLE_BAD_ARG_ERROR ("Stdio.UDP->set_backend", 1, "object(Pike.Backend)");
-  backend = (struct Backend_struct *)
-    get_storage (Pike_sp[-args].u.object, Backend_program);
-  if (!backend)
-    SIMPLE_BAD_ARG_ERROR ("Stdio.UDP->set_backend", 1, "object(Pike.Backend)");
-
-  if (u->box.backend)
-    change_backend_for_box (&u->box, backend);
-  else
-    INIT_FD_CALLBACK_BOX (&u->box, backend, u->box.ref_obj,
-			  u->box.fd, 0, got_udp_event, 0);
-
-  pop_n_elems (args - 1);
-}
-
-/*! @decl Pike.Backend query_backend()
- *!
- *! Return the backend used for the read callback.
- *!
- *! @seealso
- *!   @[set_backend]
- */
-static void udp_query_backend (INT32 args)
-{
-  pop_n_elems (args);
-  ref_push_object (get_backend_obj (THIS->box.backend ? THIS->box.backend :
-				    default_backend));
-}
-
-/*! @decl int errno()
- *!
- *! Returns the error code for the last command on this object.
- *! Error code is normally cleared when a command is successful.
- */
-static void udp_errno(INT32 args)
-{
-   pop_n_elems(args);
-   push_int(THIS->my_errno);
-}
-
-/*! @decl UDP set_type(int sock_type)
- *! @decl UDP set_type(int sock_type, int family)
- *!
- *! Sets socket type and protocol family.
- */
-static void udp_set_type(INT32 args)
-{
-   int type, proto = 0;
-
-   get_all_args("Stdio.UDP->set_type",args,"%d.%d",&type,&proto);
-
-   THIS->type=type;
-   THIS->protocol=proto;
-   
-   pop_n_elems(args);
-   ref_push_object(THISOBJ);
-}
-
-/*! @decl array(int) get_type()
- *!
- *! Returns socket type and protocol family.
- */
-static void udp_get_type(INT32 args)
-{
-   pop_n_elems(args);
-   push_int(THIS->type);
-   push_int(THIS->protocol);
-   f_aggregate(2);
-}
-
-/*! @decl void set_buffer(int bufsize, string mode)
- *! @decl void set_buffer(int bufsize)
- *!
- *! Set internal socket buffer.
- *!
- *! This function sets the internal buffer size of a socket or stream.
- *!
- *! The second argument allows you to set the read or write buffer by
- *! specifying @expr{"r"@} or @expr{"w"@}.
- *!
- *! @note
- *!   It is not guaranteed that this function actually does anything,
- *!   but it certainly helps to increase data transfer speed when it does.
- *!
- *! @seealso
- *!   @[open_socket()], @[accept()]
- */
-static void udp_set_buffer(INT32 args)
-{
-  INT_TYPE bufsize;
-  int flags = FILE_READ | FILE_WRITE;
-  char *c = NULL;
-
-  if(FD==-1)
-    Pike_error("Stdio.UDP->set_buffer() on closed file.\n");
-
-  get_all_args("Stdio.UDP->set_buffer", args, "%+.%s", &bufsize, &c);
-
-  if(bufsize < 0)
-    Pike_error("Bufsize must be larger than zero.\n");
-
-  if(c)
-  {
-    flags = 0;
-    do
-    {
-      switch( *c )
-      {
-      case 'w': flags |= FILE_WRITE; break;
-      case 'r': flags |= FILE_READ;  break;
-      }
-    } while( *c++ );
-  }
-  pop_n_elems(args);
-
-#ifdef SOCKET_BUFFER_MAX
-#if SOCKET_BUFFER_MAX
-  if(bufsize>SOCKET_BUFFER_MAX) bufsize=SOCKET_BUFFER_MAX;
-#endif
-#ifdef SO_RCVBUF
-  if(flags & FILE_READ)
-  {
-    int tmp=bufsize;
-    fd_setsockopt(FD,SOL_SOCKET, SO_RCVBUF, (char *)&tmp, sizeof(tmp));
-  }
-#endif /* SO_RCVBUF */
-
-#ifdef SO_SNDBUF
-  if(flags & FILE_WRITE)
-  {
-    int tmp=bufsize;
-    fd_setsockopt(FD,SOL_SOCKET, SO_SNDBUF, (char *)&tmp, sizeof(tmp));
-  }
-#endif /* SO_SNDBUF */
-#endif
-}
-
-/*! @decl constant MSG_OOB
- *! @fixme
- *! Document this constant.
- */
-
-/*! @decl constant MSG_PEEK
- *! @fixme
- *! Document this constant.
- */
-
-/*! @endclass
- */
-
-/*! @endmodule
- */
-
-void init_stdio_udp(void)
-{
-  START_NEW_PROGRAM_ID (STDIO_UDP);
-
-  ADD_STORAGE(struct udp_storage);
-
-  PIKE_MAP_VARIABLE("_read_callback", OFFSETOF(udp_storage, read_callback),
-		    tFunc(tNone, tInt_10), PIKE_T_MIXED, ID_PROTECTED|ID_PRIVATE);
-
-  ADD_FUNCTION("set_type",udp_set_type,
-	       tFunc(tInt tOr(tVoid,tInt),tObj),0);
-  ADD_FUNCTION("get_type",udp_get_type,
-	       tFunc(tNone,tArr(tInt)),0);
-
-  ADD_FUNCTION("close", udp_close, tFunc(tNone, tInt01), 0);
-
-  ADD_FUNCTION("bind",udp_bind,
-	       tFunc(tOr(tInt,tStr) tOr(tVoid,tStr) tOr(tVoid,tInt),tObj),0);
-
-  ADD_FUNCTION("set_fd",udp_set_fd,
-         tFunc(tInt,tObj),0);
-
-  ADD_FUNCTION("query_fd",udp_query_fd,
-         tFunc(tInt,tObj),0);
-
-  ADD_FUNCTION("enable_broadcast", udp_enable_broadcast,
-	       tFunc(tNone,tInt01), 0);
-
-  ADD_FUNCTION("enable_multicast", udp_enable_multicast,
-	       tFunc(tStr,tInt01), 0);
-
-  ADD_FUNCTION("set_multicast_ttl", udp_set_multicast_ttl,
-	       tFunc(tInt,tInt), 0);
-
-  ADD_FUNCTION("add_membership", udp_add_membership,
-	       tFunc(tStr tOr(tVoid,tStr tOr(tVoid,tInt)),tInt), 0);
-
-  ADD_FUNCTION("drop_membership", udp_drop_membership,
-	       tFunc(tStr tOr(tVoid,tStr tOr(tVoid,tInt)),tInt), 0);
-
-  ADD_FUNCTION("wait", udp_wait, tFunc(tOr(tInt, tFloat), tInt), 0);
-
-  ADD_FUNCTION("read",udp_read,
-	       tFunc(tOr(tInt,tVoid),tMap(tStr,tOr(tInt,tStr))),0);
-
-  add_integer_constant("MSG_OOB", 1, 0);
-#ifdef MSG_PEEK
-  add_integer_constant("MSG_PEEK", 2, 0);
-#endif /* MSG_PEEK */
-
-  ADD_FUNCTION("send",udp_sendto,
-	       tFunc(tStr tOr(tInt,tStr) tStr tOr(tVoid,tInt),tInt),0);
-
-  ADD_FUNCTION("connect",udp_connect,
-	       tFunc(tString tOr(tInt,tStr),tInt),0);
-  
-  ADD_FUNCTION("_set_nonblocking", udp_set_nonblocking,
-	       tFunc(tOr(tFunc(tVoid,tVoid),tVoid),tObj), 0 );
-  ADD_FUNCTION("_set_read_callback", udp_set_read_callback,
-	       tFunc(tFunc(tVoid,tVoid),tObj), 0 );
-
-  ADD_FUNCTION("set_blocking",udp_set_blocking,tFunc(tVoid,tObj), 0 );
-  ADD_FUNCTION("query_address",udp_query_address,tFunc(tNone,tStr),0);
-
-  ADD_FUNCTION ("set_backend", udp_set_backend, tFunc(tObj,tVoid), 0);
-  ADD_FUNCTION ("query_backend", udp_query_backend, tFunc(tVoid,tObj), 0);
-
-  ADD_FUNCTION("errno",udp_errno,tFunc(tNone,tInt),0);
-
-  ADD_FUNCTION("set_buffer", udp_set_buffer, tFunc(tInt tOr(tStr,tVoid),tVoid), 0);
-
-  set_init_callback(zero_udp);
-  set_exit_callback(exit_udp);
-
-  end_class("UDP",0);
-
-  START_NEW_PROGRAM_ID (STDIO_SOCK);
-#ifdef SOCK_STREAM
-  add_integer_constant("STREAM",SOCK_STREAM,0);
-#endif
-#ifdef SOCK_DGRAM
-  add_integer_constant("DGRAM",SOCK_DGRAM,0);
-#endif
-#ifdef SOCK_SEQPACKET
-  add_integer_constant("SEQPACKET",SOCK_SEQPACKET,0);
-#endif
-#ifdef SOCK_RAW
-  add_integer_constant("RAW",SOCK_RAW,0);
-#endif
-#ifdef SOCK_RDM
-  add_integer_constant("RDM",SOCK_RDM,0);
-#endif
-#ifdef SOCK_PACKET
-  add_integer_constant("PACKET",SOCK_PACKET,0);
-#endif
-   push_program(end_program());
-   f_call_function(1);
-   simple_add_constant("SOCK",Pike_sp-1,0);
-   pop_stack();
-
-   START_NEW_PROGRAM_ID (STDIO_IPPROTO);
-   add_integer_constant("IP",0,0);       /* Dummy protocol for TCP.  */
-   add_integer_constant("HOPOPTS",0,0);  /* IPv6 Hop-by-Hop options.  */
-   add_integer_constant("ICMP",1,0);     /* Internet Control Message Protocol.  */
-   add_integer_constant("IGMP",2,0);     /* Internet Group Management Protocol. */
-   add_integer_constant("GGP", 3, 0);	 /* Gateway-Gateway Protocol.  */
-   add_integer_constant("IPIP",4,0);     /* IPIP tunnels (older KA9Q tunnels use 94).  */
-   add_integer_constant("TCP",6,0);      /* Transmission Control Protocol.  */
-   add_integer_constant("EGP",8,0);      /* Exterior Gateway Protocol.  */
-   add_integer_constant("PUP",12,0);     /* PUP protocol.  */
-   add_integer_constant("UDP",17,0);     /* User Datagram Protocol.  */
-   add_integer_constant("IDP",22,0);     /* XNS IDP protocol.  */
-   add_integer_constant("RDP", 27, 0);	 /* "Reliable Datagram" Protocol.  */
-   add_integer_constant("TP",29,0);      /* SO Transport Protocol Class 4.  */
-   add_integer_constant("IPV6",41,0);    /* IPv6 header.  */
-   add_integer_constant("ROUTING",43,0); /* IPv6 routing header.  */
-   add_integer_constant("FRAGMENT",44,0);/* IPv6 fragmentation header.  */
-   add_integer_constant("RSVP",46,0);    /* Reservation Protocol.  */
-   add_integer_constant("GRE",47,0);     /* General Routing Encapsulation.  */
-   add_integer_constant("ESP",50,0);     /* encapsulating security payload.  */
-   add_integer_constant("AH",51,0);      /* authentication header.  */
-   add_integer_constant("ICMPV6",58,0);  /* ICMPv6.  */
-   add_integer_constant("NONE",59,0);    /* IPv6 no next header.  */
-   add_integer_constant("DSTOPTS",60,0); /* IPv6 destination options.  */
-   add_integer_constant("MTP",92,0);     /* Multicast Transport Protocol.  */
-   add_integer_constant("ENCAP",98,0);   /* Encapsulation Header.  */
-   add_integer_constant("PIM",103,0);    /* Protocol Independent Multicast.  */
-   add_integer_constant("COMP",108,0);   /* Compression Header Protocol.  */
-   add_integer_constant("RAW",255,0);    /* Raw IP packets.  */
-   push_program(end_program());
-   f_call_function(1);
-   simple_add_constant("IPPROTO",Pike_sp-1,0);
-   pop_stack();
-}
-
-void exit_stdio_udp(void)
-{
-}