don't need to test for SETPGRP any more as it is no longer used
[rsync/rsync.git] / util.c
... / ...
CommitLineData
1/*
2 Copyright (C) Andrew Tridgell 1996
3 Copyright (C) Paul Mackerras 1996
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20/*
21 Utilities used in rsync
22
23 tridge, June 1996
24 */
25#include "rsync.h"
26
27int num_waiting(int fd)
28{
29 int len=0;
30 ioctl(fd,FIONREAD,&len);
31 return(len);
32}
33
34
35struct map_struct *map_file(int fd,off_t len)
36{
37 struct map_struct *ret;
38 ret = (struct map_struct *)malloc(sizeof(*ret));
39 if (!ret) out_of_memory("map_file");
40
41 ret->map = NULL;
42 ret->fd = fd;
43 ret->size = len;
44 ret->p = NULL;
45 ret->p_size = 0;
46 ret->p_offset = 0;
47 ret->p_len = 0;
48
49#ifdef HAVE_MMAP
50 if (len < MAX_MAP_SIZE)
51 ret->map = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
52#endif
53 return ret;
54}
55
56
57char *map_ptr(struct map_struct *map,off_t offset,int len)
58{
59 int nread = -2;
60
61 if (map->map)
62 return map->map+offset;
63
64 if (len == 0)
65 return NULL;
66
67 if (len > (map->size-offset))
68 len = map->size-offset;
69
70 if (offset >= map->p_offset &&
71 offset+len <= map->p_offset+map->p_len) {
72 return (map->p + (offset - map->p_offset));
73 }
74
75 len = MAX(len,CHUNK_SIZE);
76 if (len > (map->size-offset))
77 len = map->size-offset;
78
79 if (len > map->p_size) {
80 if (map->p) free(map->p);
81 map->p = (char *)malloc(len);
82 if (!map->p) out_of_memory("map_ptr");
83 map->p_size = len;
84 }
85
86 if (lseek(map->fd,offset,SEEK_SET) != offset ||
87 (nread=read(map->fd,map->p,len)) != len) {
88 fprintf(FERROR,"EOF in map_ptr! (offset=%d len=%d nread=%d errno=%d)\n",
89 (int)offset, len, nread, errno);
90 exit_cleanup(1);
91 }
92
93 map->p_offset = offset;
94 map->p_len = len;
95
96 return map->p;
97}
98
99
100void unmap_file(struct map_struct *map)
101{
102#ifdef HAVE_MMAP
103 if (map->map)
104 munmap(map->map,map->size);
105#endif
106 if (map->p) free(map->p);
107 free(map);
108}
109
110
111/* this is taken from CVS */
112int piped_child(char **command,int *f_in,int *f_out)
113{
114 int pid;
115 int to_child_pipe[2];
116 int from_child_pipe[2];
117
118 if (pipe(to_child_pipe) < 0 ||
119 pipe(from_child_pipe) < 0) {
120 fprintf(FERROR,"pipe: %s\n",strerror(errno));
121 exit_cleanup(1);
122 }
123
124
125 pid = do_fork();
126 if (pid < 0) {
127 fprintf(FERROR,"fork: %s\n",strerror(errno));
128 exit_cleanup(1);
129 }
130
131 if (pid == 0)
132 {
133 extern int orig_umask;
134 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
135 close(to_child_pipe[1]) < 0 ||
136 close(from_child_pipe[0]) < 0 ||
137 dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
138 fprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
139 exit_cleanup(1);
140 }
141 if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
142 if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
143 umask(orig_umask);
144 execvp(command[0], command);
145 fprintf(FERROR,"Failed to exec %s : %s\n",
146 command[0],strerror(errno));
147 exit_cleanup(1);
148 }
149
150 if (close(from_child_pipe[1]) < 0 ||
151 close(to_child_pipe[0]) < 0) {
152 fprintf(FERROR,"Failed to close : %s\n",strerror(errno));
153 exit_cleanup(1);
154 }
155
156 *f_in = from_child_pipe[0];
157 *f_out = to_child_pipe[1];
158
159 return pid;
160}
161
162
163void out_of_memory(char *str)
164{
165 fprintf(FERROR,"out of memory in %s\n",str);
166 exit_cleanup(1);
167}
168
169
170
171int set_modtime(char *fname,time_t modtime)
172{
173 extern int dry_run;
174 if (dry_run) return 0;
175 {
176#ifdef HAVE_UTIMBUF
177 struct utimbuf tbuf;
178 tbuf.actime = time(NULL);
179 tbuf.modtime = modtime;
180 return utime(fname,&tbuf);
181#elif defined(HAVE_UTIME)
182 time_t t[2];
183 t[0] = time(NULL);
184 t[1] = modtime;
185 return utime(fname,t);
186#else
187 struct timeval t[2];
188 t[0].tv_sec = time(NULL);
189 t[0].tv_usec = 0;
190 t[1].tv_sec = modtime;
191 t[1].tv_usec = 0;
192 return utimes(fname,t);
193#endif
194 }
195}
196
197
198
199/****************************************************************************
200Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
201else
202if SYSV use O_NDELAY
203if BSD use FNDELAY
204****************************************************************************/
205int set_blocking(int fd, int set)
206{
207 int val;
208#ifdef O_NONBLOCK
209#define FLAG_TO_SET O_NONBLOCK
210#else
211#ifdef SYSV
212#define FLAG_TO_SET O_NDELAY
213#else /* BSD */
214#define FLAG_TO_SET FNDELAY
215#endif
216#endif
217
218 if((val = fcntl(fd, F_GETFL, 0)) == -1)
219 return -1;
220 if(set) /* Turn blocking on - ie. clear nonblock flag */
221 val &= ~FLAG_TO_SET;
222 else
223 val |= FLAG_TO_SET;
224 return fcntl( fd, F_SETFL, val);
225#undef FLAG_TO_SET
226}
227
228/****************************************************************************
229create any necessary directories in fname. Unfortunately we don't know
230what perms to give the directory when this is called so we need to rely
231on the umask
232****************************************************************************/
233int create_directory_path(char *fname)
234{
235 extern int orig_umask;
236 char *p;
237
238 while (*fname == '/') fname++;
239 while (strncmp(fname,"./",2)==0) fname += 2;
240
241 p = fname;
242 while ((p=strchr(p,'/'))) {
243 *p = 0;
244 mkdir(fname,0777 & ~orig_umask);
245 *p = '/';
246 p++;
247 }
248 return 0;
249}
250
251
252/* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
253 Return LEN upon success, write's (negative) error code otherwise.
254
255 derived from GNU C's cccp.c.
256*/
257int full_write(int desc, char *ptr, int len)
258{
259 int total_written;
260
261 total_written = 0;
262 while (len > 0) {
263 int written = write (desc, ptr, len);
264 if (written < 0) {
265#ifdef EINTR
266 if (errno == EINTR)
267 continue;
268#endif
269 return written;
270 }
271 total_written += written;
272 ptr += written;
273 len -= written;
274 }
275 return total_written;
276}
277
278/* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
279 Return the actual number of bytes read, zero for EOF, or negative
280 for an error.
281
282 derived from GNU C's cccp.c. */
283int safe_read(int desc, char *ptr, int len)
284{
285 int n_chars;
286
287 if (len <= 0)
288 return len;
289
290#ifdef EINTR
291 do {
292 n_chars = read(desc, ptr, len);
293 } while (n_chars < 0 && errno == EINTR);
294#else
295 n_chars = read(desc, ptr, len);
296#endif
297
298 return n_chars;
299}
300
301
302/* copy a file - this is used in conjunction with the --temp-dir option */
303int copy_file(char *source, char *dest, mode_t mode)
304{
305 int ifd;
306 int ofd;
307 char buf[1024 * 8];
308 int len; /* Number of bytes read into `buf'. */
309
310 ifd = open(source, O_RDONLY);
311 if (ifd == -1) {
312 fprintf(FERROR,"open %s: %s\n",
313 source,strerror(errno));
314 return -1;
315 }
316
317 if (do_unlink(dest) && errno != ENOENT) {
318 fprintf(FERROR,"unlink %s: %s\n",
319 dest,strerror(errno));
320 return -1;
321 }
322
323 ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
324 if (ofd < 0) {
325 fprintf(FERROR,"open %s: %s\n",
326 dest,strerror(errno));
327 close(ifd);
328 return -1;
329 }
330
331 while ((len = safe_read(ifd, buf, sizeof(buf))) > 0) {
332 if (full_write(ofd, buf, len) < 0) {
333 fprintf(FERROR,"write %s: %s\n",
334 dest,strerror(errno));
335 close(ifd);
336 close(ofd);
337 return -1;
338 }
339 }
340
341 close(ifd);
342 close(ofd);
343
344 if (len < 0) {
345 fprintf(FERROR,"read %s: %s\n",
346 source,strerror(errno));
347 return -1;
348 }
349
350 return 0;
351}
352
353/* sleep for a while via select */
354void u_sleep(int usec)
355{
356 struct timeval tv;
357
358 tv.tv_sec = 0;
359 tv.tv_usec = usec;
360 select(0, NULL, NULL, NULL, &tv);
361}
362
363
364static pid_t all_pids[10];
365static int num_pids;
366
367/* fork and record the pid of the child */
368pid_t do_fork(void)
369{
370 pid_t newpid = fork();
371
372 if (newpid) {
373 all_pids[num_pids++] = newpid;
374 }
375 return newpid;
376}
377
378/* kill all children */
379void kill_all(int sig)
380{
381 int i;
382 for (i=0;i<num_pids;i++) {
383 if (all_pids[i] != getpid())
384 kill(all_pids[i], sig);
385 }
386}