Socket.st
branchjv
changeset 4235 6648f07e2ddd
parent 4215 195c5c496e71
parent 4234 eb1b470a27ee
child 4252 be9c3684d375
equal deleted inserted replaced
4231:0608d9929411 4235:6648f07e2ddd
     1 "{ Encoding: utf8 }"
       
     2 
       
     3 "
     1 "
     4  COPYRIGHT (c) 1992 by Claus Gittinger
     2  COPYRIGHT (c) 1992 by Claus Gittinger
     5 	      All Rights Reserved
     3 	      All Rights Reserved
     6 
     4 
     7  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
    14 "{ Package: 'stx:libbasic2' }"
    12 "{ Package: 'stx:libbasic2' }"
    15 
    13 
    16 "{ NameSpace: Smalltalk }"
    14 "{ NameSpace: Smalltalk }"
    17 
    15 
    18 NonPositionableExternalStream subclass:#Socket
    16 NonPositionableExternalStream subclass:#Socket
    19 	instanceVariableNames:'domain socketType protocol port serviceName peer peerName
    17 	instanceVariableNames:'domain socketType protocol port peer peerName listening'
    20 		listening'
       
    21 	classVariableNames:''
    18 	classVariableNames:''
    22 	poolDictionaries:''
    19 	poolDictionaries:''
    23 	category:'Streams-External'
    20 	category:'Streams-External'
    24 !
    21 !
    25 
    22 
  1531 
  1528 
  1532 acceptNonBlock
  1529 acceptNonBlock
  1533     ^ self accept
  1530     ^ self accept
  1534 !
  1531 !
  1535 
  1532 
  1536 errorReporter
       
  1537     "ST-80 mimicry."
       
  1538 
       
  1539     ^ self class
       
  1540 !
       
  1541 
       
  1542 ioConnection
  1533 ioConnection
  1543     ^ self
  1534     ^ self
  1544 !
  1535 !
  1545 
  1536 
  1546 notReadySignal
  1537 notReadySignal
  1885     }
  1876     }
  1886 #endif /* NO_SOCKET */
  1877 #endif /* NO_SOCKET */
  1887 
  1878 
  1888 getOutOfHere: ;
  1879 getOutOfHere: ;
  1889 %}.
  1880 %}.
  1890     ok ~~ true ifTrue:[
  1881     ok ifFalse:[
  1891         |errorHolder errorString|
  1882         |errorHolder errorString|
  1892 
  1883 
  1893         error isInteger ifTrue:[
  1884         error isInteger ifTrue:[
  1894             errorHolder := OperatingSystem errorHolderForNumber:error.
  1885             errorHolder := OperatingSystem errorHolderForNumber:error.
  1895             errorString := errorHolder errorString.
  1886             errorString := errorHolder errorString.
  2117     |isAsync err|
  2108     |isAsync err|
  2118 
  2109 
  2119     handle isNil ifTrue:[
  2110     handle isNil ifTrue:[
  2120         ^ self errorNotOpen
  2111         ^ self errorNotOpen
  2121     ].
  2112     ].
       
  2113     isAsync := false.
  2122 
  2114 
  2123 %{  /* STACK: 100000 */
  2115 %{  /* STACK: 100000 */
  2124 #ifndef NO_SOCKET
  2116 #ifndef NO_SOCKET
  2125 //#define DUMP_ADDRESS 1
  2117 //#define DUMP_ADDRESS 1
  2126     OBJ fp = __INST(handle);
  2118     OBJ fp = __INST(handle);
  2285         lastErrorNumber := err.
  2277         lastErrorNumber := err.
  2286         ^ false.
  2278         ^ false.
  2287         "/ Once we will raise an exception instead of returning false (and have to change some code above):
  2279         "/ Once we will raise an exception instead of returning false (and have to change some code above):
  2288 "/        (OperatingSystem errorHolderForNumber:err) reportError.
  2280 "/        (OperatingSystem errorHolderForNumber:err) reportError.
  2289     ].
  2281     ].
  2290     isAsync == true ifTrue:[
  2282     isAsync ifTrue:[
  2291         (self writeExceptionWaitWithTimeoutMs:timeout) ifTrue:[
  2283         (self writeExceptionWaitWithTimeoutMs:timeout) ifTrue:[
  2292             "/ a timeout occurred
  2284             "/ a timeout occurred
  2293             "/ should I cancel the connect?
  2285             "/ should I cancel the connect?
  2294             lastErrorNumber := OperatingSystem errorNumberFor:#ETIMEDOUT.
  2286             lastErrorNumber := OperatingSystem errorNumberFor:#ETIMEDOUT.
  2295             ^ false.
  2287             ^ false.
  2438 
  2430 
  2439     |domainClass addr addrLen nReceived error|
  2431     |domainClass addr addrLen nReceived error|
  2440 
  2432 
  2441     domainClass := self class socketAddressClassForDomain:domain.
  2433     domainClass := self class socketAddressClassForDomain:domain.
  2442     domainClass isNil ifTrue:[
  2434     domainClass isNil ifTrue:[
  2443 	^ self error:'invalid (unsupported) domain'.
  2435         ^ self error:'invalid (unsupported) domain'.
  2444     ].
  2436     ].
  2445     (anAddressBuffer isKindOf:SocketAddress) ifTrue:[
  2437     anAddressBuffer isSocketAddress ifTrue:[
  2446 	anAddressBuffer class == domainClass ifFalse:[
  2438         anAddressBuffer class == domainClass ifFalse:[
  2447 	    ^ self error:'addressBuffer class mismatch (domain)'.
  2439             ^ self error:'addressBuffer class mismatch (domain)'.
  2448 	].
  2440         ].
  2449 	addr := anAddressBuffer.
  2441         addr := anAddressBuffer.
  2450     ] ifFalse:[
  2442     ] ifFalse:[
  2451 	anAddressBuffer notNil ifTrue:[
  2443         anAddressBuffer notNil ifTrue:[
  2452 	    addr := domainClass new.
  2444             addr := domainClass new.
  2453 	].
  2445         ].
  2454     ].
  2446     ].
  2455 
  2447 
  2456 %{
  2448 %{
  2457 #ifndef NO_SOCKET
  2449 #ifndef NO_SOCKET
  2458     OBJ fp = __INST(handle);
  2450     OBJ fp = __INST(handle);
  2459 
  2451 
  2460     if (fp != nil) {
  2452     if (fp != nil) {
  2461 	SOCKET sock;
  2453         SOCKET sock;
  2462 	size_t objSize;
  2454         size_t objSize;
  2463 	union sockaddr_u sa;
  2455         union sockaddr_u sa;
  2464 	socklen_t alen = 0;
  2456         socklen_t alen = 0;
  2465 	INT n, offs;
  2457         INT n, offs;
  2466 	int _flags = __longIntVal(flags);
  2458         int _flags = __longIntVal(flags);
  2467 	char *extPtr;
  2459         char *extPtr;
  2468 	unsigned char *allocatedBuffer = NULL, *buffer = NULL;
  2460         unsigned char *allocatedBuffer = NULL, *buffer = NULL;
  2469 
  2461 
  2470 	sock = SOCKET_FROM_FILE_OBJECT(fp);
  2462         sock = SOCKET_FROM_FILE_OBJECT(fp);
  2471 
  2463 
  2472 	if (! setupBufferParameters(aDataBuffer, startIndex, &extPtr, &offs, &objSize)) goto bad;
  2464         if (! setupBufferParameters(aDataBuffer, startIndex, &extPtr, &offs, &objSize)) goto bad;
  2473 	if (__isSmallInteger(nBytes)) {
  2465         if (__isSmallInteger(nBytes)) {
  2474 	    if (__intVal(nBytes) < objSize) {
  2466             if (__intVal(nBytes) < objSize) {
  2475 		objSize = __intVal(nBytes);
  2467                 objSize = __intVal(nBytes);
  2476 	    }
  2468             }
  2477 	}
  2469         }
  2478 # ifdef DO_WRAP_CALLS
  2470 # ifdef DO_WRAP_CALLS
  2479 	if (extPtr) {
  2471         if (extPtr) {
  2480 	    buffer = extPtr + offs;
  2472             buffer = extPtr + offs;
  2481 	} else {
  2473         } else {
  2482 	    allocatedBuffer = buffer = (char *)malloc(objSize);
  2474             allocatedBuffer = buffer = (char *)malloc(objSize);
  2483 	}
  2475         }
  2484 
  2476 
  2485 	do {
  2477         do {
  2486 	    __threadErrno = 0;
  2478             __threadErrno = 0;
  2487 	    alen = sizeof(sa);
  2479             alen = sizeof(sa);
  2488 	    n = (INT)STX_WSA_NOINT_CALL6("recvfrom", recvfrom, sock, buffer, objSize, _flags, (struct sockaddr *)&sa, &alen);
  2480             n = (INT)STX_WSA_NOINT_CALL6("recvfrom", recvfrom, sock, buffer, objSize, _flags, (struct sockaddr *)&sa, &alen);
  2489 	} while ((n < 0) && (__threadErrno == EINTR));
  2481         } while ((n < 0) && (__threadErrno == EINTR));
  2490 	if (n < 0) {
  2482         if (n < 0) {
  2491 	    errno = __threadErrno;
  2483             errno = __threadErrno;
  2492 	}
  2484         }
  2493 
  2485 
  2494 	if (allocatedBuffer) {
  2486         if (allocatedBuffer) {
  2495 	    if (n > 0) {
  2487             if (n > 0) {
  2496 		memcpy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, n);
  2488                 memcpy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, n);
  2497 	    }
  2489             }
  2498 	    free(allocatedBuffer);
  2490             free(allocatedBuffer);
  2499 	}
  2491         }
  2500 # else
  2492 # else
  2501 	__BEGIN_INTERRUPTABLE__
  2493         __BEGIN_INTERRUPTABLE__
  2502 	do {
  2494         do {
  2503 	    alen = sizeof(sa);
  2495             alen = sizeof(sa);
  2504 	    if (extPtr) {
  2496             if (extPtr) {
  2505 		n = recvfrom(sock, extPtr + offs, objSize, _flags, (struct sockaddr *) &sa, &alen);
  2497                 n = recvfrom(sock, extPtr + offs, objSize, _flags, (struct sockaddr *) &sa, &alen);
  2506 	    } else {
  2498             } else {
  2507 		n = recvfrom(sock, (char *)__InstPtr(aDataBuffer) + offs, objSize, _flags, (struct sockaddr *) &sa, &alen);
  2499                 n = recvfrom(sock, (char *)__InstPtr(aDataBuffer) + offs, objSize, _flags, (struct sockaddr *) &sa, &alen);
  2508 	    }
  2500             }
  2509 	} while ((n < 0) && (errno == EINTR));
  2501         } while ((n < 0) && (errno == EINTR));
  2510 	__END_INTERRUPTABLE__
  2502         __END_INTERRUPTABLE__
  2511 # endif
  2503 # endif
  2512 
  2504 
  2513 	if (n >= 0) {
  2505         if (n >= 0) {
  2514 	    if (__isNonNilObject(addr)) {
  2506             if (__isNonNilObject(addr)) {
  2515 		char *addrPtr;
  2507                 char *addrPtr;
  2516 		OBJ oClass;
  2508                 OBJ oClass;
  2517 		int nInstVars, nInstBytes, objSize;
  2509                 int nInstVars, nInstBytes, objSize;
  2518 
  2510 
  2519 		oClass = __qClass(addr);
  2511                 oClass = __qClass(addr);
  2520 		if (! __isBytes(addr) )
  2512                 if (! __isBytes(addr) )
  2521 		    goto bad;
  2513                     goto bad;
  2522 		nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  2514                 nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  2523 		nInstBytes = OHDR_SIZE + (nInstVars * sizeof(OBJ));
  2515                 nInstBytes = OHDR_SIZE + (nInstVars * sizeof(OBJ));
  2524 		objSize = __qSize(addr) - nInstBytes;
  2516                 objSize = __qSize(addr) - nInstBytes;
  2525 		addrPtr = (char *)__InstPtr(addr) + nInstBytes;
  2517                 addrPtr = (char *)__InstPtr(addr) + nInstBytes;
  2526 		if (objSize < alen)
  2518                 if (objSize < alen)
  2527 		    goto bad;
  2519                     goto bad;
  2528 
  2520 
  2529 		/*
  2521                 /*
  2530 		 * extract the datagrams address
  2522                  * extract the datagrams address
  2531 		 */
  2523                  */
  2532 		memcpy(addrPtr, (char *)&sa, alen);
  2524                 memcpy(addrPtr, (char *)&sa, alen);
  2533 		addrLen = __MKSMALLINT(alen);
  2525                 addrLen = __MKSMALLINT(alen);
  2534 	    }
  2526             }
  2535 	}
  2527         }
  2536 	if (n < 0) {
  2528         if (n < 0) {
  2537 	    error = __INST(lastErrorNumber) = __MKSMALLINT(errno);
  2529             error = __INST(lastErrorNumber) = __MKSMALLINT(errno);
  2538 	}
  2530         }
  2539 	nReceived = __MKSMALLINT(n);
  2531         nReceived = __MKSMALLINT(n);
  2540     }
  2532     }
  2541 #endif
  2533 #endif
  2542 bad: ;
  2534 bad: ;
  2543 %}.
  2535 %}.
  2544     error notNil ifTrue:[
  2536     error notNil ifTrue:[
  2545 	^ self readError:error.
  2537         ^ self readError:error.
  2546     ].
  2538     ].
  2547 
  2539 
  2548     nReceived notNil ifTrue:[
  2540     nReceived notNil ifTrue:[
  2549 	addrLen notNil ifTrue:[
  2541         addrLen notNil ifTrue:[
  2550 	    (addr == anAddressBuffer) ifFalse:[
  2542             (addr == anAddressBuffer) ifFalse:[
  2551 		self obsoleteFeatureWarning:'please use a socketAddress argument'.
  2543                 self obsoleteFeatureWarning:'please use a socketAddress argument'.
  2552 
  2544 
  2553 		"can be a ByteArray for backward compatibility"
  2545                 "can be a ByteArray for backward compatibility"
  2554 		anAddressBuffer replaceFrom:1 to:addrLen with:(addr hostAddress).
  2546                 anAddressBuffer replaceFrom:1 to:addrLen with:(addr hostAddress).
  2555 	    ].
  2547             ].
  2556 	].
  2548         ].
  2557 	^ nReceived
  2549         ^ nReceived
  2558     ].
  2550     ].
  2559     "
  2551     "
  2560      arrive here if you try to receive into an invalid buffer
  2552      arrive here if you try to receive into an invalid buffer
  2561      (i.e. not ByteArray-like),
  2553      (i.e. not ByteArray-like),
  2562      or if the addressBuffer is nonNil AND not a SocketAddress/ByteArray
  2554      or if the addressBuffer is nonNil AND not a SocketAddress/ByteArray
  2688      On error, the unix error code is left in the lastErrorNumber
  2680      On error, the unix error code is left in the lastErrorNumber
  2689      instance variable."
  2681      instance variable."
  2690 
  2682 
  2691     |domainClass addr error|
  2683     |domainClass addr error|
  2692 
  2684 
  2693     (anAddressBuffer isKindOf:SocketAddress) ifTrue:[
  2685     anAddressBuffer isSocketAddress ifTrue:[
  2694 	addr := anAddressBuffer.
  2686         addr := anAddressBuffer.
  2695     ] ifFalse:[
  2687     ] ifFalse:[
  2696 	anAddressBuffer isByteArray ifFalse:[
  2688         anAddressBuffer isByteArray ifFalse:[
  2697 	    ^ self error:'bad socketAddress argument'
  2689             ^ self error:'bad socketAddress argument'
  2698 	].
  2690         ].
  2699 	domainClass := self class socketAddressClassForDomain:domain.
  2691         domainClass := self class socketAddressClassForDomain:domain.
  2700 	domainClass isNil ifTrue:[
  2692         domainClass isNil ifTrue:[
  2701 	    ^ self error:'invalid (unsupported) domain'.
  2693             ^ self error:'invalid (unsupported) domain'.
  2702 	].
  2694         ].
  2703 	addr := domainClass hostAddress:anAddressBuffer.
  2695         addr := domainClass hostAddress:anAddressBuffer.
  2704     ].
  2696     ].
  2705 %{
  2697 %{
  2706 #ifndef NO_SOCKET
  2698 #ifndef NO_SOCKET
  2707     OBJ fp = __INST(handle);
  2699     OBJ fp = __INST(handle);
  2708 
  2700 
  2709     if ((fp != nil)
  2701     if ((fp != nil)
  2710      && __isSmallInteger(startIndex)
  2702      && __isSmallInteger(startIndex)
  2711      && __isSmallInteger(nBytes)) {
  2703      && __isSmallInteger(nBytes)) {
  2712 	SOCKET sock;
  2704         SOCKET sock;
  2713 	INT objSize;
  2705         INT objSize;
  2714 	struct sockaddr *sockaddr_ptr;
  2706         struct sockaddr *sockaddr_ptr;
  2715 	union sockaddr_u sa;
  2707         union sockaddr_u sa;
  2716 	socklen_t sockaddr_size, alen = 0;
  2708         socklen_t sockaddr_size, alen = 0;
  2717 	INT sockAddrOffs;
  2709         INT sockAddrOffs;
  2718 	INT n, offs;
  2710         INT n, offs;
  2719 	char *extPtr;
  2711         char *extPtr;
  2720 	int _flags = __longIntVal(flags);
  2712         int _flags = __longIntVal(flags);
  2721 	unsigned long norder;
  2713         unsigned long norder;
  2722 	unsigned char *buffer;
  2714         unsigned char *buffer;
  2723 	unsigned char *allocatedBuffer = NULL;
  2715         unsigned char *allocatedBuffer = NULL;
  2724 
  2716 
  2725 	sock = SOCKET_FROM_FILE_OBJECT(fp);
  2717         sock = SOCKET_FROM_FILE_OBJECT(fp);
  2726 
  2718 
  2727 	if (! __isBytes(addr)) {
  2719         if (! __isBytes(addr)) {
  2728 	    sockaddr_size = 0;
  2720             sockaddr_size = 0;
  2729 	    sockaddr_ptr = (struct sockaddr *)0;
  2721             sockaddr_ptr = (struct sockaddr *)0;
  2730 	} else {
  2722         } else {
  2731 	    int nIndex;
  2723             int nIndex;
  2732 	    OBJ cls;
  2724             OBJ cls;
  2733 
  2725 
  2734 	    sockAddrOffs = 0;
  2726             sockAddrOffs = 0;
  2735 	    if ((cls = __qClass(addr)) != @global(ByteArray))
  2727             if ((cls = __qClass(addr)) != @global(ByteArray))
  2736 		sockAddrOffs += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  2728                 sockAddrOffs += __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  2737 	    nIndex = __qSize(addr) - OHDR_SIZE;
  2729             nIndex = __qSize(addr) - OHDR_SIZE;
  2738 	    sockaddr_size = nIndex - sockAddrOffs;
  2730             sockaddr_size = nIndex - sockAddrOffs;
  2739 	    if (sockaddr_size > sizeof(sa)) {
  2731             if (sockaddr_size > sizeof(sa)) {
  2740 		console_fprintf(stderr, "Socket [warning]: bad socketAddr\n");
  2732                 console_fprintf(stderr, "Socket [warning]: bad socketAddr\n");
  2741 		goto bad;
  2733                 goto bad;
  2742 	    }
  2734             }
  2743 	    memcpy(&sa, (__byteArrayVal(addr) + sockAddrOffs), sockaddr_size);
  2735             memcpy(&sa, (__byteArrayVal(addr) + sockAddrOffs), sockaddr_size);
  2744 	    sockaddr_ptr = (struct sockaddr *)(&sa);
  2736             sockaddr_ptr = (struct sockaddr *)(&sa);
  2745 	}
  2737         }
  2746 
  2738 
  2747 	if (! setupBufferParameters(aDataBuffer, startIndex, &extPtr, &offs, &objSize)) goto bad;
  2739         if (! setupBufferParameters(aDataBuffer, startIndex, &extPtr, &offs, &objSize)) goto bad;
  2748 	if (__isSmallInteger(nBytes)) {
  2740         if (__isSmallInteger(nBytes)) {
  2749 	    if (__intVal(nBytes) < objSize) {
  2741             if (__intVal(nBytes) < objSize) {
  2750 		objSize = __intVal(nBytes);
  2742                 objSize = __intVal(nBytes);
  2751 	    }
  2743             }
  2752 	}
  2744         }
  2753 
  2745 
  2754 #ifdef DO_WRAP_CALLS
  2746 #ifdef DO_WRAP_CALLS
  2755 	if (extPtr) {
  2747         if (extPtr) {
  2756 	    buffer = extPtr + offs;
  2748             buffer = extPtr + offs;
  2757 	} else {
  2749         } else {
  2758 	    allocatedBuffer = buffer = (char *)malloc(objSize);
  2750             allocatedBuffer = buffer = (char *)malloc(objSize);
  2759 	    bcopy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, objSize);
  2751             bcopy((char *)__InstPtr(aDataBuffer) + offs, allocatedBuffer, objSize);
  2760 	}
  2752         }
  2761 
  2753 
  2762 	do {
  2754         do {
  2763 	    __threadErrno = 0;
  2755             __threadErrno = 0;
  2764 	    n = (INT)STX_WSA_NOINT_CALL6("sendto", sendto, sock, buffer, objSize, _flags, sockaddr_ptr, sockaddr_size);
  2756             n = (INT)STX_WSA_NOINT_CALL6("sendto", sendto, sock, buffer, objSize, _flags, sockaddr_ptr, sockaddr_size);
  2765 	} while ((n < 0) && (__threadErrno == EINTR));
  2757         } while ((n < 0) && (__threadErrno == EINTR));
  2766 	if (n < 0) {
  2758         if (n < 0) {
  2767 	    errno = __threadErrno;
  2759             errno = __threadErrno;
  2768 	}
  2760         }
  2769 
  2761 
  2770 	if (allocatedBuffer) {
  2762         if (allocatedBuffer) {
  2771 	    free(allocatedBuffer);
  2763             free(allocatedBuffer);
  2772 	}
  2764         }
  2773 #else
  2765 #else
  2774 	__BEGIN_INTERRUPTABLE__
  2766         __BEGIN_INTERRUPTABLE__
  2775 	do {
  2767         do {
  2776 	    if (extPtr) {
  2768             if (extPtr) {
  2777 		n = sendto(sock, extPtr + offs, objSize, _flags, sockaddr_ptr, sockaddr_size);
  2769                 n = sendto(sock, extPtr + offs, objSize, _flags, sockaddr_ptr, sockaddr_size);
  2778 	    } else {
  2770             } else {
  2779 		n = sendto(sock, (char *)__InstPtr(aDataBuffer) + offs, objSize, _flags, sockaddr_ptr, sockaddr_size);
  2771                 n = sendto(sock, (char *)__InstPtr(aDataBuffer) + offs, objSize, _flags, sockaddr_ptr, sockaddr_size);
  2780 	    }
  2772             }
  2781 	} while ((n < 0) && (errno == EINTR));
  2773         } while ((n < 0) && (errno == EINTR));
  2782 	__END_INTERRUPTABLE__
  2774         __END_INTERRUPTABLE__
  2783 #endif
  2775 #endif
  2784 
  2776 
  2785 	if (n < 0) {
  2777         if (n < 0) {
  2786 	    error = __INST(lastErrorNumber) = __MKSMALLINT(errno);
  2778             error = __INST(lastErrorNumber) = __MKSMALLINT(errno);
  2787 	} else {
  2779         } else {
  2788 	    RETURN (__MKSMALLINT(n));
  2780             RETURN (__MKSMALLINT(n));
  2789 	}
  2781         }
  2790     }
  2782     }
  2791 #endif
  2783 #endif
  2792 bad: ;
  2784 bad: ;
  2793 %}.
  2785 %}.
  2794     error notNil ifTrue:[
  2786     error notNil ifTrue:[
  2795 	self writeError:error.
  2787         self writeError:error.
  2796     ].
  2788     ].
  2797 
  2789 
  2798     "
  2790     "
  2799      arrive here if you try to send from an invalid buffer
  2791      arrive here if you try to send from an invalid buffer
  2800      (i.e. not ByteArray-like),
  2792      (i.e. not ByteArray-like),