diff options
author | Mike Frysinger <vapier@chromium.org> | 2014-04-01 02:17:20 -0400 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-04-01 23:21:47 +0000 |
commit | 7d9288a0745aa50dbcb0bb692241f0eee679254b (patch) | |
tree | 82eb157a8b0c1194363d30a8d746f1b68edafda6 | |
parent | 515197db4f204bf942b4d4f57bd994cc2e7e9c0c (diff) | |
download | rootdev-7d9288a0745aa50dbcb0bb692241f0eee679254b.tar.gz |
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>
-rw-r--r-- | rootdev.c | 14 |
1 files changed, 13 insertions, 1 deletions
@@ -404,16 +404,28 @@ int rootdev_wrapper(char *path, size_t size, 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 */ } |