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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libc/] [stdlib/] [unix_grantpt.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/* Copyright (C) 1998 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
3
   Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
4
 
5
   The GNU C Library is free software; you can redistribute it and/or
6
   modify it under the terms of the GNU Library General Public License as
7
   published by the Free Software Foundation; either version 2 of the
8
   License, or (at your option) any later version.
9
 
10
   The GNU C Library is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
   Library General Public License for more details.
14
 
15
   You should have received a copy of the GNU Library General Public
16
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
17
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
   Boston, MA 02111-1307, USA.  */
19
 
20
#include <assert.h>
21
#include <errno.h>
22
#include <grp.h>
23
#include <limits.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <sys/resource.h>
27
#include <sys/stat.h>
28
#include <sys/types.h>
29
#include <sys/wait.h>
30
#include <unistd.h>
31
#include "pty-private.h"
32
 
33
 
34
/* uClinux-2.0 has vfork, but Linux 2.0 doesn't */
35
#include <sys/syscall.h>
36
#if ! defined __NR_vfork
37
#define vfork fork      
38
#endif
39
 
40
extern int ptsname_r (int fd, char *buf, size_t buflen);
41
 
42
/* Return the result of ptsname_r in the buffer pointed to by PTS,
43
   which should be of length BUF_LEN.  If it is too long to fit in
44
   this buffer, a sufficiently long buffer is allocated using malloc,
45
   and returned in PTS.  0 is returned upon success, -1 otherwise.  */
46
static int
47
pts_name (int fd, char **pts, size_t buf_len)
48
{
49
  int rv;
50
  char *buf = *pts;
51
 
52
  for (;;)
53
    {
54
      char *new_buf;
55
 
56
      if (buf_len)
57
        {
58
          rv = ptsname_r (fd, buf, buf_len);
59
 
60
          if (rv != 0 || memchr (buf, '\0', buf_len))
61
            /* We either got an error, or we succeeded and the
62
               returned name fit in the buffer.  */
63
            break;
64
 
65
          /* Try again with a longer buffer.  */
66
          buf_len += buf_len;   /* Double it */
67
        }
68
      else
69
        /* No initial buffer; start out by mallocing one.  */
70
        buf_len = 128;          /* First time guess.  */
71
 
72
      if (buf != *pts)
73
        /* We've already malloced another buffer at least once.  */
74
        new_buf = realloc (buf, buf_len);
75
      else
76
        new_buf = malloc (buf_len);
77
      if (! new_buf)
78
        {
79
          rv = -1;
80
          errno = ENOMEM;
81
          break;
82
        }
83
      buf = new_buf;
84
    }
85
 
86
  if (rv == 0)
87
    *pts = buf;         /* Return buffer to the user.  */
88
  else if (buf != *pts)
89
    free (buf);         /* Free what we malloced when returning an error.  */
90
 
91
  return rv;
92
}
93
 
94
/* Change the ownership and access permission of the slave pseudo
95
   terminal associated with the master pseudo terminal specified
96
   by FD.  */
97
int
98
grantpt (int fd)
99
{
100
  int retval = -1;
101
#ifdef PATH_MAX
102
  char _buf[PATH_MAX];
103
#else
104
  char _buf[512];
105
#endif
106
  char *buf = _buf;
107
  struct stat st;
108
  uid_t uid;
109
  gid_t gid;
110
  pid_t pid;
111
 
112
  if (pts_name (fd, &buf, sizeof (_buf)))
113
    return -1;
114
 
115
  if (stat(buf, &st) < 0)
116
    goto cleanup;
117
 
118
  /* Make sure that we own the device.  */
119
  uid = getuid ();
120
  if (st.st_uid != uid)
121
    {
122
      if (chown (buf, uid, st.st_gid) < 0)
123
        goto helper;
124
    }
125
 
126
  gid = getgid ();
127
 
128
  /* Make sure the group of the device is that special group.  */
129
  if (st.st_gid != gid)
130
    {
131
      if (chown (buf, uid, gid) < 0)
132
        goto helper;
133
    }
134
 
135
  /* Make sure the permission mode is set to readable and writable by
136
     the owner, and writable by the group.  */
137
  if ((st.st_mode & ACCESSPERMS) != (S_IRUSR|S_IWUSR|S_IWGRP))
138
    {
139
      if (chmod (buf, S_IRUSR|S_IWUSR|S_IWGRP) < 0)
140
        goto helper;
141
    }
142
 
143
  retval = 0;
144
  goto cleanup;
145
 
146
  /* We have to use the helper program.  */
147
 helper:
148
 
149
  pid = vfork ();
150
  if (pid == -1)
151
    goto cleanup;
152
  else if (pid == 0)
153
    {
154
      /* Disable core dumps.  */
155
      struct rlimit rl = { 0, 0 };
156
      setrlimit (RLIMIT_CORE, &rl);
157
 
158
      /* We pase the master pseudo terminal as file descriptor PTY_FILENO.  */
159
      if (fd != PTY_FILENO)
160
        if (dup2 (fd, PTY_FILENO) < 0)
161
          _exit (FAIL_EBADF);
162
 
163
      execle (_PATH_PT_CHOWN, _PATH_PT_CHOWN, NULL, NULL);
164
      _exit (FAIL_EXEC);
165
    }
166
  else
167
    {
168
      int w;
169
 
170
      if (waitpid (pid, &w, 0) == -1)
171
        goto cleanup;
172
      if (!WIFEXITED (w))
173
        errno = ENOEXEC;
174
      else
175
        switch (WEXITSTATUS(w))
176
          {
177
          case 0:
178
            retval = 0;
179
            break;
180
          case FAIL_EBADF:
181
            errno = EBADF;
182
            break;
183
          case FAIL_EINVAL:
184
            errno = EINVAL;
185
            break;
186
          case FAIL_EACCES:
187
            errno = EACCES;
188
            break;
189
          case FAIL_EXEC:
190
            errno = ENOEXEC;
191
            break;
192
 
193
          default:
194
            assert(! "getpt: internal error: invalid exit code from pt_chown");
195
          }
196
    }
197
 
198
 cleanup:
199
  if (buf != _buf)
200
    free (buf);
201
 
202
  return retval;
203
}

powered by: WebSVN 2.1.0

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