class signal_h(c.Test): header = c.header_test('signal.h') sig_atomic_t = c.type_test() SIG_DFL = c.macro_test() SIG_ERR = c.macro_test() SIG_IGN = c.macro_test() SIGABRT = c.macro_test() SIGFPE = c.macro_test() SIGILL = c.macro_test() SIGINT = c.macro_test() SIGSEGV = c.macro_test() SIGTERM = c.macro_test() signal = c.function_test(c.Function('void', 'int'), 'int', c.Function('void', 'int'), test=''' #include <signal.h> void foo(int x) {} int main() { void (*f)(int) = signal(SIGTERM, foo); return 0; } ''') raise_ = c.function_test('int', 'int', name='raise', test=''' #include <signal.h> int main() { signal(SIGTERM, SIG_IGN); return raise(SIGTERM) == 0 ? 0 : 1; } ''')
def strerror_r(self): if not self.header: return None # Some implementations return a char* of the message. self.ctx.logger.check("checking strerror_r in 'string.h'") if self.builder.try_run(''' #include <string.h> int main() { char b[50]; int r = strerror_r(0, b, 50); return r == 0 ? 0 : 1; } '''): self.ctx.logger.passed() return c.Function('int', 'int', 'char*', 'size_t') if self.builder.try_run(''' #include <string.h> int main() { char b[50]; char* r = strerror_r(0, b, 50); return 0; } '''): self.ctx.logger.passed() return c.Function('char*', 'int', 'char*', 'size_t') self.ctx.logger.failed()
def fopen(self): with tempfile.NamedTemporaryFile() as f: test = ''' #include <errno.h> #include <stdio.h> int main() { FILE* f; fpos_t p; if (!(f = fopen("%s", "r"))) return 1; if (ftell(f) != 0) return 1; if (fgetpos(f, &p) != 0) return 1; if (fseek(f, 1L, SEEK_CUR) != 0) return 1; if (ftell(f) != 1) return 1; if (fsetpos(f, &p) != 0) return 1; if (ftell(f) != 0) return 1; if (fflush(NULL) != 0) return 1; if (!(f = freopen(NULL, "r", f))) return 1; errno = 0; rewind(f); if (errno) return 1; if (ferror(f) != 0) return 1; if (feof(f) != 0) return 1; if (fclose(f) != 0) return 1; return 0; } ''' % f.name if self.builder.check_run(test, "checking fopen in 'stdio.h'"): return c.Function('FILE*', 'const char*', 'const char*')
def abort(self): self.ctx.logger.check("checking abort in 'stdlib.h'") with self.builder.tempfile(''' #include <stdlib.h> #ifdef _WIN32 #include <windows.h> #endif int main() { #ifdef _WIN32 /* Turn off the windows error box */ DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX); SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX); #endif abort(); return 0; } ''') as src: dst = src.parent / 'temp' try: obj = self.builder.uncached_compile(src, quieter=1) exe = self.builder.uncached_link_exe(dst, [obj], quieter=1) except fbuild.ExecutionError: pass else: try: self.builder.ctx.execute([exe], quieter=1) except fbuild.ExecutionError as e: self.ctx.logger.passed() return c.Function('void', 'void') self.ctx.logger.failed()
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.header = 'sys/socket.h' self.socklen_t = c.IntType(4, 4, False) self.sa_family_t = c.IntType(1, 1, False) self.accept = c.Function('int', 'int', 'struct sockaddr*', 'socklen_t*')
def dlopen(self): if not self.header: return lib_code = ''' #ifdef __cplusplus extern "C" { #endif int fred(int argc, char** argv) { return 0; } #ifdef __cplusplus } #endif ''' exe_code = ''' #include <dlfcn.h> #include <stdlib.h> int main(int argc, char** argv) { void* lib = dlopen("%s", RTLD_NOW); void* fred = 0; if(!lib) return 1; fred = dlsym(lib,"fred"); if(!fred) return 1; return dlclose(lib) == 0 ? 0 : 1; } ''' self.ctx.logger.check("checking dlopen in 'dlfcn.h'") with fbuild.temp.tempfile(lib_code, self.builder.src_suffix) as lib_src: try: obj = self.shared.uncached_compile(lib_src, quieter=1) lib = self.shared.uncached_link_lib(lib_src.parent / 'temp', [obj], quieter=1) except fbuild.ExecutionError: pass else: if self.builder.try_run(exe_code % lib, lkwargs={ 'flags': self.flags, 'libpaths': self.libpaths, 'libs': self.libs, 'external_libs': self.external_libs }, quieter=1): self.ctx.logger.passed() return c.Function('void*', 'const char*', 'int') self.ctx.logger.failed() return None
def signal(self): if not self.header: return None # Some implementations don't follow the standard and use "int" as the # return type of the signal functions. self.ctx.logger.check("checking signal in 'signal.h'") if not self.builder.try_run(''' #include <signal.h> void foo(int x) {} int main() { void (*f)(int) = signal(SIGTERM, foo); return 0; } '''): self.ctx.logger.failed() return None if self.builder.try_run(''' #include <signal.h> void foo(int x) {} int main() { return *(signal (0, 0)) (0) == 1; } '''): self.ctx.logger.passed('ok int') return c.Function(c.Function('int', 'int'), 'int', c.Function('int', 'int')) else: self.ctx.logger.passed('ok void') return c.Function(c.Function('void', 'int'), 'int', c.Function('void', 'int'))
def setsockopt(self): if not self.header: return if self.socklen_t: return super().setsockopt # Some old implementations use 'int' or 'unsigned int' instead of # socklen_t. self.ctx.logger.check("checking setsockopt in 'sys/socket.h'") for typename in 'unsigned int*', 'int*': if self.builder.try_run(''' #include <sys/socket.h> int (*x)(int, int, int, const void*, %s) = setsockopt; int main() { return 0; } ''' % typename): self.ctx.logger.passed() return c.Function('int', 'int', 'int', 'const void*', typename) self.ctx.logger.failed()
def getpeername(self): if not self.header: return if self.socklen_t: return super().getpeername # Some old implementations use 'int' or 'unsigned int' instead of # socklen_t. self.ctx.logger.check("checking getpeername in 'sys/socket.h'") for typename in 'unsigned int*', 'int*': if self.builder.try_run(''' #include <sys/socket.h> int (*x)(int, struct sockaddr*, %s) = getpeername; int main() { return 0; } ''' % typename): self.ctx.logger.passed() return c.Function('int', 'int', 'struct sockaddr*', typename) self.ctx.logger.failed()
def recvfrom(self): if not self.header: return if self.socklen_t: return super().recvfrom # Some old implementations use 'int' or 'unsigned int' instead of # socklen_t. self.ctx.logger.check("checking recvfrom in 'sys/socket.h'") for typename in 'unsigned int*', 'int*': if self.builder.try_run(''' #include <sys/socket.h> ssize_t (*x)(int, void*, size_t, int, struct sockaddr*, %s) = recvfrom; int main() { return 0; } ''' % typename): self.ctx.logger.passed() return c.Function('ssize_t', 'int', 'void*', 'size_t', 'int', 'struct sockaddr*', typename) self.ctx.logger.failed()
def fsetpos(self): if self.fopen: return c.Function('int', 'FILE*', 'const fpos_t*', 'fsetpos')
def fseek(self): if self.fopen: return c.Function('int', 'FILE*', 'long int', 'int', 'fseek')
def freopen(self): if self.fopen: return c.Function('FILE*', 'const char*', 'const char*', 'FILE*')
def pthread_cond_wait(self): if self.pthread_cond_init: return c.Function('int', 'pthread_cond_t*', 'pthread_mutex_t*')
def ferror(self): if self.fopen: return c.Function('int', 'FILE*')
def pthread_cond_signal(self): if self.pthread_cond_init: return c.Function('int', 'pthread_cond_t*')
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.header = 'dlfcn.h' self.flags = [] self.dlopen = c.Function('void*', 'const char*', 'int')
def pthread_spin_trylock(self): if self.pthread_spin_init: return c.Function('int', 'pthread_spinlock_t*')
def pthread_rwlock_wrlock(self): if self.pthread_rwlock_init: return c.Function('int', 'pthread_rwlock_t*')
def pthread_mutex_unlock(self): if self.pthread_mutex_init: return c.Function('int', 'pthread_mutex_t*')
def pthread_mutex_destroy(self): if self.pthread_mutex_init: return c.Function('int', 'pthread_mutex_t*')
def ftell(self): if self.fopen: return c.Function('long int', 'FILE*', 'ftell')
def rewind(self): if self.fopen: return c.Function('void', 'FILE*', 'rewind')
def pthread_attr_setdetachstate(self): if self.pthread_create: return c.Function('int', 'pthread_attr_t*', 'int')
def pthread_barrier_wait(self): if self.pthread_barrier_init: return c.Function('int', 'pthread_barrier_t*')
def pthread_cond_destroy(self): if self.pthread_cond_init: return c.Function('int', 'pthread_cond_t*')
def fclose(self): if self.fopen: return c.Function('int', 'FILE*')
def pthread_cond_broadcast(self): if self.pthread_cond_init: return c.Function('int', 'pthread_cond_t*')
def setjmp(self): if self.longjmp: return c.Function('int', 'jmp_buf')
def pthread_cond_timedwait(self): if self.pthread_cond_init: return c.Function('int', 'pthread_cond_t*', 'pthread_mutex_t*', 'const struct timespec*')