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