Repository: JuliaLang/julia
File: src/support/ios.c (C)

Code before:
    s->fpos = 0;
    if (!rd)
        s->readable = 0;
    if (!wr)
        s->writable = 0;
    return s;
 open_file_err:
    s->fd = -1;
    return NULL;
}

#ifdef _OS_WINDOWS_
const wchar_t *ios_utf8_to_wchar(const char *str) {
    /* Fast-path empty strings, as MultiByteToWideChar() returns zero for them. */
    if (str[0] == '\0') {
        wchar_t *wstr = (wchar_t *)malloc(sizeof(wchar_t));
        wstr[0] = L'\0';
        return wstr;
    }
    size_t len = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
    if (!len)
        return NULL;
    wchar_t *wstr = (wchar_t *)malloc(len * sizeof(wchar_t));
    if (!wstr || !MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, len))
        return NULL;
    return wstr;
}
#endif // _OS_WINDOWS_

// Portable ios analogue of mkstemp: modifies fname to replace
// trailing XXXX's with unique ID and returns the file handle s
// for writing and reading.
ios_t *ios_mkstemp(ios_t *s, char *fname)
{
    int fd;
    // would be better to use a libuv function once it exists (see libuv/libuv#322)
#ifdef _OS_WINDOWS_
    size_t wlen = MultiByteToWideChar(CP_UTF8, 0, fname, -1, NULL, 0);
    if (!wlen) goto open_file_err;
    wchar_t *fname_w = (wchar_t*)alloca(wlen*sizeof(wchar_t));
    if (!MultiByteToWideChar(CP_UTF8, 0, fname, -1, fname_w, wlen) ||
        !_wmktemp(fname_w) ||
        !WideCharToMultiByte(CP_UTF8, 0, fname_w, -1, fname, strlen(fname)+1,
                             NULL, NULL))
        goto open_file_err;
    fd = _wopen(fname_w, O_CREAT|O_TRUNC|O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD | _S_IWRITE);
#else
    fd = mkstemp(fname);
#endif
    ios_fd(s, fd, 1, 1);
    if (fd == -1)

Review comment (suggestion):
```suggestion
    ssize_t wlen = uv_wtf8_length_as_utf16(str);
    wchar_t *wstr = (wchar_t *)malloc_s(sizeof(wchar_t) * wlen);
    uv_wtf8_to_utf16(str, wstr, wlen);
    return wstr;
```
This is a more reliable (and concise) version of MultiByteToWideChar now provided by libuv

Code after:
    s = ios_fd(s, fd, 1, 1);
    s->fpos = 0;
    if (!rd)
        s->readable = 0;
    if (!wr)
        s->writable = 0;
    return s;
 open_file_err:
    s->fd = -1;
    return NULL;
}

#ifdef _OS_WINDOWS_
const wchar_t *ios_utf8_to_wchar(const char *str) {
    ssize_t wlen = uv_wtf8_length_as_utf16(str);
    wchar_t *wstr = (wchar_t *)malloc_s(sizeof(wchar_t) * wlen);
    uv_wtf8_to_utf16(str, wstr, wlen);
    return wstr;
}
#endif // _OS_WINDOWS_

// Portable ios analogue of mkstemp: modifies fname to replace
// trailing XXXX's with unique ID and returns the file handle s
// for writing and reading.
ios_t *ios_mkstemp(ios_t *s, char *fname)
{
    int fd;
    // would be better to use a libuv function once it exists (see libuv/libuv#322)
#ifdef _OS_WINDOWS_
    size_t wlen = MultiByteToWideChar(CP_UTF8, 0, fname, -1, NULL, 0);
    if (!wlen) goto open_file_err;
    wchar_t *fname_w = (wchar_t*)alloca(wlen*sizeof(wchar_t));
    if (!MultiByteToWideChar(CP_UTF8, 0, fname, -1, fname_w, wlen) ||
        !_wmktemp(fname_w) ||
        !WideCharToMultiByte(CP_UTF8, 0, fname_w, -1, fname, strlen(fname)+1,
                             NULL, NULL))
        goto open_file_err;
    fd = _wopen(fname_w, O_CREAT|O_TRUNC|O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD | _S_IWRITE);
#else
    fd = mkstemp(fname);
#endif
    ios_fd(s, fd, 1, 1);
    if (fd == -1)
        goto open_file_err;
    return s;
open_file_err:
    s->fd = -1;
    return NULL;
}

ios_t *ios_mem(ios_t *s, size_t initsize)