mirror of
https://github.com/git/git.git
synced 2026-03-13 10:23:30 +01:00
Handle fstat() of a socket descriptor.
GetFileInformationByHandle() fails if it is passed a WinSock handle. Fortunately, the failure can be distinguished by the error code, and we can in this case pretend that the fstat() was actually successful. This is a valid thing to do: Calling fstat() on a descriptor makes only sense if either the caller needs information on the file (in which case we would not reach this error condition), or if it wants to distinguish a socket from a file (which implies that the caller will have to test st_mode, which happens to be the only field that we can fill in). Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
This commit is contained in:
@@ -123,8 +123,14 @@ int git_fstat(int fd, struct stat *buf)
|
||||
{
|
||||
HANDLE fh = (HANDLE)_get_osfhandle(fd);
|
||||
BY_HANDLE_FILE_INFORMATION fdata;
|
||||
char dummy[sizeof(void*)];
|
||||
int s = sizeof(void*);
|
||||
|
||||
if (fh != INVALID_HANDLE_VALUE && GetFileInformationByHandle(fh, &fdata)) {
|
||||
if (fh == INVALID_HANDLE_VALUE) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (GetFileInformationByHandle(fh, &fdata)) {
|
||||
int fMode = S_IREAD;
|
||||
if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
fMode |= S_IFDIR;
|
||||
@@ -145,7 +151,22 @@ int git_fstat(int fd, struct stat *buf)
|
||||
buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
|
||||
return 0;
|
||||
}
|
||||
errno = EBADF;
|
||||
switch (GetLastError()) {
|
||||
case ERROR_INVALID_FUNCTION:
|
||||
/* check for socket */
|
||||
if (getsockopt((int)fh, SOL_SOCKET, SO_KEEPALIVE, dummy, &s) &&
|
||||
WSAGetLastError() == WSAENOTSOCK)
|
||||
goto badf;
|
||||
memset(buf, sizeof(*buf), 0);
|
||||
buf->st_mode = S_IREAD|S_IWRITE;
|
||||
buf->st_mode |= 0x140000; /* S_IFSOCK */
|
||||
return 0;
|
||||
default:
|
||||
case ERROR_INVALID_HANDLE:
|
||||
badf:
|
||||
errno = EBADF;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user