Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e979585

Browse files
committedMay 9, 2020
Improve FreeBSD support:
- include posix_openpt() usage patch - add workaround for readdir() issue: #211 - fix few warnings
1 parent a7e1038 commit e979585

File tree

1 file changed

+57
-21
lines changed

1 file changed

+57
-21
lines changed
 

‎sshfs.c

+57-21
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <netdb.h>
3333
#include <signal.h>
3434
#include <sys/uio.h>
35+
#include <sys/param.h>
3536
#include <sys/types.h>
3637
#include <sys/time.h>
3738
#include <sys/wait.h>
@@ -311,6 +312,7 @@ struct sshfs {
311312
int unrel_append;
312313
int fstat_workaround;
313314
int createmode_workaround;
315+
int readdir_workaround;
314316
int transform_symlinks;
315317
int follow_symlinks;
316318
int no_check_root;
@@ -542,6 +544,7 @@ static struct fuse_opt workaround_opts[] = {
542544
SSHFS_OPT("none", truncate_workaround, 0),
543545
SSHFS_OPT("none", buflimit_workaround, 0),
544546
SSHFS_OPT("none", fstat_workaround, 0),
547+
SSHFS_OPT("none", readdir_workaround, 0),
545548
SSHFS_OPT("rename", rename_workaround, 1),
546549
SSHFS_OPT("norename", rename_workaround, 0),
547550
SSHFS_OPT("renamexdev", renamexdev_workaround, 1),
@@ -554,6 +557,8 @@ static struct fuse_opt workaround_opts[] = {
554557
SSHFS_OPT("nofstat", fstat_workaround, 0),
555558
SSHFS_OPT("createmode", createmode_workaround, 1),
556559
SSHFS_OPT("nocreatemode", createmode_workaround, 0),
560+
SSHFS_OPT("readdir", readdir_workaround, 1),
561+
SSHFS_OPT("noreaddir", readdir_workaround, 0),
557562
FUSE_OPT_END
558563
};
559564

@@ -1106,7 +1111,11 @@ static int pty_master(char **name)
11061111
{
11071112
int mfd;
11081113

1114+
#ifdef __FreeBSD__
1115+
mfd = posix_openpt(O_RDWR | O_NOCTTY);
1116+
#else
11091117
mfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);
1118+
#endif
11101119
if (mfd == -1) {
11111120
perror("failed to open pty");
11121121
return -1;
@@ -1886,12 +1895,20 @@ static void *sshfs_init(struct fuse_conn_info *conn,
18861895
if (conn->capable & FUSE_CAP_ASYNC_READ)
18871896
sshfs.sync_read = 1;
18881897

1889-
// These workarounds require the "path" argument.
1890-
cfg->nullpath_ok = !(sshfs.truncate_workaround || sshfs.fstat_workaround);
1891-
1892-
// When using multiple connections, release() needs to know the path
1893-
if (sshfs.max_conns > 1)
1898+
/* These workarounds require the "path" argument:
1899+
* - truncate_workaround
1900+
* - fstat_workaround
1901+
* - readdir_workaround
1902+
* Also it required when using multiple connections: release()
1903+
* needs to know the path.
1904+
*/
1905+
if (sshfs.truncate_workaround ||
1906+
sshfs.fstat_workaround ||
1907+
sshfs.readdir_workaround ||
1908+
sshfs.max_conns > 1)
18941909
cfg->nullpath_ok = 0;
1910+
else
1911+
cfg->nullpath_ok = 1;
18951912

18961913
// Lookup of . and .. is supported
18971914
conn->capable |= FUSE_CAP_EXPORT_SUPPORT;
@@ -2198,6 +2215,7 @@ static int sshfs_req_pending(struct request *req)
21982215
static int sftp_readdir_async(struct conn *conn, struct buffer *handle,
21992216
void *buf, off_t offset, fuse_fill_dir_t filler)
22002217
{
2218+
(void) offset;
22012219
int err = 0;
22022220
int outstanding = 0;
22032221
int max = READDIR_START;
@@ -2276,6 +2294,7 @@ static int sftp_readdir_async(struct conn *conn, struct buffer *handle,
22762294
static int sftp_readdir_sync(struct conn *conn, struct buffer *handle,
22772295
void *buf, off_t offset, fuse_fill_dir_t filler)
22782296
{
2297+
(void) offset;
22792298
int err;
22802299
assert(offset == 0);
22812300
do {
@@ -2321,14 +2340,38 @@ static int sshfs_opendir(const char *path, struct fuse_file_info *fi)
23212340
return err;
23222341
}
23232342

2343+
static int sshfs_releasedir(const char *path, struct fuse_file_info *fi)
2344+
{
2345+
(void) path;
2346+
int err;
2347+
struct dir_handle *handle;
2348+
2349+
handle = (struct dir_handle*) fi->fh;
2350+
err = sftp_request(handle->conn, SSH_FXP_CLOSE, &handle->buf, 0, NULL);
2351+
pthread_mutex_lock(&sshfs.lock);
2352+
handle->conn->dir_count--;
2353+
pthread_mutex_unlock(&sshfs.lock);
2354+
buf_free(&handle->buf);
2355+
g_free(handle);
2356+
return err;
2357+
}
2358+
23242359
static int sshfs_readdir(const char *path, void *dbuf, fuse_fill_dir_t filler,
23252360
off_t offset, struct fuse_file_info *fi,
23262361
enum fuse_readdir_flags flags)
23272362
{
2328-
(void) path; (void) flags;
2363+
(void) flags;
23292364
int err;
23302365
struct dir_handle *handle;
23312366

2367+
if (sshfs.readdir_workaround) {
2368+
if (path == NULL)
2369+
return -EIO;
2370+
err = sshfs_opendir(path, fi);
2371+
if (err)
2372+
return err;
2373+
}
2374+
23322375
handle = (struct dir_handle*) fi->fh;
23332376

23342377
if (sshfs.sync_readdir)
@@ -2338,22 +2381,9 @@ static int sshfs_readdir(const char *path, void *dbuf, fuse_fill_dir_t filler,
23382381
err = sftp_readdir_async(handle->conn, &handle->buf, dbuf,
23392382
offset, filler);
23402383

2341-
return err;
2342-
}
2384+
if (sshfs.readdir_workaround)
2385+
err = sshfs_releasedir(path, fi);
23432386

2344-
static int sshfs_releasedir(const char *path, struct fuse_file_info *fi)
2345-
{
2346-
(void) path;
2347-
int err;
2348-
struct dir_handle *handle;
2349-
2350-
handle = (struct dir_handle*) fi->fh;
2351-
err = sftp_request(handle->conn, SSH_FXP_CLOSE, &handle->buf, 0, NULL);
2352-
pthread_mutex_lock(&sshfs.lock);
2353-
handle->conn->dir_count--;
2354-
pthread_mutex_unlock(&sshfs.lock);
2355-
buf_free(&handle->buf);
2356-
g_free(handle);
23572387
return err;
23582388
}
23592389

@@ -3616,6 +3646,7 @@ static void usage(const char *progname)
36163646
" [no]buflimit fix buffer fillup bug in server (default: off)\n"
36173647
" [no]fstat always use stat() instead of fstat() (default: off)\n"
36183648
" [no]createmode always pass mode 0 to create (default: off)\n"
3649+
" [no]readdir always open/read/close dir on readdir (default: on for BSD)\n"
36193650
" -o idmap=TYPE user/group ID mapping (default: " IDMAP_DEFAULT ")\n"
36203651
" none no translation of the ID space\n"
36213652
" user only translate UID/GID of connecting user\n"
@@ -4173,6 +4204,11 @@ int main(int argc, char *argv[])
41734204
sshfs.truncate_workaround = 0;
41744205
sshfs.buflimit_workaround = 0;
41754206
sshfs.createmode_workaround = 0;
4207+
#ifdef BSD
4208+
sshfs.readdir_workaround = 1;
4209+
#else
4210+
sshfs.readdir_workaround = 0;
4211+
#endif
41764212
sshfs.ssh_ver = 2;
41774213
sshfs.progname = argv[0];
41784214
sshfs.max_conns = 1;

0 commit comments

Comments
 (0)
Please sign in to comment.