aboutsummaryrefslogtreecommitdiff
path: root/sshfs.c
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2006-01-31 18:34:38 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2006-01-31 18:34:38 +0000
commit89da93d07eeb3629858011358a4f07ded2f64df0 (patch)
treecfd04a454b32d33f10471f3d8ea4f032eb2ccfd0 /sshfs.c
parentcb4239036ada3acfbf7a425ef9e74d7ace7c9d3a (diff)
downloadsshfs-89da93d07eeb3629858011358a4f07ded2f64df0.tar
sshfs-89da93d07eeb3629858011358a4f07ded2f64df0.tar.gz
sshfs-89da93d07eeb3629858011358a4f07ded2f64df0.tar.bz2
sshfs-89da93d07eeb3629858011358a4f07ded2f64df0.zip
fix
Diffstat (limited to 'sshfs.c')
-rw-r--r--sshfs.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/sshfs.c b/sshfs.c
index 9e5efd9..e0ce4bf 100644
--- a/sshfs.c
+++ b/sshfs.c
@@ -22,6 +22,7 @@
#include <pthread.h>
#include <netdb.h>
#include <signal.h>
+#include <sys/uio.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/socket.h>
@@ -97,6 +98,8 @@
#define SFTP_SERVER_PATH "/usr/lib/sftp-server"
+#define SSHNODELAY_SO "sshnodelay.so"
+
struct buffer {
uint8_t *p;
size_t len;
@@ -176,6 +179,7 @@ struct sshfs {
unsigned local_uid;
int remote_uid_detected;
unsigned blksize;
+ char *progname;
};
static struct sshfs sshfs;
@@ -612,30 +616,46 @@ static void ssh_add_arg(const char *arg)
_exit(1);
}
-static void do_ssh_nodelay_workaround(void)
+static int do_ssh_nodelay_workaround(void)
{
- FILE *tmp = tmpfile();
- int fd = tmp ? dup(fileno(tmp)) : -1;
- extern const char sshnodelay_so[];
- extern const int sshnodelay_so_size;
char *oldpreload = getenv("LD_PRELOAD");
char *newpreload;
+ char sopath[PATH_MAX];
+ int res;
- fclose(tmp);
- if (fd == -1 || write(fd, sshnodelay_so, sshnodelay_so_size) == -1) {
- fprintf(stderr, "warning: failed to write file for ssh nodelay workaround\n");
- return;
+ snprintf(sopath, sizeof(sopath), "%s/%s", LIBDIR, SSHNODELAY_SO);
+ res = access(sopath, R_OK);
+ if (res == -1) {
+ char *s;
+ if (!realpath(sshfs.progname, sopath))
+ return -1;
+
+ s = strrchr(sopath, '/');
+ if (!s)
+ s = sopath;
+ else
+ s++;
+
+ if (s + strlen(SSHNODELAY_SO) >= sopath + sizeof(sopath))
+ return -1;
+
+ strcpy(s, SSHNODELAY_SO);
+ res = access(sopath, R_OK);
+ if (res == -1) {
+ fprintf(stderr, "sshfs: cannot find %s\n", SSHNODELAY_SO);
+ return -1;
+ }
}
- newpreload = g_strdup_printf("%s%s/proc/self/fd/%i",
+ newpreload = g_strdup_printf("%s%s%s",
oldpreload ? oldpreload : "",
- oldpreload ? " " : "", fd);
+ oldpreload ? " " : "",
+ sopath);
- if (!newpreload || setenv("LD_PRELOAD", newpreload, 1) == -1) {
+ if (!newpreload || setenv("LD_PRELOAD", newpreload, 1) == -1)
fprintf(stderr, "warning: failed set LD_PRELOAD for ssh nodelay workaround\n");
- close(fd);
- }
g_free(newpreload);
+ return 0;
}
static int start_ssh(void)
@@ -658,8 +678,8 @@ static int start_ssh(void)
} else if (pid == 0) {
int devnull;
- if (sshfs.nodelay_workaround)
- do_ssh_nodelay_workaround();
+ if (sshfs.nodelay_workaround && do_ssh_nodelay_workaround() == -1)
+ fprintf(stderr, "warning: ssh nodelay workaround disabled\n");
devnull = open("/dev/null", O_WRONLY);
@@ -2214,6 +2234,7 @@ int main(int argc, char *argv[])
sshfs.nodelay_workaround = 1;
sshfs.rename_workaround = 1;
sshfs.ssh_ver = 2;
+ sshfs.progname = argv[0];
ssh_add_arg("ssh");
ssh_add_arg("-x");
ssh_add_arg("-a");