Project

General

Profile

Feature #12653 » 0001-Use-wide-WinAPI-for-rb_w32_getcwd.patch

davispuh (Dāvis Mosāns), 08/03/2016 06:32 PM

View differences:

win32/win32.c
4590 4590
rb_w32_getcwd(char *buffer, int size)
4591 4591
{
4592 4592
    char *p = buffer;
4593
    int len;
4593
    WCHAR *wbuffer;
4594
    int len, r;
4595
    VALUE rp;
4594 4596

  
4595
    len = GetCurrentDirectory(0, NULL);
4597
    len = GetCurrentDirectoryW(0, NULL);
4596 4598
    if (!len) {
4597 4599
	errno = map_errno(GetLastError());
4598 4600
	return NULL;
4599 4601
    }
4600 4602

  
4601
    if (p) {
4602
	if (size < len) {
4603
	    errno = ERANGE;
4604
	    return NULL;
4605
	}
4603
    if (buffer && size < len) {
4604
        errno = ERANGE;
4605
        return NULL;
4606 4606
    }
4607
    else {
4608
	p = malloc(len);
4609
	size = len;
4610
	if (!p) {
4611
	    errno = ENOMEM;
4612
	    return NULL;
4613
	}
4607

  
4608
    wbuffer = malloc(len * sizeof(WCHAR));
4609
    if (!wbuffer) {
4610
        errno = ENOMEM;
4611
        return NULL;
4614 4612
    }
4615 4613

  
4616
    if (!GetCurrentDirectory(size, p)) {
4614
    if (!GetCurrentDirectoryW(len, wbuffer)) {
4617 4615
	errno = map_errno(GetLastError());
4618
	if (!buffer)
4619
	    free(p);
4616
        free(wbuffer);
4617
        return NULL;
4618
    }
4619

  
4620
    if (!p) {
4621
        size = WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, NULL, 0, NULL, NULL);
4622
        p = malloc(size);
4623
        if (!p) {
4624
            errno = ENOMEM;
4625
            return NULL;
4626
        }
4627
    }
4628

  
4629
    r = WideCharToMultiByte(CP_UTF8, 0, wbuffer, -1, p, size, NULL, NULL);
4630

  
4631
    free(wbuffer);
4632

  
4633
    if (r == 0) {
4634
        DWORD lastError = GetLastError();
4635
        if (!buffer) {
4636
            free(p);
4637
        }
4638
        if (lastError == ERROR_INSUFFICIENT_BUFFER) {
4639
            errno = ERANGE;
4640
            return NULL;
4641
        }
4642
        errno = map_errno(lastError);
4620 4643
        return NULL;
4621 4644
    }
4622 4645

  
4623
    translate_char(p, '\\', '/', filecp());
4646
    translate_char(p, '\\', '/', CP_UTF8);
4647

  
4648
    rp = rb_str_conv_enc_opts(rb_utf8_str_new_cstr(p), NULL, rb_filesystem_encoding(), ECONV_UNDEF_REPLACE, Qnil);
4649
    if (!buffer) {
4650
      free(p);
4651
      p = strdup(RSTRING_PTR(rp));
4652
    } else {
4653
      if (RSTRING_LEN(rp) >= size) {
4654
        errno = ERANGE;
4655
        return NULL;
4656
      }
4657
      strncpy(p, RSTRING_PTR(rp), size - 1);
4658
      p[size - 1] = '\0';
4659
    }
4624 4660

  
4625 4661
    return p;
4626 4662
}
4627
-