fix building w/ABIs that have broken stat structures
If the system's stat buffer is broken and doesn't declare st_dev as a
dev_t, we hit a build failure when we try to pass it into a func that
expects a dev_t.
Add some checks to handle this case. It produces the same code on sane
ABIs, so other than ugliness, it should be fine.
BUG=chromium:358419
TEST=`emerge-link rootdev` produces same code
TEST=`emerge-daisy rootdev` produces same code
TEST=`emerge-mipsel-o32-generic rootdev` now works
Change-Id: I956436e0c40318c8f2ac61b2e202ec739132c245
Reviewed-on: https://chromium-review.googlesource.com/192550
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Commit-Queue: Mike Frysinger <vapier@chromium.org>
Tested-by: Mike Frysinger <vapier@chromium.org>
diff --git a/rootdev.c b/rootdev.c
index 76c931c..ea88b39 100644
--- a/rootdev.c
+++ b/rootdev.c
@@ -404,16 +404,28 @@
int rootdev(char *path, size_t size, bool full, bool strip) {
struct stat root_statbuf;
+ dev_t _root_dev, *root_dev = &_root_dev;
/* Yields the containing dev_t in st_dev. */
if (stat("/", &root_statbuf) != 0)
return -1;
+ /* Some ABIs (like mips o32) are broken and the st_dev field isn't actually
+ * a dev_t. In that case, pass a pointer to a local dev_t who we took care
+ * of truncating the value into. On sane arches, gcc can optimize this to
+ * the same code, so should only be a penalty when the ABI is broken. */
+ if (sizeof(root_statbuf.st_dev) == sizeof(*root_dev)) {
+ /* Cast is OK since we verified size here. */
+ root_dev = (dev_t *)&root_statbuf.st_dev;
+ } else {
+ *root_dev = root_statbuf.st_dev;
+ }
+
return rootdev_wrapper(path,
size,
full,
strip,
- &root_statbuf.st_dev,
+ root_dev,
NULL, /* default /sys dir */
NULL); /* default /dev dir */
}