author | Tanguy Pruvot <tanguy.pruvot@gmail.com> | 2014-07-31 03:49:11 (GMT) |
---|---|---|
committer | Tanguy Pruvot <tanguy.pruvot@gmail.com> | 2014-07-31 09:37:45 (GMT) |
commit | 477b2eba8cf27cb73073a3100830164e3912d130 (patch) | |
tree | bd021830e42759006cafba43d7e41459ed04e50c | |
parent | 1f21642a8e0edab26429dbdccb8cebe83e3eaf36 (diff) | |
download | busybox-477b2eba8cf27cb73073a3100830164e3912d130.zip busybox-477b2eba8cf27cb73073a3100830164e3912d130.tar.gz busybox-477b2eba8cf27cb73073a3100830164e3912d130.tar.bz2 |
android: backport pty implementation from aosp/master
This is not (yet) in l-preview branch but on master
The only way to prevent duplicated includes was to
test the existence of a new constant added after
l-preview bionic source release.
Also use compatible hasmntopt() return type
(swapon/off compilation warnings)
Signed-off-by: Tanguy Pruvot <tanguy.pruvot@gmail.com>
Change-Id: I4ee6e7752eab84de4566ae86a90171b8241fcaea
-rw-r--r-- | Android.mk | 5 | ||||
-rw-r--r-- | android/android.c (renamed from libbb/android.c) | 18 | ||||
-rw-r--r-- | android/libc/pty.c | 118 | ||||
-rw-r--r-- | include/android.h | 21 |
4 files changed, 139 insertions, 23 deletions
@@ -79,7 +79,8 @@ SUBMAKE := make -s -C $(BB_PATH) CC=$(CC) BUSYBOX_SRC_FILES = \ $(shell cat $(BB_PATH)/busybox-$(BUSYBOX_CONFIG).sources) \ - libbb/android.c + android/libc/pty.c \ + android/android.c ifeq ($(TARGET_ARCH),arm) BUSYBOX_SRC_FILES += \ @@ -155,7 +156,6 @@ LOCAL_CFLAGS += \ -Dgetusershell=busybox_getusershell \ -Dsetusershell=busybox_setusershell \ -Dendusershell=busybox_endusershell \ - -Dttyname_r=busybox_ttyname_r \ -Dgetmntent=busybox_getmntent \ -Dgetmntent_r=busybox_getmntent_r \ -Dgenerate_uuid=busybox_generate_uuid @@ -221,7 +221,6 @@ LOCAL_CFLAGS += \ -Dgetusershell=busybox_getusershell \ -Dsetusershell=busybox_setusershell \ -Dendusershell=busybox_endusershell \ - -Dttyname_r=busybox_ttyname_r \ -Dgetmntent=busybox_getmntent \ -Dgetmntent_r=busybox_getmntent_r \ -Dgenerate_uuid=busybox_generate_uuid diff --git a/libbb/android.c b/android/android.c index f4b8df3..7d191c9 100644 --- a/libbb/android.c +++ b/android/android.c @@ -17,16 +17,6 @@ int clearenv() return 0; } -/* bionic/stubs.c:ttyname not implemented anyway */ -int ttyname_r(int fd, char *name, size_t namesize) -{ - char *t = ttyname(fd); - if (!t) - return -1; - strncpy(name, ttyname(fd), namesize); - return 0; -} - /* no /etc/shells anyway */ char *getusershell() { return NULL; } void setusershell() {} @@ -76,13 +66,13 @@ int addmntent(FILE *fp UNUSED_PARAM, const struct mntent *mnt UNUSED_PARAM) return 1; } -const char *hasmntopt(const struct mntent *mnt, const char *opt) +char *hasmntopt(const struct mntent *mnt, const char *opt) { - const char *o = mnt->mnt_opts; + char *o = mnt->mnt_opts; size_t l = strlen(opt); - while ((o = strstr(o, opt)) && - ((o > mnt->mnt_opts && o[-1] != ',') || + while ((o = strstr(o, opt)) && + ((o > mnt->mnt_opts && o[-1] != ',') || (o[l] != 0 && o[l] != ',' && o[l] != '='))); return o; } diff --git a/android/libc/pty.c b/android/libc/pty.c new file mode 100644 index 0000000..2765221 --- a/dev/null +++ b/android/libc/pty.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* #ifndef BIONIC_L (implementation was made after BIONIC_L (l-preview) */ + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <termios.h> +#include <unistd.h> + +#include <fcntl.h> +/* if this constant is not defined, we are + ttyname is not in bionic */ +#ifndef SPLICE_F_GIFT + +int posix_openpt(int flags) { + return open("/dev/ptmx", flags); +} + +int getpt(void) { + return posix_openpt(O_RDWR|O_NOCTTY); +} + +#ifndef __BIONIC__ +int grantpt(int) { + return 0; +} +#endif + +char* ptsname(int fd) { + static char buf[64]; + return ptsname_r(fd, buf, sizeof(buf)) == 0 ? buf : NULL; +} + +int ptsname_r(int fd, char* buf, size_t len) { + if (buf == NULL) { + errno = EINVAL; + return errno; + } + + unsigned int pty_num; + if (ioctl(fd, TIOCGPTN, &pty_num) != 0) { + errno = ENOTTY; + return errno; + } + + if (snprintf(buf, len, "/dev/pts/%u", pty_num) >= (int) len) { + errno = ERANGE; + return errno; + } + + return 0; +} + +int bb_ttyname_r(int fd, char* buf, size_t len) { + if (buf == NULL) { + errno = EINVAL; + return errno; + } + + if (!isatty(fd)) { + return errno; + } + + char path[64]; + snprintf(path, sizeof(path), "/proc/self/fd/%d", fd); + + ssize_t count = readlink(path, buf, len); + if (count == -1) { + return errno; + } + if ((size_t) (count) == len) { + errno = ERANGE; + return errno; + } + buf[count] = '\0'; + return 0; +} + +char* bb_ttyname(int fd) { + static char buf[64]; + return bb_ttyname_r(fd, buf, sizeof(buf)) == 0 ? buf : NULL; +} + +int unlockpt(int fd) { + int unlock = 0; + return ioctl(fd, TIOCSPTLCK, &unlock); +} + +#endif diff --git a/include/android.h b/include/android.h index a96605a..845a99d 100644 --- a/include/android.h +++ b/include/android.h @@ -31,9 +31,6 @@ void endutent(void); /* defined in bionic/mktemp.c */ char *mkdtemp(char *); -/* defined in bionic/stubs.c */ -char *ttyname(int); - /* SYSCALLS */ int stime(time_t *); int swapon(const char *, int); @@ -54,8 +51,20 @@ int getsid(pid_t); /* local definition in libbb/xfuncs_printf.c */ int fdprintf(int fd, const char *format, ...); -/* local definitions in libbb/android.c */ -int ttyname_r(int, char *, size_t); +/* local definitions in android/android.c */ +#include <fcntl.h> +#ifndef SPLICE_F_GIFT +/* if this constant is not defined, we are + ttyname is not in bionic */ +char* bb_ttyname(int); +int bb_ttyname_r(int, char *, size_t); +#define ttyname(n) bb_ttyname(n) +#define ttyname_r(n,s,z) bb_ttyname_r(n,s,z) +#else +/* should be available in android M ? */ +extern char* ttyname(int); +extern int ttyname_r(int, char *, size_t); +#endif char *getusershell(void); void setusershell(void); @@ -65,7 +74,7 @@ struct mntent; struct __sFILE; int addmntent(struct __sFILE *, const struct mntent *); struct mntent *getmntent_r(struct __sFILE *fp, struct mntent *mnt, char *buf, int buflen); -const char *hasmntopt(const struct mntent *, const char *); +char *hasmntopt(const struct mntent *, const char *); #define MNTOPT_NOAUTO "noauto" |