Cleaup read() and write() variants, plus a couple of new functions like
xlseek and fdlength() for the new mkswap.
This commit is contained in:
@@ -46,10 +46,8 @@ const char *change_identity_e2str ( const struct passwd *pw )
|
||||
return "cannot set groups";
|
||||
endgrent ( );
|
||||
|
||||
if ( setgid ( pw-> pw_gid ))
|
||||
return "cannot set group id";
|
||||
if ( setuid ( pw->pw_uid ))
|
||||
return "cannot set user id";
|
||||
xsetgid(pw-> pw_gid);
|
||||
xsetuid(pw->pw_uid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,24 +30,24 @@ static ssize_t bb_full_fd_action(int src_fd, int dst_fd, size_t size)
|
||||
if (src_fd < 0) goto out;
|
||||
while (!size || total < size)
|
||||
{
|
||||
ssize_t wrote, xread;
|
||||
ssize_t wr, rd;
|
||||
|
||||
xread = safe_read(src_fd, buffer,
|
||||
rd = safe_read(src_fd, buffer,
|
||||
(!size || size - total > BUFSIZ) ? BUFSIZ : size - total);
|
||||
|
||||
if (xread > 0) {
|
||||
if (rd > 0) {
|
||||
/* A -1 dst_fd means we need to fake it... */
|
||||
wrote = (dst_fd < 0) ? xread : bb_full_write(dst_fd, buffer, xread);
|
||||
if (wrote < xread) {
|
||||
wr = (dst_fd < 0) ? rd : full_write(dst_fd, buffer, rd);
|
||||
if (wr < rd) {
|
||||
bb_perror_msg(bb_msg_write_error);
|
||||
break;
|
||||
}
|
||||
total += wrote;
|
||||
total += wr;
|
||||
if (total == size) status = 0;
|
||||
} else if (xread < 0) {
|
||||
} else if (rd < 0) {
|
||||
bb_perror_msg(bb_msg_read_error);
|
||||
break;
|
||||
} else if (xread == 0) {
|
||||
} else if (rd == 0) {
|
||||
/* All done. */
|
||||
status = 0;
|
||||
break;
|
||||
|
||||
@@ -32,7 +32,7 @@ int create_icmp6_socket(void)
|
||||
}
|
||||
|
||||
/* drop root privs if running setuid */
|
||||
setuid(getuid());
|
||||
xsetuid(getuid());
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ int create_icmp_socket(void)
|
||||
}
|
||||
|
||||
/* drop root privs if running setuid */
|
||||
setuid(getuid());
|
||||
xsetuid(getuid());
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* Returns the amount read, or -1 on an error.
|
||||
* A short read is returned on an end of file.
|
||||
*/
|
||||
ssize_t bb_full_read(int fd, void *buf, size_t len)
|
||||
ssize_t full_read(int fd, void *buf, size_t len)
|
||||
{
|
||||
ssize_t cc;
|
||||
ssize_t total;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* This does multiple writes as necessary.
|
||||
* Returns the amount written, or -1 on an error.
|
||||
*/
|
||||
ssize_t bb_full_write(int fd, const void *buf, size_t len)
|
||||
ssize_t full_write(int fd, const void *buf, size_t len)
|
||||
{
|
||||
ssize_t cc;
|
||||
ssize_t total;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Utility routines.
|
||||
*
|
||||
* Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
|
||||
* Copyright (C) 2005 by Rob Landley <rob@landley.net>
|
||||
*
|
||||
* Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
|
||||
*/
|
||||
|
||||
@@ -120,40 +120,55 @@ int bb_xopen3(const char *pathname, int flags, int mode)
|
||||
#endif
|
||||
|
||||
#ifdef L_xread
|
||||
ssize_t bb_xread(int fd, void *buf, size_t count)
|
||||
|
||||
// Die with an error message if we can't read the entire buffer.
|
||||
|
||||
void xread(int fd, void *buf, size_t count)
|
||||
{
|
||||
ssize_t size;
|
||||
|
||||
size = read(fd, buf, count);
|
||||
if (size < 0) {
|
||||
bb_perror_msg_and_die(bb_msg_read_error);
|
||||
}
|
||||
return(size);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_xread_all
|
||||
void bb_xread_all(int fd, void *buf, size_t count)
|
||||
{
|
||||
ssize_t size;
|
||||
|
||||
while (count) {
|
||||
if ((size = bb_xread(fd, buf, count)) == 0) { /* EOF */
|
||||
ssize_t size;
|
||||
|
||||
if ((size = safe_read(fd, buf, count)) < 1)
|
||||
bb_error_msg_and_die("Short read");
|
||||
}
|
||||
count -= size;
|
||||
buf = ((char *) buf) + size;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_xwrite
|
||||
|
||||
// Die with an error message if we can't write the entire buffer.
|
||||
|
||||
void xwrite(int fd, void *buf, size_t count)
|
||||
{
|
||||
while (count) {
|
||||
ssize_t size;
|
||||
|
||||
if ((size = safe_write(fd, buf, count)) < 1)
|
||||
bb_error_msg_and_die("Short write");
|
||||
count -= size;
|
||||
buf = ((char *) buf) + size;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_xlseek
|
||||
|
||||
// Die if we can't lseek to the right spot.
|
||||
|
||||
void xlseek(int fd, off_t offset, int whence)
|
||||
{
|
||||
if (whence != lseek(fd, offset, whence)) bb_error_msg_and_die("lseek");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_xread_char
|
||||
unsigned char bb_xread_char(int fd)
|
||||
unsigned char xread_char(int fd)
|
||||
{
|
||||
char tmp;
|
||||
|
||||
bb_xread_all(fd, &tmp, 1);
|
||||
xread(fd, &tmp, 1);
|
||||
|
||||
return(tmp);
|
||||
}
|
||||
@@ -294,3 +309,41 @@ void xsetuid(uid_t uid)
|
||||
if (setuid(uid)) bb_error_msg_and_die("setuid");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef L_fdlength
|
||||
off_t fdlength(int fd)
|
||||
{
|
||||
off_t bottom = 0, top = 0, pos;
|
||||
long size;
|
||||
|
||||
// If the ioctl works for this, return it.
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE, &size) >= 0) return size*512;
|
||||
|
||||
// If not, do a binary search for the last location we can read.
|
||||
|
||||
do {
|
||||
char temp;
|
||||
|
||||
pos = bottom + (top - bottom) / 2;;
|
||||
|
||||
// If we can read from the current location, it's bigger.
|
||||
|
||||
if (lseek(fd, pos, 0)>=0 && safe_read(fd, &temp, 1)==1) {
|
||||
if (bottom == top) bottom = top = (top+1) * 2;
|
||||
else bottom = pos;
|
||||
|
||||
// If we can't, it's smaller.
|
||||
|
||||
} else {
|
||||
if (bottom == top) {
|
||||
if (!top) return 0;
|
||||
bottom = top/2;
|
||||
}
|
||||
else top = pos;
|
||||
}
|
||||
} while (bottom + 1 != top);
|
||||
|
||||
return pos + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user