1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
#ifdef __cplusplus
extern "C" {
#endif
#define WIN32_LEAN_AND_MEAN
#define WIN32IO_IS_STDIO
#define EXT
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
#include <process.h>
#include <direct.h>
#include "win32iop.h"
/*
* The following is just a basic wrapping of the stdio
*
* redirected io subsystem for all XS modules
*/
static int *
dummy_errno(void)
{
return (&(errno));
}
static char ***
dummy_environ(void)
{
return (&(_environ));
}
/* the rest are the remapped stdio routines */
static FILE *
dummy_stderr(void)
{
return stderr;
}
static FILE *
dummy_stdin(void)
{
return stdin;
}
static FILE *
dummy_stdout(void)
{
return stdout;
}
static int
dummy_globalmode(int mode)
{
int o = _fmode;
_fmode = mode;
return o;
}
#ifdef _DLL
/* It may or may not be fixed (ok on NT), but DLL runtime
does not export the functions used in the workround
*/
#define WIN95_OSFHANDLE_FIXED
#endif
#if defined(_WIN32) && !defined(WIN95_OSFHANDLE_FIXED) && defined(_M_IX86)
# ifdef __cplusplus
#define EXT_C_FUNC extern "C"
# else
#define EXT_C_FUNC extern
# endif
EXT_C_FUNC int __cdecl _alloc_osfhnd(void);
EXT_C_FUNC int __cdecl _set_osfhnd(int fh, long value);
EXT_C_FUNC void __cdecl _lock_fhandle(int);
EXT_C_FUNC void __cdecl _unlock_fhandle(int);
EXT_C_FUNC void __cdecl _unlock(int);
#if (_MSC_VER >= 1000)
typedef struct {
long osfhnd; /* underlying OS file HANDLE */
char osfile; /* attributes of file (e.g., open in text mode?) */
char pipech; /* one char buffer for handles opened on pipes */
#if defined (_MT) && !defined (DLL_FOR_WIN32S)
int lockinitflag;
CRITICAL_SECTION lock;
#endif /* defined (_MT) && !defined (DLL_FOR_WIN32S) */
} ioinfo;
EXT_C_FUNC ioinfo * __pioinfo[];
#define IOINFO_L2E 5
#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
#define _pioinfo(i) (__pioinfo[i >> IOINFO_L2E] + (i & (IOINFO_ARRAY_ELTS - 1)))
#define _osfile(i) (_pioinfo(i)->osfile)
#else /* (_MSC_VER >= 1000) */
extern char _osfile[];
#endif /* (_MSC_VER >= 1000) */
#define FOPEN 0x01 /* file handle open */
#define FAPPEND 0x20 /* file handle opened O_APPEND */
#define FDEV 0x40 /* file handle refers to device */
#define FTEXT 0x80 /* file handle is in text mode */
#define _STREAM_LOCKS 26 /* Table of stream locks */
#define _LAST_STREAM_LOCK (_STREAM_LOCKS+_NSTREAM_-1) /* Last stream lock */
#define _FH_LOCKS (_LAST_STREAM_LOCK+1) /* Table of fh locks */
/***
*int _patch_open_osfhandle(long osfhandle, int flags) - open C Runtime file handle
*
*Purpose:
* This function allocates a free C Runtime file handle and associates
* it with the Win32 HANDLE specified by the first parameter. This is a
* temperary fix for WIN95's brain damage GetFileType() error on socket
* we just bypass that call for socket
*
*Entry:
* long osfhandle - Win32 HANDLE to associate with C Runtime file handle.
* int flags - flags to associate with C Runtime file handle.
*
*Exit:
* returns index of entry in fh, if successful
* return -1, if no free entry is found
*
*Exceptions:
*
*******************************************************************************/
int
my_open_osfhandle(long osfhandle, int flags)
{
int fh;
char fileflags; /* _osfile flags */
/* copy relevant flags from second parameter */
fileflags = FDEV;
if(flags & _O_APPEND)
fileflags |= FAPPEND;
if(flags & _O_TEXT)
fileflags |= FTEXT;
/* attempt to allocate a C Runtime file handle */
if((fh = _alloc_osfhnd()) == -1) {
errno = EMFILE; /* too many open files */
_doserrno = 0L; /* not an OS error */
return -1; /* return error to caller */
}
/* the file is open. now, set the info in _osfhnd array */
_set_osfhnd(fh, osfhandle);
fileflags |= FOPEN; /* mark as open */
#if (_MSC_VER >= 1000)
_osfile(fh) = fileflags; /* set osfile entry */
_unlock_fhandle(fh);
#else
_osfile[fh] = fileflags; /* set osfile entry */
_unlock(fh+_FH_LOCKS); /* unlock handle */
#endif
return fh; /* return handle */
}
#else
int __cdecl
my_open_osfhandle(long osfhandle, int flags)
{
return _open_osfhandle(osfhandle, flags);
}
#endif /* _M_IX86 */
long
my_get_osfhandle( int filehandle )
{
return _get_osfhandle(filehandle);
}
#ifdef PERLDLL
__declspec(dllexport)
#endif
WIN32_IOSUBSYSTEM win32stdio = {
12345678L, /* begin of structure; */
dummy_errno, /* (*pfunc_errno)(void); */
dummy_environ, /* (*pfunc_environ)(void); */
dummy_stdin, /* (*pfunc_stdin)(void); */
dummy_stdout, /* (*pfunc_stdout)(void); */
dummy_stderr, /* (*pfunc_stderr)(void); */
ferror, /* (*pfunc_ferror)(FILE *fp); */
feof, /* (*pfunc_feof)(FILE *fp); */
strerror, /* (*strerror)(int e); */
vfprintf, /* (*pfunc_vfprintf)(FILE *pf, const char *format, va_list arg); */
vprintf, /* (*pfunc_vprintf)(const char *format, va_list arg); */
fread, /* (*pfunc_fread)(void *buf, size_t size, size_t count, FILE *pf); */
fwrite, /* (*pfunc_fwrite)(void *buf, size_t size, size_t count, FILE *pf); */
fopen, /* (*pfunc_fopen)(const char *path, const char *mode); */
fdopen, /* (*pfunc_fdopen)(int fh, const char *mode); */
freopen, /* (*pfunc_freopen)(const char *path, const char *mode, FILE *pf); */
fclose, /* (*pfunc_fclose)(FILE *pf); */
fputs, /* (*pfunc_fputs)(const char *s,FILE *pf); */
fputc, /* (*pfunc_fputc)(int c,FILE *pf); */
ungetc, /* (*pfunc_ungetc)(int c,FILE *pf); */
getc, /* (*pfunc_getc)(FILE *pf); */
fileno, /* (*pfunc_fileno)(FILE *pf); */
clearerr, /* (*pfunc_clearerr)(FILE *pf); */
fflush, /* (*pfunc_fflush)(FILE *pf); */
ftell, /* (*pfunc_ftell)(FILE *pf); */
fseek, /* (*pfunc_fseek)(FILE *pf,long offset,int origin); */
fgetpos, /* (*pfunc_fgetpos)(FILE *pf,fpos_t *p); */
fsetpos, /* (*pfunc_fsetpos)(FILE *pf,fpos_t *p); */
rewind, /* (*pfunc_rewind)(FILE *pf); */
tmpfile, /* (*pfunc_tmpfile)(void); */
abort, /* (*pfunc_abort)(void); */
fstat, /* (*pfunc_fstat)(int fd,struct stat *bufptr); */
stat, /* (*pfunc_stat)(const char *name,struct stat *bufptr); */
_pipe, /* (*pfunc_pipe)( int *phandles, unsigned int psize, int textmode ); */
_popen, /* (*pfunc_popen)( const char *command, const char *mode ); */
_pclose, /* (*pfunc_pclose)( FILE *pf); */
setmode, /* (*pfunc_setmode)( int fd, int mode); */
lseek, /* (*pfunc_lseek)( int fd, long offset, int origin); */
tell, /* (*pfunc_tell)( int fd); */
dup, /* (*pfunc_dup)( int fd); */
dup2, /* (*pfunc_dup2)(int h1, int h2); */
open, /* (*pfunc_open)(const char *path, int oflag,...); */
close, /* (*pfunc_close)(int fd); */
eof, /* (*pfunc_eof)(int fd); */
read, /* (*pfunc_read)(int fd, void *buf, unsigned int cnt); */
write, /* (*pfunc_write)(int fd, const void *buf, unsigned int cnt); */
dummy_globalmode, /* (*pfunc_globalmode)(int mode) */
my_open_osfhandle,
my_get_osfhandle,
spawnvpe,
_mkdir,
_rmdir,
_chdir,
87654321L, /* end of structure */
};
#ifdef __cplusplus
}
#endif
|