diff --git a/packages/libandroid-posix-semaphore/LICENSE b/packages/libandroid-posix-semaphore/LICENSE new file mode 100644 index 0000000000..2131e37a29 --- /dev/null +++ b/packages/libandroid-posix-semaphore/LICENSE @@ -0,0 +1,20 @@ +Copyright © 2005-2020 Rich Felker, et al. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/libandroid-posix-semaphore/build.sh b/packages/libandroid-posix-semaphore/build.sh new file mode 100644 index 0000000000..9cf466510e --- /dev/null +++ b/packages/libandroid-posix-semaphore/build.sh @@ -0,0 +1,20 @@ +TERMUX_PKG_HOMEPAGE=https://man7.org/linux/man-pages/man7/sem_overview.7.html +TERMUX_PKG_DESCRIPTION="Shared library for the posix semaphore system function" +TERMUX_PKG_LICENSE="MIT" +TERMUX_PKG_MAINTAINER="@termux" +TERMUX_PKG_VERSION=0.1 +TERMUX_PKG_SKIP_SRC_EXTRACT=true +TERMUX_PKG_BUILD_IN_SRC=true + +termux_step_make() { + $CC $CFLAGS $CPPFLAGS -DPREFIX="\"$TERMUX_PREFIX\"" \ + -c $TERMUX_PKG_BUILDER_DIR/semaphore.c + $CC $LDFLAGS -shared semaphore.o -o libandroid-posix-semaphore.so + $AR rcu libandroid-posix-semaphore.a semaphore.o + cp -f $TERMUX_PKG_BUILDER_DIR/LICENSE $TERMUX_PKG_SRCDIR/ +} + +termux_step_make_install() { + install -Dm600 libandroid-posix-semaphore.a $TERMUX_PREFIX/lib/libandroid-posix-semaphore.a + install -Dm600 libandroid-posix-semaphore.so $TERMUX_PREFIX/lib/libandroid-posix-semaphore.so +} diff --git a/packages/libandroid-posix-semaphore/semaphore.c b/packages/libandroid-posix-semaphore/semaphore.c new file mode 100644 index 0000000000..3e41c40c7d --- /dev/null +++ b/packages/libandroid-posix-semaphore/semaphore.c @@ -0,0 +1,248 @@ +/* This file is a port of posix named semaphore for Termux Android, + based on musl-libc which is licensed under the standard MIT license. + The ported files are listed as following. + + File(s): src/thread/sem_open.c + src/thread/sem_unlink.c + + Copyright © 2005-2020 Rich Felker, et al. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include // sem_t, sem_init() +#include // mmap(), munmap() +#include // SEM_NSEMS_MAX, NAME_MAX, INT_MAX +#include // open() +#include // write(), close(), unlink() +#include // strlen(), memcpy() +#include // va_arg +#include // errno +#include // fstat() +#include // calloc() +#include // mutex + +#ifndef SEM_NSEMS_MAX +#define SEM_NSEMS_MAX 256 +#endif // !SEM_NSEMS_MAX + +#ifndef PREFIX +#define PREFIX "/data/data/com.termux/files/usr" +#endif + +static __inline__ char *__strchrnul(const char *s, int c) +{ + c = (unsigned char)c; + if (!c) return (char *)s + strlen(s); + for (; *s && *(unsigned char *)s != c; s++); + return (char *)s; +} + +typedef struct { + ino_t ino; + sem_t *sem; + int refcnt; +} semtab_type; + +static semtab_type *semtab; +static pthread_mutex_t lock; + +#define LOCK(l) (pthread_mutex_lock(&l)) +#define UNLOCK(l) (pthread_mutex_unlock(&l)) + +#define FLAGS (O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NONBLOCK) + +static char *__sem_mapname(const char *name, char *buf) +{ + char *p; + while (*name == '/') name++; + if (*(p = __strchrnul(name, '/')) || p==name || + (p-name <= 2 && name[0]=='.' && p[-1]=='.')) { + errno = EINVAL; + return 0; + } + if (p-name > NAME_MAX-4) { + errno = ENAMETOOLONG; + return 0; + } + memcpy(buf, PREFIX"/tmp/sem.", 40); + memcpy(buf+40, name, p-name+1); + return buf; +} + +sem_t *sem_open(const char *name, int flags, ...) +{ + va_list ap; + mode_t mode; + unsigned value; + int fd, i, slot, cnt; + sem_t newsem; + void *map; + struct stat st; + char buf[NAME_MAX+41]; + + if (!(name = __sem_mapname(name, buf))) + return SEM_FAILED; + + LOCK(lock); + /* Allocate table if we don't have one yet */ + if (!semtab && !(semtab = (semtab_type *)(calloc(SEM_NSEMS_MAX, sizeof *semtab)))) { + UNLOCK(lock); + return SEM_FAILED; + } + + /* Reserve a slot in case this semaphore is not mapped yet; + * this is necessary because there is no way to handle + * failures after creation of the file. */ + slot = -1; + for (cnt=i=0; i