source: trunk/third/perl/win32/win32io.c @ 10724

Revision 10724, 8.5 KB checked in by ghudson, 27 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r10723, which included commits to RCS files with non-trunk default branches.
Line 
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>
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
28static int *
29dummy_errno(void)
30{
31    return (&(errno));
32}
33
34static char ***
35dummy_environ(void)
36{
37    return (&(_environ));
38}
39
40/* the rest are the remapped stdio routines */
41static FILE *
42dummy_stderr(void)
43{
44    return stderr;
45}
46
47static FILE *
48dummy_stdin(void)
49{
50    return stdin;
51}
52
53static FILE *
54dummy_stdout(void)
55{
56    return stdout;
57}
58
59static int
60dummy_globalmode(int mode)
61{
62    int o = _fmode;
63    _fmode = mode;
64
65    return o;
66}
67
68#if defined(_DLL) || defined(__BORLANDC__)
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
83EXT_C_FUNC int __cdecl _alloc_osfhnd(void);
84EXT_C_FUNC int __cdecl _set_osfhnd(int fh, long value);
85EXT_C_FUNC void __cdecl _lock_fhandle(int);
86EXT_C_FUNC void __cdecl _unlock_fhandle(int);
87EXT_C_FUNC void __cdecl _unlock(int);
88
89#if     (_MSC_VER >= 1000)
90typedef 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
100EXT_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) */
108extern 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
141int
142my_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
180int __cdecl
181my_open_osfhandle(long osfhandle, int flags)
182{
183    return _open_osfhandle(osfhandle, flags);
184}
185#endif  /* _M_IX86 */
186
187long
188my_get_osfhandle( int filehandle )
189{
190    return _get_osfhandle(filehandle);
191}
192
193#ifdef __BORLANDC__
194#define _chdir chdir
195#endif
196
197/* simulate flock by locking a range on the file */
198
199
200#define LK_ERR(f,i)     ((f) ? (i = 0) : (errno = GetLastError()))
201#define LK_LEN          0xffff0000
202
203int
204my_flock(int fd, int oper)
205{
206    OVERLAPPED o;
207    int i = -1;
208    HANDLE fh;
209
210    fh = (HANDLE)my_get_osfhandle(fd);
211    memset(&o, 0, sizeof(o));
212
213    switch(oper) {
214    case LOCK_SH:               /* shared lock */
215        LK_ERR(LockFileEx(fh, 0, 0, LK_LEN, 0, &o),i);
216        break;
217    case LOCK_EX:               /* exclusive lock */
218        LK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, 0, &o),i);
219        break;
220    case LOCK_SH|LOCK_NB:       /* non-blocking shared lock */
221        LK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, 0, &o),i);
222        break;
223    case LOCK_EX|LOCK_NB:       /* non-blocking exclusive lock */
224        LK_ERR(LockFileEx(fh,
225                       LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY,
226                       0, LK_LEN, 0, &o),i);
227        break;
228    case LOCK_UN:               /* unlock lock */
229        LK_ERR(UnlockFileEx(fh, 0, LK_LEN, 0, &o),i);
230        break;
231    default:                    /* unknown */
232        errno = EINVAL;
233        break;
234    }
235    return i;
236}
237
238#undef LK_ERR
239#undef LK_LEN
240
241EXT int         my_fclose(FILE *pf);
242
243#ifdef PERLDLL
244__declspec(dllexport)
245#endif
246WIN32_IOSUBSYSTEM       win32stdio = {
247    12345678L,          /* begin of structure; */
248    dummy_errno,        /* (*pfunc_errno)(void); */
249    dummy_environ,      /* (*pfunc_environ)(void); */
250    dummy_stdin,        /* (*pfunc_stdin)(void); */
251    dummy_stdout,       /* (*pfunc_stdout)(void); */
252    dummy_stderr,       /* (*pfunc_stderr)(void); */
253    ferror,             /* (*pfunc_ferror)(FILE *fp); */
254    feof,               /* (*pfunc_feof)(FILE *fp); */
255    strerror,           /* (*strerror)(int e); */
256    vfprintf,           /* (*pfunc_vfprintf)(FILE *pf, const char *format, va_list arg); */
257    vprintf,            /* (*pfunc_vprintf)(const char *format, va_list arg); */
258    fread,              /* (*pfunc_fread)(void *buf, size_t size, size_t count, FILE *pf); */
259    fwrite,             /* (*pfunc_fwrite)(void *buf, size_t size, size_t count, FILE *pf); */
260    fopen,              /* (*pfunc_fopen)(const char *path, const char *mode); */
261    fdopen,             /* (*pfunc_fdopen)(int fh, const char *mode); */
262    freopen,            /* (*pfunc_freopen)(const char *path, const char *mode, FILE *pf); */
263    my_fclose,          /* (*pfunc_fclose)(FILE *pf); */
264    fputs,              /* (*pfunc_fputs)(const char *s,FILE *pf); */
265    fputc,              /* (*pfunc_fputc)(int c,FILE *pf); */
266    ungetc,             /* (*pfunc_ungetc)(int c,FILE *pf); */
267    getc,               /* (*pfunc_getc)(FILE *pf); */
268    fileno,             /* (*pfunc_fileno)(FILE *pf); */
269    clearerr,           /* (*pfunc_clearerr)(FILE *pf); */
270    fflush,             /* (*pfunc_fflush)(FILE *pf); */
271    ftell,              /* (*pfunc_ftell)(FILE *pf); */
272    fseek,              /* (*pfunc_fseek)(FILE *pf,long offset,int origin); */
273    fgetpos,            /* (*pfunc_fgetpos)(FILE *pf,fpos_t *p); */
274    fsetpos,            /* (*pfunc_fsetpos)(FILE *pf,fpos_t *p); */
275    rewind,             /* (*pfunc_rewind)(FILE *pf); */
276    tmpfile,            /* (*pfunc_tmpfile)(void); */
277    abort,              /* (*pfunc_abort)(void); */
278    fstat,              /* (*pfunc_fstat)(int fd,struct stat *bufptr); */
279    stat,               /* (*pfunc_stat)(const char *name,struct stat *bufptr); */
280    _pipe,              /* (*pfunc_pipe)( int *phandles, unsigned int psize, int textmode ); */
281    _popen,             /* (*pfunc_popen)( const char *command, const char *mode ); */
282    _pclose,            /* (*pfunc_pclose)( FILE *pf); */
283    setmode,            /* (*pfunc_setmode)( int fd, int mode); */
284    lseek,              /* (*pfunc_lseek)( int fd, long offset, int origin); */
285    tell,               /* (*pfunc_tell)( int fd); */
286    dup,                /* (*pfunc_dup)( int fd); */
287    dup2,               /* (*pfunc_dup2)(int h1, int h2); */
288    open,               /* (*pfunc_open)(const char *path, int oflag,...); */
289    close,              /* (*pfunc_close)(int fd); */
290    eof,                /* (*pfunc_eof)(int fd); */
291    read,               /* (*pfunc_read)(int fd, void *buf, unsigned int cnt); */
292    write,              /* (*pfunc_write)(int fd, const void *buf, unsigned int cnt); */
293    dummy_globalmode,   /* (*pfunc_globalmode)(int mode) */
294    my_open_osfhandle,
295    my_get_osfhandle,
296    spawnvp,
297    mkdir,
298    rmdir,
299    chdir,
300    my_flock,           /* (*pfunc_flock)(int fd, int oper) */
301    execvp,
302    perror,
303    setbuf,
304    setvbuf,
305    flushall,
306    fcloseall,
307    fgets,
308    gets,
309    fgetc,
310    putc,
311    puts,
312    getchar,
313    putchar,
314    fscanf,
315    scanf,
316    malloc,
317    calloc,
318    realloc,
319    free,
320    87654321L,          /* end of structure */
321};
322
323
324#ifdef __cplusplus
325}
326#endif
327
Note: See TracBrowser for help on using the repository browser.