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