From owner-svn-soc-all@FreeBSD.ORG Wed Jul 17 17:17:16 2013 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 7FD045D2 for ; Wed, 17 Jul 2013 17:17:16 +0000 (UTC) (envelope-from dpl@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) by mx1.freebsd.org (Postfix) with ESMTP id 706DEE84 for ; Wed, 17 Jul 2013 17:17:16 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6HHHGiX009588 for ; Wed, 17 Jul 2013 17:17:16 GMT (envelope-from dpl@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.7/8.14.6/Submit) id r6HHHGso009577 for svn-soc-all@FreeBSD.org; Wed, 17 Jul 2013 17:17:16 GMT (envelope-from dpl@FreeBSD.org) Date: Wed, 17 Jul 2013 17:17:16 GMT Message-Id: <201307171717.r6HHHGso009577@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to dpl@FreeBSD.org using -f From: dpl@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r254890 - soc2013/dpl/head/contrib/xz/src/xz MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 17 Jul 2013 17:17:16 -0000 Author: dpl Date: Wed Jul 17 17:17:16 2013 New Revision: 254890 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=254890 Log: It works always, except when used --files/--files0 as options. Modified: soc2013/dpl/head/contrib/xz/src/xz/coder.c soc2013/dpl/head/contrib/xz/src/xz/coder.h soc2013/dpl/head/contrib/xz/src/xz/file_io.c soc2013/dpl/head/contrib/xz/src/xz/file_io.h soc2013/dpl/head/contrib/xz/src/xz/list.c soc2013/dpl/head/contrib/xz/src/xz/list.h soc2013/dpl/head/contrib/xz/src/xz/main.c soc2013/dpl/head/contrib/xz/src/xz/main.h soc2013/dpl/head/contrib/xz/src/xz/private.h Modified: soc2013/dpl/head/contrib/xz/src/xz/coder.c ============================================================================== --- soc2013/dpl/head/contrib/xz/src/xz/coder.c Wed Jul 17 14:15:00 2013 (r254889) +++ soc2013/dpl/head/contrib/xz/src/xz/coder.c Wed Jul 17 17:17:16 2013 (r254890) @@ -609,52 +609,51 @@ extern void -coder_run(file_pair pairs[], int files) +coder_run(file_pair *pair) { - int i; + if (pair == NULL ) + return; - for( i=0; i < files; i++) { - // Set and possibly print the filename for the progress message. - message_filename(pairs[i].src_name); - - // Assume that something goes wrong. - bool success = false; - - // Read the first chunk of input data. This is needed to detect - // the input file type (for now, only for decompression). - strm.next_in = in_buf.u8; - strm.avail_in = io_read(&pairs[i], &in_buf, IO_BUFFER_SIZE); - - if (strm.avail_in != SIZE_MAX) { - // Initialize the coder. This will detect the file format - // and, in decompression or testing mode, check the memory - // usage of the first Block too. This way we don't try to - // open the destination file if we see that coding wouldn't - // work at all anyway. This also avoids deleting the old - // "target" file if --force was used. - const enum coder_init_ret init_ret = coder_init(&pairs[i]); - - if (init_ret != CODER_INIT_ERROR && !user_abort) { - // Initialize the progress indicator. - const uint64_t in_size - = pairs[i].src_st.st_size <= 0 - ? 0 : pairs[i].src_st.st_size; - message_progress_start(&strm, in_size); - - // Do the actual coding or passthru. - if (init_ret == CODER_INIT_NORMAL) - success = coder_normal(&pairs[i]); - else - success = coder_passthru(&pairs[i]); + // Set and possibly print the filename for the progress message. + message_filename(pair->src_name); - message_progress_end(success); - } + // Assume that something goes wrong. + bool success = false; + + // Read the first chunk of input data. This is needed to detect + // the input file type (for now, only for decompression). + strm.next_in = in_buf.u8; + strm.avail_in = io_read(pair, &in_buf, IO_BUFFER_SIZE); + + if (strm.avail_in != SIZE_MAX) { + // Initialize the coder. This will detect the file format + // and, in decompression or testing mode, check the memory + // usage of the first Block too. This way we don't try to + // open the destination file if we see that coding wouldn't + // work at all anyway. This also avoids deleting the old + // "target" file if --force was used. + const enum coder_init_ret init_ret = coder_init(pair); + + if (init_ret != CODER_INIT_ERROR && !user_abort) { + // Initialize the progress indicator. + const uint64_t in_size + = pair->src_st.st_size <= 0 + ? 0 : pair->src_st.st_size; + message_progress_start(&strm, in_size); + + // Do the actual coding or passthru. + if (init_ret == CODER_INIT_NORMAL) + success = coder_normal(pair); + else + success = coder_passthru(pair); + + message_progress_end(success); } - - // Close the file pair. It needs to know if coding was successful to - // know if the source or target file should be unlinked. - io_close(&pairs[i], success); } + // Close the file pair. It needs to know if coding was successful to + // know if the source or target file should be unlinked. + io_close(pair, success); + return; } Modified: soc2013/dpl/head/contrib/xz/src/xz/coder.h ============================================================================== --- soc2013/dpl/head/contrib/xz/src/xz/coder.h Wed Jul 17 14:15:00 2013 (r254889) +++ soc2013/dpl/head/contrib/xz/src/xz/coder.h Wed Jul 17 17:17:16 2013 (r254890) @@ -58,4 +58,4 @@ extern void coder_set_compression_settings(void); /// Compress or decompress the given file -extern void coder_run(file_pair *pairs[], int files); +extern void coder_run(file_pair *pairs); Modified: soc2013/dpl/head/contrib/xz/src/xz/file_io.c ============================================================================== --- soc2013/dpl/head/contrib/xz/src/xz/file_io.c Wed Jul 17 14:15:00 2013 (r254889) +++ soc2013/dpl/head/contrib/xz/src/xz/file_io.c Wed Jul 17 17:17:16 2013 (r254890) @@ -91,7 +91,7 @@ /// a small unavoidable race, but this is much better than nothing (the file /// could have been moved/replaced even hours earlier). static void -io_unlink(const char *name, const struct stat *known_st) +io_unlink(file_pair *pair, int dest) { #if defined(TUKLIB_DOSLIKE) // On DOS-like systems, st_ino is meaningless, so don't bother @@ -99,6 +99,19 @@ (void)known_st; #else struct stat new_st; + const char *name; + int fd; + struct stat *known_st; + //const char *name, int *fd, int *dirfd, const struct stat *known_st) + if (dest) { + name = pair->dest_name; + fd = &pair->dest_fd; + known_st = &pair->dest_st; + } else { + name = pair->src_name; + fd = &pair->src_fd; + known_st = &pair->src_st; + } // If --force was used, use stat() instead of lstat(). This way // (de)compressing symlinks works correctly. However, it also means @@ -110,7 +123,8 @@ // Probably it's not too bad though, so this doesn't need a more // complex fix. const int stat_ret = opt_force - ? stat(name, &new_st) : lstat(name, &new_st); + ? fstatat(pair->dir_fd, basename(name), &new_st, 0) + : fstatat(pair->dir_fd, basename(name), &new_st, AT_SYMLINK_NOFOLLOW); if (stat_ret # ifdef __VMS @@ -140,7 +154,7 @@ #endif // There's a race condition between lstat() and unlink() // but at least we have tried to avoid removing wrong file. - if (unlink(name)) + if (unlinkat(pair->dir_fd, basename(name), 0)) message_error(_("%s: Cannot remove: %s"), name, strerror(errno)); @@ -355,6 +369,9 @@ // doesn't hurt to have it just in case. do { pair->src_fd = open(pair->src_name, flags); +#if defined(CAPSICUM) + pair->dir_fd = open( dirname(pair->src_name), O_DIRECTORY); +#endif } while (pair->src_fd == -1 && errno == EINTR && !user_abort); if (!reg_files_only) @@ -513,36 +530,26 @@ if (is_empty_filename(src_name)) return NULL; - // Since we have only one file open at a time, we can use - // a statically allocated structure. - static file_pair pair; - - pair = (file_pair){ - .src_name = src_name, - .dest_name = NULL, - .src_fd = -1, - .dest_fd = -1, - .src_eof = false, - .dest_try_sparse = false, - .dest_pending_sparse = 0, - }; + file_pair *pair; + + pair = (file_pair*)malloc(sizeof(file_pair)); + pair->src_name = src_name; + pair->dest_name = NULL; + pair->dir_fd = -1; + pair->src_fd = -1; + pair->dest_fd = -1; + pair->src_eof = false; + pair->dest_try_sparse = false; + pair->dest_pending_sparse = 0; -/* pair = (file_pair *)malloc(sizeof(file_pair);*/ -/* pair.src_name = src_name;*/ -/* pair.dest_name = NULL;*/ -/* pair.src_fd = -1;*/ -/* pair.dest_fd = -1;*/ -/* pair.src_eof = false;*/ -/* pair.dest_try_sparse = false;*/ -/* pair.dest_pending_sparse = 0;*/ // Block the signals, for which we have a custom signal handler, so // that we don't need to worry about EINTR. signals_block(); - const bool error = io_open_src_real(&pair); + const bool error = io_open_src_real(pair); signals_unblock(); - return error ? NULL : &pair; + return error ? NULL : pair; } @@ -567,7 +574,7 @@ // NOTE: DOS-like systems are an exception to this, because // they don't allow unlinking files that are open. *sigh* if (success && !opt_keep_original) - io_unlink(pair->src_name, &pair->src_st); + io_unlink(pair, 0); #ifndef TUKLIB_DOSLIKE (void)close(pair->src_fd); @@ -694,7 +701,9 @@ io_open_dest(file_pair *pair) { signals_block(); - const bool ret = io_open_dest_real(pair); + bool ret = true; + if(pair != NULL) + ret = io_open_dest_real(pair); signals_unblock(); return ret; } @@ -736,15 +745,15 @@ // Closing destination file failed, so we cannot trust its // contents. Get rid of junk: - io_unlink(pair->dest_name, &pair->dest_st); + io_unlink(pair, 1); free(pair->dest_name); return true; } - // If the operation using this file wasn't successful, we git rid + // If the operation using this file wasn't successful, we get rid // of the junk file. if (!success) - io_unlink(pair->dest_name, &pair->dest_st); + io_unlink(pair, 1); free(pair->dest_name); @@ -797,6 +806,8 @@ signals_unblock(); + free(pair); + return; } @@ -966,48 +977,36 @@ } extern file_pair ** -io_list_open(char *filename[], int files) +io_open_files(char *filename[], int files) { int i; - file_pair *pairs[files]; + file_pair **pairs = (file_pair **)malloc(files * sizeof(file_pair *)); - //Open files a la list_file() - if (opt_format != FORMAT_XZ && opt_format != FORMAT_AUTO) - message_fatal(_("--list works only on .xz files " - "(--format=xz or --format=auto)")); - + if( opt_mode == MODE_LIST) + if (opt_format != FORMAT_XZ && opt_format != FORMAT_AUTO) + message_fatal(_("--list works only on .xz files " + "(--format=xz or --format=auto)")); + for ( i = 0; i < files; i++) { + if (filename[i] == NULL) { + break; + } + // Set and possibly print the filename for the progress message. message_filename(filename[i]); - - if (filename[i] == stdin_filename) { - message_error(_("--list does not support reading from " - "standard input")); - continue; - } - - // Unset opt_stdout so that io_open_src() won't accept special files. - // Set opt_force so that io_open_src() will follow symlinks. - opt_stdout = false; - opt_force = true; - pairs[i] = io_open_src(filename[i]); -#if defined(CAPSICUM) - limitfd(pairs[i]); -#endif - } - return pairs; -} -extern file_pair ** -io_coder_open(char *filename[], int files) -{ - int i; - file_pair *pairs[files]; + if (opt_mode == MODE_LIST) { + if (filename[i] == stdin_filename) { + message_error(_("--list does not support reading from " + "standard input")); + break; + } + + // Unset opt_stdout so that io_open_src() won't accept special files. + // Set opt_force so that io_open_src() will follow symlinks. + opt_stdout = false; + opt_force = true; + } - for ( i = 0; i < files; i++) { - // Set and possibly print the filename for the progress message. - message_filename(filename[i]); - - // Try to open the input file. pairs[i] = io_open_src(filename[i]); if( opt_mode != MODE_TEST ) io_open_dest(pairs[i]); @@ -1015,7 +1014,6 @@ limitfd(pairs[i]); #endif } - return pairs; } @@ -1023,19 +1021,31 @@ extern void limitfd(file_pair *pair) { - cap_rights_t rights = 0; + cap_rights_t rights; - rights |= CAP_READ; - if (cap_rights_limit(pair->src_fd, rights) < 0 && errno != ENOSYS){ - message_error("%s: %s", pair->src_name, strerror(errno)); - exit(E_ERROR); + if(pair->dir_fd != -1 ){ + rights = CAP_FSTATAT|CAP_UNLINKAT|CAP_LOOKUP; + if (cap_rights_limit(pair->dir_fd, rights) < 0 && errno != ENOSYS){ + message_error("%s: %s", pair->dest_name, strerror(errno)); + exit(E_ERROR); + } } - rights |= CAP_WRITE|CAP_FSTAT|CAP_FCHOWN; - rights |= CAP_FCHMOD|CAP_FUTIMES; - if (cap_rights_limit(pair->dest_fd, rights) < 0 && errno != ENOSYS){ - message_error("%s: %s", pair->dest_name, strerror(errno)); - exit(E_ERROR); + if(pair->src_fd != -1 ){ + rights = CAP_READ|CAP_SEEK; + if (cap_rights_limit(pair->src_fd, rights) < 0 && errno != ENOSYS){ + message_error("%s: %s", pair->src_name, strerror(errno)); + exit(E_ERROR); + } + } + + if(pair->dest_fd != -1 ){ + rights = CAP_WRITE|CAP_FSTAT|CAP_FCHOWN + |CAP_FCHMOD|CAP_FUTIMES; + if (cap_rights_limit(pair->dest_fd, rights) < 0 && errno != ENOSYS){ + message_error("%s: %s", pair->dest_name, strerror(errno)); + exit(E_ERROR); + } } return; } @@ -1043,29 +1053,28 @@ extern void cap_init(void) { - cap_rights_t *rights; + cap_rights_t rights; - if( cap_rights_get(STDIN_FILENO, rights) < 0) { + if( cap_rights_get(STDIN_FILENO, &rights) < 0 && errno != ENOSYS) { message_error("%d: %s", STDIN_FILENO, strerror(errno)); exit(E_ERROR); - } else if (*rights == 0) { + } else if (rights == 0) { if (cap_rights_limit(STDIN_FILENO, CAP_WRITE) < 0 && errno != ENOSYS){ message_error("%d: %s", STDIN_FILENO, strerror(errno)); exit(E_ERROR); } } - if( cap_rights_get(STDOUT_FILENO, rights) < 0) { + if( cap_rights_get(STDOUT_FILENO, &rights) < 0 && errno != ENOSYS) { message_error("%d: %s", STDOUT_FILENO, strerror(errno)); exit(E_ERROR); - } else if (*rights == 0) { + } else if (rights == 0) { if (cap_rights_limit(STDOUT_FILENO, CAP_WRITE) < 0 && errno != ENOSYS){ message_error("%d: %s", STDOUT_FILENO, strerror(errno)); exit(E_ERROR); } } - if (cap_rights_limit(STDERR_FILENO, CAP_WRITE) < 0 && errno != ENOSYS){ message_error("%d: %s", STDERR_FILENO, strerror(errno)); exit(E_ERROR); Modified: soc2013/dpl/head/contrib/xz/src/xz/file_io.h ============================================================================== --- soc2013/dpl/head/contrib/xz/src/xz/file_io.h Wed Jul 17 14:15:00 2013 (r254889) +++ soc2013/dpl/head/contrib/xz/src/xz/file_io.h Wed Jul 17 17:17:16 2013 (r254890) @@ -93,21 +93,14 @@ extern bool io_write(file_pair *pair, const io_buf *buf, size_t size); -/// \brief Open all the files as needed in lit_file(). +/// \brief Open all the files as needed. /// /// \param filenames Array containing all the filenames to be open. /// \param files Number of files to open. /// /// \return Returns an array of file_pairs. -extern file_pair ** io_list_open(char *filenames[], int files); +extern file_pair ** io_open_files(char *filenames[], int files); -/// \brief Open all the files as needed in coder_run(). -/// -/// \param filenames Array containing all the filenames to be open. -/// \param files Number of files to open. -/// -/// \return Returns an array of file_pairs. -extern file_pair ** io_coder_open(char *filenames[], int files); #if defined(CAPSICUM) /// \brief Limits fd using FreeBSD's Capsicum framework. Modified: soc2013/dpl/head/contrib/xz/src/xz/list.c ============================================================================== --- soc2013/dpl/head/contrib/xz/src/xz/list.c Wed Jul 17 14:15:00 2013 (r254889) +++ soc2013/dpl/head/contrib/xz/src/xz/list.c Wed Jul 17 17:17:16 2013 (r254890) @@ -1057,9 +1057,8 @@ extern void -list_file(file_pair pairs[], int files) +list_file(file_pair *pair) { - int i; xz_file_info xfi = XZ_FILE_INFO_INIT; // Unset opt_stdout so that io_open_src() won't accept special files. @@ -1067,35 +1066,34 @@ opt_stdout = false; opt_force = true; - for (i = 0; i < files; i++) { - if (pairs[i] == NULL) - continue; - - if (!parse_indexes(&xfi, pairs[i])) { - bool fail; - - // We have three main modes: - // - --robot, which has submodes if --verbose is specified - // once or twice - // - Normal --list without --verbose - // - --list with one or two --verbose - if (opt_robot) - fail = print_info_robot(&xfi, pairs[i]); - else if (message_verbosity_get() <= V_WARNING) - fail = print_info_basic(&xfi, pairs[i]); - else - fail = print_info_adv(&xfi, pairs[i]); - - // Update the totals that are displayed after all - // the individual files have been listed. Don't count - // broken files. - if (!fail) - update_totals(&xfi); - - lzma_index_end(xfi.idx, NULL); - } - - io_close(pairs[i], false); + if (pair == NULL) + return; + + if (!parse_indexes(&xfi, pair)) { + bool fail; + + // We have three main modes: + // - --robot, which has submodes if --verbose is specified + // once or twice + // - Normal --list without --verbose + // - --list with one or two --verbose + if (opt_robot) + fail = print_info_robot(&xfi, pair); + else if (message_verbosity_get() <= V_WARNING) + fail = print_info_basic(&xfi, pair); + else + fail = print_info_adv(&xfi, pair); + + // Update the totals that are displayed after all + // the individual files have been listed. Don't count + // broken files. + if (!fail) + update_totals(&xfi); + + lzma_index_end(xfi.idx, NULL); } + + io_close(pair, false); + return; } Modified: soc2013/dpl/head/contrib/xz/src/xz/list.h ============================================================================== --- soc2013/dpl/head/contrib/xz/src/xz/list.h Wed Jul 17 14:15:00 2013 (r254889) +++ soc2013/dpl/head/contrib/xz/src/xz/list.h Wed Jul 17 17:17:16 2013 (r254890) @@ -11,7 +11,7 @@ /////////////////////////////////////////////////////////////////////////////// /// \brief List information about the given .xz file -extern void list_file(const char *filename); +extern void list_file(file_pair *pairs); /// \brief Show the totals after all files have been listed Modified: soc2013/dpl/head/contrib/xz/src/xz/main.c ============================================================================== --- soc2013/dpl/head/contrib/xz/src/xz/main.c Wed Jul 17 14:15:00 2013 (r254889) +++ soc2013/dpl/head/contrib/xz/src/xz/main.c Wed Jul 17 17:17:16 2013 (r254890) @@ -55,7 +55,7 @@ } -static const char * +static char * read_name(const args_info *args) { // FIXME: Maybe we should have some kind of memory usage limit here @@ -142,8 +142,7 @@ int main(int argc, char **argv) { - int files = 0; - + int forkpid, i, nfiles = 0; #if defined(_WIN32) && !defined(__CYGWIN__) InitializeCriticalSection(&exit_status_cs); #endif @@ -208,13 +207,9 @@ signals_init(); // Separate opening the files from list_file() and coder_run() - // We have to limit both functions with Capsicum. - file_pair * (*open)(const char **filename, int files) = opt_mode == MODE_LIST - ? &io_list_open : &io_coder_open; - // coder_run() handles compression, decompression, and testing. // list_file() is for --list. - void (*run)(const file_pair *pairs, int files) = opt_mode == MODE_LIST + void (*run)(file_pair *pair) = opt_mode == MODE_LIST ? &list_file : &coder_run; // Process the files given on the command line. Note that if no names @@ -248,14 +243,10 @@ // string and the code still knows that it is // handling the special case of stdin. args.arg_names[i] = (char *)stdin_filename; - files++; } + nfiles++; } - file_pair pairs[files] = open(args.arg_names, files); - cap_init(); - run(pairs, files); - // If --files or --files0 was used, process the filenames from the // given file or stdin. Note that here we don't consider "-" to // indicate stdin like we do with the command line arguments. @@ -263,19 +254,46 @@ // read_name() checks for user_abort so we don't need to // check it as loop termination condition. while (true) { - const char *name = read_name(&args); + char *name = read_name(&args); + printf("name: %s\n", name); if (name == NULL) break; // read_name() doesn't return empty names. assert(name[0] != '\0'); - run(name); + args.arg_count++; + args.arg_names[nfiles] = name; + nfiles++; } if (args.files_name != stdin_filename) (void)fclose(args.files_file); } + printf("nfiles: %d\n", nfiles); + for ( i = 0; (size_t)i < args.arg_count; i++) + printf("file: %s\n", args.arg_names[i]); + + file_pair **pairs = io_open_files(args.arg_names, nfiles); + + for( i = 0; i < nfiles; i++){ +#if defined(CAPSICUM) + if ( (forkpid = fork()) == -1 ){ + message_error("%d: %s", STDERR_FILENO, strerror(errno)); + exit(E_ERROR); + } else if ( forkpid != 0) { + /* Let the children compress */ + wait(NULL); + } else if (forkpid == 0){ + cap_init(); +#endif + run(pairs[i]); +#if defined(CAPSICUM) + exit(0); + } +#endif + } + // All files have now been handled. If in --list mode, display // the totals before exiting. We don't have signal handlers // enabled in --list mode, so we don't need to check user_abort. Modified: soc2013/dpl/head/contrib/xz/src/xz/main.h ============================================================================== --- soc2013/dpl/head/contrib/xz/src/xz/main.h Wed Jul 17 14:15:00 2013 (r254889) +++ soc2013/dpl/head/contrib/xz/src/xz/main.h Wed Jul 17 17:17:16 2013 (r254890) @@ -17,6 +17,8 @@ E_WARNING = 2, }; +// To be used with unlinkat(), fstatat() at io_close(). +int dirfd; /// Sets the exit status after a warning or error has occurred. If new_status /// is E_WARNING and the old exit status was already E_ERROR, the exit Modified: soc2013/dpl/head/contrib/xz/src/xz/private.h ============================================================================== --- soc2013/dpl/head/contrib/xz/src/xz/private.h Wed Jul 17 14:15:00 2013 (r254889) +++ soc2013/dpl/head/contrib/xz/src/xz/private.h Wed Jul 17 17:17:16 2013 (r254890) @@ -32,6 +32,8 @@ # if __FreeBSD_version >= 900041 # define CAPSICUM # include +# include +# include # endif #endif @@ -61,6 +63,11 @@ /// "(stdout)" when writing to standard output. char *dest_name; +#if defined(CAPSICUM) + // File descriptor of the directory where the files are. + int dir_fd; +#endif + /// File descriptor of the source file int src_fd;