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