correct largefile support, add comments about it.
No binary (build failed)
—
(log yok)
| @@ -4,16 +4,16 @@ | |
| BB_VER = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) | |
| - | CPPFLAGS += \ |
| - | -Iinclude -Ilibbb \ |
| - | $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) -I$(srctree)/libbb \ |
| - | -include include/autoconf.h \ |
| - | -D_GNU_SOURCE -DNDEBUG \ |
| - | -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 \ |
| - | -D"BB_VER=KBUILD_STR($(BB_VER))" -DBB_BT=AUTOCONF_TIMESTAMP \ |
| - | -Wall -Wstrict-prototypes -Wshadow -Werror \ |
| - | -funsigned-char -fno-builtin-strlen -finline-limit=0 -static-libgcc \ |
| - | -Os -march=i386 -mpreferred-stack-boundary=2 \ |
| - | -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ |
| - | -fomit-frame-pointer -ffunction-sections -fdata-sections \ |
| - | -funsigned-char -fno-builtin-strlen \ |
| + | CPPFLAGS += \ |
| + | -Iinclude -Ilibbb \ |
| + | $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) -I$(srctree)/libbb \ |
| + | -include include/autoconf.h \ |
| + | -D_GNU_SOURCE -DNDEBUG \ |
| + | $(if $(CONFIG_LFS),-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64) \ |
| + | -D"BB_VER=KBUILD_STR($(BB_VER))" -DBB_BT=AUTOCONF_TIMESTAMP \ |
| + | -Wall -Wstrict-prototypes -Wshadow -Werror \ |
| + | -funsigned-char -fno-builtin-strlen -finline-limit=0 -static-libgcc \ |
| + | -Os -march=i386 -mpreferred-stack-boundary=2 \ |
| + | -falign-functions=1 -falign-jumps=1 -falign-loops=1 \ |
| + | -fomit-frame-pointer -ffunction-sections -fdata-sections \ |
| + | -funsigned-char -fno-builtin-strlen \ |
| @@ -376,7 +376,7 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, | |
| /* If it was a regular file, write out the body */ | |
| if (inputFileFd >= 0) { | |
| - | ssize_t readSize = 0; |
| + | off_t readSize = 0; |
| /* write the file to the archive */ | |
| readSize = bb_copyfd_eof(inputFileFd, tbInfo->tarFd); | |
| @@ -51,7 +51,6 @@ typedef union { | |
| } formatted ATTRIBUTE_PACKED; | |
| } zip_header_t; | |
| - | /* This one never works with LARGEFILE-sized skips */ |
| static void unzip_skip(int fd, off_t skip) | |
| { | |
| if (lseek(fd, skip, SEEK_CUR) == (off_t)-1) { | |
| @@ -75,7 +74,7 @@ static int unzip_extract(zip_header_t *zip_header, int src_fd, int dst_fd) | |
| { | |
| if (zip_header->formatted.method == 0) { | |
| /* Method 0 - stored (not compressed) */ | |
| - | int size = zip_header->formatted.ucmpsize; |
| + | off_t size = zip_header->formatted.ucmpsize; |
| if (size && (bb_copyfd_size(src_fd, dst_fd, size) != size)) { | |
| bb_error_msg_and_die("cannot complete extraction"); | |
| } | |
| @@ -202,7 +201,7 @@ int unzip_main(int argc, char **argv) | |
| } | |
| if (src_fd == -1) { | |
| src_fn[orig_src_fn_len] = 0; | |
| - | bb_error_msg_and_die("Cannot open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn); |
| + | bb_error_msg_and_die("cannot open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn); |
| } | |
| } | |
| @@ -4,7 +4,7 @@ | |
| * | |
| * Copyright (C) 2003 Manuel Novoa III <[email protected]> | |
| * | |
| - | * Licensed under GPLv2 or later, see file License in this tarball for details. |
| + | * Licensed under GPLv2, see file License in this tarball for details. |
| */ | |
| /* BB_AUDIT SUSv3 compliant */ | |
| @@ -26,8 +26,9 @@ int cat_main(int argc, char **argv) | |
| } | |
| do { | |
| - | if ((f = bb_wfopen_input(*argv)) != NULL) { |
| - | int r = bb_copyfd_eof(fileno(f), STDOUT_FILENO); |
| + | f = bb_wfopen_input(*argv); |
| + | if (f) { |
| + | off_t r = bb_copyfd_eof(fileno(f), STDOUT_FILENO); |
| bb_fclose_nonstdin(f); | |
| if (r >= 0) { | |
| continue; | |
| @@ -15,7 +15,7 @@ | |
| int catv_main(int argc, char **argv) | |
| { | |
| int retval = EXIT_SUCCESS, fd; | |
| - | unsigned long flags; |
| + | unsigned flags; |
| flags = getopt32(argc, argv, "etv"); | |
| #define CATV_OPT_e (1<<0) | |
| @@ -51,8 +51,8 @@ int catv_main(int argc, char **argv) | |
| } | |
| if (c < 32) { | |
| if (c == 10) { | |
| - | if (flags & CATV_OPT_e) |
| - | putchar('$'); |
| + | if (flags & CATV_OPT_e) |
| + | putchar('$'); |
| } else if (flags & (c==9 ? CATV_OPT_t : CATV_OPT_v)) { | |
| bb_printf("^%c", c+'@'); | |
| continue; | |
| @@ -25,12 +25,12 @@ static const struct suffix_mult dd_suffixes[] = { | |
| { NULL, 0 } | |
| }; | |
| - | static FILEOFF_TYPE out_full, out_part, in_full, in_part; |
| + | static off_t out_full, out_part, in_full, in_part; |
| static void dd_output_status(int ATTRIBUTE_UNUSED cur_signal) | |
| { | |
| - | bb_fprintf(stderr, FILEOFF_FMT"+"FILEOFF_FMT" records in\n" |
| - | FILEOFF_FMT"+"FILEOFF_FMT" records out\n", |
| + | bb_fprintf(stderr, OFF_FMT"+"OFF_FMT" records in\n" |
| + | OFF_FMT"+"OFF_FMT" records out\n", |
| in_full, in_part, | |
| out_full, out_part); | |
| } | |
| @@ -44,7 +44,7 @@ int dd_main(int argc, char **argv) | |
| int flags = trunc_flag; | |
| size_t oc = 0, ibs = 512, obs = 512; | |
| ssize_t n; | |
| - | FILEOFF_TYPE seek = 0, skip = 0, count = MAX_FILEOFF_TYPE; |
| + | off_t seek = 0, skip = 0, count = OFF_T_MAX; |
| int oflag, ifd, ofd; | |
| const char *infile = NULL, *outfile = NULL; | |
| char *ibuf, *obuf; | |
| @@ -108,14 +108,14 @@ int dd_main(int argc, char **argv) | |
| obuf = ibuf; | |
| if (infile != NULL) | |
| - | ifd = xopen(infile, O_RDONLY | (O_LARGEFILE * ENABLE_LFS)); |
| + | ifd = xopen(infile, O_RDONLY); |
| else { | |
| ifd = STDIN_FILENO; | |
| infile = bb_msg_standard_input; | |
| } | |
| if (outfile != NULL) { | |
| - | oflag = O_WRONLY | O_CREAT | (O_LARGEFILE * ENABLE_LFS); |
| + | oflag = O_WRONLY | O_CREAT; |
| if (!seek && (flags & trunc_flag)) | |
| oflag |= O_TRUNC; | |
| @@ -137,7 +137,7 @@ int dd_main(int argc, char **argv) | |
| } | |
| if (skip) { | |
| - | if (LSEEK(ifd, skip * ibs, SEEK_CUR) < 0) { |
| + | if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) { |
| while (skip-- > 0) { | |
| n = safe_read(ifd, ibuf, ibs); | |
| if (n < 0) | |
| @@ -149,7 +149,7 @@ int dd_main(int argc, char **argv) | |
| } | |
| if (seek) { | |
| - | if (LSEEK(ofd, seek * obs, SEEK_CUR) < 0) |
| + | if (lseek(ofd, seek * obs, SEEK_CUR) < 0) |
| goto die_outfile; | |
| } | |
| @@ -112,9 +112,9 @@ static int chattr_dir_proc(const char *, struct dirent *, void *); | |
| static void change_attributes(const char * name) | |
| { | |
| unsigned long fsflags; | |
| - | STRUCT_STAT st; |
| + | struct stat st; |
| - | if (LSTAT(name, &st) == -1) { |
| + | if (lstat(name, &st) == -1) { |
| bb_error_msg("stat %s failed", name); | |
| return; | |
| } | |
| @@ -72,9 +72,9 @@ static int lsattr_dir_proc(const char *, struct dirent *, void *); | |
| static void lsattr_args(const char *name) | |
| { | |
| - | STRUCT_STAT st; |
| + | struct stat st; |
| - | if (LSTAT(name, &st) == -1) { |
| + | if (lstat(name, &st) == -1) { |
| bb_perror_msg("stating %s", name); | |
| } else { | |
| if (S_ISDIR(st.st_mode) && !(flags & OPT_DIRS_OPT)) | |
| @@ -87,12 +87,12 @@ static void lsattr_args(const char *name) | |
| static int lsattr_dir_proc(const char *dir_name, struct dirent *de, | |
| void *private) | |
| { | |
| - | STRUCT_STAT st; |
| + | struct stat st; |
| char *path; | |
| path = concat_path_file(dir_name, de->d_name); | |
| - | if (LSTAT(path, &st) == -1) |
| + | if (lstat(path, &st) == -1) |
| bb_perror_msg(path); | |
| else { | |
| if (de->d_name[0] != '.' || (flags & OPT_ALL)) { | |
| @@ -33,12 +33,12 @@ void proceed_question(void) | |
| void check_plausibility(const char *device, int force) | |
| { | |
| int val; | |
| - | STRUCT_STAT s; |
| - | val = STAT(device, &s); |
| + | struct stat s; |
| + | val = stat(device, &s); |
| if (force) | |
| return; | |
| if(val == -1) | |
| - | bb_perror_msg_and_die("Could not stat %s", device); |
| + | bb_perror_msg_and_die("cannot stat %s", device); |
| if (!S_ISBLK(s.st_mode)) { | |
| printf("%s is not a block special device.\n", device); | |
| proceed_question(); | |
| @@ -61,30 +61,56 @@ | |
| #define PATH_MAX 256 | |
| #endif | |
| + | /* Not (yet) used, but tested to work correctly |
| + | #define MAXINT(T) (T)( \ |
| + | ((T)-1) > 0 \ |
| + | ? (T)-1 \ |
| + | : (T)~((T)1 << (sizeof(T)*8-1)) \ |
| + | ) |
| + | |
| + | #define MININT(T) (T)( \ |
| + | ((T)-1) > 0 \ |
| + | ? (T)0 \ |
| + | : ((T)1 << (sizeof(T)*8-1)) \ |
| + | ) |
| + | */ |
| + | |
| /* Large file support */ | |
| - | #ifdef CONFIG_LFS |
| - | # define FILEOFF_TYPE off64_t |
| - | # define FILEOFF_FMT "%lld" |
| - | # define LSEEK lseek64 |
| - | # define STAT stat64 |
| - | # define LSTAT lstat64 |
| - | # define STRUCT_STAT struct stat64 |
| - | # define STRTOOFF strtoll |
| - | # define SAFE_STRTOOFF safe_strtoll |
| + | /* Note that CONFIG_LFS forces bbox to be built with all common ops |
| + | * (stat, lseek etc) mapped to "largefile" variants by libc. |
| + | * Practically it means that open() automatically has O_LARGEFILE added |
| + | * and all filesize/file_offset parameters and struct members are "large" |
| + | * (in today's world - signed 64bit). For full support of large files, |
| + | * we need a few helper #defines (below) and careful use of off_t |
| + | * instead of int/ssize_t. No lseek64(), O_LARGEFILE etc necessary */ |
| + | #if ENBALE_LFS |
| + | /* CONFIG_LFS is on */ |
| + | # if ULONG_MAX > 0xffffffff |
| + | /* "long" is long enough on this system */ |
| + | # define STRTOOFF strtol |
| + | # define SAFE_STRTOOFF safe_strtol |
| + | # define OFF_FMT "%ld" |
| + | # else |
| + | /* "long" is too short, need "lomg long" */ |
| + | # define STRTOOFF strtoll |
| + | # define SAFE_STRTOOFF safe_strtoll |
| + | # define OFF_FMT "%lld" |
| + | # endif |
| #else | |
| - | # define FILEOFF_TYPE off_t |
| - | # define FILEOFF_FMT "%ld" |
| - | # define LSEEK lseek |
| - | # define STAT stat |
| - | # define LSTAT lstat |
| - | # define STRUCT_STAT struct stat |
| - | # define STRTOOFF strtol |
| - | # define SAFE_STRTOOFF safe_strtol |
| - | /* Do we need to undefine O_LARGEFILE? */ |
| + | # if 0 /* UINT_MAX == 0xffffffff */ |
| + | /* Doesn't work. off_t is a long. gcc will throw warnings on printf("%d", off_t) |
| + | * even if long==int on this arch. Crap... */ |
| + | # define STRTOOFF strtol |
| + | # define SAFE_STRTOOFF safe_strtoi |
| + | # define OFF_FMT "%d" |
| + | # else |
| + | # define STRTOOFF strtol |
| + | # define SAFE_STRTOOFF safe_strtol |
| + | # define OFF_FMT "%ld" |
| + | # endif |
| #endif | |
| /* scary. better ideas? (but do *test* them first!) */ | |
| - | #define MAX_FILEOFF_TYPE \ |
| - | ((FILEOFF_TYPE)~((FILEOFF_TYPE)1 << (sizeof(FILEOFF_TYPE)*8-1))) |
| + | #define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1))) |
| /* Some useful definitions */ | |
| #undef FALSE | |
| @@ -203,8 +229,8 @@ extern char *find_block_device(char *path); | |
| extern char *bb_get_line_from_file(FILE *file); | |
| extern char *bb_get_chomped_line_from_file(FILE *file); | |
| extern char *bb_get_chunk_from_file(FILE *file, int *end); | |
| - | extern int bb_copyfd_size(int fd1, int fd2, const off_t size); |
| - | extern int bb_copyfd_eof(int fd1, int fd2); |
| + | extern off_t bb_copyfd_size(int fd1, int fd2, off_t size); |
| + | extern off_t bb_copyfd_eof(int fd1, int fd2); |
| extern char bb_process_escape_sequence(const char **ptr); | |
| extern char *bb_get_last_path_component(char *path); | |
| extern FILE *bb_wfopen(const char *path, const char *mode); | |
| @@ -21,10 +21,10 @@ | |
| #endif | |
| - | static ssize_t bb_full_fd_action(int src_fd, int dst_fd, size_t size) |
| + | static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size) |
| { | |
| int status = -1; | |
| - | size_t total = 0; |
| + | off_t total = 0; |
| RESERVE_CONFIG_BUFFER(buffer,BUFSIZ); | |
| if (src_fd < 0) goto out; | |
| @@ -56,11 +56,11 @@ static ssize_t bb_full_fd_action(int src_fd, int dst_fd, size_t size) | |
| out: | |
| RELEASE_CONFIG_BUFFER(buffer); | |
| - | return status ? status : (ssize_t)total; |
| + | return status ? status : total; |
| } | |
| - | int bb_copyfd_size(int fd1, int fd2, const off_t size) |
| + | off_t bb_copyfd_size(int fd1, int fd2, off_t size) |
| { | |
| if (size) { | |
| return bb_full_fd_action(fd1, fd2, size); | |
| @@ -68,7 +68,7 @@ int bb_copyfd_size(int fd1, int fd2, const off_t size) | |
| return 0; | |
| } | |
| - | int bb_copyfd_eof(int fd1, int fd2) |
| + | off_t bb_copyfd_eof(int fd1, int fd2) |
| { | |
| return bb_full_fd_action(fd1, fd2, 0); | |
| } | |
| @@ -133,7 +133,9 @@ int set_loop(char **device, const char *file, unsigned long long offset) | |
| without using losetup manually is problematic.) | |
| */ | |
| } else if (strcmp(file,(char *)loopinfo.lo_file_name) | |
| - | || offset!=loopinfo.lo_offset) rc = -1; |
| + | || offset != loopinfo.lo_offset) { |
| + | rc = -1; |
| + | } |
| close(dfd); | |
| try_again: | |
| if (*device) break; | |
| @@ -104,9 +104,11 @@ static FILE *ftp_login(ftp_host_info_t *server) | |
| } | |
| #if !ENABLE_FTPGET | |
| - | #define ftp_receive 0 |
| + | int ftp_receive(ftp_host_info_t *server, FILE *control_stream, |
| + | const char *local_path, char *server_path); |
| #else | |
| - | static int ftp_receive(ftp_host_info_t *server, FILE *control_stream, |
| + | static |
| + | int ftp_receive(ftp_host_info_t *server, FILE *control_stream, |
| const char *local_path, char *server_path) | |
| { | |
| char buf[512]; | |
| @@ -122,10 +124,8 @@ static int ftp_receive(ftp_host_info_t *server, FILE *control_stream, | |
| fd_data = xconnect_ftpdata(server, buf); | |
| if (ftpcmd("SIZE ", server_path, control_stream, buf) == 213) { | |
| - | unsigned long value=filesize; |
| - | if (safe_strtoul(buf + 4, &value)) |
| + | if (SAFE_STRTOOFF(buf + 4, &filesize)) |
| bb_error_msg_and_die("SIZE error: %s", buf + 4); | |
| - | filesize = value; |
| } else { | |
| filesize = -1; | |
| do_continue = 0; | |
| @@ -139,7 +139,7 @@ static int ftp_receive(ftp_host_info_t *server, FILE *control_stream, | |
| if (do_continue) { | |
| struct stat sbuf; | |
| if (lstat(local_path, &sbuf) < 0) { | |
| - | bb_perror_msg_and_die("fstat()"); |
| + | bb_perror_msg_and_die("lstat"); |
| } | |
| if (sbuf.st_size > 0) { | |
| beg_range = sbuf.st_size; | |
| @@ -149,7 +149,7 @@ static int ftp_receive(ftp_host_info_t *server, FILE *control_stream, | |
| } | |
| if (do_continue) { | |
| - | sprintf(buf, "REST %ld", (long)beg_range); |
| + | sprintf(buf, "REST "OFF_FMT, beg_range); |
| if (ftpcmd(buf, NULL, control_stream, buf) != 350) { | |
| do_continue = 0; | |
| } else { | |
| @@ -191,9 +191,11 @@ static int ftp_receive(ftp_host_info_t *server, FILE *control_stream, | |
| #endif | |
| #if !ENABLE_FTPPUT | |
| - | #define ftp_send 0 |
| + | int ftp_send(ftp_host_info_t *server, FILE *control_stream, |
| + | const char *server_path, char *local_path); |
| #else | |
| - | static int ftp_send(ftp_host_info_t *server, FILE *control_stream, |
| + | static |
| + | int ftp_send(ftp_host_info_t *server, FILE *control_stream, |
| const char *server_path, char *local_path) | |
| { | |
| struct stat sbuf; | |
| @@ -919,8 +919,8 @@ static int sendHeaders(HttpResponseNum responseNum) | |
| if (config->ContentLength != -1) { /* file */ | |
| strftime(timeStr, sizeof(timeStr), RFC1123FMT, gmtime(&config->last_mod)); | |
| - | len += sprintf(buf+len, "Last-Modified: %s\r\n%s "FILEOFF_FMT"\r\n", |
| - | timeStr, Content_length, (FILEOFF_TYPE) config->ContentLength); |
| + | len += sprintf(buf+len, "Last-Modified: %s\r\n%s "OFF_FMT"\r\n", |
| + | timeStr, Content_length, (off_t) config->ContentLength); |
| } | |
| strcat(buf, "\r\n"); | |
| len += 2; | |
| @@ -29,9 +29,9 @@ static char *gethdr(char *buf, size_t bufsiz, FILE *fp, int *istrunc); | |
| static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf); | |
| /* Globals (can be accessed from signal handlers */ | |
| - | static FILEOFF_TYPE content_len; /* Content-length of the file */ |
| - | static FILEOFF_TYPE beg_range; /* Range at which continue begins */ |
| - | static FILEOFF_TYPE transferred; /* Number of bytes transferred so far */ |
| + | static off_t content_len; /* Content-length of the file */ |
| + | static off_t beg_range; /* Range at which continue begins */ |
| + | static off_t transferred; /* Number of bytes transferred so far */ |
| static int chunked; /* chunked transfer encoding */ | |
| #ifdef CONFIG_FEATURE_WGET_STATUSBAR | |
| static void progressmeter(int flag); | |
| @@ -215,10 +215,10 @@ int wget_main(int argc, char **argv) | |
| opt |= WGET_OPT_QUIET; | |
| opt &= ~WGET_OPT_CONTINUE; | |
| } else if (opt & WGET_OPT_CONTINUE) { | |
| - | output_fd = open(fname_out, O_WRONLY|O_LARGEFILE); |
| + | output_fd = open(fname_out, O_WRONLY); |
| if (output_fd >= 0) { | |
| - | beg_range = LSEEK(output_fd, 0, SEEK_END); |
| - | if (beg_range == (FILEOFF_TYPE)-1) |
| + | beg_range = lseek(output_fd, 0, SEEK_END); |
| + | if (beg_range == (off_t)-1) |
| bb_perror_msg_and_die("lseek"); | |
| } | |
| /* File doesn't exist. We do not create file here yet. | |
| @@ -282,7 +282,7 @@ int wget_main(int argc, char **argv) | |
| #endif | |
| if (beg_range) | |
| - | fprintf(sfp, "Range: bytes="FILEOFF_FMT"-\r\n", beg_range); |
| + | fprintf(sfp, "Range: bytes="OFF_FMT"-\r\n", beg_range); |
| if(extra_headers_left < sizeof(extra_headers)) | |
| fputs(extra_headers,sfp); | |
| fprintf(sfp,"Connection: close\r\n\r\n"); | |
| @@ -413,7 +413,7 @@ read_response: | |
| dfp = open_socket(&s_in); | |
| if (beg_range) { | |
| - | sprintf(buf, "REST "FILEOFF_FMT, beg_range); |
| + | sprintf(buf, "REST "OFF_FMT, beg_range); |
| if (ftpcmd(buf, NULL, sfp, buf) == 350) | |
| content_len -= beg_range; | |
| } | |
| @@ -435,7 +435,7 @@ read_response: | |
| /* Do it before progressmeter (want to have nice error message) */ | |
| if (output_fd < 0) | |
| output_fd = xopen3(fname_out, | |
| - | O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_LARGEFILE, 0666); |
| + | O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0666); |
| if (!(opt & WGET_OPT_QUIET)) | |
| progressmeter(-1); | |
| @@ -685,10 +685,10 @@ static void | |
| progressmeter(int flag) | |
| { | |
| static struct timeval lastupdate; | |
| - | static FILEOFF_TYPE lastsize, totalsize; |
| + | static off_t lastsize, totalsize; |
| struct timeval now, td, tvwait; | |
| - | FILEOFF_TYPE abbrevsize; |
| + | off_t abbrevsize; |
| int elapsed, ratio, barlength, i; | |
| char buf[256]; | |
| @@ -739,7 +739,7 @@ progressmeter(int flag) | |
| if (tvwait.tv_sec >= STALLTIME) { | |
| fprintf(stderr, " - stalled -"); | |
| } else { | |
| - | FILEOFF_TYPE to_download = totalsize - beg_range; |
| + | off_t to_download = totalsize - beg_range; |
| if (transferred <= 0 || elapsed <= 0 || transferred > to_download || chunked) { | |
| fprintf(stderr, "--:--:-- ETA"); | |
| } else { | |