diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs index 22cdb5a11765d94a26d256532a2523d88ed9decb..86892cb97c19bcb7fdc5868a20f01fad1ad3ff7a 100644 --- a/src/header/stdlib/mod.rs +++ b/src/header/stdlib/mod.rs @@ -25,6 +25,7 @@ use crate::{ }; mod lcg48; +mod random; mod sort; pub const EXIT_FAILURE: c_int = 1; @@ -369,9 +370,31 @@ pub extern "C" fn grantpt(fildes: c_int) -> c_int { unimplemented!(); } -// #[no_mangle] -pub extern "C" fn initstate(seec: c_uint, state: *mut c_char, size: size_t) -> *mut c_char { - unimplemented!(); +#[no_mangle] +pub unsafe extern "C" fn initstate(seed: c_uint, state: *mut c_char, size: size_t) -> *mut c_char { + // Ported from musl + + if size < 8 { + ptr::null_mut() + } else { + // TODO: lock? + let old_state = random::save_state(); + random::N = match size { + 0..=7 => unreachable!(), // ensured above + 8..=31 => 0, + 32..=63 => 7, + 64..=127 => 15, + 128..=255 => 31, + _ => 63, + }; + + random::X_PTR = (state as *mut u32).offset(1); + random::seed(seed); + random::save_state(); + // TODO: unlock? + + old_state as _ + } } #[no_mangle] @@ -731,9 +754,37 @@ pub unsafe extern "C" fn rand_r(seed: *mut c_uint) -> c_int { } } -// #[no_mangle] -pub extern "C" fn random() -> c_long { - unimplemented!(); +#[no_mangle] +pub unsafe extern "C" fn random() -> c_long { + // Ported from musl + + let k: u32; + // TODO: lock? + random::ensure_x_ptr_init(); + + if random::N == 0 { + *random::X_PTR = random::lcg31_step(*random::X_PTR); + k = *random::X_PTR; + } else { + *random::X_PTR.add(usize::from(random::I)) += *random::X_PTR.add(usize::from(random::J)); + + k = *random::X_PTR.add(usize::from(random::I)) >> 1; + + random::I += 1; + if random::I == random::N { + random::I = 0; + } + + random::J += 1; + if random::J == random::N { + random::J = 0; + } + } + // TODO: unlock? + + /* Both branches of this function result in a "u31", which will + * always fit in a c_long. */ + c_long::try_from(k).unwrap() } #[no_mangle] @@ -858,9 +909,16 @@ pub extern "C" fn setkey(key: *const c_char) { unimplemented!(); } -// #[no_mangle] -pub extern "C" fn setstate(state: *const c_char) -> *mut c_char { - unimplemented!(); +#[no_mangle] +pub unsafe extern "C" fn setstate(state: *mut c_char) -> *mut c_char { + /* Ported from musl. The state parameter is no longer const in newer + * versions of POSIX. */ + + // TODO: lock? + let old_state = random::save_state(); + random::load_state(state as *mut u32); + // TODO: unlock? + old_state as _ } #[no_mangle] @@ -879,9 +937,13 @@ pub unsafe extern "C" fn srand48(seedval: c_long) { lcg48::DEFAULT_XSUBI = lcg48::ushort_arr3_from_u48(xsubi_value); } -// #[no_mangle] -pub extern "C" fn srandom(seed: c_uint) { - unimplemented!(); +#[no_mangle] +pub unsafe extern "C" fn srandom(seed: c_uint) { + // Ported from musl + + // TODO: lock? + random::seed(seed); + // TODO: unlock? } #[no_mangle] diff --git a/src/header/stdlib/random.rs b/src/header/stdlib/random.rs new file mode 100644 index 0000000000000000000000000000000000000000..b390d5e487b8d3754cc8564ae170e86ce1167067 --- /dev/null +++ b/src/header/stdlib/random.rs @@ -0,0 +1,89 @@ +//! Helper functions for random() and friends, see https://pubs.opengroup.org/onlinepubs/7908799/xsh/initstate.html +/* Ported from musl's implementation (src/prng/random.c). Does not + * currently implement locking, though. */ + +use crate::platform::types::*; +use core::{convert::TryFrom, ptr}; + +#[rustfmt::skip] +static mut X_INIT: [u32; 32] = [ + 0x00000000, 0x5851f42d, 0xc0b18ccf, 0xcbb5f646, + 0xc7033129, 0x30705b04, 0x20fd5db4, 0x9a8b7f78, + 0x502959d8, 0xab894868, 0x6c0356a7, 0x88cdb7ff, + 0xb477d43f, 0x70a3a52b, 0xa8e4baf1, 0xfd8341fc, + 0x8ae16fd9, 0x742d2f7a, 0x0d1f0796, 0x76035e09, + 0x40f7702c, 0x6fa72ca5, 0xaaa84157, 0x58a0df74, + 0xc74a0364, 0xae533cc4, 0x04185faf, 0x6de3b115, + 0x0cab8628, 0xf043bfa4, 0x398150e9, 0x37521657, +]; + +/* N needs to accommodate values up to 63, corresponding to the maximum + * state array size of 256 bytes. I and J must be able to accommodate + * values less than or equal to N. */ +pub static mut N: u8 = 31; +pub static mut I: u8 = 3; +pub static mut J: u8 = 0; + +/* Unlike in C, we can't take the address of the initializing array + * outside of a function. */ +pub static mut X_PTR: *mut u32 = ptr::null_mut(); + +// To be called in any function that may read from X_PTR +pub unsafe fn ensure_x_ptr_init() { + if X_PTR.is_null() { + X_PTR = &mut X_INIT[1]; + } +} + +pub fn lcg31_step(x: u32) -> u32 { + 1103515245_u32.wrapping_mul(x).wrapping_add(12345_u32) & 0x7fffffff +} + +pub fn lcg64_step(x: u64) -> u64 { + 6364136223846793005_u64.wrapping_mul(x).wrapping_add(1_u64) +} + +pub unsafe fn save_state() -> *mut u32 { + ensure_x_ptr_init(); + *X_PTR.offset(-1) = (u32::from(N) << 16) | (u32::from(I) << 8) | u32::from(J); + X_PTR.offset(-1) +} + +pub unsafe fn load_state(state_ptr: *mut u32) { + let prev_x = *state_ptr; + X_PTR = state_ptr.offset(1); + + /* This calculation of N does not have a bit mask in the musl + * original, in principle resulting in a u16, but obtaining a value + * larger than 63 can probably be dismissed as pathological. */ + N = u8::try_from((prev_x >> 16) & 0xff).unwrap(); + + // I and J calculations are straight from musl + I = u8::try_from((prev_x >> 8) & 0xff).unwrap(); + J = u8::try_from(prev_x & 0xff).unwrap(); +} + +pub unsafe fn seed(seed: c_uint) { + ensure_x_ptr_init(); + + let mut s = seed as u64; + + if N == 0 { + *X_PTR = s as u32; + } else { + I = if N == 31 || N == 7 { 3 } else { 1 }; + + J = 0; + + for k in 0..usize::from(N) { + s = lcg64_step(s); + + // Conversion will always succeed (value is a 32-bit right- + // shift of a 64-bit integer). + *X_PTR.add(k) = u32::try_from(s >> 32).unwrap(); + } + + // ensure X contains at least one odd number + *X_PTR |= 1; + } +} diff --git a/tests/Makefile b/tests/Makefile index 594b17d6d422ec88370babeb16786e6652b4adc7..4efe68130ad690ed53516fbcb14196b3be677146 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -56,6 +56,7 @@ EXPECT_NAMES=\ stdlib/lcg48 \ stdlib/mkostemps \ stdlib/rand \ + stdlib/random \ stdlib/strtod \ stdlib/strtol \ stdlib/strtoul \ diff --git a/tests/expected/stdlib/random.stderr b/tests/expected/stdlib/random.stderr new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/expected/stdlib/random.stdout b/tests/expected/stdlib/random.stdout new file mode 100644 index 0000000000000000000000000000000000000000..9a754a9eb6cd5e6ee01d0392925a499cb96e34b0 --- /dev/null +++ b/tests/expected/stdlib/random.stdout @@ -0,0 +1,1011 @@ +Uninitialized: +262836907 +2022765545 +1985587709 +1559253607 +547725525 +1277054513 +317849018 +1695317205 +643446864 +1262735440 +964614733 +622582094 +280266812 +1939173898 +732650777 +1270232897 +336669216 +1669264236 +554325996 +1080138202 +1193538846 +2016671310 +1114491314 +2115358120 +2122955106 +982493572 +450262557 +439534734 +1723376538 +2066693252 +901041 +1986213445 +1941975150 +1986488750 +1397983404 +342217027 +1116059615 +1715832423 +2037534232 +1759506479 +831084215 +854665318 +234604926 +1111351027 +646355568 +967255703 +234100276 +983024785 +489036291 +788426273 +2063162987 +1682575137 +657613935 +1030170653 +1650449610 +633085394 +2012664225 +2100712167 +1072620128 +1588557116 +2019921771 +1073521169 +1427286913 +1814413273 +912526271 +677786670 +9146653 +2028585886 +246135445 +2046680885 + +Seed 1: +262836907 +2022765545 +1985587709 +1559253607 +547725525 +1277054513 +317849018 +1695317205 +643446864 +1262735440 +964614733 +622582094 +280266812 +1939173898 +732650777 +1270232897 +336669216 +1669264236 +554325996 +1080138202 +1193538846 +2016671310 +1114491314 +2115358120 +2122955106 +982493572 +450262557 +439534734 +1723376538 +2066693252 +901041 +1986213445 +1941975150 +1986488750 +1397983404 +342217027 +1116059615 +1715832423 +2037534232 +1759506479 +831084215 +854665318 +234604926 +1111351027 +646355568 +967255703 +234100276 +983024785 +489036291 +788426273 +2063162987 +1682575137 +657613935 +1030170653 +1650449610 +633085394 +2012664225 +2100712167 +1072620128 +1588557116 +2019921771 +1073521169 +1427286913 +1814413273 +912526271 +677786670 +9146653 +2028585886 +246135445 +2046680885 + +Seed 1337: +1124688561 +1792831582 +1708122057 +1060061055 +2060905921 +703006049 +867046930 +1599327113 +1946461956 +1851068511 +2107308161 +1080994526 +361067458 +2035914970 +1577981791 +72922558 +783590643 +1752267570 +1350489214 +1338091804 +225460930 +62532035 +540341638 +1391100769 +1535109757 +2039272559 +206716062 +1139547941 +462353593 +1176324546 +1766476968 +1587042155 +821672480 +1327115377 +499619562 +735094753 +2030121427 +1366666492 +186938219 +1829099735 +1070251355 +146762732 +762610613 +1431318813 +35194054 +193108756 +1504241371 +818784698 +1945376326 +707246937 +9392854 +23353608 +769778973 +549734493 +1414454377 +157405082 +441523404 +1621170440 +1296953024 +903876997 +650011338 +915946344 +343435504 +1471683818 +95578073 +843055066 +59294924 +2125699500 +62237911 +246233143 + +Seed 42, size 8: +1250496027 +1116302264 +1000676753 +1668674806 +908095735 +71666532 +896336333 +1736731266 +1314989459 +1535244752 +391441865 +1108520142 +1206814703 +534045436 +1974836613 +238077914 +1413854219 +705377000 +397905153 +1440974758 +1972995559 +282367380 +881784893 +1823504434 +879663491 +70219520 +1215814457 +1726604670 +318196447 +1939145516 +1030877685 +968547210 +1513076219 +1793402392 +1673312369 +1341335126 +481933015 +1376947140 +1980983981 +529748450 +192473459 +2072944688 +631833769 +202943022 +2012129743 +762679132 +1776566885 +562641722 +542512107 +293225800 +266051553 +1950339334 +562037703 +932343284 +1167153437 +829945746 +711923043 +392328544 +485452313 +748288734 +1303618751 +1013548940 +1115918037 +1967580906 +210226651 +149786744 +1677411153 +1109690294 +2007723191 +1000815652 + +Seed 42, size 31: +1250496027 +1116302264 +1000676753 +1668674806 +908095735 +71666532 +896336333 +1736731266 +1314989459 +1535244752 +391441865 +1108520142 +1206814703 +534045436 +1974836613 +238077914 +1413854219 +705377000 +397905153 +1440974758 +1972995559 +282367380 +881784893 +1823504434 +879663491 +70219520 +1215814457 +1726604670 +318196447 +1939145516 +1030877685 +968547210 +1513076219 +1793402392 +1673312369 +1341335126 +481933015 +1376947140 +1980983981 +529748450 +192473459 +2072944688 +631833769 +202943022 +2012129743 +762679132 +1776566885 +562641722 +542512107 +293225800 +266051553 +1950339334 +562037703 +932343284 +1167153437 +829945746 +711923043 +392328544 +485452313 +748288734 +1303618751 +1013548940 +1115918037 +1967580906 +210226651 +149786744 +1677411153 +1109690294 +2007723191 +1000815652 + +Seed 42, size 32: +1105844101 +1165395678 +461296413 +1259424640 +70225557 +1467961981 +315013290 +1176069659 +485874011 +776309703 +288010651 +556099569 +96788036 +603023941 +1732169228 +582662048 +1379333644 +2020179879 +1138761617 +1476121681 +475720173 +723447197 +2058783729 +1855053817 +596143428 +1050061698 +1183691850 +1071863601 +1773508895 +1094991931 +779433771 +222168675 +2145053629 +1963125621 +1294032277 +1771078876 +910633905 +2073466048 +1993247552 +908203886 +1889108021 +1139796181 +531799115 +652258278 +1065778581 +377563019 +1560462165 +807402954 +1517359200 +2092261280 +1459661233 +435654133 +322340651 +872639750 +1243057087 +1839699851 +817417382 +555234672 +127870336 +1139758033 +1427874422 +1370927423 +831974236 +97808156 +1926162096 +959844572 +1237566189 +1206552870 +183288347 +2069540425 + +Seed 42, size 63: +1105844101 +1165395678 +461296413 +1259424640 +70225557 +1467961981 +315013290 +1176069659 +485874011 +776309703 +288010651 +556099569 +96788036 +603023941 +1732169228 +582662048 +1379333644 +2020179879 +1138761617 +1476121681 +475720173 +723447197 +2058783729 +1855053817 +596143428 +1050061698 +1183691850 +1071863601 +1773508895 +1094991931 +779433771 +222168675 +2145053629 +1963125621 +1294032277 +1771078876 +910633905 +2073466048 +1993247552 +908203886 +1889108021 +1139796181 +531799115 +652258278 +1065778581 +377563019 +1560462165 +807402954 +1517359200 +2092261280 +1459661233 +435654133 +322340651 +872639750 +1243057087 +1839699851 +817417382 +555234672 +127870336 +1139758033 +1427874422 +1370927423 +831974236 +97808156 +1926162096 +959844572 +1237566189 +1206552870 +183288347 +2069540425 + +Seed 42, size 64: +2058979096 +1114567745 +1168098319 +1326828429 +585052544 +738633083 +1597984519 +103976400 +637164838 +949355699 +301019638 +1539653489 +829283131 +1994476715 +899306595 +810802043 +1925369788 +945984460 +125329241 +710381785 +1449014869 +899515740 +1003492141 +1640656979 +442529030 +743548669 +135718510 +965001641 +811994708 +1711301303 +374619698 +152505839 +1098490299 +1223819540 +1934201325 +1235732546 +2135248287 +991256780 +484430111 +926959142 +1670507811 +1806226321 +623744314 +1435739022 +999556678 +1374176376 +1526682215 +477688866 +1701508406 +1488226084 +576474982 +564239621 +1555496401 +2039926513 +819402007 +342426170 +1168843 +624913157 +2060652179 +912725209 +139417938 +1666100153 +2143789020 +1697813778 +1038556214 +1615031197 +31787170 +1587283572 +1479726437 +151644796 + +Seed 42, size 127: +2058979096 +1114567745 +1168098319 +1326828429 +585052544 +738633083 +1597984519 +103976400 +637164838 +949355699 +301019638 +1539653489 +829283131 +1994476715 +899306595 +810802043 +1925369788 +945984460 +125329241 +710381785 +1449014869 +899515740 +1003492141 +1640656979 +442529030 +743548669 +135718510 +965001641 +811994708 +1711301303 +374619698 +152505839 +1098490299 +1223819540 +1934201325 +1235732546 +2135248287 +991256780 +484430111 +926959142 +1670507811 +1806226321 +623744314 +1435739022 +999556678 +1374176376 +1526682215 +477688866 +1701508406 +1488226084 +576474982 +564239621 +1555496401 +2039926513 +819402007 +342426170 +1168843 +624913157 +2060652179 +912725209 +139417938 +1666100153 +2143789020 +1697813778 +1038556214 +1615031197 +31787170 +1587283572 +1479726437 +151644796 + +Seed 42, size 128: +1105844101 +1165395678 +461296413 +1259424640 +2024747114 +1114771942 +1792613078 +189454326 +466435881 +883763281 +1626567616 +1631629466 +1277725798 +1234887654 +657326752 +1836263319 +715263951 +471085233 +2086498417 +1163602145 +1547997976 +1405363974 +632333445 +201224285 +286947872 +1468210882 +103627486 +2147177614 +373040761 +1110293054 +1202766264 +1478884863 +128205084 +1664062677 +590825855 +5468550 +631350971 +235955286 +194922877 +1097786852 +1119718567 +1821490493 +581932670 +249960717 +908894499 +1239259422 +2086224037 +1624158450 +1710344655 +2025238806 +640276948 +1110858983 +1283119132 +1272610393 +1312083268 +1570067004 +593337627 +1415710754 +1569760970 +966378389 +378520161 +625043586 +297779604 +506725245 +141622615 +888605459 +512193796 +772973586 +1124560745 +707116673 + +Seed 42, size 255: +1105844101 +1165395678 +461296413 +1259424640 +2024747114 +1114771942 +1792613078 +189454326 +466435881 +883763281 +1626567616 +1631629466 +1277725798 +1234887654 +657326752 +1836263319 +715263951 +471085233 +2086498417 +1163602145 +1547997976 +1405363974 +632333445 +201224285 +286947872 +1468210882 +103627486 +2147177614 +373040761 +1110293054 +1202766264 +1478884863 +128205084 +1664062677 +590825855 +5468550 +631350971 +235955286 +194922877 +1097786852 +1119718567 +1821490493 +581932670 +249960717 +908894499 +1239259422 +2086224037 +1624158450 +1710344655 +2025238806 +640276948 +1110858983 +1283119132 +1272610393 +1312083268 +1570067004 +593337627 +1415710754 +1569760970 +966378389 +378520161 +625043586 +297779604 +506725245 +141622615 +888605459 +512193796 +772973586 +1124560745 +707116673 + +Seed 42, size 256: +2058979096 +1114567745 +1168098319 +1326828429 +585052544 +738633083 +1597984519 +103976400 +637164838 +949355699 +301019638 +1539653489 +829283131 +1994476715 +240955585 +1996759270 +1022456556 +1580994077 +1061370374 +875128855 +1125363953 +1573702147 +503131242 +1969480447 +1438211747 +91438056 +1120505602 +1956383039 +1858786240 +1571532334 +1295962411 +342691299 +190922750 +587812343 +1882440834 +1251108553 +1546539316 +237235092 +229958515 +1788514159 +1180131104 +1278005195 +1236529116 +1834489224 +2008240486 +153071308 +1122241977 +1443493489 +827253675 +1844422894 +1615942404 +1444719301 +1322997186 +2068652336 +1108669174 +1117641112 +329168079 +1033958612 +870068653 +1235189147 +1628422544 +186507460 +1238820988 +1150316436 +117400533 +1285498853 +464843634 +1049896178 +1788529262 +1239030133 + +Seed 42, other state array: +1105844101 +1165395678 +461296413 +1259424640 +70225557 +1467961981 +315013290 +1176069659 +485874011 +776309703 +288010651 +556099569 +96788036 +603023941 +1732169228 +582662048 +1379333644 +2020179879 +1138761617 +1476121681 +475720173 +723447197 +2058783729 +1855053817 +596143428 +1050061698 +1183691850 +1071863601 +1773508895 +1094991931 +779433771 +222168675 +2145053629 +1963125621 +1294032277 +1771078876 +910633905 +2073466048 +1993247552 +908203886 +1889108021 +1139796181 +531799115 +652258278 +1065778581 +377563019 +1560462165 +807402954 +1517359200 +2092261280 +1459661233 +435654133 +322340651 +872639750 +1243057087 +1839699851 +817417382 +555234672 +127870336 +1139758033 +1427874422 +1370927423 +831974236 +97808156 +1926162096 +959844572 +1237566189 +1206552870 +183288347 +2069540425 + +State data pointer restored correctly by setstate(). + +Seed 42, back to first state array: +1343006534 +1980171372 +782043423 +1083063062 +475232903 +1304516034 +1151509101 +1392464686 +1241740309 +116713217 +1697707295 +611594021 +1486722877 +464603182 +2038305329 +393952924 +215949723 +1654161471 +1745599527 +718621482 +527520873 +238823465 +1810355799 +958834563 +1301525862 +1492448612 +2080260955 +1815218141 +918843046 +317898715 +555133807 +785092322 +426122834 +1606253938 +736775485 +1973304601 +1660310177 +1521067015 +1674138324 +648896653 +2092390142 +772160169 +469099415 +2085041819 +1382277472 +557791010 +478959698 +1587628873 +557786337 +886954417 +1920913029 +643498035 +1878687182 +1359626079 +1546133539 +637470879 +1787787315 +1905187849 +1043203054 +1508046688 +410459218 +51504832 +1290534966 +486057852 +318745576 +1100789000 +36368414 +511601317 +1816117351 +820142804 + +Pointer returned by initstate with size < 8: (nil) diff --git a/tests/stdlib/random.c b/tests/stdlib/random.c new file mode 100644 index 0000000000000000000000000000000000000000..1c468613464593386f32ab3edb84f32c94a7558f --- /dev/null +++ b/tests/stdlib/random.c @@ -0,0 +1,100 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "test_helpers.h" + +/* The output of these tests are checked against that from musl. Other + * algorithms may yield different results and still comply with the + * POSIX requirements. */ + +int main(void) { + /* Should be enough to exercise the rollover branching in random() + * for all possible state array sizes (up to 256 bytes, i.e. 64 + * 32-bit values). */ + size_t test_seq_len = 70; + + long random_result; + + // Should give same result as with seed 1 + puts("Uninitialized:"); + for (size_t i = 0; i < test_seq_len; i++) { + random_result = random(); + printf("%ld\n", random_result); + } + + puts("\nSeed 1:"); + srandom(1); + for (size_t i = 0; i < test_seq_len; i++) { + random_result = random(); + printf("%ld\n", random_result); + } + + puts("\nSeed 1337:"); + srandom(1337); + for (size_t i = 0; i < test_seq_len; i++) { + random_result = random(); + printf("%ld\n", random_result); + } + + /* 256 bytes (as below) is the largest possible amount of state + * data. Created as a uint32_t to avoid possible alignment issues + * with char. */ + uint32_t new_state[64] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + unsigned int seed = 42; + + // Should exercise the different branches in initstate() + size_t sizes[] = {8, 31, 32, 63, 64, 127, 128, 255, 256}; + + for (size_t j = 0; j < sizeof(sizes)/sizeof(size_t); j++) { + size_t size = sizes[j]; + printf("\nSeed %d, size %ld:\n", seed, size); + initstate(seed, (char *)new_state, size); + + for (size_t i = 0; i < test_seq_len; i++) { + random_result = random(); + printf("%ld\n", random_result); + } + } + + /* Test that setstate() allows the use of a different state array, + * and that it correctly returns the old value. */ + uint32_t other_new_state[64] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + initstate(seed, (char *)other_new_state, 32); + printf("\nSeed %d, other state array:\n", seed); + for (size_t i = 0; i < test_seq_len; i++) { + random_result = random(); + printf("%ld\n", random_result); + } + + char *should_be_other_new_state_ptr = setstate((char *)new_state); + if (should_be_other_new_state_ptr == (char *)other_new_state) { + puts("\nState data pointer restored correctly by setstate()."); + } + else { + puts("\nState data pointer NOT restored correctly by setstate()."); + } + printf("\nSeed %d, back to first state array:\n", seed); + for (size_t i = 0; i < test_seq_len; i++) { + random_result = random(); + printf("%ld\n", random_result); + } + + // Should yield NULL + char *state_with_size_less_than_8 = initstate(seed, (char *)new_state, 7); + printf("\nPointer returned by initstate with size < 8: %p\n", + state_with_size_less_than_8); + + return 0; +}