char * readlink_malloc (const char *filename)
{
    int size = 100;
    char *buffer = NULL;
          
    while (1)
    {
        buffer = (char *) XMLVM_ATOMIC_MALLOC (size);
        int nchars = readlink (filename, buffer, size);
        if (nchars < 0)
        {
            XMLVM_FREE(buffer);
            return NULL;
        }
        if (nchars < size)
            return buffer;
        XMLVM_FREE(buffer);
        size *= 2;
    }
}
Ejemplo n.º 2
0
I_32 hysock_close (hysocket_t * sock)
{
    I_32 rc = 0;
    
    if (*sock == INVALID_SOCKET) {
        return hyerror_set_last_error(HYPORT_ERROR_SOCKET_UNIX_EBADF, HYPORT_ERROR_SOCKET_BADSOCKET);
    }
    
    if (close (SOCKET_CAST (*sock)) < 0) {
        rc = errno;
        rc = hyerror_set_last_error(rc, HYPORT_ERROR_SOCKET_BADSOCKET);
    }
    
    XMLVM_FREE(*sock);
    *sock = INVALID_SOCKET;
    return rc;
}
Ejemplo n.º 3
0
I_32 hysock_getnameinfo (hysockaddr_t in_addr, I_32 sockaddr_size, char *name, 
                         I_32 name_length, int flags)
{
    
    /* If we have the IPv6 functions available we will call them, otherwise we'll call the IPv4 function */
#if defined(IPv6_FUNCTION_SUPPORT)
    int rc = 0;
    rc =
    getnameinfo ((OSADDR *) & in_addr->addr, sizeof (in_addr->addr), name,
                 name_length, NULL, 0, flags);
    if (rc != 0)
    {
        rc = errno;
        HYSOCKDEBUG ("<gethostbyaddr failed, err=%d>\n", rc);
        return portLibrary->error_set_last_error (portLibrary, rc,
                                                  findError (rc));
    }
    return 0;
#else /* IPv6_FUNCTION_SUPPORT */
#if !HOSTENT_DATA_R
    OSHOSTENT *result;
#endif
    
#if GLIBC_R||OTHER_R
    BOOLEAN allocBuffer = FALSE;
#endif
    int herr = 0;
    int i = 0;
    int rc = 0;
    int length;
    OSSOCKADDR *addr;
#if HOSTENT_DATA_R||GLIBC_R||OTHER_R||NO_R
    PortlibPTBuffers_t ptBuffers;
#endif /* HOSTENT_DATA_R || GLIBC_R || OTHER_R || NO_R */
    addr = (OSSOCKADDR *) & in_addr->addr;
    if (addr->sin_family == OS_AF_INET4)
    {
        length = 4;
    }
    else
    {
        length = 16;
    }
#if HOSTENT_DATA_R||GLIBC_R||OTHER_R||NO_R
    ptBuffers = hyport_tls_get ();
    if (NULL == ptBuffers)
    {
        return HYPORT_ERROR_SOCKET_SYSTEMFULL;
    }
#define hostentBuffer (&ptBuffers->hostent)
#endif /* HOSTENT_DATA_R || GLIBC_R || OTHER_R || NO_R */
    /* one of several threadsafe gethostbyaddr calls must be made depending on the current platform */
    /* if there is a transient error (HYPORT_ERROR_SOCKET_UNIX_TRYAGAIN), try making the call again */
    for (i = 0; i < MAX_RETRIES; i++)
    {
#if HOSTENT_DATA_R
#define dataBuffer (ptBuffers->hostent_data)
        if (!dataBuffer)
        {
            dataBuffer =
            portLibrary->mem_allocate_memory (portLibrary,
                                              sizeof (OSHOSTENT_DATA));
            if (!dataBuffer)
            {
                return HYPORT_ERROR_SOCKET_SYSTEMFULL;
            }
        }
        herr =
        gethostbyaddr_r (&addr->sin_addr, length, addr->sin_family,
                         hostentBuffer, dataBuffer);
#undef dataBuffer
#elif ORIGINAL_R || NO_R
#if NO_R
        MUTEX_ENTER (hostentLock);
#endif
        result = gethostbyaddr (&addr->sin_addr, length, addr->sin_family);
#if NO_R
        if (result)
        {
            herr = copy_hostent (result, &ptBuffers);
        }
        MUTEX_EXIT (hostentLock);
        if (herr != 0)
        {
            return herr;
        }
#endif
        herr = h_errno;
#elif GLIBC_R || OTHER_R
#define buffer (ptBuffers->gethostBuffer)
#define bufferSize (ptBuffers->gethostBufferSize)
        if (!buffer)
        {
            bufferSize = GET_HOST_BUFFER_SIZE;
        }
        while (TRUE)
        {
            if (allocBuffer == TRUE || !buffer)
            {
                /* The buffer is allocated bufferSize + EXTRA_SPACE, while gethostby*_r is only aware of bufferSize
                 * because there seems to be a bug on Linux 386 where gethostbyname_r writes past the end of the
                 * buffer.  This bug has not been observed on other platforms, but EXTRA_SPACE is added anyway as a precaution.*/
                buffer = XMLVM_ATOMIC_MALLOC(bufferSize + EXTRA_SPACE);
                if (!buffer)
                {
                    return HYPORT_ERROR_SOCKET_SYSTEMFULL;
                }
                allocBuffer = FALSE;
            }
#if GLIBC_R
            gethostbyaddr_r ((char *) &addr->sin_addr, length, addr->sin_family,
                             hostentBuffer, buffer, bufferSize, &result, &herr);
#elif OTHER_R
            result =
            gethostbyaddr_r ((char *) &addr->sin_addr, length,
                             addr->sin_family, hostentBuffer, buffer,
                             bufferSize, &herr);
#endif /* GLIBC_R */
            /* allocate more space if the buffer is too small */
            if (errno == ERANGE || herr == ERANGE)
            {
                XMLVM_FREE(buffer);
                bufferSize *= 2;
                allocBuffer = TRUE;
            }
            else
            {
                break;
            }
        }
#undef buffer
#undef bufferSize
#endif
        if (herr != HYPORT_ERROR_SOCKET_UNIX_TRYAGAIN)
        {
            break;
        }
    }
#if HOSTENT_DATA_R
    if (herr != 0)
    {
        herr = h_errno;
        HYSOCKDEBUGH ("<gethostbyaddr failed, err=%d>\n", herr);
        return portLibrary->error_set_last_error (portLibrary, herr,
                                                  findHostError (herr));
    }
#else
    if (result == NULL)
    {
        HYSOCKDEBUGH ("<gethostbyaddr failed, err=%d>\n", herr);
        return hyerror_set_last_error(herr, findError(herr));
    }
#endif
    else
    {
        memset (name, 0, sizeof (char) * name_length);
#if HOSTENT_DATA_R||NO_R
        strcpy (name, hostentBuffer->h_name);
#else
        strcpy (name, result->h_name);
#endif
    }
#if HOSTENT_DATA_R||GLIBC_R||OTHER_R
#undef hostentBuffer
#endif /*HOSTENT_DATA_R || GLIBC_R || OTHER_R */
    return 0;
#endif /* IPv6_FUNCTION_SUPPORT */
    
}