summaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended/logrotate/logrotate-3.8.1/act-as-mv-when-rotate.patch
blob: c9fb1d2525f43b0d7210b46f04851715cc8044d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
Act as the "mv" command when rotate log

Act as the "mv" command when rotate log, first rename, if failed, then
read and write.

Upstream-Status: Pending

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
 logrotate.c |   59 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/logrotate.c b/logrotate.c
index 537e8d6..b04482f 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -808,6 +808,53 @@ int findNeedRotating(struct logInfo *log, int logNum)
     return 0;
 }
 
+/* Act as the "mv" command, if rename failed, then read the old file and
+ * write to new file. The function which invokes the mvFile will use
+ * the strerror(errorno) to handle the error message, so we don't have
+ * to print the error message here */
+
+int mvFile (char *oldName, char *newName, struct logInfo *log)
+{
+    struct stat sbprev;
+    int fd_old, fd_new, n;
+    char buf[BUFSIZ];
+
+    /* Do the rename first */
+    if (!rename(oldName, newName))
+        return 0;
+
+    /* If the errno is EXDEV, then read old file, write newfile and
+     * remove the oldfile */
+    if (errno == EXDEV) {
+        /* Open the old file to read */
+        if ((fd_old = open(oldName, O_RDONLY)) < 0)
+            return 1;
+
+        /* Create the file to write, keep the same attribute as the old file */
+        if (stat(oldName, &sbprev))
+            return 1;
+        else {
+            if ((fd_new = createOutputFile(newName,
+                O_WRONLY | O_CREAT | O_TRUNC, &sbprev)) < 0 )
+                return 1;
+        }
+
+        /* Read and write */
+        while ((n = read(fd_old, buf, BUFSIZ)) > 0)
+            if (write(fd_new, buf, n) != n)
+                return 1;
+
+        if ((close(fd_old) < 0) ||
+            removeLogFile(oldName, log) ||
+            (close(fd_new) < 0))
+            return 1;
+
+        return 0;
+    }
+
+    return 1;
+}
+
 int prerotateSingleLog(struct logInfo *log, int logNum, struct logState *state,
 		       struct logNames *rotNames)
 {
@@ -1148,15 +1195,15 @@ int prerotateSingleLog(struct logInfo *log, int logNum, struct logState *state,
 		    rotNames->baseName, i, fileext, compext);
 
 	    message(MESS_DEBUG,
-		    "renaming %s to %s (rotatecount %d, logstart %d, i %d), \n",
+		    "moving %s to %s (rotatecount %d, logstart %d, i %d), \n",
 		    oldName, newName, rotateCount, logStart, i);
 
-	    if (!debug && rename(oldName, newName)) {
+	    if (!debug && mvFile(oldName, newName, log)) {
 		if (errno == ENOENT) {
 		    message(MESS_DEBUG, "old log %s does not exist\n",
 			    oldName);
 		} else {
-		    message(MESS_ERROR, "error renaming %s to %s: %s\n",
+		    message(MESS_ERROR, "error moving %s to %s: %s\n",
 			    oldName, newName, strerror(errno));
 		    hasErrors = 1;
 		}
@@ -1286,11 +1333,11 @@ int rotateSingleLog(struct logInfo *log, int logNum, struct logState *state,
 			}
 		}
 #endif /* WITH_ACL */
-		message(MESS_DEBUG, "renaming %s to %s\n", log->files[logNum],
+        message(MESS_DEBUG, "moving %s to %s\n", log->files[logNum],
 		    rotNames->finalName);
 	    if (!debug && !hasErrors &&
-		rename(log->files[logNum], rotNames->finalName)) {
-		message(MESS_ERROR, "failed to rename %s to %s: %s\n",
+        mvFile(log->files[logNum], rotNames->finalName, log)) {
+        message(MESS_ERROR, "failed to move %s to %s: %s\n",
 			log->files[logNum], rotNames->finalName,
 			strerror(errno));
 			hasErrors = 1;
-- 
1.7.4.1