libbb: prevent xmalloc_open_read_close from dying on seek failure

start_stop_daemon: use open_read_close instead of xmalloc_open_read_close
start_stop_daemon: use local structure instead of global one

function                                             old     new   delta
check                                               1620    1661     +41
xmalloc_open_read_close                              171     190     +19
start_stop_daemon_main                               976     954     -22
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 60/-22)             Total: 38 bytes
This commit is contained in:
Denis Vlasenko 2008-04-20 01:27:59 +00:00
parent 5b3adae7e8
commit 25cfe4996e
2 changed files with 32 additions and 29 deletions

View File

@ -32,7 +32,6 @@ struct globals {
int user_id; int user_id;
smallint quiet; smallint quiet;
smallint signal_nr; smallint signal_nr;
struct stat execstat;
}; };
#define G (*(struct globals*)&bb_common_bufsiz1) #define G (*(struct globals*)&bb_common_bufsiz1)
#define found (G.found ) #define found (G.found )
@ -43,7 +42,6 @@ struct globals {
#define user_id (G.user_id ) #define user_id (G.user_id )
#define quiet (G.quiet ) #define quiet (G.quiet )
#define signal_nr (G.signal_nr ) #define signal_nr (G.signal_nr )
#define execstat (G.execstat )
#define INIT_G() \ #define INIT_G() \
do { \ do { \
user_id = -1; \ user_id = -1; \
@ -53,12 +51,13 @@ struct globals {
static int pid_is_exec(pid_t pid) static int pid_is_exec(pid_t pid)
{ {
struct stat st; struct stat st, execstat;
char buf[sizeof("/proc//exe") + sizeof(int)*3]; char buf[sizeof("/proc//exe") + sizeof(int)*3];
sprintf(buf, "/proc/%u/exe", pid); sprintf(buf, "/proc/%u/exe", pid);
if (stat(buf, &st) < 0) if (stat(buf, &st) < 0)
return 0; return 0;
xstat(execname, &execstat);
if (st.st_dev == execstat.st_dev if (st.st_dev == execstat.st_dev
&& st.st_ino == execstat.st_ino) && st.st_ino == execstat.st_ino)
return 1; return 1;
@ -78,24 +77,21 @@ static int pid_is_user(int pid)
static int pid_is_cmd(pid_t pid) static int pid_is_cmd(pid_t pid)
{ {
char fname[sizeof("/proc//stat") + sizeof(int)*3]; char buf[256]; /* is it big enough? */
char *buf; char *p, *pe;
int r = 0;
sprintf(fname, "/proc/%u/stat", pid); sprintf(buf, "/proc/%u/stat", pid);
buf = xmalloc_open_read_close(fname, NULL); if (open_read_close(buf, buf, sizeof(buf) - 1) < 0)
if (buf) { return 0;
char *p = strchr(buf, '('); buf[sizeof(buf) - 1] = '\0'; /* paranoia */
if (p) { p = strchr(buf, '(');
char *pe = strrchr(++p, ')'); if (!p)
if (pe) { return 0;
*pe = '\0'; pe = strrchr(++p, ')');
r = !strcmp(p, cmdname); if (!pe)
} return 0;
} *pe = '\0';
free(buf); return !strcmp(p, cmdname);
}
return r;
} }
static void check(int pid) static void check(int pid)
@ -303,8 +299,6 @@ int start_stop_daemon_main(int argc ATTRIBUTE_UNUSED, char **argv)
if (errno) if (errno)
user_id = xuname2uid(userspec); user_id = xuname2uid(userspec);
} }
if (execname)
xstat(execname, &execstat);
do_procinit(); /* Both start and stop needs to know current processes */ do_procinit(); /* Both start and stop needs to know current processes */

View File

@ -208,25 +208,34 @@ ssize_t open_read_close(const char *filename, void *buf, size_t size)
void *xmalloc_open_read_close(const char *filename, size_t *sizep) void *xmalloc_open_read_close(const char *filename, size_t *sizep)
{ {
char *buf; char *buf;
size_t size = sizep ? *sizep : INT_MAX; size_t size;
int fd; int fd;
off_t len; off_t len;
fd = open(filename, O_RDONLY); fd = open(filename, O_RDONLY);
if (fd < 0) if (fd < 0)
return NULL; return NULL;
/* /proc/N/stat files report len 0 here */ /* /proc/N/stat files report len 0 here */
/* In order to make such files readable, we add small const */ /* In order to make such files readable, we add small const */
len = xlseek(fd, 0, SEEK_END) | 0x3ff; /* + up to 1k */ size = 0x3ff; /* read only 1k on unseekable files */
xlseek(fd, 0, SEEK_SET); len = lseek(fd, 0, SEEK_END) | 0x3ff; /* + up to 1k */
if (len < size) if (len != (off_t)-1) {
size = len; xlseek(fd, 0, SEEK_SET);
size = sizep ? *sizep : INT_MAX;
if (len < size)
size = len;
}
buf = xmalloc(size + 1); buf = xmalloc(size + 1);
size = read_close(fd, buf, size); size = read_close(fd, buf, size);
if ((ssize_t)size < 0) if ((ssize_t)size < 0) {
bb_perror_msg_and_die("'%s'", filename); free(buf);
return NULL;
}
xrealloc(buf, size + 1); xrealloc(buf, size + 1);
buf[size] = '\0'; buf[size] = '\0';
if (sizep) if (sizep)
*sizep = size; *sizep = size;
return buf; return buf;