Re: Another rsync over ssh hang (repeatable, with 2.4.1 on both ends)

From: Ton Hospel (linux-kernel@ton.iguana.be)
Date: Sun Mar 04 2001 - 16:28:45 EST


Notice also that by default ssh opens stdin/stdout blocking, and can
relatively easily deadlock if the pipes it talks over really want to do
a write before a read or the other way round.

You can try compile the following file, put it in the same directory
as ssh, and then run rsync over this instead of plain ssh (I use it in
fact in all places where I connect to ssh over pipes).

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#ifndef HAVE_NO_UNISTD_H
# include <unistd.h>
#endif /* HAVE_NO_UNISTD_H */
#include <fcntl.h>

static char ssh[] = "ssh";

int unblock(FILE *fp) {
    int fd, rc, flags;

    fd = fileno(fp);
    if (isatty(fd)) return 0;

    flags = fcntl(fd, F_GETFL, 0);
    if (flags < 0) {
        fprintf(stderr, "Could not query fd %d: %s\n", fd, strerror(errno));
        return 1;
    }
    rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    if (rc < 0) {
        fprintf(stderr, "Could not unblock fd %d: %s\n", fd, strerror(errno));
        return 1;
    }
    return 0;
}

int main(int argc, char **argv) {
    int rc;
    char *ptr, *work;

    if (unblock(stdin)) return 1;
    if (unblock(stdout)) return 1;
    if (unblock(stderr)) return 1;
    
    ptr = strrchr(argv[0], '/');
    if (ptr == NULL) ptr = argv[0];
    else ptr++;
    work = malloc(ptr-argv[0]+sizeof(ssh));
    if (!work) {
        fprintf(stderr, "Out of memory. Buy more ?\n");
        return 1;
    }
    memcpy(work, argv[0], ptr-argv[0]);
    memcpy(work+(ptr-argv[0]), ssh, sizeof(ssh));
    argv[0] = work;
    rc = execvp(work, argv);
    fprintf(stderr, "Could not exec %.300s: %s\n", work, strerror(errno));
    return rc;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Mar 07 2001 - 21:00:16 EST