1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19: #include <hurd.h>
20: #include <hurd/fd.h>
21: #include <hurd/resource.h>
22: #include <stdlib.h>
23: #include "hurdmalloc.h"
24:
25:
26:
27:
28:
29:
30: struct hurd_fd *
31: _hurd_alloc_fd (int *fd, int first_fd)
32: {
33: int i;
34: void *crit;
35: long int rlimit;
36:
37: if (first_fd < 0)
38: {
39: errno = EINVAL;
40: return NULL;
41: }
42:
43: crit = _hurd_critical_section_lock ();
44:
45: __mutex_lock (&_hurd_dtable_lock);
46:
47: search:
48: for (i = first_fd; i < _hurd_dtablesize; ++i)
49: {
50: struct hurd_fd *d = _hurd_dtable[i];
51: if (d == NULL)
52: {
53:
54:
55:
56: d = _hurd_new_fd (MACH_PORT_NULL, MACH_PORT_NULL);
57: if (d == NULL)
58: {
59: __mutex_unlock (&_hurd_dtable_lock);
60: _hurd_critical_section_unlock (crit);
61: return NULL;
62: }
63: _hurd_dtable[i] = d;
64: }
65:
66: __spin_lock (&d->port.lock);
67: if (d->port.port == MACH_PORT_NULL)
68: {
69: __mutex_unlock (&_hurd_dtable_lock);
70: _hurd_critical_section_unlock (crit);
71: if (fd != NULL)
72: *fd = i;
73: return d;
74: }
75: else
76: __spin_unlock (&d->port.lock);
77: }
78:
79: __mutex_lock (&_hurd_rlimit_lock);
80: rlimit = _hurd_rlimits[RLIMIT_OFILE].rlim_cur;
81: __mutex_unlock (&_hurd_rlimit_lock);
82:
83: if (first_fd < rlimit)
84: {
85:
86:
87: if (_hurd_dtablesize < rlimit)
88: {
89:
90: int save = errno;
91: struct hurd_fd **new;
92:
93:
94: int size = _hurd_dtablesize * 2;
95: if (size > rlimit)
96: size = rlimit;
97: else if (size <= first_fd)
98: size = first_fd + 1;
99:
100: if (size * sizeof (*_hurd_dtable) < size)
101: {
102:
103: errno = ENOMEM;
104: goto out;
105: }
106:
107:
108:
109: do
110: new = realloc (_hurd_dtable, size * sizeof (*_hurd_dtable));
111: while (new == NULL && size-- > first_fd);
112:
113: if (new != NULL)
114: {
115:
116: errno = save;
117: if (first_fd < _hurd_dtablesize)
118: first_fd = _hurd_dtablesize;
119:
120: for (i = _hurd_dtablesize; i < size; ++i)
121: new[i] = NULL;
122: _hurd_dtablesize = size;
123: _hurd_dtable = new;
124:
125: goto search;
126: }
127: else
128: errno = ENOMEM;
129: }
130: else
131: errno = EMFILE;
132: }
133: else
134: errno = EINVAL;
135:
136: out:
137: __mutex_unlock (&_hurd_dtable_lock);
138: _hurd_critical_section_unlock (crit);
139:
140: return NULL;
141: }