Socket.st
branchjv
changeset 3623 8d9865be083a
parent 3619 ae55ba1cd11e
parent 3620 c648d063bccc
child 3634 d702e00e8533
equal deleted inserted replaced
3619:ae55ba1cd11e 3623:8d9865be083a
    49 // linger.onoff=off linger.time= *irrelevant*
    49 // linger.onoff=off linger.time= *irrelevant*
    50 //# define SET_LINGER_WHEN_CREATING_SOCKET
    50 //# define SET_LINGER_WHEN_CREATING_SOCKET
    51 
    51 
    52 # ifdef __MINGW__
    52 # ifdef __MINGW__
    53 extern HANDLE _get_osfhandle();
    53 extern HANDLE _get_osfhandle();
       
    54 # endif
       
    55 
       
    56 # if defined(__BORLANDC__)
       
    57 // not defined in borland headers
       
    58 typedef unsigned int socklen_t;
    54 # endif
    59 # endif
    55 
    60 
    56 # if 0 && (defined( __BORLANDC__ ) || defined( __MINGW__ ))
    61 # if 0 && (defined( __BORLANDC__ ) || defined( __MINGW__ ))
    57 #  define SOCKET_FROM_FD(fd)               (SOCKET)(_get_osfhandle(fd))
    62 #  define SOCKET_FROM_FD(fd)               (SOCKET)(_get_osfhandle(fd))
    58 # else
    63 # else
  2909      If blocking is false, this call will return immediately, if there is no connection pending."
  2914      If blocking is false, this call will return immediately, if there is no connection pending."
  2910 
  2915 
  2911     |serverSocketHandle addr domainClass newHandle|
  2916     |serverSocketHandle addr domainClass newHandle|
  2912 
  2917 
  2913     handle notNil ifTrue:[
  2918     handle notNil ifTrue:[
  2914 	^ self errorAlreadyOpen
  2919         ^ self errorAlreadyOpen
  2915     ].
  2920     ].
  2916 
  2921 
  2917     domain := aServerSocket domain.
  2922     domain := aServerSocket domain.
  2918     socketType := aServerSocket type.
  2923     socketType := aServerSocket type.
  2919     handleType := aServerSocket handleType.
  2924     handleType := aServerSocket handleType.
  2920     serverSocketHandle := aServerSocket fileHandle.
  2925     serverSocketHandle := aServerSocket fileHandle.
  2921     serverSocketHandle isNil ifTrue:[
  2926     serverSocketHandle isNil ifTrue:[
  2922 	^ self error:'invalid server socket'
  2927         ^ self error:'invalid server socket'
  2923     ].
  2928     ].
  2924     "unix domain sockets do not return a valid peer name on accept"
  2929     "unix domain sockets do not return a valid peer name on accept"
  2925     domainClass := self class socketAddressClassForDomain:domain.
  2930     domainClass := self class socketAddressClassForDomain:domain.
  2926     domainClass isNil ifTrue:[
  2931     domainClass isNil ifTrue:[
  2927 	^ self error:'invalid (unsupported) domain'.
  2932         ^ self error:'invalid (unsupported) domain'.
  2928     ].
  2933     ].
  2929     addr := domainClass new.
  2934     addr := domainClass new.
  2930     newHandle := OperatingSystem socketAccessor new.
  2935     newHandle := OperatingSystem socketAccessor new.
  2931 
  2936 
  2932 %{  /* STACK: 100000 */
  2937 %{  /* STACK: 100000 */
  2944     serverSocket = __intVal(serverSocketHandle);
  2949     serverSocket = __intVal(serverSocketHandle);
  2945 #endif
  2950 #endif
  2946 
  2951 
  2947 # if defined(O_NONBLOCK) && defined(SET_NDELAY)
  2952 # if defined(O_NONBLOCK) && defined(SET_NDELAY)
  2948     if (blocking == false) {
  2953     if (blocking == false) {
  2949 	flags = fcntl(serverSocket, F_GETFL);
  2954         flags = fcntl(serverSocket, F_GETFL);
  2950 	fcntl(serverSocket, F_SETFL, flags | O_NONBLOCK);
  2955         fcntl(serverSocket, F_SETFL, flags | O_NONBLOCK);
  2951     }
  2956     }
  2952 # endif
  2957 # endif
  2953 
  2958 
  2954 # ifdef DO_WRAP_CALLS
  2959 # ifdef DO_WRAP_CALLS
  2955     do {
  2960     do {
  2956 	__threadErrno = 0;
  2961         __threadErrno = 0;
  2957 	alen = sizeof(sa);
  2962         alen = sizeof(sa);
  2958 	newSock = (SOCKET)STX_WSA_CALL3("accept", accept, serverSocket, &sa, &alen);
  2963         newSock = (SOCKET)STX_WSA_CALL3("accept", accept, serverSocket, &sa, &alen);
  2959     } while ((newSock < 0) && (__threadErrno == EINTR));
  2964     } while ((newSock < 0) && (__threadErrno == EINTR));
  2960     if (newSock < 0) {
  2965     if (newSock < 0) {
  2961 	errno = __threadErrno;
  2966         errno = __threadErrno;
  2962     }
  2967     }
  2963 # else
  2968 # else
  2964     __BEGIN_INTERRUPTABLE__
  2969     __BEGIN_INTERRUPTABLE__
  2965     do {
  2970     do {
  2966 	alen = sizeof(sa);
  2971         alen = sizeof(sa);
  2967 	newSock = accept(serverSocket, (struct sockaddr *) &sa, &alen);
  2972         newSock = accept(serverSocket, (struct sockaddr *) &sa, &alen);
  2968     } while ((newSock < 0) && (errno == EINTR));
  2973     } while ((newSock < 0) && (errno == EINTR));
  2969     __END_INTERRUPTABLE__
  2974     __END_INTERRUPTABLE__
  2970 # endif
  2975 # endif
  2971     DBGFPRINTF((stderr, "SOCKET: accept newSock=%d\n", newSock));
  2976     DBGFPRINTF((stderr, "SOCKET: accept newSock=%d\n", newSock));
  2972 
  2977 
  2973 # if defined(O_NDELAY) && defined(SET_NDELAY)
  2978 # if defined(O_NDELAY) && defined(SET_NDELAY)
  2974     if (blocking == false) {
  2979     if (blocking == false) {
  2975 	fcntl(serverSocket, F_SETFL, flags);
  2980         fcntl(serverSocket, F_SETFL, flags);
  2976     }
  2981     }
  2977 # endif
  2982 # endif
  2978 
  2983 
  2979     if (newSock == -1) {
  2984     if (newSock == -1) {
  2980 	DBGPRINTF(("SOCKET: accept call failed errno=%d\n", errno));
  2985         DBGPRINTF(("SOCKET: accept call failed errno=%d\n", errno));
  2981 	__INST(lastErrorNumber) = __MKSMALLINT(errno);
  2986         __INST(lastErrorNumber) = __MKSMALLINT(errno);
  2982 	RETURN (false);
  2987         RETURN (false);
  2983     }
  2988     }
  2984 
  2989 
  2985     if (__isNonNilObject(addr)) {
  2990     if (__isNonNilObject(addr)) {
  2986 	OBJ oClass = __qClass(addr);
  2991         OBJ oClass = __qClass(addr);
  2987 	int nInstVars, nInstBytes, objSize;
  2992         int nInstVars, nInstBytes, objSize;
  2988 	char *addrP;
  2993         char *addrP;
  2989 
  2994 
  2990 	if (! __isBytes(addr) ) {
  2995         if (! __isBytes(addr) ) {
  2991 	    DBGPRINTF(("SOCKET: bad addr\n"));
  2996             DBGPRINTF(("SOCKET: bad addr\n"));
  2992 	    closesocket(newSock);
  2997             closesocket(newSock);
  2993 	    RETURN (false);
  2998             RETURN (false);
  2994 	}
  2999         }
  2995 
  3000 
  2996 	nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  3001         nInstVars = __intVal(__ClassInstPtr(oClass)->c_ninstvars);
  2997 	nInstBytes = OHDR_SIZE + (nInstVars * sizeof(OBJ));
  3002         nInstBytes = OHDR_SIZE + (nInstVars * sizeof(OBJ));
  2998 	objSize = __qSize(addr) - nInstBytes;
  3003         objSize = __qSize(addr) - nInstBytes;
  2999 	addrP = (char *)__InstPtr(addr) + nInstBytes;
  3004         addrP = (char *)__InstPtr(addr) + nInstBytes;
  3000 	if (objSize < alen) {
  3005         if (objSize < alen) {
  3001 	    DBGPRINTF(("SOCKET: bad addr\n"));
  3006             DBGPRINTF(("SOCKET: bad addr\n"));
  3002 	    closesocket(newSock);
  3007             closesocket(newSock);
  3003 	    RETURN (false);
  3008             RETURN (false);
  3004 	}
  3009         }
  3005 
  3010 
  3006 	/*
  3011         /*
  3007 	 * extract the partners address
  3012          * extract the partners address
  3008 	 */
  3013          */
  3009 	memcpy(addrP, (char *)&sa, alen);
  3014         memcpy(addrP, (char *)&sa, alen);
  3010     }
  3015     }
  3011 
  3016 
  3012     /*
  3017     /*
  3013      * make it a FILE *
  3018      * make it a FILE *
  3014      */
  3019      */
  3022     _fd = (int)newSock;
  3027     _fd = (int)newSock;
  3023 #  endif
  3028 #  endif
  3024 # else // ! WIN32
  3029 # else // ! WIN32
  3025     fp = fdopen(newSock, "r+");
  3030     fp = fdopen(newSock, "r+");
  3026     if (! fp) {
  3031     if (! fp) {
  3027 	DBGPRINTF(("SOCKET: fdopen call failed\n"));
  3032         DBGPRINTF(("SOCKET: fdopen call failed\n"));
  3028 	__INST(lastErrorNumber) = __MKSMALLINT(errno);
  3033         __INST(lastErrorNumber) = __MKSMALLINT(errno);
  3029 	closesocket(newSock);
  3034         closesocket(newSock);
  3030 	DBGFPRINTF((stderr, "SOCKET: close (fdopen failed) (%d)\n", newSock));
  3035         DBGFPRINTF((stderr, "SOCKET: close (fdopen failed) (%d)\n", newSock));
  3031 	RETURN (false);
  3036         RETURN (false);
  3032     }
  3037     }
  3033 # endif // ! WIN32
  3038 # endif // ! WIN32
  3034 
  3039 
  3035     if ((@global(FileOpenTrace) == true) || __debugging__) {
  3040     if ((@global(FileOpenTrace) == true) || __debugging__) {
  3036 # ifdef WIN32
  3041 # ifdef WIN32
  3037 	console_fprintf(stderr, "fdopen [Socket accept] -> fd: %d (H: %"_lx_")\n", _fd, (INT)newSock);
  3042         console_fprintf(stderr, "fdopen [Socket accept] -> fd: %d (H: %"_lx_")\n", _fd, (INT)newSock);
  3038 # else
  3043 # else
  3039 	console_fprintf(stderr, "fdopen [Socket accept] -> %"_lx_" (fd: %d)\n", (INT)fp, newSock);
  3044         console_fprintf(stderr, "fdopen [Socket accept] -> %"_lx_" (fd: %d)\n", (INT)fp, newSock);
  3040 # endif
  3045 # endif
  3041     }
  3046     }
  3042 
  3047 
  3043 # ifdef WIN32
  3048 # ifdef WIN32
  3044     __externalAddressVal(newHandle) = _fd;
  3049     __externalAddressVal(newHandle) = _fd;
  3052 
  3057 
  3053     handle := newHandle.
  3058     handle := newHandle.
  3054     buffered := false.
  3059     buffered := false.
  3055     mode := #readwrite.
  3060     mode := #readwrite.
  3056     binary := false.
  3061     binary := false.
  3057     Lobby register:self.
  3062     self registerForFinalization.
  3058     peer := addr.
  3063     peer := addr.
  3059     port := aServerSocket port.
  3064     port := aServerSocket port.
  3060 
  3065 
  3061     ^ true
  3066     ^ true
  3062 !
  3067 !
  3642      #AF_INET, #AF_INET6, #AF_UNIX ... and #stream, #datagram, #raw resp."
  3647      #AF_INET, #AF_INET6, #AF_UNIX ... and #stream, #datagram, #raw resp."
  3643 
  3648 
  3644     |domainName domainCode typeCode error newHandle|
  3649     |domainName domainCode typeCode error newHandle|
  3645 
  3650 
  3646     handle notNil ifTrue:[
  3651     handle notNil ifTrue:[
  3647 	^ self errorAlreadyOpen
  3652         ^ self errorAlreadyOpen
  3648     ].
  3653     ].
  3649     domainName := SocketAddress domainCodeFromName:domainArg.
  3654     domainName := SocketAddress domainCodeFromName:domainArg.
  3650     domainCode := OperatingSystem domainCodeOf:domainName.
  3655     domainCode := OperatingSystem domainCodeOf:domainName.
  3651     typeCode := OperatingSystem socketTypeCodeOf:typeArg.
  3656     typeCode := OperatingSystem socketTypeCodeOf:typeArg.
  3652     newHandle := OperatingSystem socketAccessor new.
  3657     newHandle := OperatingSystem socketAccessor new.
  3664 #  endif
  3669 #  endif
  3665     static int noInheritFlag = WSA_FLAG_NO_HANDLE_INHERIT;
  3670     static int noInheritFlag = WSA_FLAG_NO_HANDLE_INHERIT;
  3666 # endif
  3671 # endif
  3667 
  3672 
  3668     if (! __isSmallInteger(domainCode)) {
  3673     if (! __isSmallInteger(domainCode)) {
  3669 	error = @symbol(badArgument1);
  3674         error = @symbol(badArgument1);
  3670 	goto out;
  3675         goto out;
  3671     }
  3676     }
  3672     if (! __isSmallInteger(typeCode)) {
  3677     if (! __isSmallInteger(typeCode)) {
  3673 	error = @symbol(badArgument2);
  3678         error = @symbol(badArgument2);
  3674 	goto out;
  3679         goto out;
  3675     }
  3680     }
  3676     if (protocolNumber != nil) {
  3681     if (protocolNumber != nil) {
  3677 	if (!__isSmallInteger(protocolNumber)) {
  3682         if (!__isSmallInteger(protocolNumber)) {
  3678 	    error = @symbol(badArgument3);
  3683             error = @symbol(badArgument3);
  3679 	    goto out;
  3684             goto out;
  3680 	}
  3685         }
  3681 	proto = __intVal(protocolNumber);
  3686         proto = __intVal(protocolNumber);
  3682     }
  3687     }
  3683 
  3688 
  3684     /*
  3689     /*
  3685      * get address and protocol-family
  3690      * get address and protocol-family
  3686      */
  3691      */
  3688     typ = __intVal(typeCode);
  3693     typ = __intVal(typeCode);
  3689 
  3694 
  3690 # ifdef WIN32
  3695 # ifdef WIN32
  3691     sock = WSASocket(dom, typ, proto, 0, 0, noInheritFlag);
  3696     sock = WSASocket(dom, typ, proto, 0, 0, noInheritFlag);
  3692     if (sock == INVALID_SOCKET && noInheritFlag) {
  3697     if (sock == INVALID_SOCKET && noInheritFlag) {
  3693 	// tried to open socket with WSA_FLAG_NO_HANDLE_INHERIT
  3698         // tried to open socket with WSA_FLAG_NO_HANDLE_INHERIT
  3694 	// This fails on older windows versions, e.g. Windows XP
  3699         // This fails on older windows versions, e.g. Windows XP
  3695 	sock = WSASocket(dom, typ, proto, 0, 0, 0);
  3700         sock = WSASocket(dom, typ, proto, 0, 0, 0);
  3696 	if (sock != INVALID_SOCKET) {
  3701         if (sock != INVALID_SOCKET) {
  3697 	    // no error without WSA_FLAG_NO_HANDLE_INHERIT,
  3702             // no error without WSA_FLAG_NO_HANDLE_INHERIT,
  3698 	    // never use this flag again!
  3703             // never use this flag again!
  3699 	    noInheritFlag = 0;
  3704             noInheritFlag = 0;
  3700 	}
  3705         }
  3701     }
  3706     }
  3702     if (sock == INVALID_SOCKET) {
  3707     if (sock == INVALID_SOCKET) {
  3703 	errno = WSAGetLastError();
  3708         errno = WSAGetLastError();
  3704 
  3709 
  3705 # else  // !WIN32
  3710 # else  // !WIN32
  3706 
  3711 
  3707     sock = socket(dom, typ, proto);
  3712     sock = socket(dom, typ, proto);
  3708 # if defined(EPROTONOSUPPORT) /* for SGI */
  3713 # if defined(EPROTONOSUPPORT) /* for SGI */
  3709     if ((sock < 0) && (proto != 0) && (errno == EPROTONOSUPPORT)) {
  3714     if ((sock < 0) && (proto != 0) && (errno == EPROTONOSUPPORT)) {
  3710 	DBGPRINTF(("SOCKET: retry with UNSPEC protocol\n"));
  3715         DBGPRINTF(("SOCKET: retry with UNSPEC protocol\n"));
  3711 	proto = 0;
  3716         proto = 0;
  3712 	sock = socket(dom, typ, 0);
  3717         sock = socket(dom, typ, 0);
  3713     }
  3718     }
  3714 # endif
  3719 # endif
  3715     if (sock < 0) {
  3720     if (sock < 0) {
  3716 # endif // !WIN32
  3721 # endif // !WIN32
  3717 
  3722 
  3718 	DBGPRINTF(("SOCKET: socket(dom=%d typ=%d proto=%d) call failed errno=%d\n", dom, typ, proto, errno));
  3723         DBGPRINTF(("SOCKET: socket(dom=%d typ=%d proto=%d) call failed errno=%d\n", dom, typ, proto, errno));
  3719 	error = __MKSMALLINT(errno);
  3724         error = __MKSMALLINT(errno);
  3720     } else {
  3725     } else {
  3721 # if defined(SET_LINGER_WHEN_CREATING_SOCKET) && defined(SO_LINGER)
  3726 # if defined(SET_LINGER_WHEN_CREATING_SOCKET) && defined(SO_LINGER)
  3722 	{
  3727         {
  3723 	    struct linger l;
  3728             struct linger l;
  3724 
  3729 
  3725 	    l.l_onoff = 1;
  3730             l.l_onoff = 1;
  3726 	    l.l_linger = 30;
  3731             l.l_linger = 30;
  3727 	    setsockopt( sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
  3732             setsockopt( sock, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
  3728 	}
  3733         }
  3729 # endif
  3734 # endif
  3730 # ifdef WIN32
  3735 # ifdef WIN32
  3731 	/*
  3736         /*
  3732 	 * make it blocking
  3737          * make it blocking
  3733 	 */
  3738          */
  3734 	{
  3739         {
  3735 	    unsigned long zero = 0;
  3740             unsigned long zero = 0;
  3736 	    ioctlsocket(sock, FIONBIO, &zero);
  3741             ioctlsocket(sock, FIONBIO, &zero);
  3737 	}
  3742         }
  3738 	{
  3743         {
  3739 #  if 0 && (defined( __BORLANDC__ ) || defined( __MINGW__ ))
  3744 #  if 0 && (defined( __BORLANDC__ ) || defined( __MINGW__ ))
  3740 	    /*
  3745             /*
  3741 	     * make it a FILE *
  3746              * make it a FILE *
  3742 	     */
  3747              */
  3743 	    __stxWrapApiEnterCritical();
  3748             __stxWrapApiEnterCritical();
  3744 	    _fd = _open_osfhandle((long)sock, 0);
  3749             _fd = _open_osfhandle((long)sock, 0);
  3745 	    __stxWrapApiLeaveCritical();
  3750             __stxWrapApiLeaveCritical();
  3746 #  else
  3751 #  else
  3747 	    _fd = (int)sock;
  3752             _fd = (int)sock;
  3748 #  endif
  3753 #  endif
  3749 	    DBGPRINTF(("SOCKET: sock=%d fd=%d\n", sock, _fd));
  3754             DBGPRINTF(("SOCKET: sock=%d fd=%d\n", sock, _fd));
  3750 	}
  3755         }
  3751 # else  // !WIN32
  3756 # else  // !WIN32
  3752 	fp = fdopen(sock, "r+");
  3757         fp = fdopen(sock, "r+");
  3753 	if (! fp) {
  3758         if (! fp) {
  3754 	    DBGPRINTF(("SOCKET: fdopen call failed\n"));
  3759             DBGPRINTF(("SOCKET: fdopen call failed\n"));
  3755 	    error = __MKSMALLINT(errno);
  3760             error = __MKSMALLINT(errno);
  3756 	    __BEGIN_INTERRUPTABLE__
  3761             __BEGIN_INTERRUPTABLE__
  3757 	    closesocket(sock);
  3762             closesocket(sock);
  3758 	    DBGFPRINTF((stderr, "SOCKET: fdopen failed (%d)\n", sock));
  3763             DBGFPRINTF((stderr, "SOCKET: fdopen failed (%d)\n", sock));
  3759 	    __END_INTERRUPTABLE__
  3764             __END_INTERRUPTABLE__
  3760 	    goto out;
  3765             goto out;
  3761 	}
  3766         }
  3762 # endif // !WIN32
  3767 # endif // !WIN32
  3763 
  3768 
  3764 	if (@global(FileOpenTrace) == true) {
  3769         if (@global(FileOpenTrace) == true) {
  3765 # ifdef WIN32
  3770 # ifdef WIN32
  3766 	    console_fprintf(stderr, "fdopen [Socket create] -> fd: %d (H: %"_lx_")\n", (INT)_fd, (INT)sock);
  3771             console_fprintf(stderr, "fdopen [Socket create] -> fd: %d (H: %"_lx_")\n", (INT)_fd, (INT)sock);
  3767 # else
  3772 # else
  3768 	    console_fprintf(stderr, "fdopen [Socket] -> %"_lx_" (fd: %d)\n", (INT)fp, sock);
  3773             console_fprintf(stderr, "fdopen [Socket] -> %"_lx_" (fd: %d)\n", (INT)fp, sock);
  3769 # endif
  3774 # endif
  3770 	}
  3775         }
  3771 
  3776 
  3772 # ifdef WIN32
  3777 # ifdef WIN32
  3773 	__externalAddressVal(newHandle) = _fd;
  3778         __externalAddressVal(newHandle) = _fd;
  3774 	__INST(handleType) = @symbol(socketHandle);
  3779         __INST(handleType) = @symbol(socketHandle);
  3775 # else
  3780 # else
  3776 	__externalAddressVal(newHandle) = fp;
  3781         __externalAddressVal(newHandle) = fp;
  3777 	__INST(handleType) = @symbol(socketFilePointer);
  3782         __INST(handleType) = @symbol(socketFilePointer);
  3778 # endif
  3783 # endif
  3779     }
  3784     }
  3780 #endif
  3785 #endif
  3781 out:;
  3786 out:;
  3782 %}.
  3787 %}.
  3783 
  3788 
  3784     "all ok?"
  3789     "all ok?"
  3785     handleType notNil ifTrue:[
  3790     handleType notNil ifTrue:[
  3786 	handle := newHandle.
  3791         handle := newHandle.
  3787 	domain := domainArg.
  3792         domain := domainArg.
  3788 	socketType := typeArg.
  3793         socketType := typeArg.
  3789 	Lobby register:self.
  3794         self registerForFinalization.
  3790 	^ self.
  3795         ^ self.
  3791     ].
  3796     ].
  3792     error isInteger ifTrue:[
  3797     error isInteger ifTrue:[
  3793 	lastErrorNumber := error.
  3798         lastErrorNumber := error.
  3794 	^ self openError:error.
  3799         ^ self openError:error.
  3795     ].
  3800     ].
  3796     ^ self primitiveFailed:error.
  3801     ^ self primitiveFailed:error.
  3797 
  3802 
  3798     "
  3803     "
  3799      Socket new domain:#AF_INET type:#stream
  3804      Socket new domain:#AF_INET type:#stream