diff --git a/src/vol/ntops.c b/src/vol/ntops.c index cf546b4eb6..905c4e7c54 100644 --- a/src/vol/ntops.c +++ b/src/vol/ntops.c @@ -116,11 +116,44 @@ nt_open(char *name, int flags, int mode) break; } + retry: fh = CreateFile(name, nt_access, nt_share, NULL, nt_create, FandA, NULL); - if (fh == INVALID_HANDLE_VALUE) { - fh = INVALID_FD; - errno = nterr_nt2unix(GetLastError(), EBADF); + DWORD gle = GetLastError(); + + if (gle == ERROR_PATH_NOT_FOUND) { + /* + * one or more of the directories in the path + * does not exist. We must create them and + * try again to create the file. + */ + char * p; + + for (p=name; *p && *p != OS_DIRSEPC; p++); + while (*p == OS_DIRSEPC) p++; /* ignore the first dirsep */ + for (; *p; p++) { + if (*p == OS_DIRSEPC) { + *p = '\0'; + if (CreateDirectory(name, NULL)) + gle = 0; + else + gle = GetLastError(); + *p = OS_DIRSEPC; + if (gle != ERROR_SUCCESS && + gle != ERROR_ALREADY_EXISTS) { + /* The directory creation failed. */ + fh = INVALID_FD; + break; + } else { + while (*(p+1) == OS_DIRSEPC) p++; + } + } + } + + if (!*p) /* successful creation of the path */ + goto retry; + } + errno = nterr_nt2unix(gle, EBADF); } return fh; } @@ -187,8 +220,11 @@ nt_read(FD_t fd, char *buf, size_t size) code = ReadFile((HANDLE) fd, (void *)buf, (DWORD) size, &nbytes, NULL); if (!code) { - errno = nterr_nt2unix(GetLastError(), EBADF); - return -1; + DWORD gle = GetLastError(); + if (gle != ERROR_HANDLE_EOF) { + errno = nterr_nt2unix(GetLastError(), EBADF); + return -1; + } } return (int)nbytes; } @@ -214,8 +250,11 @@ nt_pread(FD_t fd, void * buf, size_t count, afs_foff_t offset) code = ReadFile((HANDLE) fd, (void *)buf, (DWORD) count, &nbytes, &overlap); if (!code) { - errno = nterr_nt2unix(GetLastError(), EBADF); - return -1; + DWORD gle = GetLastError(); + if (gle != ERROR_HANDLE_EOF) { + errno = nterr_nt2unix(GetLastError(), EBADF); + return -1; + } } return (ssize_t)nbytes; }