Q:

Share variables internally across functions

Suppose I have a function like this:
static int init_processing(char *buf, FILE *stream, enum operationMode mode) {
    /* save index of `stream' in current operations */
    /* start processing */
    /* save some important variables for continue_processing */
    off_t position;
    enum operationMode _mode;
    return num_processing_operations_left;
}

.. that I would be calling occasionally. And I have another function that does the actual processing I want:
static int continue_processing(FILE *stream) {
    /* lookup the index of `stream' in current operations */
    /* do some stuff */
    /* save some static variables */
    static off_t left = position;
    static void *some_ptr;
    return --num_processing_operations_left;
}

I also have a cleaning function to invoke when finishing up a certain operation:
static int end_processing(FILE *stream) {
    /* check */
    if (num_processing_operations_left)
        return 1;
    /* clean everything */
    return 0;
}

As you can see, this related functions technique is very familiar that it is used by the standard library itself (e.g [malloc, free, realloc], [fdopen, fopen, fclose]).
What I want to achieve here, is how to share some variables across a bunch of functions ?
I thought of two solutions:

Put each set of functions in a file of their own, providing static variables valid only for the file itself.
Use only one function that takes an extra enum parameter as a mode and structure the function accordingly.

But these solutions aren't actually solutions, they're just workarounds to cope with the problem. So, is there any standard technique to share variables among functions ?

A:

Create a context structure keeping all you need:
struct Context
{
  FILE * stream;
  off_t position;
  unsigned num_processing_operations_left;
  /* define some more important variables */
}

and pass it to all functions in question:
static int init_processing(struct Context * pctx, char *buf, enum operationMode mode);
static int continue_processing(struct Context * pctx);
static int end_processing(struct Context * pctx);

int main(void)
{
  struct Context ctx = {0};

  /* init ctx here */

  int result = init_processing(&ctx, ...);

  ...

  result = continue_processing(&ctx);

  ...

  result = end_processing(&ctx);

  ...
}

