[DOC PATCH] perlre, minor error
[p5sagit/p5-mst-13.2.git] / win32 / win32.c
index a77ec88..ba2af59 100644 (file)
@@ -208,7 +208,6 @@ get_emd_part(SV **prev_pathp, char *trailing_path, ...)
     char *ptr;
     char *optr;
     char *strip;
-    int oldsize, newsize;
     STRLEN baselen;
 
     va_start(ap, trailing_path);
@@ -286,8 +285,6 @@ win32_get_xlib(const char *pl, const char *xlib, const char *libname)
     dTHX;
     char regstr[40];
     char pathstr[MAX_PATH+1];
-    DWORD datalen;
-    int len, newsize;
     SV *sv1 = Nullsv;
     SV *sv2 = Nullsv;
 
@@ -733,7 +730,7 @@ win32_opendir(char *filename)
     long               len;
     long               idx;
     char               scanname[MAX_PATH+3];
-    struct stat                sbuf;
+    Stat_t             sbuf;
     WIN32_FIND_DATAA   aFindData;
     WIN32_FIND_DATAW   wFindData;
     HANDLE             fh;
@@ -1022,7 +1019,7 @@ find_pid(int pid)
     dTHX;
     long child = w32_num_children;
     while (--child >= 0) {
-       if (w32_child_pids[child] == pid)
+       if ((int)w32_child_pids[child] == pid)
            return child;
     }
     return -1;
@@ -1049,7 +1046,7 @@ find_pseudo_pid(int pid)
     dTHX;
     long child = w32_num_pseudo_children;
     while (--child >= 0) {
-       if (w32_pseudo_child_pids[child] == pid)
+       if ((int)w32_pseudo_child_pids[child] == pid)
            return child;
     }
     return -1;
@@ -1160,7 +1157,7 @@ alien_process:
 }
 
 DllExport int
-win32_stat(const char *path, struct stat *sbuf)
+win32_stat(const char *path, Stat_t *sbuf)
 {
     dTHX;
     char       buffer[MAX_PATH+1];
@@ -1217,10 +1214,18 @@ win32_stat(const char *path, struct stat *sbuf)
 
     /* pwbuffer or path will be mapped correctly above */
     if (USING_WIDE()) {
-       res = _wstat(pwbuffer, (struct _stat *)sbuf);
+#if defined(WIN64) || defined(USE_LARGE_FILES)
+       res = _wstati64(pwbuffer, sbuf);
+#else
+       res = _wstat(pwbuffer, (struct _stat*)sbuf);
+#endif
     }
     else {
+#if defined(WIN64) || defined(USE_LARGE_FILES)
+       res = _stati64(path, sbuf);
+#else
        res = stat(path, sbuf);
+#endif
     }
     sbuf->st_nlink = nlink;
 
@@ -1238,7 +1243,7 @@ win32_stat(const char *path, struct stat *sbuf)
        }
        if (r != 0xffffffff && (r & FILE_ATTRIBUTE_DIRECTORY)) {
            /* sbuf may still contain old garbage since stat() failed */
-           Zero(sbuf, 1, struct stat);
+           Zero(sbuf, 1, Stat_t);
            sbuf->st_mode = S_IFDIR | S_IREAD;
            errno = 0;
            if (!(r & FILE_ATTRIBUTE_READONLY))
@@ -1503,22 +1508,21 @@ win32_times(struct tms *timebuf)
     FILETIME user;
     FILETIME kernel;
     FILETIME dummy;
+    clock_t process_time_so_far = clock();
     if (GetProcessTimes(GetCurrentProcess(), &dummy, &dummy,
                         &kernel,&user)) {
        timebuf->tms_utime = filetime_to_clock(&user);
        timebuf->tms_stime = filetime_to_clock(&kernel);
        timebuf->tms_cutime = 0;
        timebuf->tms_cstime = 0;
-
     } else {
         /* That failed - e.g. Win95 fallback to clock() */
-        clock_t t = clock();
-       timebuf->tms_utime = t;
+       timebuf->tms_utime = process_time_so_far;
        timebuf->tms_stime = 0;
        timebuf->tms_cutime = 0;
        timebuf->tms_cstime = 0;
     }
-    return 0;
+    return process_time_so_far;
 }
 
 /* fix utime() so it works on directories in NT */
@@ -1647,6 +1651,38 @@ win32_utime(const char *filename, struct utimbuf *times)
     return rc;
 }
 
