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;
}
}
}
/*
*/
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;
}
/*
*/
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.