mirror of
https://git.openafs.org/openafs.git
synced 2025-01-21 00:10:15 +00:00
vol: Fix ntops to provide expected semantics
nt_open() can be asked to open a file with a path containing directory components that do not yet exist. Modify nt_open() to automatically create directories if necessary. nt_read() and nt_pread() should not treat partial reads due to reaching EOF as an error. Instead, return the bytes read. Change-Id: If088393a842d6f6d7ad901345e94e92d23f2321c Reviewed-on: http://gerrit.openafs.org/3666 Reviewed-by: Derrick Brashear <shadow@dementia.org> Tested-by: BuildBot <buildbot@rampaginggeek.com>
This commit is contained in:
parent
98f633c60d
commit
714b3ffb22
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user