From 1d6b0c76d27ea3b1b727d1bcf57383414525cce4 Mon Sep 17 00:00:00 2001
From: Per Hedbor <ph@opera.com>
Date: Thu, 21 Aug 1997 15:59:25 +0200
Subject: [PATCH] Stay, DumUDP, STAY!

Rev: src/modules/spider/dumudp.c:1.11
---
 src/modules/spider/dumudp.c | 101 ++++++++++++++++++++++++------------
 1 file changed, 67 insertions(+), 34 deletions(-)

diff --git a/src/modules/spider/dumudp.c b/src/modules/spider/dumudp.c
index 7e1a70ef7a..826a4764e7 100644
--- a/src/modules/spider/dumudp.c
+++ b/src/modules/spider/dumudp.c
@@ -1,18 +1,14 @@
 #include <config.h>
 
 #include "global.h"
-RCSID("$Id: dumudp.c,v 1.10 1997/05/19 22:53:26 hubbe Exp $");
+RCSID("$Id: dumudp.c,v 1.11 1997/08/21 13:59:25 per Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "stralloc.h"
 #include "array.h"
 #include "object.h"
-#include "pike_macros.h"
 #include "backend.h"
 #include "fd_control.h"
-#include "error.h"
-#include "builtin_functions.h"
-#include "mapping.h"
 
 #include "error.h"
 #include "signal_handler.h"
@@ -51,10 +47,6 @@ RCSID("$Id: dumudp.c,v 1.10 1997/05/19 22:53:26 hubbe Exp $");
 #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
@@ -65,9 +57,11 @@ RCSID("$Id: dumudp.c,v 1.10 1997/05/19 22:53:26 hubbe Exp $");
 
 struct dumudp {
   int fd;
+  struct svalue read_callback;
 };
 
 #define THIS ((struct dumudp *)fp->current_storage)
+#define FD (THIS->fd)
 
 extern void get_inet_addr(struct sockaddr_in *addr,char *name);
 
@@ -94,14 +88,11 @@ static void udp_bind(INT32 args)
   o=1;
   if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&o, sizeof(int)) < 0)
   {
-/*    THIS->my_errno=errno;*/
     close(fd);
     error("setsockopt failed\n");
     return;
   }
 
-  /* set_close_on_exec(fd,1); */
-
   MEMSET((char *)&addr,0,sizeof(struct sockaddr_in));
 
   if(args > 2 && sp[2-args].type==T_STRING) {
@@ -118,24 +109,13 @@ static void udp_bind(INT32 args)
 
   if(tmp)
   {
-/*    THIS->my_errno=errno;*/
     close(fd);
     pop_n_elems(args);
     push_int(0);
     return;
   }
 
-/*
-  if(args > 1)
-  {
-    assign_svalue(& THIS->accept_callback, sp+1-args);
-    if(!IS_ZERO(& THIS->accept_callback))
-      set_read_callback(fd, port_accept_callback, (void *)THIS);
-    set_nonblocking(fd,1);
-  }
-*/
   THIS->fd=fd;
-/*  THIS->my_errno=0;*/
   pop_n_elems(args);
   push_int(1);
 }
@@ -144,7 +124,7 @@ static void udp_bind(INT32 args)
 
 void udp_read(INT32 args)
 {
-  int flags = 0, res=0;
+  int flags = 0, res=0, fd;
   struct sockaddr_in from;
   int  fromlen = sizeof(struct sockaddr_in);
   char buffer[UDP_BUFFSIZE];
@@ -161,8 +141,9 @@ void udp_read(INT32 args)
       error("Illegal 'flags' value passed to udp->read([int flags])\n");
   }
   pop_n_elems(args);
+  fd = THIS->fd;
   THREADS_ALLOW();
