What's the difference between eina file, ecore file, eo file? Daniel Juyung Seo (SeoZ)
On Tue, Jan 1, 2013 at 8:17 AM, Enlightenment SVN < [email protected]> wrote: > Log: > efl: add eina_file_copy() > > it's useful to copy file from one place to another and this will be > used in eio' s implementation. > > NOTE: did not use mmap here as mmap faults may be cumbersome to handle > (Eina_File itself does that, but in a nasty way) and the > implementation would be severely different as there is no Eina_File > from FD, and there is no way to inject custom memory/fd into the > Eina_File's fault handling. The performance would not be that > different anyways and the splice() is already in there for systems > with good performance (read: Linux). > > > > Author: barbieri > Date: 2012-12-31 15:17:18 -0800 (Mon, 31 Dec 2012) > New Revision: 81942 > Trac: http://trac.enlightenment.org/e/changeset/81942 > > Added: > trunk/efl/src/examples/eina/eina_file_02.c > Modified: > trunk/efl/ChangeLog trunk/efl/NEWS trunk/efl/src/examples/eina/ > trunk/efl/src/examples/eina/Makefile.am trunk/efl/src/lib/eina/eina_file.c > trunk/efl/src/lib/eina/eina_file.h > > Modified: trunk/efl/ChangeLog > =================================================================== > --- trunk/efl/ChangeLog 2012-12-31 21:05:58 UTC (rev 81941) > +++ trunk/efl/ChangeLog 2012-12-31 23:17:18 UTC (rev 81942) > @@ -4,6 +4,7 @@ > * Added eina_xattr_fd_get(), eina_xattr_fd_set(), > eina_xattr_del(), eina_xattr_fd_del(), eina_xattr_copy() and > eina_xattr_fd_copy() > + * Added eina_file_copy() > > 2012-12-24 Mike Blumenkrantz > > > Modified: trunk/efl/NEWS > =================================================================== > --- trunk/efl/NEWS 2012-12-31 21:05:58 UTC (rev 81941) > +++ trunk/efl/NEWS 2012-12-31 23:17:18 UTC (rev 81942) > @@ -46,6 +46,7 @@ > * Added eina_xattr_fd_get(), eina_xattr_fd_set(), > eina_xattr_del(), eina_xattr_fd_del(), eina_xattr_copy() and > eina_xattr_fd_copy() > + * Added eina_file_copy() > > Deprecations: > * ecore_x: > > > Property changes on: trunk/efl/src/examples/eina > ___________________________________________________________________ > Modified: svn:ignore > - Makefile > Makefile.in > .deps > eina_simple_xml_parser_01 > eina_error_01 > eina_strbuf_01 > eina_inarray_01 > eina_inarray_02 > eina_array_01 > eina_file_01 > eina_tiler_01 > eina_array_02 > eina_magic_01 > eina_accessor_01 > eina_hash_01 > eina_hash_02 > eina_hash_03 > eina_hash_04 > eina_hash_05 > eina_hash_06 > eina_hash_07 > eina_hash_08 > eina_list_01 > eina_list_02 > eina_list_03 > eina_list_04 > eina_log_01 > eina_log_02 > eina_log_03 > eina_stringshare_01 > eina_iterator_01 > eina_inlist_01 > eina_inlist_02 > eina_inlist_03 > eina_str_01 > eina_value_01 > eina_value_02 > eina_value_03 > eina_simple_xml_parser_01.exe > eina_error_01.exe > eina_strbuf_01.exe > eina_inarray_01.exe > eina_inarray_02.exe > eina_array_01.exe > eina_file_01.exe > eina_tiler_01.exe > eina_array_02.exe > eina_magic_01.exe > eina_accessor_01.exe > eina_hash_01.exe > eina_hash_02.exe > eina_hash_03.exe > eina_hash_04.exe > eina_hash_05.exe > eina_hash_06.exe > eina_hash_07.exe > eina_hash_08.exe > eina_list_01.exe > eina_list_02.exe > eina_list_03.exe > eina_list_04.exe > eina_log_01.exe > eina_log_02.exe > eina_log_03.exe > eina_stringshare_01.exe > eina_iterator_01.exe > eina_inlist_01.exe > eina_inlist_02.exe > eina_inlist_03.exe > eina_str_01.exe > eina_value_01.exe > eina_value_02.exe > eina_value_03.exe > eina_xattr_01 > eina_xattr_02 > > + Makefile > Makefile.in > .deps > eina_simple_xml_parser_01 > eina_error_01 > eina_strbuf_01 > eina_inarray_01 > eina_inarray_02 > eina_array_01 > eina_file_01 > eina_file_02 > eina_tiler_01 > eina_array_02 > eina_magic_01 > eina_accessor_01 > eina_hash_01 > eina_hash_02 > eina_hash_03 > eina_hash_04 > eina_hash_05 > eina_hash_06 > eina_hash_07 > eina_hash_08 > eina_list_01 > eina_list_02 > eina_list_03 > eina_list_04 > eina_log_01 > eina_log_02 > eina_log_03 > eina_stringshare_01 > eina_iterator_01 > eina_inlist_01 > eina_inlist_02 > eina_inlist_03 > eina_str_01 > eina_value_01 > eina_value_02 > eina_value_03 > eina_simple_xml_parser_01.exe > eina_error_01.exe > eina_strbuf_01.exe > eina_inarray_01.exe > eina_inarray_02.exe > eina_array_01.exe > eina_file_01.exe > eina_tiler_01.exe > eina_array_02.exe > eina_magic_01.exe > eina_accessor_01.exe > eina_hash_01.exe > eina_hash_02.exe > eina_hash_03.exe > eina_hash_04.exe > eina_hash_05.exe > eina_hash_06.exe > eina_hash_07.exe > eina_hash_08.exe > eina_list_01.exe > eina_list_02.exe > eina_list_03.exe > eina_list_04.exe > eina_log_01.exe > eina_log_02.exe > eina_log_03.exe > eina_stringshare_01.exe > eina_iterator_01.exe > eina_inlist_01.exe > eina_inlist_02.exe > eina_inlist_03.exe > eina_str_01.exe > eina_value_01.exe > eina_value_02.exe > eina_value_03.exe > eina_xattr_01 > eina_xattr_02 > > > Modified: trunk/efl/src/examples/eina/Makefile.am > =================================================================== > --- trunk/efl/src/examples/eina/Makefile.am 2012-12-31 21:05:58 UTC > (rev 81941) > +++ trunk/efl/src/examples/eina/Makefile.am 2012-12-31 23:17:18 UTC > (rev 81942) > @@ -13,6 +13,7 @@ > eina_array_02.c \ > eina_error_01.c \ > eina_file_01.c \ > +eina_file_02.c \ > eina_hash_01.c \ > eina_hash_02.c \ > eina_hash_03.c \ > @@ -56,6 +57,7 @@ > eina_array_02 \ > eina_error_01 \ > eina_file_01 \ > +eina_file_02 \ > eina_hash_01 \ > eina_hash_02 \ > eina_hash_03 \ > > Modified: trunk/efl/src/lib/eina/eina_file.c > =================================================================== > --- trunk/efl/src/lib/eina/eina_file.c 2012-12-31 21:05:58 UTC (rev 81941) > +++ trunk/efl/src/lib/eina/eina_file.c 2012-12-31 23:17:18 UTC (rev 81942) > @@ -54,6 +54,7 @@ > #include <fcntl.h> > > #define PATH_DELIM '/' > +#define COPY_BLOCKSIZE (4 * 1024 * 1024) > > #include "eina_config.h" > #include "eina_private.h" > @@ -95,6 +96,11 @@ > #endif > #define WRN(...) EINA_LOG_DOM_WARN(_eina_file_log_dom, __VA_ARGS__) > > +#ifdef INF > +#undef INF > +#endif > +#define INF(...) EINA_LOG_DOM_INFO(_eina_file_log_dom, __VA_ARGS__) > + > #ifdef DBG > #undef DBG > #endif > @@ -1518,3 +1524,256 @@ > #endif > return 0; > } > + > +static Eina_Bool > +_eina_file_copy_write_internal(int fd, char *buf, size_t size) > +{ > + size_t done = 0; > + while (done < size) > + { > + ssize_t w = write(fd, buf + done, size - done); > + if (w >= 0) > + done += w; > + else if ((errno != EAGAIN) && (errno != EINTR)) > + { > + ERR("Error writing destination file during copy: %s", > + strerror(errno)); > + return EINA_FALSE; > + } > + } > + return EINA_TRUE; > +} > + > +static Eina_Bool > +_eina_file_copy_read_internal(int fd, char *buf, off_t bufsize, ssize_t > *readsize) > +{ > + while (1) > + { > + ssize_t r = read(fd, buf, bufsize); > + if (r == 0) > + { > + ERR("Premature end of source file during copy."); > + return EINA_FALSE; > + } > + else if (r < 0) > + { > + if ((errno != EAGAIN) && (errno != EINTR)) > + { > + ERR("Error reading source file during copy: %s", > + strerror(errno)); > + return EINA_FALSE; > + } > + } > + else > + { > + *readsize = r; > + return EINA_TRUE; > + } > + } > +} > + > +static Eina_Bool > +_eina_file_copy_write_splice_internal(int fd, int pipefd, size_t size) > +{ > + size_t done = 0; > + while (done < size) > + { > + ssize_t w = splice(pipefd, NULL, fd, NULL, size - done, > SPLICE_F_MORE); > + if (w >= 0) > + done += w; > + else if (errno == EINVAL) > + { > + INF("Splicing is not supported for destination file"); > + return EINA_FALSE; > + } > + else if ((errno != EAGAIN) && (errno != EINTR)) > + { > + ERR("Error splicing to destination file during copy: %s", > + strerror(errno)); > + return EINA_FALSE; > + } > + } > + return EINA_TRUE; > +} > + > +static Eina_Bool > +_eina_file_copy_read_splice_internal(int fd, int pipefd, off_t bufsize, > ssize_t *readsize) > +{ > + while (1) > + { > + ssize_t r = splice(fd, NULL, pipefd, NULL, bufsize, > SPLICE_F_MORE); > + if (r == 0) > + { > + ERR("Premature end of source file during splice."); > + return EINA_FALSE; > + } > + else if (r < 0) > + { > + if (errno == EINVAL) > + { > + INF("Splicing is not supported for source file"); > + return EINA_FALSE; > + } > + else if ((errno != EAGAIN) && (errno != EINTR)) > + { > + ERR("Error splicing from source file during copy: %s", > + strerror(errno)); > + return EINA_FALSE; > + } > + } > + else > + { > + *readsize = r; > + return EINA_TRUE; > + } > + } > +} > + > +static Eina_Bool > +_eina_file_copy_splice_internal(int s, int d, off_t total, > Eina_File_Copy_Progress cb, const void *cb_data, Eina_Bool > *splice_unsupported) > +{ > +#ifdef HAVE_SPLICE > + off_t bufsize = COPY_BLOCKSIZE; > + off_t done; > + Eina_Bool ret; > + int pipefd[2]; > + > + *splice_unsupported = EINA_TRUE; > + > + if (pipe(pipefd) < 0) return EINA_FALSE; > + > + done = 0; > + ret = EINA_TRUE; > + while (done < total) > + { > + size_t todo; > + ssize_t r; > + > + if (done + bufsize < total) > + todo = bufsize; > + else > + todo = total - done; > + > + printf("loop done=%lld, total=%lld, todo=%zd\n", done, total, > todo); > + > + ret = _eina_file_copy_read_splice_internal(s, pipefd[1], todo, > &r); > + if (!ret) break; > + > + ret = _eina_file_copy_write_splice_internal(d, pipefd[0], r); > + if (!ret) break; > + > + *splice_unsupported = EINA_FALSE; > + done += r; > + > + if (cb) > + { > + ret = cb((void *)cb_data, done, total); > + if (!ret) break; > + } > + } > + > + close(pipefd[0]); > + close(pipefd[1]); > + > + return ret; > +#endif > + *splice_unsupported = EINA_TRUE; > + return EINA_FALSE; > + (void)s; > + (void)d; > + (void)total; > + (void)cb; > + (void)cb_data; > +} > + > +static Eina_Bool > +_eina_file_copy_internal(int s, int d, off_t total, > Eina_File_Copy_Progress cb, const void *cb_data) > +{ > + void *buf = NULL; > + off_t bufsize = COPY_BLOCKSIZE; > + off_t done; > + Eina_Bool ret, splice_unsupported; > + > + ret = _eina_file_copy_splice_internal(s, d, total, cb, cb_data, > + &splice_unsupported); > + if (ret) > + return EINA_TRUE; > + else if (!splice_unsupported) /* splice works, but copy failed anyway > */ > + return EINA_FALSE; > + > + /* make sure splice didn't change the position */ > + lseek(s, 0, SEEK_SET); > + lseek(d, 0, SEEK_SET); > + > + while ((bufsize > 0) && ((buf = malloc(bufsize)) == NULL)) > + bufsize /= 128; > + > + EINA_SAFETY_ON_NULL_RETURN_VAL(buf, EINA_FALSE); > + > + done = 0; > + ret = EINA_TRUE; > + while (done < total) > + { > + size_t todo; > + ssize_t r; > + > + if (done + bufsize < total) > + todo = bufsize; > + else > + todo = total - done; > + > + ret = _eina_file_copy_read_internal(s, buf, todo, &r); > + if (!ret) break; > + > + ret = _eina_file_copy_write_internal(d, buf, r); > + if (!ret) break; > + > + done += r; > + > + if (cb) > + { > + ret = cb((void *)cb_data, done, total); > + if (!ret) break; > + } > + } > + > + free(buf); > + return ret; > +} > + > +EAPI Eina_Bool > +eina_file_copy(const char *src, const char *dst, Eina_File_Copy_Flags > flags, Eina_File_Copy_Progress cb, const void *cb_data) > +{ > + struct stat st; > + int s, d; > + Eina_Bool success; > + > + EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE); > + EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE); > + > + s = open(src, O_RDONLY); > + EINA_SAFETY_ON_TRUE_RETURN_VAL (s < 0, EINA_FALSE); > + > + success = (fstat(s, &st) == 0); > + EINA_SAFETY_ON_FALSE_GOTO(success, end); > + > + d = open(dst, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); > + EINA_SAFETY_ON_TRUE_GOTO(d < 0, end); > + > + success = _eina_file_copy_internal(s, d, st.st_size, cb, cb_data); > + if (success) > + { > + if (flags & EINA_FILE_COPY_PERMISSION) > + fchmod(d, st.st_mode); > + if (flags & EINA_FILE_COPY_XATTR) > + eina_xattr_fd_copy(s, d); > + } > + > + end: > + close(s); > + > + if (!success) > + unlink(dst); > + > + return success; > +} > > Modified: trunk/efl/src/lib/eina/eina_file.h > =================================================================== > --- trunk/efl/src/lib/eina/eina_file.h 2012-12-31 21:05:58 UTC (rev 81941) > +++ trunk/efl/src/lib/eina/eina_file.h 2012-12-31 23:17:18 UTC (rev 81942) > @@ -369,7 +369,47 @@ > */ > EAPI char *eina_file_path_sanitize(const char *path); > > + > /** > + * @typedef Eina_File_Copy_Progress > + * used to report progress during eina_file_copy(), where @c done > + * is the bytes already copied and @c size is the total file size. > + * > + * If returns #EINA_FALSE, it will stop the copy. > + */ > +typedef Eina_Bool (*Eina_File_Copy_Progress)(void *data, unsigned long > long done, unsigned long long total); > + > +/** > + * @typedef Eina_File_Copy_Flags > + * what to copy from file. > + */ > +typedef enum { > + EINA_FILE_COPY_DATA = 0, > + EINA_FILE_COPY_PERMISSION = (1 << 0), > + EINA_FILE_COPY_XATTR = (1 << 1) > +} Eina_File_Copy_Flags; > + > +/** > + * Copy one file to another using the fastest possible way, report > progress. > + * > + * This function will try splice if it is available. It > + * will block until the whole file is copied or it fails. > + * > + * During the progress it may call back @a cb with the progress summary. > + * > + * @param src the source file. > + * @param dst the destination file. > + * @param flags controls what is copied (data is always copied). > + * @param cb if provided will be called with file copy progress > information. > + * @param cb_data context data to provide to @a cb during copy. > + * @return #EINA_TRUE on success, #EINA_FALSE otherwise (and @a dst > + * will be deleted) > + */ > +EAPI Eina_Bool eina_file_copy(const char *src, const char *dst, > Eina_File_Copy_Flags flags, Eina_File_Copy_Progress cb, const void > *cb_data) EINA_ARG_NONNULL(1, 2); > + > + > + > +/** > * @brief Get a read-only handler to a file. > * > * @param name Filename to open > > > > ------------------------------------------------------------------------------ > Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS, > MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current > with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft > MVPs and experts. SALE $99.99 this month only -- learn more at: > http://p.sf.net/sfu/learnmore_122412 > _______________________________________________ > enlightenment-svn mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/enlightenment-svn > ------------------------------------------------------------------------------ Master SQL Server Development, Administration, T-SQL, SSAS, SSIS, SSRS and more. Get SQL Server skills now (including 2012) with LearnDevNow - 200+ hours of step-by-step video tutorials by Microsoft MVPs and experts. SALE $99.99 this month only - learn more at: http://p.sf.net/sfu/learnmore_122512 _______________________________________________ enlightenment-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
