4 int gitfo_open(const char *path
, int flags
)
6 int fd
= open(path
, flags
| O_BINARY
);
7 return fd
>= 0 ? fd
: git_os_error();
10 int gitfo_creat(const char *path
, int mode
)
12 int fd
= open(path
, O_WRONLY
| O_CREAT
| O_TRUNC
| O_BINARY
, mode
);
13 return fd
>= 0 ? fd
: git_os_error();
16 int gitfo_read(git_file fd
, void *buf
, size_t cnt
)
20 ssize_t r
= read(fd
, b
, cnt
);
22 if (errno
== EINTR
|| errno
== EAGAIN
)
24 return git_os_error();
28 return git_os_error();
36 int gitfo_write(git_file fd
, void *buf
, size_t cnt
)
40 ssize_t r
= write(fd
, b
, cnt
);
42 if (errno
== EINTR
|| errno
== EAGAIN
)
44 return git_os_error();
48 return git_os_error();
56 int gitfo_exists(const char *path
)
58 return access(path
, F_OK
);
61 off_t
gitfo_size(git_file fd
)
64 if (gitfo_fstat(fd
, &sb
))
65 return git_os_error();
69 int gitfo_read_file(gitfo_buf
*obj
, const char *path
)
76 assert(obj
&& path
&& *path
);
78 if ((fd
= gitfo_open(path
, O_RDONLY
)) < 0)
81 if (((size
= gitfo_size(fd
)) < 0) || !git__is_sizet(size
+1)) {
87 if ((buff
= git__malloc(len
+ 1)) == NULL
) {
92 if (gitfo_read(fd
, buff
, len
) < 0) {
107 void gitfo_free_buf(gitfo_buf
*obj
)
114 int gitfo_move_file(char *from
, char *to
)
116 if (!link(from
, to
)) {
121 if (!rename(from
, to
))
124 return git_os_error();
127 int gitfo_map_ro(git_map
*out
, git_file fd
, off_t begin
, size_t len
)
129 if (git__mmap(out
, len
, GIT_PROT_READ
, GIT_MAP_SHARED
, fd
, begin
) < 0)
130 return git_os_error();
134 void gitfo_free_map(git_map
*out
)
142 size_t cache_size
, pos
;
143 unsigned char *cache
;
146 gitfo_cache
*gitfo_enable_caching(git_file fd
, size_t cache_size
)
150 ioc
= git__malloc(sizeof(*ioc
));
156 ioc
->cache_size
= cache_size
;
157 ioc
->cache
= git__malloc(cache_size
);
166 GIT_INLINE(void) gitfo_add_to_cache(gitfo_cache
*ioc
, void *buf
, size_t len
)
168 memcpy(ioc
->cache
+ ioc
->pos
, buf
, len
);
172 int gitfo_flush_cached(gitfo_cache
*ioc
)
174 int result
= GIT_SUCCESS
;
177 result
= gitfo_write(ioc
->fd
, ioc
->cache
, ioc
->pos
);
184 int gitfo_write_cached(gitfo_cache
*ioc
, void *buff
, size_t len
)
186 unsigned char *buf
= buff
;
189 size_t space_left
= ioc
->cache_size
- ioc
->pos
;
190 /* cache if it's small */
191 if (space_left
> len
) {
192 gitfo_add_to_cache(ioc
, buf
, len
);
196 /* flush the cache if it doesn't fit */
199 gitfo_add_to_cache(ioc
, buf
, space_left
);
200 rc
= gitfo_flush_cached(ioc
);
208 /* write too-large chunks immediately */
209 if (len
> ioc
->cache_size
)
210 return gitfo_write(ioc
->fd
, buf
, len
);
214 int gitfo_close_cached(gitfo_cache
*ioc
)
218 if (gitfo_flush_cached(ioc
) < 0)
225 return gitfo_close(fd
);
231 int (*fn
)(void *, char *),
234 size_t wd_len
= strlen(path
);
238 if (!wd_len
|| path_sz
< wd_len
+ 2)
241 while (path
[wd_len
- 1] == '/')
243 path
[wd_len
++] = '/';
248 return git_os_error();
250 while ((de
= readdir(dir
)) != NULL
) {
254 /* always skip '.' and '..' */
255 if (de
->d_name
[0] == '.') {
256 if (de
->d_name
[1] == '\0')
258 if (de
->d_name
[1] == '.' && de
->d_name
[2] == '\0')
262 de_len
= strlen(de
->d_name
);
263 if (path_sz
< wd_len
+ de_len
+ 1) {
268 strcpy(path
+ wd_len
, de
->d_name
);
269 result
= fn(arg
, path
);