+typedef union {
+    unsigned __int64   ft_i64;
+    FILETIME           ft_val;
+} FT_t;
+
+#ifdef __GNUC__
+#define Const64(x) x##LL
+#else
+#define Const64(x) x##i64
+#endif
+/* Number of 100 nanosecond units from 1/1/1601 to 1/1/1970 */
+#define EPOCH_BIAS  Const64(116444736000000000)
+
+/* NOTE: This does not compute the timezone info (doing so can be expensive,
+ * and appears to be unsupported even by glibc) */
+DllExport int
+win32_gettimeofday(struct timeval *tp, void *not_used)
+{
+    FT_t ft;
+
+    /* this returns time in 100-nanosecond units  (i.e. tens of usecs) */
+    GetSystemTimeAsFileTime(&ft.ft_val);
+
+    /* seconds since epoch */
+    tp->tv_sec = (long)((ft.ft_i64 - EPOCH_BIAS) / Const64(10000000));
+
+    /* microseconds remaining */
+    tp->tv_usec = (long)((ft.ft_i64 / Const64(10)) % Const64(1000000));
+
+    return 0;
+}
+
 DllExport int
 win32_uname(struct utsname *name)
 {
@@ -1713,15 +1749,17 @@ win32_uname(struct utsname *name)
     /* machine (architecture) */
     {
        SYSTEM_INFO info;
+       DWORD procarch;
        char *arch;
        GetSystemInfo(&info);
 
 #if (defined(__BORLANDC__)&&(__BORLANDC__<=0x520)) \
  || (defined(__MINGW32__) && !defined(_ANONYMOUS_UNION))
-       switch (info.u.s.wProcessorArchitecture) {
+       procarch = info.u.s.wProcessorArchitecture;
 #else
-       switch (info.wProcessorArchitecture) {
+       procarch = info.wProcessorArchitecture;
 #endif
+       switch (procarch) {
        case PROCESSOR_ARCHITECTURE_INTEL:
            arch = "x86"; break;
        case PROCESSOR_ARCHITECTURE_MIPS:
@@ -1730,10 +1768,45 @@ win32_uname(struct utsname *name)
            arch = "alpha"; break;
        case PROCESSOR_ARCHITECTURE_PPC:
            arch = "ppc"; break;
-       default:
+#ifdef PROCESSOR_ARCHITECTURE_SHX
+       case PROCESSOR_ARCHITECTURE_SHX:
+           arch = "shx"; break;
+#endif
+#ifdef PROCESSOR_ARCHITECTURE_ARM
+       case PROCESSOR_ARCHITECTURE_ARM:
+           arch = "arm"; break;
+#endif
+#ifdef PROCESSOR_ARCHITECTURE_IA64
+       case PROCESSOR_ARCHITECTURE_IA64:
+           arch = "ia64"; break;
+#endif
+#ifdef PROCESSOR_ARCHITECTURE_ALPHA64
+       case PROCESSOR_ARCHITECTURE_ALPHA64:
+           arch = "alpha64"; break;
+#endif
+#ifdef PROCESSOR_ARCHITECTURE_MSIL
+       case PROCESSOR_ARCHITECTURE_MSIL:
+           arch = "msil"; break;
+#endif
+#ifdef PROCESSOR_ARCHITECTURE_AMD64
+       case PROCESSOR_ARCHITECTURE_AMD64:
+           arch = "amd64"; break;
+#endif
+#ifdef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
+       case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
+           arch = "ia32-64"; break;
+#endif
+#ifdef PROCESSOR_ARCHITECTURE_UNKNOWN
+       case PROCESSOR_ARCHITECTURE_UNKNOWN:
            arch = "unknown"; break;
+#endif
+       default:
+           sprintf(name->machine, "unknown(0x%x)", procarch);
+           arch = name->machine;
+           break;
        }
-       strcpy(name->machine, arch);
+       if (name->machine != arch)
+           strcpy(name->machine, arch);
     }
     return 0;
 }
@@ -1945,7 +2018,6 @@ win32_internal_wait(int *status, DWORD timeout)
        }
     }
 
-FAILED:
     errno = GetLastError();
     return -1;
 }
@@ -2093,7 +2165,7 @@ win32_crypt(const char *txt, const char *salt)
 #define FTEXT                  0x80    /* file handle is in text mode */
 
 /***
-*int my_open_osfhandle(long osfhandle, int flags) - open C Runtime file handle
+*int my_open_osfhandle(intptr_t osfhandle, int flags) - open C Runtime file handle
 *
 *Purpose:
 *       This function allocates a free C Runtime file handle and associates
@@ -2104,7 +2176,7 @@ win32_crypt(const char *txt, const char *salt)
 *      This works with MSVC++ 4.0+ or GCC/Mingw32
 *
 *Entry:
-*       long osfhandle - Win32 HANDLE to associate with C Runtime file handle.
+*       intptr_t osfhandle - Win32 HANDLE to associate with C Runtime file handle.
 *       int flags      - flags to associate with C Runtime file handle.
 *
 *Exit:
@@ -2128,7 +2200,7 @@ static int
 _alloc_osfhnd(void)
 {
     HANDLE hF = CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
-    int fh = _open_osfhandle((long)hF, 0);
+    int fh = _open_osfhandle((intptr_t)hF, 0);
     CloseHandle(hF);
     if (fh == -1)
         return fh;
@@ -2137,7 +2209,7 @@ _alloc_osfhnd(void)
 }
 
 static int
-my_open_osfhandle(long osfhandle, int flags)
+my_open_osfhandle(intptr_t osfhandle, int flags)
 {
     int fh;
     char fileflags;            /* _osfile flags */
