blob: 74df43f1341922e34569d7b78655a5b1113c3307 [file] [log] [blame]
import os
import sys
class APRConfigureBase:
def __init__(self, env):
self.env = env
def Check_apr_big_endian(self, context):
import struct
context.Message("Checking for big endianess... ")
array = struct.pack('cccc', '\x01', '\x02', '\x03', '\x04')
i = struct.unpack('i', array)
if i == struct.unpack('>i', array):
context.Result('yes')
return 1
else:
context.Result('no')
return 0
def CheckFile(self, context, path):
context.Message("Checking if %s exists... " % (path))
if os.path.exists(path):
context.Result('yes')
return 1
else:
context.Result('no')
return 0
def CheckTypesCompatible(self, context, t1, t2, includes):
context.Message('Checking %s is the same as %s... ' % (t1, t2))
source = """
%s
void main(void)
{
int foo[0 - !__builtin_types_compatible_p(%s, %s)];
}
""" % (includes, t1, t2)
result = context.TryCompile(source, '.c')
self.env.Filter(CPPFLAGS = ['-D_LARGEFILE64_SOURCE'])
context.Result(result)
return result
def Check_apr_atomic_builtins(self, context):
context.Message('Checking whether the compiler provides atomic builtins... ')
source = """
int main()
{
unsigned long val = 1010, tmp, *mem = &val;
if (__sync_fetch_and_add(&val, 1010) != 1010 || val != 2020)
return 1;
tmp = val;
if (__sync_fetch_and_sub(mem, 1010) != tmp || val != 1010)
return 1;
if (__sync_sub_and_fetch(&val, 1010) != 0 || val != 0)
return 1;
tmp = 3030;
if (__sync_val_compare_and_swap(mem, 0, tmp) != 0 || val != tmp)
return 1;
if (__sync_lock_test_and_set(&val, 4040) != 3030)
return 1;
mem = &tmp;
if (__sync_val_compare_and_swap(&mem, &tmp, &val) != &tmp)
return 1;
__sync_synchronize();
if (mem != &val)
return 1;
return 0;
}
"""
result = context.TryRun(source, '.c')
context.Result(result[0] == 1)
return result[0] == 1
def Check_apr_ebcdic(self, context):
context.Message('Checking whether system uses EBCDIC.. ')
source = """
int main(void) {
return (unsigned char)'A' != (unsigned char)0xC1;
}"""
result = context.TryRun(source, '.c')
context.Result(result[0] == 1)
return result[0] == 1
def Check_apr_nonblock_inherited(self, context):
context.Message('Checking whether O_NONBLOCK setting is inherited from listening sockets... ')
source = """
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifndef HAVE_SOCKLEN_T
typedef int socklen_t;
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
int main(void) {
int listen_s, connected_s, client_s;
int listen_port, rc;
struct sockaddr_in sa;
socklen_t sa_len;
listen_s = socket(AF_INET, SOCK_STREAM, 0);
if (listen_s < 0) {
perror("socket");
exit(1);
}
memset(&sa, 0, sizeof sa);
sa.sin_family = AF_INET;
#ifdef BEOS
sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
#endif
/* leave port 0 to get ephemeral */
rc = bind(listen_s, (struct sockaddr *)&sa, sizeof sa);
if (rc < 0) {
perror("bind for ephemeral port");
exit(1);
}
/* find ephemeral port */
sa_len = sizeof(sa);
rc = getsockname(listen_s, (struct sockaddr *)&sa, &sa_len);
if (rc < 0) {
perror("getsockname");
exit(1);
}
listen_port = sa.sin_port;
rc = listen(listen_s, 5);
if (rc < 0) {
perror("listen");
exit(1);
}
rc = fcntl(listen_s, F_SETFL, O_NONBLOCK);
if (rc < 0) {
perror("fcntl(F_SETFL)");
exit(1);
}
client_s = socket(AF_INET, SOCK_STREAM, 0);
if (client_s < 0) {
perror("socket");
exit(1);
}
memset(&sa, 0, sizeof sa);
sa.sin_family = AF_INET;
sa.sin_port = listen_port;
#ifdef BEOS
sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
#endif
/* leave sin_addr all zeros to use loopback */
rc = connect(client_s, (struct sockaddr *)&sa, sizeof sa);
if (rc < 0) {
perror("connect");
exit(1);
}
sa_len = sizeof sa;
connected_s = accept(listen_s, (struct sockaddr *)&sa, &sa_len);
if (connected_s < 0) {
perror("accept");
exit(1);
}
rc = fcntl(connected_s, F_GETFL, 0);
if (rc < 0) {
perror("fcntl(F_GETFL)");
exit(1);
}
if (!(rc & O_NONBLOCK)) {
fprintf(stderr, "O_NONBLOCK is not set in the child.\n");
exit(1);
}
return 0;
}"""
result = context.TryRun(source, '.c')
context.Result(result[0] == 1)
return result[0] == 1
def Check_apr_largefile64(self, context):
context.Message('Checking whether to enable -D_LARGEFILE64_SOURCE... ')
self.env.AppendUnique(CPPFLAGS = ['-D_LARGEFILE64_SOURCE'])
source = """
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
void main(void)
{
int fd, ret = 0;
struct stat64 st;
off64_t off = 4242;
if (sizeof(off64_t) != 8 || sizeof(off_t) != 4)
exit(1);
if ((fd = open("conftest.lfs", O_LARGEFILE|O_CREAT|O_WRONLY, 0644)) < 0)
exit(2);
if (ftruncate64(fd, off) != 0)
ret = 3;
else if (fstat64(fd, &st) != 0 || st.st_size != off)
ret = 4;
else if (lseek64(fd, off, SEEK_SET) != off)
ret = 5;
else if (close(fd) != 0)
ret = 6;
else if (lstat64("conftest.lfs", &st) != 0 || st.st_size != off)
ret = 7;
else if (stat64("conftest.lfs", &st) != 0 || st.st_size != off)
ret = 8;
unlink("conftest.lfs");
exit(ret);
}"""
result = context.TryRun(source, '.c')
self.env.Filter(CPPFLAGS = ['-D_LARGEFILE64_SOURCE'])
context.Result(result[0] == 1)
return result[0] == 1
def Check_apr_mmap_mapping_dev_zero(self, context):
context.Message('Checking for mmap that can map /dev/zero... ')
source = """
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
int main()
{
int fd;
void *m;
fd = open("/dev/zero", O_RDWR);
if (fd < 0) {
return 1;
}
m = mmap(0, sizeof(void*), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (m == (void *)-1) { /* aka MAP_FAILED */
return 2;
}
if (munmap(m, sizeof(void*)) < 0) {
return 3;
}
return 0;
}
"""
result = context.TryRun(source, '.c')
context.Result(result[0] == 1)
return result[0] == 1
def Check_apr_semaphores(self, context):
context.Message('Checking for sem_open, sem_close, sem_unlink... ')
source = """
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <semaphore.h>
#ifndef SEM_FAILED
#define SEM_FAILED (-1)
#endif
main()
{
sem_t *psem;
const char *sem_name = "/apr_autoconf";
psem = sem_open(sem_name, O_CREAT, 0644, 1);
if (psem == (sem_t *)SEM_FAILED) {
exit(1);
}
sem_close(psem);
psem = sem_open(sem_name, O_CREAT | O_EXCL, 0644, 1);
if (psem != (sem_t *)SEM_FAILED) {
sem_close(psem);
exit(1);
}
sem_unlink(sem_name);
exit(0);
}
"""
result = context.TryCompile(source, '.c')
context.Result(result)
return result
def Check_apr_check_tcp_nodelay_inherited(self, context):
context.Message('Checking for tcp nodelay inherited... ')
source = """
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
int main(void) {
int listen_s, connected_s, client_s;
int listen_port, rc;
struct sockaddr_in sa;
socklen_t sa_len;
socklen_t option_len;
int option;
listen_s = socket(AF_INET, SOCK_STREAM, 0);
if (listen_s < 0) {
perror("socket");
exit(1);
}
option = 1;
rc = setsockopt(listen_s, IPPROTO_TCP, TCP_NODELAY, &option, sizeof option);
if (rc < 0) {
perror("setsockopt TCP_NODELAY");
exit(1);
}
memset(&sa, 0, sizeof sa);
sa.sin_family = AF_INET;
#ifdef BEOS
sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
#endif
/* leave port 0 to get ephemeral */
rc = bind(listen_s, (struct sockaddr *)&sa, sizeof sa);
if (rc < 0) {
perror("bind for ephemeral port");
exit(1);
}
/* find ephemeral port */
sa_len = sizeof(sa);
rc = getsockname(listen_s, (struct sockaddr *)&sa, &sa_len);
if (rc < 0) {
perror("getsockname");
exit(1);
}
listen_port = sa.sin_port;
rc = listen(listen_s, 5);
if (rc < 0) {
perror("listen");
exit(1);
}
client_s = socket(AF_INET, SOCK_STREAM, 0);
if (client_s < 0) {
perror("socket");
exit(1);
}
memset(&sa, 0, sizeof sa);
sa.sin_family = AF_INET;
sa.sin_port = listen_port;
#ifdef BEOS
sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
#endif
/* leave sin_addr all zeros to use loopback */
rc = connect(client_s, (struct sockaddr *)&sa, sizeof sa);
if (rc < 0) {
perror("connect");
exit(1);
}
sa_len = sizeof sa;
connected_s = accept(listen_s, (struct sockaddr *)&sa, &sa_len);
if (connected_s < 0) {
perror("accept");
exit(1);
}
option_len = sizeof option;
rc = getsockopt(connected_s, IPPROTO_TCP, TCP_NODELAY, &option, &option_len);
if (rc < 0) {
perror("getsockopt");
exit(1);
}
if (!option) {
fprintf(stderr, "TCP_NODELAY is not set in the child.\n");
exit(1);
}
return 0;
} """
result = context.TryRun(source, '.c')
context.Result(result[0] == 1)
return result[0] == 1
def Check_apr_semun(self, context):
context.Message('Checking for semun... ')
source = """
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
main()
{
union semun arg;
semctl(0, 0, 0, arg);
exit(0);
}
"""
result = context.TryCompile(source, '.c')
context.Result(result)
return result
def Check_apr_sctp(self, context):
context.Message('Checking for sctp support... ')
source = """
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <netinet/sctp_uio.h>
#include <stdlib.h>
int main(void) {
int s, opt = 1;
if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0)
exit(1);
if (setsockopt(s, IPPROTO_SCTP, SCTP_NODELAY, &opt, sizeof(int)) < 0)
exit(2);
exit(0);
}
"""
result = context.TryRun(source, '.c')
context.Result(result[0] == 1)
return result[0] == 1
class APRConfigure(APRConfigureBase):
def __init__(self, env):
APRConfigureBase.__init__(self, env)