source: trunk/libs/newlib/src/libgloss/spu/dirfuncs.c @ 500

Last change on this file since 500 was 444, checked in by satin@…, 7 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 4.4 KB
Line 
1/*
2  Copyright 2007
3  International Business Machines Corporation,
4  Sony Computer Entertainment, Incorporated,
5  Toshiba Corporation,
6
7  All rights reserved.
8
9  Redistribution and use in source and binary forms, with or without
10  modification, are permitted provided that the following conditions are met:
11
12    * Redistributions of source code must retain the above copyright notice,
13  this list of conditions and the following disclaimer.
14    * Redistributions in binary form must reproduce the above copyright
15  notice, this list of conditions and the following disclaimer in the
16  documentation and/or other materials provided with the distribution.
17    * Neither the names of the copyright holders nor the names of their
18  contributors may be used to endorse or promote products derived from
19  this software without specific prior written permission.
20
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
25  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*/
33
34/*
35 * Put all of the dir functions in one file here, since it is not useful
36 * to use opendir without readdir, and then we can put the handling of the
37 * struct dirent here too.
38 */
39
40#include <stdint.h>
41#include <unistd.h>
42#include <dirent.h>
43#include <errno.h>
44#include "jsre.h"
45
46/*
47 * The SPU DIR includes space for one dirent, and is 256 + 4 bytes in
48 * size, so keep this small.
49 */
50#define SPE_OPENDIR_MAX 4
51
52static DIR spe_dir[SPE_OPENDIR_MAX]; /* zero by default */
53
54typedef struct {
55  unsigned int name;
56  unsigned int pad0[3];
57} syscall_opendir_t;
58
59typedef struct {
60  uint64_t dir;
61  unsigned int pad0[2];
62} syscall_opendir_ret_t;
63
64DIR *
65opendir (const char *name)
66{
67  DIR *dir;
68  int i;
69  union {
70    syscall_opendir_t sys;
71    syscall_opendir_ret_t ret;
72  } u;
73
74  u.sys.name = (unsigned int) name;
75  for (i = 0; i < SPE_OPENDIR_MAX; i++) {
76    if (!spe_dir[i].ppc_dir) {
77      dir = &spe_dir[i];
78      __send_to_ppe (JSRE_POSIX1_SIGNALCODE, JSRE_OPENDIR, &u);
79      /*
80       * Pull 64 bits out of the result.
81       */
82      dir->ppc_dir = u.ret.dir;
83      if (!dir->ppc_dir) {
84        dir = NULL;
85      }
86      return dir;
87    }
88  }
89
90  errno = EMFILE;
91  return NULL;
92}
93
94int
95closedir (DIR *dir)
96{
97  int rc, i;
98  uint64_t ppc_dir;
99
100  if (dir) {
101    /*
102     * Don't pass &dir->ppc_dir to __send_to_ppe, since it would be
103     * overwritten by the assist call.
104     */
105    ppc_dir = dir->ppc_dir;
106    rc = __send_to_ppe (JSRE_POSIX1_SIGNALCODE, JSRE_CLOSEDIR, &ppc_dir);
107
108    /*
109     * Try to release the dir even if the closedir failed.
110     */
111    for (i = 0; i < SPE_OPENDIR_MAX; i++) {
112      if (spe_dir[i].ppc_dir == dir->ppc_dir) {
113        spe_dir[i].ppc_dir = 0;
114      }
115    }
116  } else {
117    /*
118     * Gracefully handle NULL, but not other invalid dir values.
119     */
120    rc = -1;
121    errno = EBADF;
122  }
123  return rc;
124}
125
126typedef struct {
127  uint64_t ppc_dir;
128  unsigned int pad0[2];
129  unsigned int dirent;
130  unsigned int pad1[3];
131} syscall_readdir_t;
132
133struct dirent *
134readdir (DIR *dir)
135{
136  syscall_readdir_t sys;
137
138  sys.ppc_dir = dir->ppc_dir;
139  sys.dirent = (unsigned int) &dir->dirent;
140  return (struct dirent *) __send_to_ppe (JSRE_POSIX1_SIGNALCODE,
141                                         JSRE_READDIR, &sys);
142}
143
144void
145rewinddir (DIR *dir)
146{
147  uint64_t ppc_dir = dir->ppc_dir;
148
149  __send_to_ppe (JSRE_POSIX1_SIGNALCODE, JSRE_REWINDDIR, &ppc_dir);
150}
151
152typedef struct {
153  uint64_t ppc_dir;
154  unsigned int pad0[2];
155  unsigned int offset;
156  unsigned int pad1[3];
157} syscall_seekdir_t;
158
159void
160seekdir (DIR *dir, off_t offset)
161{
162  syscall_seekdir_t sys;
163
164  sys.ppc_dir = dir->ppc_dir;
165  sys.offset = offset;
166  __send_to_ppe (JSRE_POSIX1_SIGNALCODE, JSRE_SEEKDIR, &sys);
167}
168
169off_t
170telldir (DIR *dir)
171{
172  uint64_t ppc_dir = dir->ppc_dir;
173
174  return __send_to_ppe (JSRE_POSIX1_SIGNALCODE, JSRE_TELLDIR, &ppc_dir);
175}
Note: See TracBrowser for help on using the repository browser.