@@ -2490,16 +2562,45 @@ win32_fflush(FILE *pf)
     return fflush(pf);
 }
 
-DllExport long
+DllExport Off_t
 win32_ftell(FILE *pf)
 {
+#if defined(WIN64) || defined(USE_LARGE_FILES)
+    fpos_t pos;
+    if (fgetpos(pf, &pos))
+       return -1;
+    return (Off_t)pos;
+#else
     return ftell(pf);
+#endif
 }
 
 DllExport int
-win32_fseek(FILE *pf,long offset,int origin)
+win32_fseek(FILE *pf, Off_t offset,int origin)
 {
+#if defined(WIN64) || defined(USE_LARGE_FILES)
+    fpos_t pos;
+    switch (origin) {
+    case SEEK_CUR:
+       if (fgetpos(pf, &pos))
+           return -1;
+       offset += pos;
+       break;
+    case SEEK_END:
+       fseek(pf, 0, SEEK_END);
+       pos = _telli64(fileno(pf));
+       offset += pos;
+       break;
+    case SEEK_SET:
+       break;
+    default:
+       errno = EINVAL;
+       return -1;
+    }
+    return fsetpos(pf, &offset);
+#else
     return fseek(pf, offset, origin);
+#endif
 }
 
 DllExport int
@@ -2539,7 +2640,7 @@ win32_tmpfile(void)
                                   | FILE_FLAG_DELETE_ON_CLOSE,
                                   NULL);
            if (fh != INVALID_HANDLE_VALUE) {
-               int fd = win32_open_osfhandle((long)fh, 0);
+               int fd = win32_open_osfhandle((intptr_t)fh, 0);
                if (fd >= 0) {
 #if defined(__BORLANDC__)
                    setmode(fd,O_BINARY);
@@ -2562,7 +2663,7 @@ win32_abort(void)
 }
 
 DllExport int
-win32_fstat(int fd,struct stat *sbufptr)
+win32_fstat(int fd, Stat_t *sbufptr)
 {
 #ifdef __BORLANDC__
     /* A file designated by filehandle is not shown as accessible
@@ -2611,6 +2712,7 @@ win32_popen(const char *command, const char *mode)
 #ifdef USE_RTL_POPEN
     return _popen(command, mode);
 #else
+    dTHX;
     int p[2];
     int parent, child;
     int stdfd, oldfd;
@@ -2954,16 +3056,24 @@ win32_setmode(int fd, int mode)
     return setmode(fd, mode);
 }
 
-DllExport long
-win32_lseek(int fd, long offset, int origin)
+DllExport Off_t
+win32_lseek(int fd, Off_t offset, int origin)
 {
+#if defined(WIN64) || defined(USE_LARGE_FILES)
+    return _lseeki64(fd, offset, origin);
+#else
     return lseek(fd, offset, origin);
+#endif
 }
 
-DllExport long
+DllExport Off_t
 win32_tell(int fd)
 {
+#if defined(WIN64) || defined(USE_LARGE_FILES)
+    return _telli64(fd);
+#else
     return tell(fd);
+#endif
 }
 
 DllExport int
@@ -3507,7 +3617,7 @@ qualified_path(const char *cmd)
            if (*pathstr == '"') {      /* foo;"baz;etc";bar */
                pathstr++;              /* skip initial '"' */
                while (*pathstr && *pathstr != '"') {
-                   if (curfullcmd-fullcmd < MAX_PATH-cmdlen-5)
+                   if ((STRLEN)(curfullcmd-fullcmd) < MAX_PATH-cmdlen-5)
                        *curfullcmd++ = *pathstr;
                    pathstr++;
                }
@@ -3515,7 +3625,7 @@ qualified_path(const char *cmd)
                    pathstr++;          /* skip trailing '"' */
            }
            else {
-               if (curfullcmd-fullcmd < MAX_PATH-cmdlen-5)
+               if ((STRLEN)(curfullcmd-fullcmd) < MAX_PATH-cmdlen-5)
                    *curfullcmd++ = *pathstr;
                pathstr++;
            }
@@ -3528,7 +3638,7 @@ qualified_path(const char *cmd)
            *curfullcmd++ = '\\';
        }
     }
