#define Win32_Winsock
#endif
#include <windows.h>
+#include <winnt.h>
+#include <io.h>
/* #include "config.h" */
char *optr;
char *strip;
int oldsize, newsize;
+ STRLEN baselen;
va_start(ap, trailing_path);
strip = va_arg(ap, char *);
- sprintf(base, "%5.3f",
- (double)PERL_REVISION + ((double)PERL_VERSION / (double)1000));
+ sprintf(base, "%d.%d", (int)PERL_REVISION, (int)PERL_VERSION);
+ baselen = strlen(base);
if (!*w32_module_name) {
GetModuleFileName((HMODULE)((w32_perldll_handle == INVALID_HANDLE_VALUE)
/* avoid stripping component if there is no slash,
* or it doesn't match ... */
if (!ptr || stricmp(ptr+1, strip) != 0) {
- /* ... but not if component matches 5.00X* */
+ /* ... but not if component matches m|5\.$patchlevel.*| */
if (!ptr || !(*strip == '5' && *(ptr+1) == '5'
- && strncmp(strip, base, 5) == 0
- && strncmp(ptr+1, base, 5) == 0))
+ && strncmp(strip, base, baselen) == 0
+ && strncmp(ptr+1, base, baselen) == 0))
{
*optr = '/';
ptr = optr;
* ";$EMD/" . ((-d $EMD/../../../$]) ? "../../.." : "../.."). "/site/$]/lib"; */
sprintf(pathstr, "site/%s/lib", pl);
(void)get_emd_part(&sv1, pathstr, ARCHNAME, "bin", pl, Nullch);
- if (!sv1 && strlen(pl) == 7) {
- /* pl may have been SUBVERSION-specific; try again without
- * SUBVERSION */
- sprintf(pathstr, "site/%.5s/lib", pl);
- (void)get_emd_part(&sv1, pathstr, ARCHNAME, "bin", pl, Nullch);
- }
/* $HKCU{'sitelib'} || $HKLM{'sitelib'} . ---; */
(void)get_regstr(sitelib, &sv2);
return dup2(fd1,fd2);
}
+#ifdef PERL_MSVCRT_READFIX
+
+#define LF 10 /* line feed */
+#define CR 13 /* carriage return */
+#define CTRLZ 26 /* ctrl-z means eof for text */
+#define FOPEN 0x01 /* file handle open */
+#define FEOFLAG 0x02 /* end of file has been encountered */
+#define FCRLF 0x04 /* CR-LF across read buffer (in text mode) */
+#define FPIPE 0x08 /* file handle refers to a pipe */
+#define FAPPEND 0x20 /* file handle opened O_APPEND */
+#define FDEV 0x40 /* file handle refers to device */
+#define FTEXT 0x80 /* file handle is in text mode */
+#define MAX_DESCRIPTOR_COUNT (64*32) /* this is the maximun that MSVCRT can handle */
+
+/*
+ * Control structure for lowio file handles
+ */
+typedef struct {
+ long osfhnd; /* underlying OS file HANDLE */
+ char osfile; /* attributes of file (e.g., open in text mode?) */
+ char pipech; /* one char buffer for handles opened on pipes */
+ int lockinitflag;
+ CRITICAL_SECTION lock;
+} ioinfo;
+
+
+/*
+ * Array of arrays of control structures for lowio files.
+ */
+EXTERN_C _CRTIMP ioinfo* __pioinfo[];
+
+/*
+ * Definition of IOINFO_L2E, the log base 2 of the number of elements in each
+ * array of ioinfo structs.
+ */
+#define IOINFO_L2E 5
+
+/*
+ * Definition of IOINFO_ARRAY_ELTS, the number of elements in ioinfo array
+ */
+#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
+
+/*
+ * Access macros for getting at an ioinfo struct and its fields from a
+ * file handle
+ */
+#define _pioinfo(i) (__pioinfo[(i) >> IOINFO_L2E] + ((i) & (IOINFO_ARRAY_ELTS - 1)))
+#define _osfhnd(i) (_pioinfo(i)->osfhnd)
+#define _osfile(i) (_pioinfo(i)->osfile)
+#define _pipech(i) (_pioinfo(i)->pipech)
+
+int __cdecl _fixed_read(int fh, void *buf, unsigned cnt)
+{
+ int bytes_read; /* number of bytes read */
+ char *buffer; /* buffer to read to */
+ int os_read; /* bytes read on OS call */
+ char *p, *q; /* pointers into buffer */
+ char peekchr; /* peek-ahead character */
+ ULONG filepos; /* file position after seek */
+ ULONG dosretval; /* o.s. return value */
+
+ /* validate handle */
+ if (((unsigned)fh >= (unsigned)MAX_DESCRIPTOR_COUNT) ||
+ !(_osfile(fh) & FOPEN))
+ {
+ /* out of range -- return error */
+ errno = EBADF;
+ _doserrno = 0; /* not o.s. error */
+ return -1;
+ }
+
+ EnterCriticalSection(&(_pioinfo(fh)->lock)); /* lock file */
+
+ bytes_read = 0; /* nothing read yet */
+ buffer = (char*)buf;
+
+ if (cnt == 0 || (_osfile(fh) & FEOFLAG)) {
+ /* nothing to read or at EOF, so return 0 read */
+ goto functionexit;
+ }
+
+ if ((_osfile(fh) & (FPIPE|FDEV)) && _pipech(fh) != LF) {
+ /* a pipe/device and pipe lookahead non-empty: read the lookahead
+ * char */
+ *buffer++ = _pipech(fh);
+ ++bytes_read;
+ --cnt;
+ _pipech(fh) = LF; /* mark as empty */
+ }
+
+ /* read the data */
+
+ if (!ReadFile((HANDLE)_osfhnd(fh), buffer, cnt, (LPDWORD)&os_read, NULL))
+ {
+ /* ReadFile has reported an error. recognize two special cases.
+ *
+ * 1. map ERROR_ACCESS_DENIED to EBADF
+ *
+ * 2. just return 0 if ERROR_BROKEN_PIPE has occurred. it
+ * means the handle is a read-handle on a pipe for which
+ * all write-handles have been closed and all data has been
+ * read. */
+
+ if ((dosretval = GetLastError()) == ERROR_ACCESS_DENIED) {
+ /* wrong read/write mode should return EBADF, not EACCES */
+ errno = EBADF;
+ _doserrno = dosretval;
+ bytes_read = -1;
+ goto functionexit;
+ }
+ else if (dosretval == ERROR_BROKEN_PIPE) {
+ bytes_read = 0;
+ goto functionexit;
+ }
+ else {
+ bytes_read = -1;
+ goto functionexit;
+ }
+ }
+
+ bytes_read += os_read; /* update bytes read */
+
+ if (_osfile(fh) & FTEXT) {
+ /* now must translate CR-LFs to LFs in the buffer */
+
+ /* set CRLF flag to indicate LF at beginning of buffer */
+ /* if ((os_read != 0) && (*(char *)buf == LF)) */
+ /* _osfile(fh) |= FCRLF; */
+ /* else */
+ /* _osfile(fh) &= ~FCRLF; */
+
+ _osfile(fh) &= ~FCRLF;
+
+ /* convert chars in the buffer: p is src, q is dest */
+ p = q = (char*)buf;
+ while (p < (char *)buf + bytes_read) {
+ if (*p == CTRLZ) {
+ /* if fh is not a device, set ctrl-z flag */
+ if (!(_osfile(fh) & FDEV))
+ _osfile(fh) |= FEOFLAG;
+ break; /* stop translating */
+ }
+ else if (*p != CR)
+ *q++ = *p++;
+ else {
+ /* *p is CR, so must check next char for LF */
+ if (p < (char *)buf + bytes_read - 1) {
+ if (*(p+1) == LF) {
+ p += 2;
+ *q++ = LF; /* convert CR-LF to LF */
+ }
+ else
+ *q++ = *p++; /* store char normally */
+ }
+ else {
+ /* This is the hard part. We found a CR at end of
+ buffer. We must peek ahead to see if next char
+ is an LF. */
+ ++p;
+
+ dosretval = 0;
+ if (!ReadFile((HANDLE)_osfhnd(fh), &peekchr, 1,
+ (LPDWORD)&os_read, NULL))
+ dosretval = GetLastError();
+
+ if (dosretval != 0 || os_read == 0) {
+ /* couldn't read ahead, store CR */
+ *q++ = CR;
+ }
+ else {
+ /* peekchr now has the extra character -- we now
+ have several possibilities:
+ 1. disk file and char is not LF; just seek back
+ and copy CR
+ 2. disk file and char is LF; store LF, don't seek back
+ 3. pipe/device and char is LF; store LF.
+ 4. pipe/device and char isn't LF, store CR and
+ put char in pipe lookahead buffer. */
+ if (_osfile(fh) & (FDEV|FPIPE)) {
+ /* non-seekable device */
+ if (peekchr == LF)
+ *q++ = LF;
+ else {
+ *q++ = CR;
+ _pipech(fh) = peekchr;
+ }
+ }
+ else {
+ /* disk file */
+ if (peekchr == LF) {
+ /* nothing read yet; must make some
+ progress */
+ *q++ = LF;
+ /* turn on this flag for tell routine */
+ _osfile(fh) |= FCRLF;
+ }
+ else {
+ HANDLE osHandle; /* o.s. handle value */
+ /* seek back */
+ if ((osHandle = (HANDLE)_get_osfhandle(fh)) != (HANDLE)-1)
+ {
+ if ((filepos = SetFilePointer(osHandle, -1, NULL, FILE_CURRENT)) == -1)
+ dosretval = GetLastError();
+ }
+ if (peekchr != LF)
+ *q++ = CR;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* we now change bytes_read to reflect the true number of chars
+ in the buffer */
+ bytes_read = q - (char *)buf;
+ }
+
+functionexit:
+ LeaveCriticalSection(&(_pioinfo(fh)->lock)); /* unlock file */
+
+ return bytes_read;
+}
+
+#endif /* PERL_MSVCRT_READFIX */
+
DllExport int
win32_read(int fd, void *buf, unsigned int cnt)
{
+#ifdef PERL_MSVCRT_READFIX
+ return _fixed_read(fd, buf, cnt);
+#else
return read(fd, buf, cnt);
+#endif
}
DllExport int
MALLOC_INIT;
}
-#ifdef USE_BINMODE_SCRIPTS
-
-void
-win32_strip_return(SV *sv)
-{
- char *s = SvPVX(sv);
- char *e = s+SvCUR(sv);
- char *d = s;
- while (s < e)
- {
- if (*s == '\r' && s[1] == '\n')
- {
- *d++ = '\n';
- s += 2;
- }
- else
- {
- *d++ = *s++;
- }
- }
- SvCUR_set(sv,d-SvPVX(sv));
-}
-
-#endif
-
#ifdef USE_ITHREADS
# ifdef PERL_OBJECT