in reply to foreach interruption

I don't understand what you mean by 'interrupts'. As far as I can see, the only way that will happen is if the file cannot be found. In that case, you'll get an error message, which you didn't mention. (If you did get the error message, please post it!)

If I were you, I would print the contents of @products to a log file before the loop, or at least the number of elements (print scalar @products) to verify that it contains what you think it contains.

I might also write your open code as:

open(INF, $ref->{prodname) or die "Can't open $$ref{prodname}: $!"; print while <INF>; close INF;
... but I can't see where that will have a great effect.