-GIVE_UP:
+
     Safefree(fullcmd);
     return Nullch;
 }
@@ -3687,14 +3797,14 @@ win32_spawnvp(int mode, const char *cmdname, const char *const *argv)
     StartupInfo.hStdInput      = tbl.childStdIn;
     StartupInfo.hStdOutput     = tbl.childStdOut;
     StartupInfo.hStdError      = tbl.childStdErr;
-    if (StartupInfo.hStdInput != INVALID_HANDLE_VALUE &&
-       StartupInfo.hStdOutput != INVALID_HANDLE_VALUE &&
-       StartupInfo.hStdError != INVALID_HANDLE_VALUE)
+    if (StartupInfo.hStdInput == INVALID_HANDLE_VALUE &&
+       StartupInfo.hStdOutput == INVALID_HANDLE_VALUE &&
+       StartupInfo.hStdError == INVALID_HANDLE_VALUE)
     {
-       StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
+       create |= CREATE_NEW_CONSOLE;
     }
     else {
-       create |= CREATE_NEW_CONSOLE;
+       StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
     }
     if (w32_use_showwindow) {
         StartupInfo.dwFlags |= STARTF_USESHOWWINDOW;
@@ -3888,7 +3998,7 @@ static DWORD pagesize  = 0;               /* XXX threadead */
 static DWORD allocsize = 0;            /* XXX threadead */
 
 void *
-sbrk(int need)
+sbrk(ptrdiff_t need)
 {
  void *result;
  if (!pagesize)
@@ -3980,8 +4090,8 @@ win32_free(void *block)
 }
 
 
-int
-win32_open_osfhandle(long handle, int flags)
+DllExport int
+win32_open_osfhandle(intptr_t handle, int flags)
 {
 #ifdef USE_FIXED_OSFHANDLE
     if (IsWin95())
@@ -3990,10 +4100,62 @@ win32_open_osfhandle(long handle, int flags)
     return _open_osfhandle(handle, flags);
 }
 
-long
+DllExport intptr_t
 win32_get_osfhandle(int fd)
 {
-    return _get_osfhandle(fd);
+    return (intptr_t)_get_osfhandle(fd);
+}
+
+DllExport FILE *
+win32_fdupopen(FILE *pf)
+{
+    FILE* pfdup;
+    fpos_t pos;
+    char mode[3];
+    int fileno = win32_dup(win32_fileno(pf));
+
+    /* open the file in the same mode */
+#ifdef __BORLANDC__
+    if((pf)->flags & _F_READ) {
+       mode[0] = 'r';
+       mode[1] = 0;
+    }
+    else if((pf)->flags & _F_WRIT) {
+       mode[0] = 'a';
+       mode[1] = 0;
+    }
+    else if((pf)->flags & _F_RDWR) {
+       mode[0] = 'r';
+       mode[1] = '+';
+       mode[2] = 0;
+    }
+#else
+    if((pf)->_flag & _IOREAD) {
+       mode[0] = 'r';
+       mode[1] = 0;
+    }
+    else if((pf)->_flag & _IOWRT) {
+       mode[0] = 'a';
+       mode[1] = 0;
+    }
+    else if((pf)->_flag & _IORW) {
+       mode[0] = 'r';
+       mode[1] = '+';
+       mode[2] = 0;
+    }
+#endif
+
+    /* it appears that the binmode is attached to the
+     * file descriptor so binmode files will be handled
+     * correctly
+     */
+    pfdup = win32_fdopen(fileno, mode);
+
+    /* move the file pointer to the same position */
+    if (!fgetpos(pf, &pos)) {
+       fsetpos(pfdup, &pos);
+    }
+    return pfdup;
 }
 
 DllExport void*
@@ -4561,20 +4723,25 @@ Perl_init_os_extras(void)
      */
 }
 
-#ifdef MULTIPLICITY
-
-PerlInterpreter *
+void *
 win32_signal_context(void)
 {
     dTHX;
+#ifdef MULTIPLICITY
     if (!my_perl) {
        my_perl = PL_curinterp;
        PERL_SET_THX(my_perl);
     }
     return my_perl;
+#else
+#ifdef USE_5005THREADS
+    return aTHX;
+#else
+    return PL_curinterp;
+#endif
+#endif
 }
 
-#endif
 
 BOOL WINAPI
 win32_ctrlhandler(DWORD dwCtrlType)
@@ -4584,6 +4751,10 @@ win32_ctrlhandler(DWORD dwCtrlType)
 
     if (!my_perl)
        return FALSE;
+#else
+#ifdef USE_5005THREADS
+    dTHX;
+#endif
 #endif
 
     switch(dwCtrlType) {