went to full non-blocking writes for the send_files() process
[rsync/rsync.git] / util.c
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
27 int num_waiting(int fd)
28 {
29   int len=0;
30   ioctl(fd,FIONREAD,&len);
31   return(len);
32 }
33
34 char *map_file(int fd,off_t len)
35 {
36   char *ret = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
37   return ret;
38 }
39
40 void unmap_file(char *buf,off_t len)
41 {
42   if (len > 0 && buf)
43     munmap(buf,len);
44 }
45
46
47 /* this is taken from CVS */
48 int piped_child(char **command,int *f_in,int *f_out)
49 {
50   int pid;
51   int to_child_pipe[2];
52   int from_child_pipe[2];
53
54   if (pipe(to_child_pipe) < 0 ||
55       pipe(from_child_pipe) < 0) {
56     fprintf(stderr,"pipe: %s\n",strerror(errno));
57     exit(1);
58   }
59
60
61   pid = fork();
62   if (pid < 0) {
63     fprintf(stderr,"fork: %s\n",strerror(errno));
64     exit(1);
65   }
66
67   if (pid == 0)
68     {
69       if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
70           close(to_child_pipe[1]) < 0 ||
71           close(from_child_pipe[0]) < 0 ||
72           dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
73         fprintf(stderr,"Failed to dup/close : %s\n",strerror(errno));
74         exit(1);
75       }
76       execvp(command[0], command);
77       fprintf(stderr,"Failed to exec %s : %s\n",
78               command[0],strerror(errno));
79       exit(1);
80     }
81
82   if (close(from_child_pipe[1]) < 0 ||
83       close(to_child_pipe[0]) < 0) {
84     fprintf(stderr,"Failed to close : %s\n",strerror(errno));   
85     exit(1);
86   }
87
88   *f_in = from_child_pipe[0];
89   *f_out = to_child_pipe[1];
90   
91   return pid;
92 }
93
94
95 void out_of_memory(char *str)
96 {
97   fprintf(stderr,"out of memory in %s\n",str);
98   exit(1);
99 }
100
101
102 #ifndef HAVE_STRDUP
103  char *strdup(char *s)
104 {
105   int l = strlen(s) + 1;
106   char *ret = (char *)malloc(l);
107   if (ret)
108     strcpy(ret,s);
109   return ret;
110 }
111 #endif
112
113
114 int set_modtime(char *fname,time_t modtime)
115 {
116 #ifdef HAVE_UTIME_H
117   struct utimbuf tbuf;  
118   tbuf.actime = time(NULL);
119   tbuf.modtime = modtime;
120   return utime(fname,&tbuf);
121 #elif defined(HAVE_UTIME)
122   time_t t[2];
123   t[0] = time(NULL);
124   t[1] = modtime;
125   return utime(fname,t);
126 #else
127   struct timeval t[2];
128   t[0].tv_sec = time(NULL);
129   t[0].tv_usec = 0;
130   t[1].tv_sec = modtime;
131   t[1].tv_usec = 0;
132   return utimes(fname,t);
133 #endif
134 }
135
136
137
138 /****************************************************************************
139 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
140 else
141 if SYSV use O_NDELAY
142 if BSD use FNDELAY
143 ****************************************************************************/
144 int set_blocking(int fd, int set)
145 {
146   int val;
147 #ifdef O_NONBLOCK
148 #define FLAG_TO_SET O_NONBLOCK
149 #else
150 #ifdef SYSV
151 #define FLAG_TO_SET O_NDELAY
152 #else /* BSD */
153 #define FLAG_TO_SET FNDELAY
154 #endif
155 #endif
156
157   if((val = fcntl(fd, F_GETFL, 0)) == -1)
158         return -1;
159   if(set) /* Turn blocking on - ie. clear nonblock flag */
160         val &= ~FLAG_TO_SET;
161   else
162     val |= FLAG_TO_SET;
163   return fcntl( fd, F_SETFL, val);
164 #undef FLAG_TO_SET
165 }