I guess that read functions can mess things up, since reading from empty, non existing ect file will return -1.Thus, rest of computations will fall. Try to avoid that by including if firective:
while ((numOfBytes = read(fd_in, buf, 4096))!=0)
{
numOfBytes_key=read(fd_key, buf_key, numOfBytes);
if (numOfBytes>numOfBytes_key && (numOfBytes >= 0) &&(numOfBytes_key >= 0 ))
{
lseek(fd_in, -(numOfBytes - numOfBytes_key), SEEK_CUR);
lseek(fd_key, 0, SEEK_SET);
}
for (i = 0; i < numOfBytes_key; i++){
buf_out[i] = buf[i] ^ buf_key[i];
}
write(fd_out, buf_out, numOfBytes_key);
}