-  while(((res = recvfrom(THIS->fd, buffer, UDP_BUFFSIZE, flags,
+  while(((res = recvfrom(fd, buffer, UDP_BUFFSIZE, flags,
 			 (struct sockaddr *)&from, &fromlen))==-1)
 	&&(errno==EINTR));
   THREADS_DISALLOW();
@@ -177,9 +158,7 @@ void udp_read(INT32 args)
      case EIO:
       error("I/O error\n");
      case ENOMEM:
-#ifdef ENOSR
      case ENOSR:
-#endif /* ENOSR */
       error("Out of memory\n");
      case ENOTSOCK:
       fatal("reading from non-socket fd!!!\n");
@@ -227,10 +206,11 @@ void udp_sendto(INT32 args)
   else
     error("Illegal type of argument to sendto, got non-string to-address.\n");
 
-  to.sin_port = sp[1-args].u.integer;
+  to.sin_port = htons( ((u_short)sp[1-args].u.integer) );
 
+  fd = THIS->fd;
   THREADS_ALLOW();
-  while(((res = sendto(THIS->fd, sp[2-args].u.string->str, sp[2-args].u.string->len, flags,
+  while(((res = sendto( fd, sp[2-args].u.string->str, sp[2-args].u.string->len, flags,
 		       (struct sockaddr *)&to,
 		       sizeof( struct sockaddr_in )))==-1)
 	&& errno==EINTR);
@@ -245,9 +225,7 @@ void udp_sendto(INT32 args)
      case EBADF:
       error("Socket closed\n");
      case ENOMEM:
-#ifdef ENOSR
      case ENOSR:
-#endif /* ENOSR */
       error("Out of memory\n");
      case EINVAL:
      case ENOTSOCK:
@@ -261,14 +239,63 @@ void udp_sendto(INT32 args)
 }
 
 
-void zero_udp(struct object *o)
+void zero_udp()
 {
   MEMSET(THIS, 0, sizeof(struct dumudp));
 }
 
-void exit_udp(struct object *o)
+void exit_udp()
+{
+  if(THIS->fd)
+  {
+    set_read_callback( THIS->fd, 0, 0 );
+    if (& THIS->read_callback)
+      free_svalue(& THIS->read_callback );
+    close(THIS->fd);
+  }
+}
+
+#define THIS_DATA ((struct dumudp *)data)
+
+static void udp_read_callback( int fd, void *data )
 {
-  if(THIS->fd) close(THIS->fd);
+  /*  fp->current_object->refs++;
+      push_object( fp->current_object ); */
+  apply_svalue(& THIS_DATA->read_callback, 0);
+  pop_stack(); 
+  return;
+}
+
+static void udp_set_read_callback(INT32 args)
+{
+  if(FD < 0)
+    error("File is not open.\n");
+
+  if(args < 1)
+    error("Too few arguments to file->set_read_callback().\n");
+
+  if(IS_ZERO(& THIS->read_callback))
+    assign_svalue(& THIS->read_callback, sp-args);
+  else
+    assign_svalue_no_free(& THIS->read_callback, sp-args);
+
+  if(IS_ZERO(& THIS->read_callback))
+    set_read_callback(FD, 0, 0);
+  else
+    set_read_callback(FD, udp_read_callback, THIS);
+  pop_n_elems(args);
+}
+
+static void udp_set_nonblocking(INT32 args)
+{
+  if (FD < 0) error("File not open.\n");
+
+  switch(args)
+  {
+  default: pop_n_elems(args-1);
+  case 1: udp_set_read_callback(1);
+  }
+  set_nonblocking(FD,1);
 }
 
 void init_udp()
@@ -279,7 +306,13 @@ void init_udp()
   add_function("bind",udp_bind,"function(int,void|function,void|string:int)",0);
   add_function("read",udp_read,"function(int|void:mapping(string:int|string))",0);
   add_function("send",udp_sendto,"function(string,int,string,void|int:int)",0);
+  add_function( "set_nonblocking", udp_set_nonblocking,
+		"function(function(void:void):void)", 0 );
+  add_function( "set_read_callback", udp_set_read_callback,
+		"function(function(void:void):void)", 0 );
   set_init_callback(zero_udp);
   set_exit_callback(exit_udp);
+  /*  end_c_program( "/precompiled/dumUDP" )->refs++; // For pike 0.4 */
+  /* otherwise... */
   end_class("dumUDP",0);
 }
-- 
GitLab