PS2SDK
PS2 Homebrew Libraries
fdman.c
Go to the documentation of this file.
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # (C)2001, Gustavo Scotti (gustavo@scotti.com)
7 # (c) 2003 Marcus R. Brown <mrbrown@0xd6.org>
8 # (c) 2023 Francisco Javier Trujillo Mata <fjtrujy@gmail.com>
9 # Licenced under Academic Free License version 2.0
10 # Review ps2sdk README & LICENSE files for further details.
11 */
12 
18 #include <string.h>
19 #include <stdlib.h>
20 #include <errno.h>
21 #include <unistd.h>
22 
23 #include <kernel.h>
24 #include "fdman.h"
25 
26 #ifdef F___fdman_sema
27 int __fdman_sema;
28 #else
29 extern int __fdman_sema;
30 #endif
31 
32 #ifdef F___descriptor_data_pool
33 __descriptormap_type __descriptor_data_pool[__FILENO_MAX];
34 #else
35 extern __descriptormap_type __descriptor_data_pool[__FILENO_MAX];
36 #endif
37 
38 #ifdef F___descriptormap
39 __descriptormap_type *__descriptormap[__FILENO_MAX];
40 #else
41 extern __descriptormap_type *__descriptormap[__FILENO_MAX];
42 #endif
43 
44 
45 #ifdef F___fdman_init
46 void __fdman_init()
47 {
48  ee_sema_t sema;
49 
50  /* Initialize mutex */
51  sema.init_count = 1;
52  sema.max_count = 1;
53  sema.option = 0;
54  __fdman_sema = CreateSema(&sema);
55  if (__fdman_sema <= 0) {
56  __fdman_sema = 0;
57  abort();
58  }
59 
60  /* Initialize descriptor data*/
61  memset(__descriptor_data_pool, 0, sizeof(__descriptormap_type) *__FILENO_MAX);
62  /* Initialize descriptor map*/
63  memset(__descriptormap, 0, sizeof(__descriptormap_type*)*__FILENO_MAX);
64 
65  // We assume STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO are initialized
66  __descriptormap[STDIN_FILENO] = &__descriptor_data_pool[STDIN_FILENO];
67  __libcglue_init_stdio(&(__descriptormap[STDIN_FILENO]->info), 0);
68 
69  __descriptormap[STDOUT_FILENO] = &__descriptor_data_pool[STDOUT_FILENO];
70  __libcglue_init_stdio(&(__descriptormap[STDOUT_FILENO]->info), 1);
71 
72  __descriptormap[STDERR_FILENO] = &__descriptor_data_pool[STDERR_FILENO];
73  __libcglue_init_stdio(&(__descriptormap[STDERR_FILENO]->info), 1 /* ioman doesn't have 2 (stderr) by default, so just use 1 (stdout) */);
74 }
75 #endif
76 
77 #ifdef F___fdman_deinit
78 void __fdman_deinit()
79 {
80  if (__fdman_sema > 0) {
81  DeleteSema(__fdman_sema);
82  }
83 }
84 #endif
85 
86 
87 #ifdef F___fdman_get_new_descriptor
88 int __fdman_get_new_descriptor()
89 {
90  int i = 0;
91 
92  WaitSema(__fdman_sema); /* lock here to make thread safe */
93  for (i = 0; i < __FILENO_MAX; i++) {
94  if (__descriptormap[i] == NULL) {
95  __descriptormap[i] = &__descriptor_data_pool[i];
96  __descriptormap[i]->ref_count++;
97  SignalSema(__fdman_sema); /* release lock */
98  return i;
99  }
100  }
101  SignalSema(__fdman_sema); /* release lock */
102 
103  errno = ENOMEM;
104  return -1;
105 }
106 #endif
107 
108 
109 #ifdef F___fdman_get_dup_descriptor
110 int __fdman_get_dup_descriptor(int fd)
111 {
112  int i = 0;
113 
114  if (!__IS_FD_VALID(fd)) {
115  errno = EBADF;
116  return -1;
117  }
118 
119  WaitSema(__fdman_sema); /* lock here to make thread safe */
120  for (i = 0; i < __FILENO_MAX; i++) {
121  if (__descriptormap[i] == NULL) {
122  __descriptormap[i] = &__descriptor_data_pool[fd];
123  __descriptormap[i]->ref_count++;
124  SignalSema(__fdman_sema); /* release lock */
125  return i;
126  }
127  }
128  SignalSema(__fdman_sema); /* release lock */
129 
130  errno = ENOMEM;
131  return -1;
132 }
133 #endif
134 
135 #ifdef F___fdman_get_dup_descriptor
136 int __fdman_get_dup2_descriptor(int fd, int newfd)
137 {
138  if (!__IS_FD_VALID(fd)) {
139  errno = EBADF;
140  return -1;
141  }
142 
143  WaitSema(__fdman_sema); /* lock here to make thread safe */
144  __descriptormap[newfd] = &__descriptor_data_pool[fd];
145  __descriptormap[newfd]->ref_count++;
146  SignalSema(__fdman_sema); /* release lock */
147 
148  return newfd;
149 }
150 #endif
151 
152 #ifdef F___fdman_release_descriptor
153 void __fdman_release_descriptor(int fd)
154 {
155  if (!__IS_FD_VALID(fd)) {
156  errno = EBADF;
157  return;
158  }
159 
160  __descriptormap[fd]->ref_count--;
161 
162  if (__descriptormap[fd]->ref_count == 0) {
163  memset(__descriptormap[fd], 0, sizeof(__descriptormap_type));
164  }
165  __descriptormap[fd] = NULL;
166 }
167 #endif
kernel.h
ENOMEM
#define ENOMEM
Definition: errno.h:43
s_info
Definition: xprintf.c:78
t_ee_sema
Definition: kernel.h:193
__descriptormap_type
Definition: fdman.h:23
EBADF
#define EBADF
Definition: errno.h:37
stdlib.h
errno.h