Hi Bastian,
thanks a lot for your help. I have already opened a bug report on Launchpad:
https://bugs.launchpad.net/ubuntu/+source/reprepro/+bug/2047775, but I got no
answer so far. Unfortunately, the proposed change does not work properly when
mirroring the main component of the Ubuntu Jammy repository:
Shutting down aptmethods...
Installing (and possibly deleting) packages...
/*stdin*\ : Read error (39) : premature end
Segmentation fault (core dumped)
The best result, we were able to achieve, was to solely modify the timeout
entry in the poll function from 0 to -1 and to keep the rest of the code as it
is. This solves the hanging issue, but causes "/*stdin*\ : Read error (39) :
premature end". Fortunately, the exports succeeds and seems to be ok. We are
currently not able to remove the "Premature End" error and have no idea where
it is being caused. We cannot guarantee the fully correctness of the following
code. We are already using it in practice. It looks good so far:
static inline retvalue drain_pipe_fd(struct compressedfile *file, int *errno_p,
const char **msg_p) {
int e = 0;
struct pollfd pollfd = {
file->fd,
POLLIN,
0
};
unsigned char buffer[4096] = {};
while ((e = poll(, 1, -1)) > 0) {
e = read(file->fd, buffer, 4096);
if (e <= 0)
break;
}
if (e < 0) {
*errno_p = e;
*msg_p = strerror(file->error);
return RET_ERRNO(e);
}
return RET_OK;
}
static retvalue uncompress_commonclose(struct compressedfile *file, int
*errno_p, const char **msg_p) {
retvalue result;
int ret;
int e;
pid_t pid;
int status;
int output_fd;
#define ERRORBUFFERSIZE 100
static char errorbuffer[ERRORBUFFERSIZE];
if (file == NULL)
return RET_OK;
if (file->external) {
free(file->intermediate.buffer);
if (file->pipeinfd != -1)
(void)close(file->pipeinfd);
// Drain the child's stdout in the unlikely case it's blocking
on it
e = drain_pipe_fd(file, errno_p, msg_p);
if (e != RET_OK)
return e;
output_fd = file->fd;
file->fd = file->infd;
result = RET_OK;
if (file->pid <= 0) {
(void)close(output_fd);
return RET_OK;
}
do {
if (interrupted()) {
*errno_p = EINTR;
*msg_p = "Interrupted";
result = RET_ERROR_INTERRUPTED;
}
pid = waitpid(file->pid, , 0);
e = errno;
} while (pid == -1 && (e == EINTR || e == EAGAIN));
(void)close(output_fd);
[...]
}
Regards,
Christoph