mirror of
https://github.com/git/git.git
synced 2026-01-09 17:46:37 +00:00
Merge branch 'jk/pipe-command-nonblock' into maint
Fix deadlocks between main Git process and subprocess spawned via the pipe_command() API, that can kill "git add -p" that was reimplemented in C recently. * jk/pipe-command-nonblock: pipe_command(): mark stdin descriptor as non-blocking pipe_command(): handle ENOSPC when writing to a pipe pipe_command(): avoid xwrite() for writing to pipe git-compat-util: make MAX_IO_SIZE define globally available nonblock: support Windows compat: add function to enable nonblocking pipes
This commit is contained in:
50
compat/nonblock.c
Normal file
50
compat/nonblock.c
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "git-compat-util.h"
|
||||
#include "nonblock.h"
|
||||
|
||||
#ifdef O_NONBLOCK
|
||||
|
||||
int enable_pipe_nonblock(int fd)
|
||||
{
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
if (flags < 0)
|
||||
return -1;
|
||||
flags |= O_NONBLOCK;
|
||||
return fcntl(fd, F_SETFL, flags);
|
||||
}
|
||||
|
||||
#elif defined(GIT_WINDOWS_NATIVE)
|
||||
|
||||
#include "win32.h"
|
||||
|
||||
int enable_pipe_nonblock(int fd)
|
||||
{
|
||||
HANDLE h = (HANDLE)_get_osfhandle(fd);
|
||||
DWORD mode;
|
||||
DWORD type = GetFileType(h);
|
||||
if (type == FILE_TYPE_UNKNOWN && GetLastError() != NO_ERROR) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (type != FILE_TYPE_PIPE)
|
||||
BUG("unsupported file type: %lu", type);
|
||||
if (!GetNamedPipeHandleState(h, &mode, NULL, NULL, NULL, NULL, 0)) {
|
||||
errno = err_win_to_posix(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
mode |= PIPE_NOWAIT;
|
||||
if (!SetNamedPipeHandleState(h, &mode, NULL, NULL)) {
|
||||
errno = err_win_to_posix(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int enable_pipe_nonblock(int fd)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
9
compat/nonblock.h
Normal file
9
compat/nonblock.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef COMPAT_NONBLOCK_H
|
||||
#define COMPAT_NONBLOCK_H
|
||||
|
||||
/*
|
||||
* Enable non-blocking I/O for the pipe specified by the passed-in descriptor.
|
||||
*/
|
||||
int enable_pipe_nonblock(int fd);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user