~ubuntu-branches/ubuntu/trusty/rsync/trusty

« back to all changes in this revision

Viewing changes to syscall.c

  • Committer: Package Import Robot
  • Author(s): Paul Slootman
  • Date: 2013-10-27 12:01:10 UTC
  • mfrom: (1.3.2)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: package-import@ubuntu.com-20131027120110-eyksys8yzm1siekf
Tags: upstream-3.1.0
ImportĀ upstreamĀ versionĀ 3.1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 *
5
5
 * Copyright (C) 1998 Andrew Tridgell
6
6
 * Copyright (C) 2002 Martin Pool
7
 
 * Copyright (C) 2003-2009 Wayne Davison
 
7
 * Copyright (C) 2003-2013 Wayne Davison
8
8
 *
9
9
 * This program is free software; you can redistribute it and/or modify
10
10
 * it under the terms of the GNU General Public License as published by
29
29
#include <sys/attr.h>
30
30
#endif
31
31
 
 
32
#if defined HAVE_SYS_FALLOCATE && !defined HAVE_FALLOCATE
 
33
#include <sys/syscall.h>
 
34
#endif
 
35
 
32
36
extern int dry_run;
33
37
extern int am_root;
 
38
extern int am_sender;
34
39
extern int read_only;
35
40
extern int list_only;
36
41
extern int preserve_perms;
53
58
        return unlink(fname);
54
59
}
55
60
 
56
 
int do_symlink(const char *fname1, const char *fname2)
 
61
#ifdef SUPPORT_LINKS
 
62
int do_symlink(const char *lnk, const char *fname)
57
63
{
58
64
        if (dry_run) return 0;
59
65
        RETURN_ERROR_IF_RO_OR_LO;
60
 
        return symlink(fname1, fname2);
61
 
}
 
66
 
 
67
#if defined NO_SYMLINK_XATTRS || defined NO_SYMLINK_USER_XATTRS
 
68
        /* For --fake-super, we create a normal file with mode 0600
 
69
         * and write the lnk into it. */
 
70
        if (am_root < 0) {
 
71
                int ok, len = strlen(lnk);
 
72
                int fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR);
 
73
                if (fd < 0)
 
74
                        return -1;
 
75
                ok = write(fd, lnk, len) == len;
 
76
                if (close(fd) < 0)
 
77
                        ok = 0;
 
78
                return ok ? 0 : -1;
 
79
        }
 
80
#endif
 
81
 
 
82
        return symlink(lnk, fname);
 
83
}
 
84
 
 
85
#if defined NO_SYMLINK_XATTRS || defined NO_SYMLINK_USER_XATTRS
 
86
ssize_t do_readlink(const char *path, char *buf, size_t bufsiz)
 
87
{
 
88
        /* For --fake-super, we read the link from the file. */
 
89
        if (am_root < 0) {
 
90
                int fd = do_open_nofollow(path, O_RDONLY);
 
91
                if (fd >= 0) {
 
92
                        int len = read(fd, buf, bufsiz);
 
93
                        close(fd);
 
94
                        return len;
 
95
                }
 
96
                if (errno != ELOOP)
 
97
                        return -1;
 
98
                /* A real symlink needs to be turned into a fake one on the receiving
 
99
                 * side, so tell the generator that the link has no length. */
 
100
                if (!am_sender)
 
101
                        return 0;
 
102
                /* Otherwise fall through and let the sender report the real length. */
 
103
        }
 
104
 
 
105
        return readlink(path, buf, bufsiz);
 
106
}
 
107
#endif
 
108
#endif
62
109
 
63
110
#ifdef HAVE_LINK
64
111
int do_link(const char *fname1, const char *fname2)
374
421
#else
375
422
#error Need utimes or utime function.
376
423
#endif
 
424
 
 
425
#ifdef SUPPORT_PREALLOCATION
 
426
int do_fallocate(int fd, OFF_T offset, OFF_T length)
 
427
{
 
428
#ifdef FALLOC_FL_KEEP_SIZE
 
429
#define DO_FALLOC_OPTIONS FALLOC_FL_KEEP_SIZE
 
430
#else
 
431
#define DO_FALLOC_OPTIONS 0
 
432
#endif
 
433
        RETURN_ERROR_IF(dry_run, 0);
 
434
        RETURN_ERROR_IF_RO_OR_LO;
 
435
#if defined HAVE_FALLOCATE
 
436
        return fallocate(fd, DO_FALLOC_OPTIONS, offset, length);
 
437
#elif defined HAVE_SYS_FALLOCATE
 
438
        return syscall(SYS_fallocate, fd, DO_FALLOC_OPTIONS, (loff_t)offset, (loff_t)length);
 
439
#elif defined HAVE_EFFICIENT_POSIX_FALLOCATE
 
440
        return posix_fallocate(fd, offset, length);
 
441
#else
 
442
#error Coding error in SUPPORT_PREALLOCATION logic.
 
443
#endif
 
444
}
 
445
#endif
 
446
 
 
447
int do_open_nofollow(const char *pathname, int flags)
 
448
{
 
449
#ifndef O_NOFOLLOW
 
450
        STRUCT_STAT f_st, l_st;
 
451
#endif
 
452
        int fd;
 
453
 
 
454
        if (flags != O_RDONLY) {
 
455
                RETURN_ERROR_IF(dry_run, 0);
 
456
                RETURN_ERROR_IF_RO_OR_LO;
 
457
#ifndef O_NOFOLLOW
 
458
                /* This function doesn't support write attempts w/o O_NOFOLLOW. */
 
459
                errno = EINVAL;
 
460
                return -1;
 
461
#endif
 
462
        }
 
463
 
 
464
#ifdef O_NOFOLLOW
 
465
        fd = open(pathname, flags|O_NOFOLLOW);
 
466
#else
 
467
        if (do_lstat(pathname, &l_st) < 0)
 
468
                return -1;
 
469
        if (S_ISLNK(l_st.st_mode)) {
 
470
                errno = ELOOP;
 
471
                return -1;
 
472
        }
 
473
        if ((fd = open(pathname, flags)) < 0)
 
474
                return fd;
 
475
        if (do_fstat(fd, &f_st) < 0) {
 
476
          close_and_return_error:
 
477
                {
 
478
                        int save_errno = errno;
 
479
                        close(fd);
 
480
                        errno = save_errno;
 
481
                }
 
482
                return -1;
 
483
        }
 
484
        if (l_st.st_dev != f_st.st_dev || l_st.st_ino != f_st.st_ino) {
 
485
                errno = EINVAL;
 
486
                goto close_and_return_error;
 
487
        }
 
488
#endif
 
489
 
 
490
        return fd;
 
491
}