sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
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
17
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
26int __fdman_sema;
27
28__descriptormap_type __descriptor_data_pool[__FILENO_MAX];
29
30__descriptormap_type *__descriptormap[__FILENO_MAX];
31
32
33void __fdman_init()
34{
35 ee_sema_t sema;
36
37 /* Initialize mutex */
38 sema.init_count = 1;
39 sema.max_count = 1;
40 sema.option = 0;
41 __fdman_sema = CreateSema(&sema);
42 if (__fdman_sema <= 0) {
43 __fdman_sema = 0;
44 abort();
45 }
46
47 /* Initialize descriptor data*/
48 memset(__descriptor_data_pool, 0, sizeof(__descriptormap_type) *__FILENO_MAX);
49 /* Initialize descriptor map*/
50 memset(__descriptormap, 0, sizeof(__descriptormap_type*)*__FILENO_MAX);
51
52 // We assume STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO are initialized
53 __descriptormap[STDIN_FILENO] = &__descriptor_data_pool[STDIN_FILENO];
54 __libcglue_init_stdio(&(__descriptormap[STDIN_FILENO]->info), 0);
55
56 __descriptormap[STDOUT_FILENO] = &__descriptor_data_pool[STDOUT_FILENO];
57 __libcglue_init_stdio(&(__descriptormap[STDOUT_FILENO]->info), 1);
58
59 __descriptormap[STDERR_FILENO] = &__descriptor_data_pool[STDERR_FILENO];
60 __libcglue_init_stdio(&(__descriptormap[STDERR_FILENO]->info), 1 /* ioman doesn't have 2 (stderr) by default, so just use 1 (stdout) */);
61}
62
63void __fdman_deinit()
64{
65 if (__fdman_sema > 0) {
66 DeleteSema(__fdman_sema);
67 }
68}
69
70
71int __fdman_get_new_descriptor()
72{
73 int i = 0;
74
75 WaitSema(__fdman_sema); /* lock here to make thread safe */
76 for (i = 0; i < __FILENO_MAX; i++) {
77 if (__descriptormap[i] == NULL) {
78 __descriptormap[i] = &__descriptor_data_pool[i];
79 __descriptormap[i]->ref_count++;
80 SignalSema(__fdman_sema); /* release lock */
81 return i;
82 }
83 }
84 SignalSema(__fdman_sema); /* release lock */
85
86 errno = ENOMEM;
87 return -1;
88}
89
90
91int __fdman_get_dup_descriptor(int fd)
92{
93 int i = 0;
94
95 if (!__IS_FD_VALID(fd)) {
96 errno = EBADF;
97 return -1;
98 }
99
100 WaitSema(__fdman_sema); /* lock here to make thread safe */
101 for (i = 0; i < __FILENO_MAX; i++) {
102 if (__descriptormap[i] == NULL) {
103 __descriptormap[i] = &__descriptor_data_pool[fd];
104 __descriptormap[i]->ref_count++;
105 SignalSema(__fdman_sema); /* release lock */
106 return i;
107 }
108 }
109 SignalSema(__fdman_sema); /* release lock */
110
111 errno = ENOMEM;
112 return -1;
113}
114
115int __fdman_get_dup2_descriptor(int fd, int newfd)
116{
117 if (!__IS_FD_VALID(fd)) {
118 errno = EBADF;
119 return -1;
120 }
121
122 WaitSema(__fdman_sema); /* lock here to make thread safe */
123 __descriptormap[newfd] = &__descriptor_data_pool[fd];
124 __descriptormap[newfd]->ref_count++;
125 SignalSema(__fdman_sema); /* release lock */
126
127 return newfd;
128}
129
130void __fdman_release_descriptor(int fd)
131{
132 if (!__IS_FD_VALID(fd)) {
133 errno = EBADF;
134 return;
135 }
136
137 __descriptormap[fd]->ref_count--;
138
139 if (__descriptormap[fd]->ref_count == 0) {
140 memset(__descriptormap[fd], 0, sizeof(__descriptormap_type));
141 }
142 __descriptormap[fd] = NULL;
143}
#define ENOMEM
Definition errno.h:52
#define EBADF
Definition errno.h:46