Subversion Repositories Kolibri OS

Rev

Rev 4874 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4874 Rev 4921
1
/* This header file provides the reentrancy.  */
1
/* This header file provides the reentrancy.  */
2
 
2
 
3
/* The reentrant system calls here serve two purposes:
3
/* The reentrant system calls here serve two purposes:
4
 
4
 
5
   1) Provide reentrant versions of the system calls the ANSI C library
5
   1) Provide reentrant versions of the system calls the ANSI C library
6
      requires.
6
      requires.
7
   2) Provide these system calls in a namespace clean way.
7
   2) Provide these system calls in a namespace clean way.
8
 
8
 
9
   It is intended that *all* system calls that the ANSI C library needs
9
   It is intended that *all* system calls that the ANSI C library needs
10
   be declared here.  It documents them all in one place.  All library access
10
   be declared here.  It documents them all in one place.  All library access
11
   to the system is via some form of these functions.
11
   to the system is via some form of these functions.
12
 
12
 
13
   The target may provide the needed syscalls by any of the following:
13
   The target may provide the needed syscalls by any of the following:
14
 
14
 
15
   1) Define the reentrant versions of the syscalls directly.
15
   1) Define the reentrant versions of the syscalls directly.
16
      (eg: _open_r, _close_r, etc.).  Please keep the namespace clean.
16
      (eg: _open_r, _close_r, etc.).  Please keep the namespace clean.
17
      When you do this, set "syscall_dir" to "syscalls" and add
17
      When you do this, set "syscall_dir" to "syscalls" and add
18
      -DREENTRANT_SYSCALLS_PROVIDED to newlib_cflags in configure.host.
18
      -DREENTRANT_SYSCALLS_PROVIDED to newlib_cflags in configure.host.
19
 
19
 
20
   2) Define namespace clean versions of the system calls by prefixing
20
   2) Define namespace clean versions of the system calls by prefixing
21
      them with '_' (eg: _open, _close, etc.).  Technically, there won't be
21
      them with '_' (eg: _open, _close, etc.).  Technically, there won't be
22
      true reentrancy at the syscall level, but the library will be namespace
22
      true reentrancy at the syscall level, but the library will be namespace
23
      clean.
23
      clean.
24
      When you do this, set "syscall_dir" to "syscalls" in configure.host.
24
      When you do this, set "syscall_dir" to "syscalls" in configure.host.
25
 
25
 
26
   3) Define or otherwise provide the regular versions of the syscalls
26
   3) Define or otherwise provide the regular versions of the syscalls
27
      (eg: open, close, etc.).  The library won't be reentrant nor namespace
27
      (eg: open, close, etc.).  The library won't be reentrant nor namespace
28
      clean, but at least it will work.
28
      clean, but at least it will work.
29
      When you do this, add -DMISSING_SYSCALL_NAMES to newlib_cflags in
29
      When you do this, add -DMISSING_SYSCALL_NAMES to newlib_cflags in
30
      configure.host.
30
      configure.host.
31
 
31
 
32
   4) Define or otherwise provide the regular versions of the syscalls,
32
   4) Define or otherwise provide the regular versions of the syscalls,
33
      and do not supply functional interfaces for any of the reentrant
33
      and do not supply functional interfaces for any of the reentrant
34
      calls. With this method, the reentrant syscalls are redefined to
34
      calls. With this method, the reentrant syscalls are redefined to
35
      directly call the regular system call without the reentrancy argument.
35
      directly call the regular system call without the reentrancy argument.
36
      When you do this, specify both -DREENTRANT_SYSCALLS_PROVIDED and
36
      When you do this, specify both -DREENTRANT_SYSCALLS_PROVIDED and
37
      -DMISSING_SYSCALL_NAMES via newlib_cflags in configure.host and do
37
      -DMISSING_SYSCALL_NAMES via newlib_cflags in configure.host and do
38
      not specify "syscall_dir".
38
      not specify "syscall_dir".
39
 
39
 
40
   Stubs of the reentrant versions of the syscalls exist in the libc/reent
40
   Stubs of the reentrant versions of the syscalls exist in the libc/reent
41
   source directory and are provided if REENTRANT_SYSCALLS_PROVIDED isn't
41
   source directory and are provided if REENTRANT_SYSCALLS_PROVIDED isn't
42
   defined.  These stubs call the native system calls: _open, _close, etc.
42
   defined.  These stubs call the native system calls: _open, _close, etc.
43
   if MISSING_SYSCALL_NAMES is *not* defined, otherwise they call the
43
   if MISSING_SYSCALL_NAMES is *not* defined, otherwise they call the
44
   non-underscored versions: open, close, etc. when MISSING_SYSCALL_NAMES
44
   non-underscored versions: open, close, etc. when MISSING_SYSCALL_NAMES
45
   *is* defined.
45
   *is* defined.
46
 
46
 
47
   By default, newlib functions call the reentrant syscalls internally,
47
   By default, newlib functions call the reentrant syscalls internally,
48
   passing a reentrancy structure as an argument.  This reentrancy structure
48
   passing a reentrancy structure as an argument.  This reentrancy structure
49
   contains data that is thread-specific.  For example, the errno value is
49
   contains data that is thread-specific.  For example, the errno value is
50
   kept in the reentrancy structure.  If multiple threads exist, each will
50
   kept in the reentrancy structure.  If multiple threads exist, each will
51
   keep a separate errno value which is intuitive since the application flow
51
   keep a separate errno value which is intuitive since the application flow
52
   cannot check for failure reliably otherwise.
52
   cannot check for failure reliably otherwise.
53
 
53
 
54
   The reentrant syscalls are either provided by the platform, by the
54
   The reentrant syscalls are either provided by the platform, by the
55
   libc/reent stubs, or in the case of both MISSING_SYSCALL_NAMES and
55
   libc/reent stubs, or in the case of both MISSING_SYSCALL_NAMES and
56
   REENTRANT_SYSCALLS_PROVIDED being defined, the calls are redefined to
56
   REENTRANT_SYSCALLS_PROVIDED being defined, the calls are redefined to
57
   simply call the regular syscalls with no reentrancy struct argument.
57
   simply call the regular syscalls with no reentrancy struct argument.
58
 
58
 
59
   A single-threaded application does not need to worry about the reentrancy
59
   A single-threaded application does not need to worry about the reentrancy
60
   structure.  It is used internally.
60
   structure.  It is used internally.
61
 
61
 
62
   A multi-threaded application needs either to manually manage reentrancy
62
   A multi-threaded application needs either to manually manage reentrancy
63
   structures or use dynamic reentrancy.
63
   structures or use dynamic reentrancy.
64
 
64
 
65
   Manually managing reentrancy structures entails calling special reentrant
65
   Manually managing reentrancy structures entails calling special reentrant
66
   versions of newlib functions that have an additional reentrancy argument.
66
   versions of newlib functions that have an additional reentrancy argument.
67
   For example, _printf_r.  By convention, the first argument is the
67
   For example, _printf_r.  By convention, the first argument is the
68
   reentrancy structure.  By default, the normal version of the function
68
   reentrancy structure.  By default, the normal version of the function
69
   uses the default reentrancy structure: _REENT.  The reentrancy structure
69
   uses the default reentrancy structure: _REENT.  The reentrancy structure
70
   is passed internally, eventually to the reentrant syscalls themselves.
70
   is passed internally, eventually to the reentrant syscalls themselves.
71
   How the structures are stored and accessed in this model is up to the
71
   How the structures are stored and accessed in this model is up to the
72
   application.
72
   application.
73
 
73
 
74
   Dynamic reentrancy is specified by the __DYNAMIC_REENT__ flag.  This
74
   Dynamic reentrancy is specified by the __DYNAMIC_REENT__ flag.  This
75
   flag denotes setting up a macro to replace _REENT with a function call
75
   flag denotes setting up a macro to replace _REENT with a function call
76
   to __getreent().  This function needs to be implemented by the platform
76
   to __getreent().  This function needs to be implemented by the platform
77
   and it is meant to return the reentrancy structure for the current
77
   and it is meant to return the reentrancy structure for the current
78
   thread.  When the regular C functions (e.g. printf) go to call internal
78
   thread.  When the regular C functions (e.g. printf) go to call internal
79
   routines with the default _REENT structure, they end up calling with
79
   routines with the default _REENT structure, they end up calling with
80
   the reentrancy structure for the thread.  Thus, application code does not
80
   the reentrancy structure for the thread.  Thus, application code does not
81
   need to call the _r routines nor worry about reentrancy structures.  */
