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 */ }