You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							212 lines
						
					
					
						
							5.7 KiB
						
					
					
				
			
		
		
	
	
							212 lines
						
					
					
						
							5.7 KiB
						
					
					
				# --- 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
 | 
						|
 |