It's safe because all the environ_*() calls operate on the result of nih_str_array_new(). That function will return a block of memory big enough to hold a single 'char *' pointer, and set it to NULL. The NihAllocCtx is situated _below_ the return value of nih_str_array_new() in memory and that single NihAllocCtx will be used to keep track of the size and child allocations of the entire array (should it grow bigger than its current size of zero (the terminator is not counted)).
Subsequent to nih_str_array_new() being called, that zero-sized array will be increased in size by calls to environ_add(), which in turn calls nih_str_array_addp(). That latter function then calls nih_realloc() to increase the size of the single NihAllocCtx previously mentioned. So, if the array contains pointers to 10 env vars, it has size 11 (10 + 1 for the NULL terminator), and has a single NihAllocCtx just before the zeroth element. So it's actual byte size is: sizeof (NihAllocCtx) + (sizeof (char *) * (number_of_elements + 1)) As such, it is safe to call memmove to shuffle those pointers since they are the user-accessible way to reference the strings the array points to - Nih keeps track itself using the NihAllocCtx object. I've added a call to nih_relloc() to compact the size of the array (from NIH's perspective) as it is wasteful (but not actually incorrect) not to call nih_realloc() and leave 'sizeof (char *)' bytes lying around until the array eventually gets deallocated. -- https://code.launchpad.net/~jamesodhunt/upstart/bug-1222705-reprise/+merge/226983 Your team Upstart Reviewers is subscribed to branch lp:upstart. -- upstart-devel mailing list upstart-devel@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/upstart-devel