81
   need to call the _r routines nor worry about reentrancy structures.  */
82
 
82
 
83
/* WARNING: All identifiers here must begin with an underscore.  This file is
83
/* WARNING: All identifiers here must begin with an underscore.  This file is
84
   included by stdio.h and others and we therefore must only use identifiers
84
   included by stdio.h and others and we therefore must only use identifiers
85
   in the namespace allotted to us.  */
85
   in the namespace allotted to us.  */
86
 
86
 
87
#ifndef _REENT_H_
87
#ifndef _REENT_H_
88
#ifdef __cplusplus
88
#ifdef __cplusplus
89
extern "C" {
89
extern "C" {
90
#endif
90
#endif
91
#define _REENT_H_
91
#define _REENT_H_
92
 
92
 
93
#include 
93
#include 
94
#include 
94
#include 
95
#include 
95
#include 
96
 
96
 
97
#define __need_size_t
97
#define __need_size_t
98
#define __need_ptrdiff_t
98
#define __need_ptrdiff_t
99
#include 
99
#include 
100
 
100
 
101
/* FIXME: not namespace clean */
101
/* FIXME: not namespace clean */
102
struct stat;
102
struct stat;
103
struct tms;
103
struct tms;
104
struct timeval;
104
struct timeval;
105
struct timezone;
105
struct timezone;
106
 
-
 
107
typedef struct
-
 
108
{
-
 
109
  char     *name;
-
 
110
  unsigned int offset;
-
 
111
  int (*write)(const char*, const void *, size_t, size_t, size_t*);
-
 
112
}__file_handle;
-
 
113
 
-
 
114
 
106
 
115
#if defined(REENTRANT_SYSCALLS_PROVIDED) && defined(MISSING_SYSCALL_NAMES)
107
#if defined(REENTRANT_SYSCALLS_PROVIDED) && defined(MISSING_SYSCALL_NAMES)
116
 
108
 
117
#define _close_r(__reent, __fd)                   close(__fd)
109
#define _close_r(__reent, __fd)                   close(__fd)
118
#define _execve_r(__reent, __f, __arg, __env)     execve(__f, __arg, __env)
110
#define _execve_r(__reent, __f, __arg, __env)     execve(__f, __arg, __env)
119
#define _fcntl_r(__reent, __fd, __cmd, __arg)     fcntl(__fd, __cmd, __arg)
111
#define _fcntl_r(__reent, __fd, __cmd, __arg)     fcntl(__fd, __cmd, __arg)
120
#define _fork_r(__reent)                          fork()
112
#define _fork_r(__reent)                          fork()
121
#define _fstat_r(__reent, __fdes, __stat)         fstat(__fdes, __stat)
113
#define _fstat_r(__reent, __fdes, __stat)         fstat(__fdes, __stat)
122
#define _getpid_r(__reent)                        getpid()
114
#define _getpid_r(__reent)                        getpid()
123
#define _isatty_r(__reent, __desc)                isatty(__desc)
115
#define _isatty_r(__reent, __desc)                isatty(__desc)
124
#define _kill_r(__reent, __pid, __signal)         kill(__pid, __signal)
116
#define _kill_r(__reent, __pid, __signal)         kill(__pid, __signal)
125
#define _link_r(__reent, __oldpath, __newpath)    link(__oldpath, __newpath)
117
#define _link_r(__reent, __oldpath, __newpath)    link(__oldpath, __newpath)
126
#define _lseek_r(__reent, __fdes, __off, __w)     lseek(__fdes, __off, __w)
118
#define _lseek_r(__reent, __fdes, __off, __w)     lseek(__fdes, __off, __w)
127
#define _mkdir_r(__reent, __path, __m)            mkdir(__path, __m)
119
#define _mkdir_r(__reent, __path, __m)            mkdir(__path, __m)
128
#define _open_r(__reent, __path, __flag, __m)     open(__path, __flag, __m)
120
#define _open_r(__reent, __path, __flag, __m)     open(__path, __flag, __m)
129
#define _read_r(__reent, __fd, __buff, __cnt)     read(__fd, __buff, __cnt)
121
#define _read_r(__reent, __fd, __buff, __cnt)     read(__fd, __buff, __cnt)
130
#define _rename_r(__reent, __old, __new)          rename(__old, __new)
122
#define _rename_r(__reent, __old, __new)          rename(__old, __new)
131
#define _sbrk_r(__reent, __incr)                  sbrk(__incr)
123
#define _sbrk_r(__reent, __incr)                  sbrk(__incr)
132
#define _stat_r(__reent, __path, __buff)          stat(__path, __buff)
124
#define _stat_r(__reent, __path, __buff)          stat(__path, __buff)
133
#define _times_r(__reent, __time)                 times(__time)
125
#define _times_r(__reent, __time)                 times(__time)
134
#define _unlink_r(__reent, __path)                unlink(__path)
126
#define _unlink_r(__reent, __path)                unlink(__path)
135
#define _wait_r(__reent, __status)                wait(__status)
127
#define _wait_r(__reent, __status)                wait(__status)
136
#define _write_r(__reent, __fd, __buff, __cnt)    write(__fd, __buff, __cnt)
128
#define _write_r(__reent, __fd, __buff, __cnt)    write(__fd, __buff, __cnt)
137
#define _gettimeofday_r(__reent, __tp, __tzp)     gettimeofday(__tp, __tzp)
129
#define _gettimeofday_r(__reent, __tp, __tzp)     gettimeofday(__tp, __tzp)
138
 
130
 
139
#ifdef __LARGE64_FILES
131
#ifdef __LARGE64_FILES
140
#define _lseek64_r(__reent, __fd, __off, __w)     lseek64(__fd, __off, __w)
132
#define _lseek64_r(__reent, __fd, __off, __w)     lseek64(__fd, __off, __w)
141
#define _fstat64_r(__reent, __fd, __buff)         fstat64(__fd, __buff)
133
#define _fstat64_r(__reent, __fd, __buff)         fstat64(__fd, __buff)
142
#define _open64_r(__reent, __path, __flag, __m)   open64(__path, __flag, __m)
134
#define _open64_r(__reent, __path, __flag, __m)   open64(__path, __flag, __m)
143
#endif
135
#endif
144
 
136
 
145
#else
137
#else
146
/* Reentrant versions of system calls.  */
138
/* Reentrant versions of system calls.  */
147
 
139
 
148
extern int _close_r _PARAMS ((struct _reent *, int));
140
extern int _close_r _PARAMS ((struct _reent *, int));
149
extern int _execve_r _PARAMS ((struct _reent *, const char *, char *const *, char *const *));
141
extern int _execve_r _PARAMS ((struct _reent *, const char *, char *const *, char *const *));
150
extern int _fcntl_r _PARAMS ((struct _reent *, int, int, int));
142
extern int _fcntl_r _PARAMS ((struct _reent *, int, int, int));
151
extern int _fork_r _PARAMS ((struct _reent *));
143
extern int _fork_r _PARAMS ((struct _reent *));
152
extern int _fstat_r _PARAMS ((struct _reent *, int, struct stat *));
144
extern int _fstat_r _PARAMS ((struct _reent *, int, struct stat *));
153
static inline int _getpid_r (struct _reent *r)
145
static inline int _getpid_r (struct _reent *r)
154
{
146
{
155
  int pid;
147
  int pid;
156
  (void)r;
148
  (void)r;
157
  __asm__ __volatile__(
149
  __asm__ __volatile__(
158
  "movl %%fs:0, %0 \n\t"
150
  "movl %%fs:0, %0 \n\t"
159
  :"=r"(pid));
151
  :"=r"(pid));
160
  return pid;
152
  return pid;
161
}
153
}
162
extern int _isatty_r _PARAMS ((struct _reent *, int));
154
extern int _isatty_r _PARAMS ((struct _reent *, int));
163
extern int _kill_r _PARAMS ((struct _reent *, int, int));
155
extern int _kill_r _PARAMS ((struct _reent *, int, int));
164
extern int _link_r _PARAMS ((struct _reent *, const char *, const char *));
156
extern int _link_r _PARAMS ((struct _reent *, const char *, const char *));
165
extern _off_t _lseek_r _PARAMS ((struct _reent *, int, _off_t, int));
157
extern _off_t _lseek_r _PARAMS ((struct _reent *, int, _off_t, int));
166
extern int _mkdir_r _PARAMS ((struct _reent *, const char *, int));
158
extern int _mkdir_r _PARAMS ((struct _reent *, const char *, int));
167
extern int _open_r _PARAMS ((struct _reent *, const char *, int, int));
159
extern int _open_r _PARAMS ((struct _reent *, const char *, int, int));
168
extern _ssize_t _read_r _PARAMS ((struct _reent *, int, void *, size_t));
160
extern _ssize_t _read_r _PARAMS ((struct _reent *, int, void *, size_t));
169
extern int _rename_r _PARAMS ((struct _reent *, const char *, const char *));
161
extern int _rename_r _PARAMS ((struct _reent *, const char *, const char *));
170
extern void *_sbrk_r _PARAMS ((struct _reent *, ptrdiff_t));
162
extern void *_sbrk_r _PARAMS ((struct _reent *, ptrdiff_t));
171
extern int _stat_r _PARAMS ((struct _reent *, const char *, struct stat *));
163
extern int _stat_r _PARAMS ((struct _reent *, const char *, struct stat *));
172
extern _CLOCK_T_ _times_r _PARAMS ((struct _reent *, struct tms *));
164
extern _CLOCK_T_ _times_r _PARAMS ((struct _reent *, struct tms *));
173
extern int _unlink_r _PARAMS ((struct _reent *, const char *));
165
extern int _unlink_r _PARAMS ((struct _reent *, const char *));
174
extern int _wait_r _PARAMS ((struct _reent *, int *));
166
extern int _wait_r _PARAMS ((struct _reent *, int *));
175
extern _ssize_t _write_r _PARAMS ((struct _reent *, int, const void *, size_t));
167
extern _ssize_t _write_r _PARAMS ((struct _reent *, int, const void *, size_t));
176
 
168
 
177
/* This one is not guaranteed to be available on all targets.  */
169
/* This one is not guaranteed to be available on all targets.  */
178
extern int _gettimeofday_r _PARAMS ((struct _reent *, struct timeval *__tp, void *__tzp));
170
extern int _gettimeofday_r _PARAMS ((struct _reent *, struct timeval *__tp, void *__tzp));
179
 
171
 
180
#ifdef __LARGE64_FILES
172
#ifdef __LARGE64_FILES
181
 
-
 
182
#if defined(__CYGWIN__) && defined(_COMPILING_NEWLIB)
-
 
183
#define stat64 __stat64
-
 
-
 
173
 
-
 
174
 
-
 
175
#if defined(__CYGWIN__)
184
#endif
176
#define stat64 stat
185
 
177
#endif
186
struct stat64;
178
struct stat64;
187
 
179
 
188
extern _off64_t _lseek64_r _PARAMS ((struct _reent *, int, _off64_t, int));
180
extern _off64_t _lseek64_r _PARAMS ((struct _reent *, int, _off64_t, int));
189
extern int _fstat64_r _PARAMS ((struct _reent *, int, struct stat64 *));
181
extern int _fstat64_r _PARAMS ((struct _reent *, int, struct stat64 *));
190
extern int _open64_r _PARAMS ((struct _reent *, const char *, int, int));
182
extern int _open64_r _PARAMS ((struct _reent *, const char *, int, int));
191
extern int _stat64_r _PARAMS ((struct _reent *, const char *, struct stat64 *));
183
extern int _stat64_r _PARAMS ((struct _reent *, const char *, struct stat64 *));
-
 
184
 
-
 
185
/* Don't pollute namespace if not building newlib. */
-
 
186
#if defined (__CYGWIN__) && !defined (_COMPILING_NEWLIB)
-
 
187
#undef stat64
-
 
188
#endif
-
 
189
 
192
#endif
190
#endif
193
 
191
 
194
#endif
192
#endif
195
 
193
 
196
#ifdef __cplusplus
194
#ifdef __cplusplus
197
}
195
}
198
#endif
196
#endif
199
#endif /* _REENT_H_ */
197
#endif /* _REENT_H_ */