OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [linux/] [uClibc/] [libc/] [termios/] [ttyname.c] - Blame information for rev 1325

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
#include <string.h>
2
#include <errno.h>
3
#include <assert.h>
4
#include <unistd.h>
5
#include <dirent.h>
6
#include <sys/stat.h>
7
 
8
/* Jan 1, 2004    Manuel Novoa III
9
 *
10
 * Kept the same approach, but rewrote the code for the most part.
11
 * Fixed some minor issues plus (as I recall) one SUSv3 errno case.
12
 */
13
 
14
/* This is a fairly slow approach.  We do a linear search through some
15
 * directories looking for a match.  Yes this is lame.  But it should
16
 * work, should be small, and will return names that match what is on
17
 * disk.  Another approach we could use would be to use the info in
18
 * /proc/self/fd, but that is even more lame since it requires /proc */
19
 
20
/* SUSv3 mandates TTY_NAME_MAX as 9.  This is obviously insufficient.
21
 * However, there is no need to waste space and support non-standard
22
 * tty names either.  So we compromise and use the following buffer
23
 * length.  (Erik and Manuel agreed that 32 was more than reasonable.)
24
 */
25
#define TTYNAME_BUFLEN          32
26
 
27
char *ttyname(int fd)
28
{
29
        static char name[TTYNAME_BUFLEN];
30
 
31
        return ttyname_r(fd, name, TTYNAME_BUFLEN) ? NULL : name;
32
}
33
 
34
static const char dirlist[] =
35
/*   12345670123 */
36
"\010/dev/vc/\0"        /* Try /dev/vc first (be devfs compatible) */
37
"\011/dev/tts/\0"       /* and /dev/tts next (be devfs compatible) */
38
"\011/dev/pts/\0"       /* and try /dev/pts next */
39
"\005/dev/\0";          /* and try walking through /dev last */
40
 
41
int ttyname_r(int fd, char *ubuf, size_t ubuflen)
42
{
43
        struct dirent *d;
44
        struct stat st;
45
        struct stat dst;
46
        const char *p;
47
        char *s;
48
        DIR *fp;
49
        int rv;
50
        int len;
51
        char buf[TTYNAME_BUFLEN];
52
 
53
        if (fstat(fd, &st) < 0) {
54
                return errno;
55
        }
56
 
57
        rv = ENOTTY;                            /* Set up the default return value. */
58
 
59
        if (!isatty(fd)) {
60
                goto DONE;
61
        }
62
 
63
        for (p = dirlist ; *p ; p += 1 + p[-1]) {
64
                len = *p++;
65
 
66
                assert(len + 2 <= TTYNAME_BUFLEN); /* dirname + 1 char + nul */
67
 
68
                strcpy(buf, p);
69
                s = buf + len;
70
                len =  (TTYNAME_BUFLEN-2) - len; /* Available non-nul space. */
71
 
72
                if (!(fp = opendir(p))) {
73
                        continue;
74
                }
75
 
76
                while ((d = readdir(fp)) != NULL) {
77
                        /* This should never trigger for standard names, but we
78
                         * check it to be safe.  */
79
                        if (strlen(d->d_name) > len) { /* Too big? */
80
                                continue;
81
                        }
82
 
83
                        strcpy(s, d->d_name);
84
 
85
                        if ((lstat(buf, &dst) == 0)
86
#if 0
87
                                /* Stupid filesystems like cramfs fail to guarantee that
88
                                 * st_ino and st_dev uniquely identify a file, contrary to
89
                                 * SuSv3, so we cannot be quite so precise as to require an
90
                                 * exact match.  Settle for something less...  Grumble... */
91
                                && (st.st_dev == dst.st_dev) && (st.st_ino == dst.st_ino)
92
#else
93
                                && S_ISCHR(dst.st_mode) && (st.st_rdev == dst.st_rdev)
94
#endif
95
                                ) {                             /* Found it! */
96
                                closedir(fp);
97
 
98
                                /* We treat NULL buf as ERANGE rather than EINVAL. */
99
                                rv = ERANGE;
100
                                if (ubuf && (strlen(buf) <= ubuflen)) {
101
                                        strcpy(ubuf, buf);
102
                                        rv = 0;
103
                                }
104
                                goto DONE;
105
                        }
106
                }
107
 
108
                closedir(fp);
109
        }
110
 
111
 DONE:
112
        __set_errno(rv);
113
 
114
        return rv;
115
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.