src/windows/native/java/io/io_util_md.c

Print this page




  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include "jni.h"
  27 #include "jni_util.h"
  28 #include "jvm.h"
  29 #include "io_util.h"
  30 #include "io_util_md.h"
  31 #include <stdio.h>

  32 
  33 #include <wchar.h>
  34 #include <io.h>
  35 #include <fcntl.h>
  36 #include <errno.h>
  37 #include <string.h>
  38 #include <sys/types.h>
  39 #include <sys/stat.h>
  40 #include <limits.h>
  41 #include <wincon.h>
  42 

  43 static DWORD MAX_INPUT_EVENTS = 2000;
  44 
  45 /* If this returns NULL then an exception is pending */
  46 WCHAR*
  47 fileToNTPath(JNIEnv *env, jobject file, jfieldID id) {
  48     jstring path = NULL;
  49     if (file != NULL) {
  50         path = (*env)->GetObjectField(env, file, id);
  51     }
  52     return pathToNTPath(env, path, JNI_FALSE);
  53 }
  54 
  55 /* Returns the working directory for the given drive, or NULL */
  56 WCHAR*
  57 currentDir(int di) {
  58     UINT dt;
  59     WCHAR root[4];
  60     // verify drive is valid as _wgetdcwd in the VC++ 2010 runtime
  61     // library does not handle invalid drives.
  62     root[0] = L'A' + (WCHAR)(di - 1);


 552     HANDLE h = (HANDLE)fd;
 553 
 554     if (whence == SEEK_END) {
 555         op = FILE_END;
 556     }
 557     if (whence == SEEK_CUR) {
 558         op = FILE_CURRENT;
 559     }
 560     if (whence == SEEK_SET) {
 561         op = FILE_BEGIN;
 562     }
 563 
 564     distance.QuadPart = offset;
 565     if (SetFilePointerEx(h, distance, &pos, op) == 0) {
 566         return -1;
 567     }
 568     return long_to_jlong(pos.QuadPart);
 569 }
 570 
 571 size_t
 572 getLastErrorString(char *buf, size_t len)
 573 {
 574     DWORD errval;
 575     if (len > 0) {
 576         if ((errval = GetLastError()) != 0) {
 577             // DOS error
 578             size_t n = (size_t)FormatMessage(










 579                 FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
 580                 NULL,
 581                 errval,
 582                 0,
 583                 buf,
 584                 (DWORD)len,
 585                 NULL);
 586             if (n > 3) {
 587                 // Drop final '.', CR, LF
 588                 if (buf[n - 1] == '\n') n--;
 589                 if (buf[n - 1] == '\r') n--;
 590                 if (buf[n - 1] == '.') n--;
 591                 buf[n] = '\0';
 592             }
 593             return n;
 594         }





















 595 
 596         if (errno != 0) {
 597             // C runtime error that has no corresponding DOS error code
 598             const char *err = strerror(errno);
 599             size_t n = strlen(err);
 600             if (n >= len)
 601                 n = len - 1;
 602 
 603             strncpy(buf, err, n);
 604             buf[n] = '\0';
 605             return n;


 606         }
 607     }
 608 
 609     return 0;


 610 }


  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include "jni.h"
  27 #include "jni_util.h"
  28 #include "jvm.h"
  29 #include "io_util.h"
  30 #include "io_util_md.h"
  31 #include <stdio.h>
  32 #include <windows.h>
  33 
  34 #include <wchar.h>
  35 #include <io.h>
  36 #include <fcntl.h>
  37 #include <errno.h>
  38 #include <string.h>
  39 #include <sys/types.h>
  40 #include <sys/stat.h>
  41 #include <limits.h>
  42 #include <wincon.h>
  43 
  44 
  45 static DWORD MAX_INPUT_EVENTS = 2000;
  46 
  47 /* If this returns NULL then an exception is pending */
  48 WCHAR*
  49 fileToNTPath(JNIEnv *env, jobject file, jfieldID id) {
  50     jstring path = NULL;
  51     if (file != NULL) {
  52         path = (*env)->GetObjectField(env, file, id);
  53     }
  54     return pathToNTPath(env, path, JNI_FALSE);
  55 }
  56 
  57 /* Returns the working directory for the given drive, or NULL */
  58 WCHAR*
  59 currentDir(int di) {
  60     UINT dt;
  61     WCHAR root[4];
  62     // verify drive is valid as _wgetdcwd in the VC++ 2010 runtime
  63     // library does not handle invalid drives.
  64     root[0] = L'A' + (WCHAR)(di - 1);


 554     HANDLE h = (HANDLE)fd;
 555 
 556     if (whence == SEEK_END) {
 557         op = FILE_END;
 558     }
 559     if (whence == SEEK_CUR) {
 560         op = FILE_CURRENT;
 561     }
 562     if (whence == SEEK_SET) {
 563         op = FILE_BEGIN;
 564     }
 565 
 566     distance.QuadPart = offset;
 567     if (SetFilePointerEx(h, distance, &pos, op) == 0) {
 568         return -1;
 569     }
 570     return long_to_jlong(pos.QuadPart);
 571 }
 572 
 573 size_t
 574 getLastErrorString(char *utf8_jvmErrorMsg, size_t cbErrorMsg)
 575 {
 576     size_t n = 0;
 577     if (cbErrorMsg > 0) {
 578         BOOLEAN noError = FALSE;
 579         WCHAR *utf16_osErrorMsg = (WCHAR *)malloc(cbErrorMsg*sizeof(WCHAR));
 580         if (utf16_osErrorMsg == NULL) {
 581             // OOM accident 
 582             strncpy(utf8_jvmErrorMsg, "Out of memory", cbErrorMsg);
 583             // truncate if too long
 584             utf8_jvmErrorMsg[cbErrorMsg - 1] = '\0';
 585             n = strlen(utf8_jvmErrorMsg);
 586         } else {
 587             DWORD errval = GetLastError();
 588             if (errval != 0) {
 589                 // WIN32 error
 590                 n = (size_t)FormatMessageW(
 591                     FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
 592                     NULL,
 593                     errval,
 594                     0,
 595                     utf16_osErrorMsg,
 596                     (DWORD)cbErrorMsg,
 597                     NULL);
 598                 if (n > 3) {
 599                     // Drop final '.', CR, LF
 600                     if (utf16_osErrorMsg[n - 1] == L'\n') --n;
 601                     if (utf16_osErrorMsg[n - 1] == L'\r') --n;
 602                     if (utf16_osErrorMsg[n - 1] == L'.') --n;
 603                     utf16_osErrorMsg[n] = L'\0';
 604                 }
 605             } else if (errno != 0) {
 606                 // C runtime error that has no corresponding WIN32 error code
 607                 const WCHAR *rtError = _wcserror(errno);
 608                 if (rtError != NULL) {
 609                     wcsncpy(utf16_osErrorMsg, rtError, cbErrorMsg);
 610                     // truncate if too long
 611                     utf16_osErrorMsg[cbErrorMsg - 1] = L'\0';
 612                     n = wcslen(utf16_osErrorMsg);
 613                 }
 614             } else
 615                 noError = TRUE; //OS has no error to report
 616 
 617             if (!noError) {
 618                 if (n > 0) {
 619                     n = WideCharToMultiByte(
 620                         CP_UTF8,
 621                         0,
 622                         utf16_osErrorMsg,
 623                         n,
 624                         utf8_jvmErrorMsg,
 625                         cbErrorMsg,
 626                         NULL,
 627                         NULL);
 628 
 629                     // no way to die
 630                     if (n > 0)
 631                         utf8_jvmErrorMsg[min(cbErrorMsg - 1, n)] = '\0';
 632                 }


 633 
 634                 if (n <= 0) {
 635                     strncpy(utf8_jvmErrorMsg, "Secondary error while OS message extraction", cbErrorMsg);
 636                     // truncate if too long
 637                     utf8_jvmErrorMsg[cbErrorMsg - 1] = '\0';
 638                     n = strlen(utf8_jvmErrorMsg);
 639                 }
 640             }
 641             free(utf16_osErrorMsg);
 642         }
 643     }
 644     return n;
 645 }