Example of returning _IO_CONNECT_RET_LINK?

Can someone post a quick snippet of an example of returning _IO_CONNECT_RET_LINK
(for the non-terminal symlink case) and the data structures that have to be set?

Specifically, I’m wondering about the “struct _io_connect_link_reply” members
and what their values need to be, there’s an nd, pid, chid, handle, key, … ???

Thanks in advance!
-RK


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

Robert Krten <nospam83@parse.com> wrote:

Can someone post a quick snippet of an example of returning
_IO_CONNECT_RET_LINK
(for the non-terminal symlink case) and the data structures that
have to be set?

Specifically, I’m wondering about the “struct _io_connect_link_reply”
members and what their values need to be, there’s an
nd, pid, chid, handle, key, … ???

Thanks in advance!

Hm…

This is a device the is kind of a “permanent” symlink.

It seems to work, hope it helps.

-David

/*

  • redirect.c
  •  This module contains sample source code for /dev/redirect.
    
  •  Any open on /dev/redirect will be re-directed to a device
    
  •  specified on the command line.
    
  • This module contains all of the functions necessary.

*/

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <sys/neutrino.h>
#include <sys/resmgr.h>


/*

  • these prototypes are needed since we are using their names in main ()
    */

void options (int argc, char **argv);
int io_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra);
int io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb);
int io_write(resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb);

/*

  • our connect and I/O functions
    */

resmgr_connect_funcs_t connect_funcs;
resmgr_io_funcs_t io_funcs;

/*

  • our dispatch, resource manager and iofunc variables
    */

dispatch_t *dpp;
resmgr_attr_t rattr;
dispatch_context_t *ctp;
iofunc_attr_t ioattr;

char *progname = “redirect”;
int optv; // -v for verbose operation

char new_path; / what they will really open, set in options */

main (int argc, char **argv)
{
int pathID;

printf ("%s: starting…\n", progname);

options (argc, argv);

/*

  • allocate and initialize a dispatch structure for use by our
  • main loop
    */

dpp = dispatch_create ();
if (dpp == NULL) {
fprintf (stderr, “%s: couldn’t dispatch_create: %s\n”,
progname, strerror (errno));
exit (1);
}

/*

  • set up the resource manager attributes structure, we’ll
  • use this as a way of passing information to resmgr_attach().
  • For now, we just use defaults.
    */

memset (&rattr, 0, sizeof (rattr)); /* using the defaults for rattr */

/*

  • intialize the connect functions and I/O functions tables to
  • their defaults and then override the defaults with the
  • functions that we are providing.
    */

iofunc_func_init (_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);
connect_funcs.open = io_open;
io_funcs.read = io_read;
io_funcs.write = io_write;

/*

  • call resmgr_attach to register our prefix with the
  • process manager, and also to let it know about our connect
  • and I/O functions.
  • On error, returns -1 and errno is set.
    */

iofunc_attr_init (&ioattr, S_IFCHR | 0666, NULL, NULL);
pathID = resmgr_attach (dpp, &rattr, “/dev/redirect”, _FTYPE_ANY, 0,
&connect_funcs, &io_funcs, &ioattr);
if (pathID == -1) {
fprintf (stderr, “%s: couldn’t attach pathname: %s\n”,
progname, strerror (errno));
exit (1);
}

ctp = dispatch_context_alloc (dpp);

while (1) {
if ((ctp = dispatch_block (ctp)) == NULL) {
fprintf (stderr, “%s: dispatch_block failed: %s\n”,
progname, strerror (errno));
exit (1);
}
dispatch_handler (ctp);
}
}

/*

  • options
  • This routine handles the command line options.
  • For our simple /dev/redirect, we support:
  •   -v		verbose operation
    
  • dev_name where to redirect
    */

void
options (int argc, char **argv)
{
int opt;
int i;

optv = 0;

i = 0;
while (optind < argc) {
while ((opt = getopt (argc, argv, “v”)) != -1) {
switch (opt) {
case ‘v’:
optv = 1;
break;
}
}
if (optind < argc)
{
new_path = argv[optind];
printf(“redirect path is %s\n”, new_path );
break;
}
}
}

/*

  • io_open
  •  This gets called when the client opens our device.  We're going to
    
  •  to re-direct their open to another device.
    

*/

int
io_open (resmgr_context_t *ctp, io_open_t *msg, RESMGR_HANDLE_T *handle, void *extra)
{
int eflag, ftype, retlen;

if (optv) {
printf ("%s: in io_open\n", progname);
}
/* These are generally preserved for the new search */
eflag = msg->connect.eflag;
ftype = msg->connect.file_type;

/*
The new_path must not be a part of msg->connect.path
since we zero the structure, and might overwrite it.
*/
memset(&msg->link_reply, 0, sizeof(msg->link_reply));

_IO_SET_CONNECT_RET(ctp, _IO_CONNECT_RET_LINK);
msg->link_reply.file_type = ftype;
msg->link_reply.eflag = eflag;
msg->link_reply.nentries = 0;

msg->link_reply.path_len = strlen(new_path)+1;
strcpy((char *)((char *)msg + sizeof(msg->link_reply)), new_path);

retlen = sizeof(msg->link_reply)+msg->link_reply.path_len;
return _RESMGR_PTR( ctp, msg, retlen );

/*

  • Note: we don’t do an iofunc_open_default() since we’re not allocating
  • an OCB and we aren’t handling the open ourselves.
    */
    }

/*

  • io_read
  • Shouldn’t get here as we re-direct all opens.
    */

int
io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb)
{

printf(“got to io_read\n”);
return ENOSYS;
}

/*

  • io_write
  •  Shouldn't get here as we re-direct all opens.
    

*/

int
io_write (resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb)
{
printf(“got to io_write\n”);
return ENOSYS;

}

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

David Gibbs <dagibbs@qnx.com> wrote:

Robert Krten <> nospam83@parse.com> > wrote:
Can someone post a quick snippet of an example of returning
_IO_CONNECT_RET_LINK
(for the non-terminal symlink case) and the data structures that
have to be set?

Specifically, I’m wondering about the “struct _io_connect_link_reply”
members and what their values need to be, there’s an
nd, pid, chid, handle, key, … ???

Thanks in advance!

Hm…

This is a device the is kind of a “permanent” symlink.

It seems to work, hope it helps.

[snip]

Thanks, Dave, this should help tremendously!

Cheers,
-RK


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

Robert Krten wrote:

Thanks, Dave, this should help tremendously!

I second that !

Rennie