Nagy Karoly Gabriel
15 years ago
2 changed files with 214 additions and 2 deletions
@ -0,0 +1,212 @@
|
||||
# --- SDE-COPYRIGHT-NOTE-BEGIN ---
|
||||
# This copyright note is auto-generated by ./scripts/Create-CopyPatch.
|
||||
#
|
||||
# Filename: package/.../dietlibc/ttyname_r.diff
|
||||
# Copyright (C) 2009 The OpenSDE Project
|
||||
#
|
||||
# More information can be found in the files COPYING and README.
|
||||
#
|
||||
# This patch file is dual-licensed. It is available under the license the
|
||||
# patched project is licensed under, as long as it is an OpenSource license
|
||||
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
|
||||
# of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option) any later
|
||||
# version.
|
||||
# --- SDE-COPYRIGHT-NOTE-END ---
|
||||
|
||||
This patch replaces dietlibc functionality with uClibc equivalent.
|
||||
It is needed because modern software expects ttyname_r function to
|
||||
be available in the C library.
|
||||
--- ./include/unistd.h.orig 2009-11-09 15:39:52.000000000 +0100
|
||||
+++ ./include/unistd.h 2009-11-09 15:41:48.000000000 +0100
|
||||
@@ -105,6 +105,10 @@
|
||||
|
||||
char *ttyname (int desc) __THROW;
|
||||
|
||||
+/* Store at most BUFLEN characters of the pathname of the terminal FD is
|
||||
+ open on in BUF. Return 0 on success, otherwise an error number. */
|
||||
+int ttyname_r (int __fd, char *__buf, size_t __buflen) __THROW;
|
||||
+
|
||||
int brk(void *end_data_segment) __THROW;
|
||||
void *sbrk(ptrdiff_t increment) __THROW;
|
||||
|
||||
|
||||
--- ./lib/ttyname.c.orig 2002-02-23 23:18:42.000000000 +0100
|
||||
+++ ./lib/ttyname.c 2009-11-09 15:43:20.000000000 +0100
|
||||
@@ -1,66 +1,119 @@
|
||||
-#include "dietfeatures.h"
|
||||
+#include <string.h>
|
||||
+#include <errno.h>
|
||||
+#include <assert.h>
|
||||
#include <unistd.h>
|
||||
+#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
-#include <string.h>
|
||||
|
||||
-#ifdef __linux__
|
||||
+/* Jan 1, 2004 Manuel Novoa III
|
||||
+ *
|
||||
+ * Kept the same approach, but rewrote the code for the most part.
|
||||
+ * Fixed some minor issues plus (as I recall) one SUSv3 errno case.
|
||||
+ */
|
||||
+
|
||||
+/* This is a fairly slow approach. We do a linear search through some
|
||||
+ * directories looking for a match. Yes this is lame. But it should
|
||||
+ * work, should be small, and will return names that match what is on
|
||||
+ * disk. Another approach we could use would be to use the info in
|
||||
+ * /proc/self/fd, but that is even more lame since it requires /proc */
|
||||
+
|
||||
+/* SUSv3 mandates TTY_NAME_MAX as 9. This is obviously insufficient.
|
||||
+ * However, there is no need to waste space and support non-standard
|
||||
+ * tty names either. So we compromise and use the following buffer
|
||||
+ * length. (Erik and Manuel agreed that 32 was more than reasonable.)
|
||||
+ *
|
||||
+ * If you change this, also change _SC_TTY_NAME_MAX in libc/unistd/sysconf.c
|
||||
+ */
|
||||
+#define TTYNAME_BUFLEN 32
|
||||
+
|
||||
+char *ttyname(int fd)
|
||||
+{
|
||||
+ static char name[TTYNAME_BUFLEN];
|
||||
+
|
||||
+ return ttyname_r(fd, name, TTYNAME_BUFLEN) ? NULL : name;
|
||||
+}
|
||||
+
|
||||
+static const char dirlist[] =
|
||||
+/* 12345670123 */
|
||||
+"\010/dev/vc/\0" /* Try /dev/vc first (be devfs compatible) */
|
||||
+"\011/dev/tts/\0" /* and /dev/tts next (be devfs compatible) */
|
||||
+"\011/dev/pty/\0" /* and /dev/pty next (be devfs compatible) */
|
||||
+"\011/dev/pts/\0" /* and try /dev/pts next */
|
||||
+"\005/dev/\0"; /* and try walking through /dev last */
|
||||
+
|
||||
+int ttyname_r(int fd, char *ubuf, size_t ubuflen)
|
||||
+{
|
||||
+ struct dirent *d;
|
||||
+ struct stat st;
|
||||
+ struct stat dst;
|
||||
+ const char *p;
|
||||
+ char *s;
|
||||
+ DIR *fp;
|
||||
+ int rv;
|
||||
+ int len;
|
||||
+ char buf[TTYNAME_BUFLEN];
|
||||
+
|
||||
+ if (fstat(fd, &st) < 0) {
|
||||
+ return errno;
|
||||
+ }
|
||||
+
|
||||
+ rv = ENOTTY; /* Set up the default return value. */
|
||||
|
||||
-#include <stdlib.h>
|
||||
+ if (!isatty(fd)) {
|
||||
+ goto DONE;
|
||||
+ }
|
||||
|
||||
-char *ttyname(int fd) {
|
||||
-#ifdef SLASH_PROC_OK
|
||||
- char ibuf[20];
|
||||
- static char obuf[20];
|
||||
- int len;
|
||||
- if (!isatty(fd)) return 0;
|
||||
- strcpy(ibuf,"/proc/self/fd/");
|
||||
- ibuf[__ltostr(ibuf+14,6,(unsigned long)fd,10,0)+14]=0;
|
||||
- if ((len=readlink(ibuf,obuf,sizeof(obuf)-1))<0) return 0;
|
||||
- obuf[len]=0;
|
||||
- return obuf;
|
||||
+ for (p = dirlist ; *p ; p += 1 + p[-1]) {
|
||||
+ len = *p++;
|
||||
+
|
||||
+ assert(len + 2 <= TTYNAME_BUFLEN); /* dirname + 1 char + nul */
|
||||
+
|
||||
+ strcpy(buf, p);
|
||||
+ s = buf + len;
|
||||
+ len = (TTYNAME_BUFLEN-2) - len; /* Available non-nul space. */
|
||||
+
|
||||
+ if (!(fp = opendir(p))) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ while ((d = readdir(fp)) != NULL) {
|
||||
+ /* This should never trigger for standard names, but we
|
||||
+ * check it to be safe. */
|
||||
+ if (strlen(d->d_name) > len) { /* Too big? */
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ strcpy(s, d->d_name);
|
||||
+
|
||||
+ if ((lstat(buf, &dst) == 0)
|
||||
+#if 0
|
||||
+ /* Stupid filesystems like cramfs fail to guarantee that
|
||||
+ * st_ino and st_dev uniquely identify a file, contrary to
|
||||
+ * SuSv3, so we cannot be quite so precise as to require an
|
||||
+ * exact match. Settle for something less... Grumble... */
|
||||
+ && (st.st_dev == dst.st_dev) && (st.st_ino == dst.st_ino)
|
||||
#else
|
||||
- static char buf[20];
|
||||
- struct stat s;
|
||||
- char *c=buf+8;
|
||||
- int n;
|
||||
- if (!isatty(fd)) return 0;
|
||||
- if (fstat(fd,&s)) return 0;
|
||||
- strcpy(buf,"/dev/tty");
|
||||
- if (S_ISCHR(s.st_mode)) {
|
||||
- n=minor(s.st_rdev);
|
||||
- switch (major(s.st_rdev)) {
|
||||
- case 4:
|
||||
- if (n>63) {
|
||||
- n-=64;
|
||||
- *c='S';
|
||||
- ++c;
|
||||
- }
|
||||
-num:
|
||||
- c[__ltostr(c,6,n,10,0)]=0;
|
||||
- break;
|
||||
- case 2:
|
||||
- buf[8]='p'-(n>>4);
|
||||
- buf[9]=n%4+'0';
|
||||
- if (buf[9]>'9') *c+='a'-'0';
|
||||
- buf[10]=0;
|
||||
- goto duh;
|
||||
- case 136:
|
||||
- case 137:
|
||||
- case 138:
|
||||
- case 139:
|
||||
- buf[7]='s';
|
||||
-duh:
|
||||
- buf[5]='p';
|
||||
- n+=(major(s.st_rdev)-136)<<8;
|
||||
- *c='/'; ++c;
|
||||
- goto num;
|
||||
- default:
|
||||
- return 0;
|
||||
- }
|
||||
- return buf;
|
||||
- }
|
||||
- return 0;
|
||||
+ && S_ISCHR(dst.st_mode) && (st.st_rdev == dst.st_rdev)
|
||||
#endif
|
||||
+ ) { /* Found it! */
|
||||
+ closedir(fp);
|
||||
+
|
||||
+ /* We treat NULL buf as ERANGE rather than EINVAL. */
|
||||
+ rv = ERANGE;
|
||||
+ if (ubuf && (strlen(buf) <= ubuflen)) {
|
||||
+ strcpy(ubuf, buf);
|
||||
+ rv = 0;
|
||||
+ }
|
||||
+ goto DONE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ closedir(fp);
|
||||
+ }
|
||||
+
|
||||
+ DONE:
|
||||
+ __set_errno(rv);
|
||||
+
|
||||
+ return rv;
|
||||
}
|
||||
|
||||
-#endif
|
Loading…
Reference in new issue