Example #1
0
int S_windows_open_exclusive(char *who, char *path, int flags) {
  HANDLE hfile;
  int fd;
  DWORD access = 0;
  DWORD crdisp = 0;

 /* could implement this later with more difficulty */
  if ((flags & (O_TRUNC|O_CREAT)) == (O_TRUNC|O_CREAT))
    S_error("open_exclusive", "O_TRUNC|O_CREAT not supported");

  if (flags & O_RDWR) access |= GENERIC_READ|GENERIC_WRITE;
  if (flags & O_RDONLY) access |= GENERIC_READ;
  if (flags & O_WRONLY) access |= GENERIC_WRITE;

  if (flags & O_CREAT) crdisp = OPEN_ALWAYS;
  if (flags & O_TRUNC) crdisp = TRUNCATE_EXISTING;
  
  hfile = CreateFile(path, access, 0, (SECURITY_ATTRIBUTES *)0,
                     crdisp, FILE_ATTRIBUTE_NORMAL, (HANDLE)0);
  if (hfile == INVALID_HANDLE_VALUE)
    S_error1(who, "~a", s_ErrorString(GetLastError()));

  flags &= O_RDONLY|O_WRONLY|O_RDWR|O_APPEND;
  fd = _open_osfhandle((long)hfile, flags);
  if (fd == -1) S_error(who, "open_osfhandle failed");

  return fd;
}
Example #2
0
/* raises an exception if insufficient space cannot be malloc'd.
   returns NULL if utf-8 path cannot be converted to wchars.
   otherwise returns a freshly allocated, wide-character version
   of inpath with ~ (home directory) prefix expanded, if possible */
wchar_t *S_malloc_wide_pathname(const char *inpath) {
    size_t n;
    char *path;
    wchar_t *wpath;

    path = S_malloc_pathname(inpath);
    n = strlen(path) + 1;
    /* counting on utf-8 representation having at least as many chars as wchar representation */
    if ((wpath = (wchar_t *)malloc(n * sizeof(wchar_t))) == NULL) {
        free(path);
        S_error("expand_pathname", "malloc failed");
    }
    if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, (int)n) == 0) {
        free(path);
        free(wpath);
        return NULL;
    }
    free(path);
    return wpath;
}
Example #3
0
/* primitive version of flock compatible with Windows 95/98/ME.  A better
   version could be implemented for Windows NT/2000/XP using LockFileEx. */
int S_windows_flock(int fd, int operation) {
  HANDLE hfile = (HANDLE)_get_osfhandle(fd);

  switch (operation) {
    case LOCK_EX|LOCK_NB:
      if (LockFile(hfile, 0, 0, 0x0fffffff, 0)) return 0;
      errno = EWOULDBLOCK;
      return -1;
    case LOCK_EX:
      while (LockFile(hfile, 0, 0, 0x0fffffff, 0) == 0) Sleep(10);
      return 0;
    case LOCK_SH:
    case LOCK_SH|LOCK_NB:
      S_error("flock", "shared locks unsupported");
      return -1;
    case LOCK_UN:
    case LOCK_UN|LOCK_NB:
      UnlockFile(hfile, 0, 0, 0x0fffffff, 0);
      return 0;
    default:
      errno = EINVAL;
      return -1;
  }
}
Example #4
0
/* raises an exception if insufficient space cannot be malloc'd.
   otherwise returns a freshly allocated version of inpath with ~ (home directory)
   prefix expanded, if possible */
char *S_malloc_pathname(const char *inpath) {
    char *outpath;
    const char *ip;

#ifdef WIN32
    if (*inpath == '~' && (*(ip = inpath + 1) == 0 || DIRMARKERP(*ip))) {
        const char *homedrive, *homepath;
        size_t n1, n2, n3;

        if ((homedrive = getenv("HOMEDRIVE")) != NULL && (homepath = getenv("HOMEPATH")) != NULL) {
            n1 = strlen(homedrive);
            n2 = strlen(homepath);
            n3 = strlen(ip) + 1;
            if ((outpath = malloc(n1 + n2 + n3)) == NULL) S_error("expand_pathname", "malloc failed");
            memcpy(outpath, homedrive, n1);
            memcpy(outpath + n1, homepath, n2);
            memcpy(outpath + n1 + n2, ip, n3);
            return outpath;
        }
    }
#else /* WIN32 */
    if (*inpath == '~') {
        const char *dir;
        size_t n1, n2;
        struct passwd *pwent;
        if (*(ip = inpath + 1) == 0 || DIRMARKERP(*ip)) {
            if ((dir = getenv("HOME")) == NULL)
                if ((pwent = getpwuid(getuid())) != NULL)
                    dir = pwent->pw_dir;
        } else {
            char *userbuf;
            const char *user_start = ip;
            do {
                ip += 1;
            }
            while (*ip != 0 && !DIRMARKERP(*ip));
            if ((userbuf = malloc(ip - user_start + 1)) == NULL) S_error("expand_pathname", "malloc failed");
            memcpy(userbuf, user_start, ip - user_start);
            userbuf[ip - user_start] = 0;
            dir = (pwent = getpwnam(userbuf)) != NULL ? pwent->pw_dir : NULL;
            free(userbuf);
        }
        if (dir != NULL) {
            n1 = strlen(dir);
            n2 = strlen(ip) + 1;
            if ((outpath = malloc(n1 + n2)) == NULL) S_error("expand_pathname", "malloc failed");
            memcpy(outpath, dir, n1);
            memcpy(outpath + n1, ip, n2);
            return outpath;
        }
    }
#endif /* WIN32 */

    /* if no ~ or tilde dir can't be found, copy inpath */
    {
        size_t n = strlen(inpath) + 1;
        outpath = (char *)malloc(n);
        memcpy(outpath, inpath, n);
        return outpath;
    }
}