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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-newlib/] [newlib-1.17.0/] [newlib/] [libc/] [sys/] [linux/] [ttyname_r.c] - Blame information for rev 9

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 jlechner
/* Copyright (C) 1991,92,93,1995-1999,2000,2001 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
3
 
4
   The GNU C Library is free software; you can redistribute it and/or
5
   modify it under the terms of the GNU Lesser General Public
6
   License as published by the Free Software Foundation; either
7
   version 2.1 of the License, or (at your option) any later version.
8
 
9
   The GNU C Library is distributed in the hope that it will be useful,
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
   Lesser General Public License for more details.
13
 
14
   You should have received a copy of the GNU Lesser General Public
15
   License along with the GNU C Library; if not, write to the Free
16
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17
   02111-1307 USA.  */
18
 
19
#include <errno.h>
20
#include <limits.h>
21
#include <stddef.h>
22
#include <dirent.h>
23
#include <sys/types.h>
24
#include <sys/stat.h>
25
#include <unistd.h>
26
#include <string.h>
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <machine/weakalias.h>
30
 
31
static int getttyname_r (char *buf, size_t buflen,
32
                         dev_t mydev, ino64_t myino, int save,
33
                         int *dostat);
34
 
35
extern struct dirent64 *__readdir64 (DIR *);
36
 
37
static int
38
getttyname_r (char *buf, size_t buflen, dev_t mydev, ino64_t myino,
39
              int save, int *dostat)
40
{
41
  struct stat64 st;
42
  DIR *dirstream;
43
  struct dirent64 *d;
44
  size_t devlen = strlen (buf);
45
 
46
  dirstream = opendir (buf);
47
  if (dirstream == NULL)
48
    {
49
      *dostat = -1;
50
      return errno;
51
    }
52
 
53
  while ((d = __readdir64 (dirstream)) != NULL)
54
    {
55
      if ((d->d_ino == myino || *dostat)
56
          && strcmp (d->d_name, "stdin")
57
          && strcmp (d->d_name, "stdout")
58
          && strcmp (d->d_name, "stderr"))
59
        {
60
          size_t needed = strlen (d->d_name) + 1;
61
 
62
          if (needed > buflen)
63
            {
64
              *dostat = -1;
65
              (void) closedir (dirstream);
66
              __set_errno (ERANGE);
67
              return ERANGE;
68
            }
69
 
70
          strncpy (buf + devlen, d->d_name, needed);
71
 
72
          if (stat64 (buf, &st) == 0
73
#ifdef _STATBUF_ST_RDEV
74
              && S_ISCHR (st.st_mode) && st.st_rdev == mydev
75
#else
76
              && d->d_ino == myino && st.st_dev == mydev
77
#endif
78
             )
79
            {
80
              (void) closedir (dirstream);
81
              __set_errno (save);
82
              return 0;
83
            }
84
        }
85
    }
86
 
87
  (void) closedir (dirstream);
88
  __set_errno (save);
89
  /* It is not clear what to return in this case.  `isatty' says FD
90
     refers to a TTY but no entry in /dev has this inode.  */
91
  return ENOTTY;
92
}
93
 
94
/* Store at most BUFLEN character of the pathname of the terminal FD is
95
   open on in BUF.  Return 0 on success,  otherwise an error number.  */
96
int
97
__ttyname_r (int fd, char *buf, size_t buflen)
98
{
99
  char procname[30];
100
  struct stat64 st, st1;
101
  int dostat = 0;
102
  int save = errno;
103
  int ret;
104
 
105
  /* Test for the absolute minimal size.  This makes life easier inside
106
     the loop.  */
107
  if (!buf)
108
    {
109
      __set_errno (EINVAL);
110
      return EINVAL;
111
    }
112
 
113
  if (buflen < sizeof ("/dev/pts/"))
114
    {
115
      __set_errno (ERANGE);
116
      return ERANGE;
117
    }
118
 
119
  if (!isatty (fd))
120
    {
121
      __set_errno (ENOTTY);
122
      return ENOTTY;
123
    }
124
 
125
  /* We try using the /proc filesystem.  */
126
  sprintf (procname, "/proc/self/fd/%d", fd);
127
 
128
  ret = readlink (procname, buf, buflen - 1);
129
  if (ret != -1 && buf[0] != '[')
130
    {
131
      buf[ret] = '\0';
132
      return 0;
133
    }
134
  if (ret == -1 && errno == ENAMETOOLONG)
135
    {
136
      __set_errno (ERANGE);
137
      return ERANGE;
138
    }
139
 
140
  if (fstat64 (fd, &st) < 0)
141
    return errno;
142
 
143
  /* Prepare the result buffer.  */
144
  memcpy (buf, "/dev/pts/", sizeof ("/dev/pts/"));
145
  buflen -= sizeof ("/dev/pts/") - 1;
146
 
147
  if (stat64 (buf, &st1) == 0 && S_ISDIR (st1.st_mode))
148
    {
149
#ifdef _STATBUF_ST_RDEV
150
      ret = getttyname_r (buf, buflen, st.st_rdev, st.st_ino, save,
151
                          &dostat);
152
#else
153
      ret = getttyname_r (buf, buflen, st.st_dev, st.st_ino, save,
154
                          &dostat);
155
#endif
156
    }
157
  else
158
    {
159
      __set_errno (save);
160
      ret = ENOENT;
161
    }
162
 
163
  if (ret && dostat != -1)
164
    {
165
      buf[sizeof ("/dev/") - 1] = '\0';
166
      buflen += sizeof ("pts/") - 1;
167
#ifdef _STATBUF_ST_RDEV
168
      ret = getttyname_r (buf, buflen, st.st_rdev, st.st_ino, save,
169
                          &dostat);
170
#else
171
      ret = getttyname_r (buf, buflen, st.st_dev, st.st_ino, save,
172
                          &dostat);
173
#endif
174
    }
175
 
176
  if (ret && dostat != -1)
177
    {
178
      buf[sizeof ("/dev/") - 1] = '\0';
179
      dostat = 1;
180
#ifdef _STATBUF_ST_RDEV
181
      ret = getttyname_r (buf, buflen, st.st_rdev, st.st_ino,
182
                          save, &dostat);
183
#else
184
      ret = getttyname_r (buf, buflen, st.st_dev, st.st_ino,
185
                          save, &dostat);
186
#endif
187
    }
188
 
189
  return ret;
190
}
191
 
192
weak_alias (__ttyname_r, ttyname_r)

powered by: WebSVN 2.1.0

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