diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag
index d103045201bded5e62e688e00aaf0731aea4fb62..d3d3976bd423d857f73955140c6c73991dda7542 100644
--- a/compiler/C_CodeGen.jrag
+++ b/compiler/C_CodeGen.jrag
@@ -191,8 +191,7 @@ aspect C_CodeGen {
   public void Program.C_emitH(C_env env) {
     for (int i = 0; i < getNumDecl(); i++) {
       getDecl(i).C_emitType(env);
-//      getDecl(i).C_emitSignatureDeclaration(env);
-      getDecl(i).C_emitDecoderRegisterDeclaration(env);
+      getDecl(i).C_emitDecoderDeclaration(env);
       getDecl(i).C_emitEncoderDeclaration(env);
       getDecl(i).C_emitSizeofDeclaration(env);
       env.println("");
@@ -205,8 +204,10 @@ aspect C_CodeGen {
     for (int i = 0; i < getNumDecl(); i++) {
       getDecl(i).C_emitDecoder(env);
       getDecl(i).C_emitDecoderRegisterHandler(env);
+      getDecl(i).C_emitDecoderIoctl(env);
       getDecl(i).C_emitEncoder(env);
       getDecl(i).C_emitEncoderRegisterHandler(env);
+      getDecl(i).C_emitEncoderIoctl(env);
       getDecl(i).C_emitSizeof(env);
     }
   }
@@ -330,10 +331,10 @@ aspect C_Type {
 
 aspect C_Declarations {
 
-  public void Decl.C_emitDecoderRegisterDeclaration(C_env env) {
+  public void Decl.C_emitDecoderDeclaration(C_env env) {
   }
 
-  public void SampleDecl.C_emitDecoderRegisterDeclaration(C_env env) {
+  public void SampleDecl.C_emitDecoderDeclaration(C_env env) {
     env.println("void labcomm_decoder_register_" + 
 		env.prefix + getName() + "(");
     env.indent();
@@ -347,6 +348,14 @@ aspect C_Declarations {
     env.println("void *context");
     env.unindent();
     env.println(");");
+
+    env.println("int labcomm_decoder_ioctl_" + env.prefix + getName() + "(");
+    env.indent();
+    env.println("struct labcomm_decoder *d,");
+    env.println("int ioctl_action,");
+    env.println("...");
+    env.unindent();
+    env.println(");");
   }
   
   public void Decl.C_emitEncoderDeclaration(C_env env) {
@@ -365,6 +374,14 @@ aspect C_Declarations {
     env.println(env.prefix + getName() + " *v");
     env.unindent();
     env.println(");");
+
+    env.println("int labcomm_encoder_ioctl_" + env.prefix + getName() + "(");
+    env.indent();
+    env.println("struct labcomm_encoder *e,");
+    env.println("int ioctl_action,");
+    env.println("...");
+    env.unindent();
+    env.println(");");
   }
 
 }
@@ -627,6 +644,42 @@ aspect C_Decoder {
 
 }
 
+aspect C_DecoderIoctl {
+
+  public void Decl.C_emitDecoderIoctl(C_env env) {
+    throw new Error(this.getClass().getName() + 
+		    ".C_emitDecoderIoctl(C_env env)" + 
+		    " not declared");
+  }
+
+  public void TypeDecl.C_emitDecoderIoctl(C_env env) {
+  }
+
+  public void SampleDecl.C_emitDecoderIoctl(C_env env) {
+    env.println("int labcomm_decoder_ioctl_" + env.prefix + getName() + "(");
+    env.indent();
+    env.println("struct labcomm_decoder *d,");
+    env.println("int ioctl_action,");
+    env.println("...");
+    env.unindent();
+    env.println(")");
+    env.println("{");
+    env.indent();
+    env.println("int result;");
+    env.println("va_list va;");
+    env.println("va_start(va, ioctl_action);");
+    env.println("result = labcomm_internal_decoder_ioctl(");
+    env.indent();
+    env.println("d, ioctl_action,");
+    env.println("&labcomm_signature_" + env.prefix + getName() + ", va);");
+    env.unindent();
+    env.println("va_end(va);");
+    env.println("return result;");
+    env.unindent();
+    env.println("}");
+  }
+}
+
 
 aspect C_Encoder {
 
@@ -767,7 +820,43 @@ aspect C_Encoder {
     env.unindent();
     env.println("}");
   }
- 
+
+}
+
+aspect C_EncoderIoctl {
+
+  public void Decl.C_emitEncoderIoctl(C_env env) {
+    throw new Error(this.getClass().getName() + 
+		    ".C_emitEncoderIoctl()" + 
+		    " not declared");
+  }
+
+  public void TypeDecl.C_emitEncoderIoctl(C_env env) {
+  }
+
+  public void SampleDecl.C_emitEncoderIoctl(C_env env) {
+    env.println("int labcomm_encoder_ioctl_" + env.prefix + getName() + "(");
+    env.indent();
+    env.println("struct labcomm_encoder *e,");
+    env.println("int ioctl_action,");
+    env.println("...");
+    env.unindent();
+    env.println(")");
+    env.println("{");
+    env.indent();
+    env.println("int result;");
+    env.println("va_list va;");
+    env.println("va_start(va, ioctl_action);");
+    env.println("result = labcomm_internal_encoder_ioctl(");
+    env.indent();
+    env.println("e, ioctl_action,");
+    env.println("&labcomm_signature_" + env.prefix + getName() + ", va);");
+    env.unindent();
+    env.println("va_end(va);");
+    env.println("return result;");
+    env.unindent();
+    env.println("}");
+  }
 
 }
 
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
index 86dcfcc25099e5e9e26ca61e3be39b61bb78f3c3..5c443d2b7fe597b884ca25fb2c31f4d83d534266 100644
--- a/lib/c/labcomm.c
+++ b/lib/c/labcomm.c
@@ -470,12 +470,25 @@ int labcomm_encoder_ioctl(struct labcomm_encoder *encoder,
     va_list va;
     
     va_start(va, action);
-    result = encoder->writer.ioctl(&encoder->writer, action, va);
+    result = encoder->writer.ioctl(&encoder->writer, action, NULL, va);
     va_end(va);
   }
   return result;
 }
 
+int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, 
+				   int action,
+				   labcomm_signature_t *signature,
+                                   va_list va)
+{
+  int result = -ENOTSUP;
+  
+  if (encoder->writer.ioctl != NULL) {
+    result = encoder->writer.ioctl(&encoder->writer, action, signature, va);
+  }
+  return result;
+}
+
 static void collect_flat_signature(
   labcomm_decoder_t *decoder,
   labcomm_encoder_t *signature_writer)
@@ -715,3 +728,33 @@ void labcomm_decoder_free(labcomm_decoder_t* d)
   free(d->context);
   free(d);
 }
+
+int labcomm_decoder_ioctl(struct labcomm_decoder *decoder, 
+			  int action,
+			  ...)
+{
+  int result = -ENOTSUP;
+  
+  if (decoder->reader.ioctl != NULL) {
+    va_list va;
+    
+    va_start(va, action);
+    result = decoder->reader.ioctl(&decoder->reader, action, NULL, va);
+    va_end(va);
+  }
+  return result;
+}
+
+int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder, 
+				   int action,
+				   labcomm_signature_t *signature,
+                                   va_list va)
+{
+  int result = -ENOTSUP;
+  
+  if (decoder->reader.ioctl != NULL) {
+    result = decoder->reader.ioctl(&decoder->reader, action, NULL, va);
+  }
+  return result;
+}
+
diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h
index 41420b6c760a362caea579ecbb673c9ec683e18a..8bc80cf56d591ac93fd6c60507ea951a0297148b 100644
--- a/lib/c/labcomm.h
+++ b/lib/c/labcomm.h
@@ -98,7 +98,7 @@ typedef struct labcomm_reader {
   int count;
   int pos;
   int (*read)(struct labcomm_reader *, labcomm_reader_action_t, ...);
-  int (*ioctl)(struct labcomm_reader *, int, va_list);
+  int (*ioctl)(struct labcomm_reader *, int, labcomm_signature_t *, va_list);
   labcomm_error_handler_callback on_error;
 }  labcomm_reader_t;
 
@@ -112,6 +112,11 @@ void labcomm_decoder_run(
 void labcomm_decoder_free(
   struct labcomm_decoder *decoder);
 
+/* See labcomm_ioctl.h for predefined ioctl_action values */
+int labcomm_decoder_ioctl(struct labcomm_decoder *decoder, 
+			  int ioctl_action,
+			  ...);
+
 /*
  * Encoder
  */
@@ -144,7 +149,7 @@ typedef struct labcomm_writer {
   int pos;
   int error;
   int (*write)(struct labcomm_writer *, labcomm_writer_action_t, ...);
-  int (*ioctl)(struct labcomm_writer *, int, va_list);
+  int (*ioctl)(struct labcomm_writer *, int, labcomm_signature_t *, va_list);
   labcomm_error_handler_callback on_error;
 } labcomm_writer_t;
 
diff --git a/lib/c/labcomm_dynamic_buffer_writer.c b/lib/c/labcomm_dynamic_buffer_writer.c
index 4c2017119fa385b2167fe4bc497d03ac8c550968..4197857dc3b6700eb13e09890b581043579368a4 100644
--- a/lib/c/labcomm_dynamic_buffer_writer.c
+++ b/lib/c/labcomm_dynamic_buffer_writer.c
@@ -5,7 +5,10 @@
 #include "labcomm_dynamic_buffer_writer.h"
 
 static int labcomm_dynamic_buffer_writer_ioctl(
-  struct labcomm_writer *w, int action, va_list arg)
+  struct labcomm_writer *w, 
+  int action, 
+  labcomm_signature_t *signature,
+  va_list arg)
 {
   int result = -ENOTSUP;
   switch (action) {
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index e75a06496265dec5fe7d9fea0687835c37e4e651..36c122e565e3b9d3442ad7f17feb0755ad58f56b 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -78,6 +78,11 @@ void labcomm_internal_decoder_register(
   labcomm_handler_typecast_t,
   void *context);
 
+int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder, 
+				   int ioctl_action,
+				   labcomm_signature_t *signature,
+				   va_list args);
+
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 
 #define LABCOMM_DECODE(name, type)					\
@@ -253,6 +258,11 @@ int labcomm_internal_encode(
   labcomm_encoder_function encode,
   void *value);
 
+int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, 
+				   int ioctl_action,
+				   labcomm_signature_t *signature,
+				   va_list args);
+
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 
 #define LABCOMM_ENCODE(name, type)					\
diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c
index 1b174726e54a89d20ca73db14be31951c8a3ffe4..6548978f9028b85295ac9887612d445e3c7fd9fa 100644
--- a/lib/c/test/test_labcomm_generated_encoding.c
+++ b/lib/c/test/test_labcomm_generated_encoding.c
@@ -23,7 +23,10 @@ int test_read(struct labcomm_reader *r, labcomm_reader_action_t a, ...)
 static unsigned char buffer[128];
 
 static int buffer_writer_ioctl(
-  struct labcomm_writer *w, int action, va_list arg)
+  struct labcomm_writer *w, 
+  int action, 
+  labcomm_signature_t *signature,
+  va_list arg)
 {
   int result = -ENOTSUP;
   switch (action) {