Add missing win32_closesocket() and export it (extension writers' complaint).
[p5sagit/p5-mst-13.2.git] / win32 / win32io.c
CommitLineData
68dc0745 1
68dc0745 2
3#define WIN32_LEAN_AND_MEAN
d55594ae 4#include <stdio.h>
5extern int my_fclose(FILE *pf);
6#include "EXTERN.h"
68dc0745 7#define WIN32IO_IS_STDIO
68dc0745 8#include <windows.h>
68dc0745 9#include <stdlib.h>
10#include <io.h>
11#include <sys/stat.h>
12#include <sys/socket.h>
13#include <fcntl.h>
14#include <assert.h>
15#include <errno.h>
16#include <process.h>
5aabfad6 17#include <direct.h>
d55594ae 18
68dc0745 19#include "win32iop.h"
20
21/*
22 * The following is just a basic wrapping of the stdio
23 *
24 * redirected io subsystem for all XS modules
25 */
26
27static int *
28dummy_errno(void)
29{
30 return (&(errno));
31}
32
dcb2879a 33static char ***
34dummy_environ(void)
35{
36 return (&(_environ));
37}
38
68dc0745 39/* the rest are the remapped stdio routines */
40static FILE *
41dummy_stderr(void)
42{
43 return stderr;
44}
45
46static FILE *
47dummy_stdin(void)
48{
49 return stdin;
50}
51
52static FILE *
53dummy_stdout(void)
54{
55 return stdout;
56}
57
58static int
59dummy_globalmode(int mode)
60{
61 int o = _fmode;
62 _fmode = mode;
63
64 return o;
65}
66
3e3baf6d 67#if defined(_DLL) || defined(__BORLANDC__)
137443ea 68/* It may or may not be fixed (ok on NT), but DLL runtime
69 does not export the functions used in the workround
70*/
71#define WIN95_OSFHANDLE_FIXED
72#endif
68dc0745 73
74#if defined(_WIN32) && !defined(WIN95_OSFHANDLE_FIXED) && defined(_M_IX86)
75
76# ifdef __cplusplus
77#define EXT_C_FUNC extern "C"
78# else
79#define EXT_C_FUNC extern
80# endif
81
82EXT_C_FUNC int __cdecl _alloc_osfhnd(void);
83EXT_C_FUNC int __cdecl _set_osfhnd(int fh, long value);
84EXT_C_FUNC void __cdecl _lock_fhandle(int);
85EXT_C_FUNC void __cdecl _unlock_fhandle(int);
86EXT_C_FUNC void __cdecl _unlock(int);
87
88#if (_MSC_VER >= 1000)
89typedef struct {
90 long osfhnd; /* underlying OS file HANDLE */
91 char osfile; /* attributes of file (e.g., open in text mode?) */
92 char pipech; /* one char buffer for handles opened on pipes */
93#if defined (_MT) && !defined (DLL_FOR_WIN32S)
94 int lockinitflag;
95 CRITICAL_SECTION lock;
96#endif /* defined (_MT) && !defined (DLL_FOR_WIN32S) */
97} ioinfo;
98
99EXT_C_FUNC ioinfo * __pioinfo[];
100
101#define IOINFO_L2E 5
102#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
103#define _pioinfo(i) (__pioinfo[i >> IOINFO_L2E] + (i & (IOINFO_ARRAY_ELTS - 1)))
104#define _osfile(i) (_pioinfo(i)->osfile)
105
106#else /* (_MSC_VER >= 1000) */
107extern char _osfile[];
108#endif /* (_MSC_VER >= 1000) */
109
110#define FOPEN 0x01 /* file handle open */
111#define FAPPEND 0x20 /* file handle opened O_APPEND */
112#define FDEV 0x40 /* file handle refers to device */
113#define FTEXT 0x80 /* file handle is in text mode */
114
115#define _STREAM_LOCKS 26 /* Table of stream locks */
116#define _LAST_STREAM_LOCK (_STREAM_LOCKS+_NSTREAM_-1) /* Last stream lock */
117#define _FH_LOCKS (_LAST_STREAM_LOCK+1) /* Table of fh locks */
118
119/***
120*int _patch_open_osfhandle(long osfhandle, int flags) - open C Runtime file handle
121*
122*Purpose:
123* This function allocates a free C Runtime file handle and associates
124* it with the Win32 HANDLE specified by the first parameter. This is a
125* temperary fix for WIN95's brain damage GetFileType() error on socket
126* we just bypass that call for socket
127*
128*Entry:
129* long osfhandle - Win32 HANDLE to associate with C Runtime file handle.
130* int flags - flags to associate with C Runtime file handle.
131*
132*Exit:
133* returns index of entry in fh, if successful
134* return -1, if no free entry is found
135*
136*Exceptions:
137*
138*******************************************************************************/
139
140int
141my_open_osfhandle(long osfhandle, int flags)
142{
143 int fh;
144 char fileflags; /* _osfile flags */
145
146 /* copy relevant flags from second parameter */
147 fileflags = FDEV;
148
3e3baf6d 149 if(flags & O_APPEND)
68dc0745 150 fileflags |= FAPPEND;
151
3e3baf6d 152 if(flags & O_TEXT)
68dc0745 153 fileflags |= FTEXT;
154
155 /* attempt to allocate a C Runtime file handle */
156 if((fh = _alloc_osfhnd()) == -1) {
157 errno = EMFILE; /* too many open files */
158 _doserrno = 0L; /* not an OS error */
159 return -1; /* return error to caller */
160 }
161
162 /* the file is open. now, set the info in _osfhnd array */
163 _set_osfhnd(fh, osfhandle);
164
165 fileflags |= FOPEN; /* mark as open */
166
167#if (_MSC_VER >= 1000)
168 _osfile(fh) = fileflags; /* set osfile entry */
169 _unlock_fhandle(fh);
170#else
171 _osfile[fh] = fileflags; /* set osfile entry */
172 _unlock(fh+_FH_LOCKS); /* unlock handle */
173#endif
174
175 return fh; /* return handle */
176}
177#else
178
179int __cdecl
137443ea 180my_open_osfhandle(long osfhandle, int flags)
68dc0745 181{
182 return _open_osfhandle(osfhandle, flags);
183}
184#endif /* _M_IX86 */
185
186long
187my_get_osfhandle( int filehandle )
188{
189 return _get_osfhandle(filehandle);
190}
191
3e3baf6d 192#ifdef __BORLANDC__
193#define _chdir chdir
194#endif
c90c0ff4 195
196/* simulate flock by locking a range on the file */
197
198
199#define LK_ERR(f,i) ((f) ? (i = 0) : (errno = GetLastError()))
200#define LK_LEN 0xffff0000
201
202int
203my_flock(int fd, int oper)
204{
205 OVERLAPPED o;
206 int i = -1;
207 HANDLE fh;
208
209 fh = (HANDLE)my_get_osfhandle(fd);
210 memset(&o, 0, sizeof(o));
211
212 switch(oper) {
213 case LOCK_SH: /* shared lock */
214 LK_ERR(LockFileEx(fh, 0, 0, LK_LEN, 0, &o),i);
215 break;
216 case LOCK_EX: /* exclusive lock */
217 LK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, 0, &o),i);
218 break;
219 case LOCK_SH|LOCK_NB: /* non-blocking shared lock */
220 LK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, 0, &o),i);
221 break;
222 case LOCK_EX|LOCK_NB: /* non-blocking exclusive lock */
223 LK_ERR(LockFileEx(fh,
224 LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
225 0, LK_LEN, 0, &o),i);
226 break;
227 case LOCK_UN: /* unlock lock */
228 LK_ERR(UnlockFileEx(fh, 0, LK_LEN, 0, &o),i);
229 break;
230 default: /* unknown */
231 errno = EINVAL;
232 break;
233 }
234 return i;
235}
236
237#undef LK_ERR
238#undef LK_LEN
239
240
54310121 241#ifdef PERLDLL
242__declspec(dllexport)
243#endif
68dc0745 244WIN32_IOSUBSYSTEM win32stdio = {
245 12345678L, /* begin of structure; */
246 dummy_errno, /* (*pfunc_errno)(void); */
dcb2879a 247 dummy_environ, /* (*pfunc_environ)(void); */
68dc0745 248 dummy_stdin, /* (*pfunc_stdin)(void); */
249 dummy_stdout, /* (*pfunc_stdout)(void); */
250 dummy_stderr, /* (*pfunc_stderr)(void); */
251 ferror, /* (*pfunc_ferror)(FILE *fp); */
252 feof, /* (*pfunc_feof)(FILE *fp); */
253 strerror, /* (*strerror)(int e); */
254 vfprintf, /* (*pfunc_vfprintf)(FILE *pf, const char *format, va_list arg); */
255 vprintf, /* (*pfunc_vprintf)(const char *format, va_list arg); */
256 fread, /* (*pfunc_fread)(void *buf, size_t size, size_t count, FILE *pf); */
257 fwrite, /* (*pfunc_fwrite)(void *buf, size_t size, size_t count, FILE *pf); */
258 fopen, /* (*pfunc_fopen)(const char *path, const char *mode); */
259 fdopen, /* (*pfunc_fdopen)(int fh, const char *mode); */
260 freopen, /* (*pfunc_freopen)(const char *path, const char *mode, FILE *pf); */
fb73857a 261 my_fclose, /* (*pfunc_fclose)(FILE *pf); */
68dc0745 262 fputs, /* (*pfunc_fputs)(const char *s,FILE *pf); */
263 fputc, /* (*pfunc_fputc)(int c,FILE *pf); */
264 ungetc, /* (*pfunc_ungetc)(int c,FILE *pf); */
265 getc, /* (*pfunc_getc)(FILE *pf); */
266 fileno, /* (*pfunc_fileno)(FILE *pf); */
267 clearerr, /* (*pfunc_clearerr)(FILE *pf); */
268 fflush, /* (*pfunc_fflush)(FILE *pf); */
269 ftell, /* (*pfunc_ftell)(FILE *pf); */
270 fseek, /* (*pfunc_fseek)(FILE *pf,long offset,int origin); */
271 fgetpos, /* (*pfunc_fgetpos)(FILE *pf,fpos_t *p); */
272 fsetpos, /* (*pfunc_fsetpos)(FILE *pf,fpos_t *p); */
273 rewind, /* (*pfunc_rewind)(FILE *pf); */
274 tmpfile, /* (*pfunc_tmpfile)(void); */
275 abort, /* (*pfunc_abort)(void); */
276 fstat, /* (*pfunc_fstat)(int fd,struct stat *bufptr); */
277 stat, /* (*pfunc_stat)(const char *name,struct stat *bufptr); */
278 _pipe, /* (*pfunc_pipe)( int *phandles, unsigned int psize, int textmode ); */
279 _popen, /* (*pfunc_popen)( const char *command, const char *mode ); */
280 _pclose, /* (*pfunc_pclose)( FILE *pf); */
281 setmode, /* (*pfunc_setmode)( int fd, int mode); */
282 lseek, /* (*pfunc_lseek)( int fd, long offset, int origin); */
283 tell, /* (*pfunc_tell)( int fd); */
284 dup, /* (*pfunc_dup)( int fd); */
285 dup2, /* (*pfunc_dup2)(int h1, int h2); */
286 open, /* (*pfunc_open)(const char *path, int oflag,...); */
287 close, /* (*pfunc_close)(int fd); */
288 eof, /* (*pfunc_eof)(int fd); */
289 read, /* (*pfunc_read)(int fd, void *buf, unsigned int cnt); */
290 write, /* (*pfunc_write)(int fd, const void *buf, unsigned int cnt); */
291 dummy_globalmode, /* (*pfunc_globalmode)(int mode) */
292 my_open_osfhandle,
293 my_get_osfhandle,
3e3baf6d 294 spawnvp,
84902520 295 mkdir,
296 rmdir,
297 chdir,
c90c0ff4 298 my_flock, /* (*pfunc_flock)(int fd, int oper) */
6890e559 299 execvp,
84902520 300 perror,
301 setbuf,
302 setvbuf,
303 flushall,
304 fcloseall,
305 fgets,
306 gets,
307 fgetc,
308 putc,
309 puts,
310 getchar,
311 putchar,
312 fscanf,
313 scanf,
314 malloc,
315 calloc,
316 realloc,
317 free,
68dc0745 318 87654321L, /* end of structure */
319};
320
321
d55594ae 322
323
68dc0745 324