How can I make a character device ?

Hi,
I want to make a character device.
The following code is example in QNX 6 Programmer’s Guide.
I expected the code makes a character device, but doesn’t so.
When I do ‘ls -l /dev/sample’, the result is

nrw-rw-rw- 1 root root 0 Dec 04 22:25 /dev/sample

,instead of

crw-rw-rw- 1 root root 0 Dec 04 22:25 /dev/sample

I know ‘c’ means character device, however what does mean ‘n’ ? network ?
And how do I modify the code for making a character device ?

Thanks in advance,
Hoon

#include <errno.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>

static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;

main(int argc, char *argv)
{
/
declare variables we’ll be using */
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
dispatch_context_t *ctp;
int id;

/* initialize dispatch interface */
if((dpp = dispatch_create()) == NULL) {
fprintf(stderr, “%s: Unable to allocate dispatch handle.\n”,
argv[0]);
return EXIT_FAILURE;
}

/* initialize resource manager attributes */
memset(&resmgr_attr, 0, sizeof resmgr_attr);
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;

/* initialize functions for handling messages */
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

/* initialize attribute structure used by the device */
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

/* attach our device name /
id = resmgr_attach(dpp, /
dispatch handle /
&resmgr_attr, /
resource manager attrs /
“/dev/sample”, /
device name /
_FTYPE_ANY, /
open type /
0, /
flags /
&connect_funcs, /
connect routines /
&io_funcs, /
I/O routines /
&attr); /
handle */
if(id == -1) {
fprintf(stderr, “%s: Unable to attach name.\n”, argv[0]);
return EXIT_FAILURE;
}

/* allocate a context structure */
ctp = dispatch_context_alloc(dpp);

/* start the resource manager message loop */
while(1) {
if((ctp = dispatch_block(ctp)) == NULL) {
fprintf(stderr, “block error\n”);
return EXIT_FAILURE;
}
dispatch_handler(ctp);
}
}

The ‘n’ I believe indicates a ‘Special named file’ (see <sys/stat.h>). The
flag that you are passing into the iofunc_attr_init() function is S_IFNAM
which will result in a’Special named file’ device. To make a character
device, specify S_IFCHR instead of S_IFNAM.


“Hoon Jung” <hjung@3ic.co.kr> wrote in message
news:9uijmb$s4s$1@inn.qnx.com

Hi,
I want to make a character device.
The following code is example in QNX 6 Programmer’s Guide.
I expected the code makes a character device, but doesn’t so.
When I do ‘ls -l /dev/sample’, the result is

nrw-rw-rw- 1 root root 0 Dec 04 22:25 /dev/sample

,instead of

crw-rw-rw- 1 root root 0 Dec 04 22:25 /dev/sample

I know ‘c’ means character device, however what does mean ‘n’ ? network ?
And how do I modify the code for making a character device ?

Thanks in advance,
Hoon

#include <errno.h
#include <stdio.h
#include <stddef.h
#include <stdlib.h
#include <unistd.h
#include <sys/iofunc.h
#include <sys/dispatch.h

static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;

main(int argc, char *argv)
{
/
declare variables we’ll be using */
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
dispatch_context_t *ctp;
int id;

/* initialize dispatch interface */
if((dpp = dispatch_create()) == NULL) {
fprintf(stderr, “%s: Unable to allocate dispatch handle.\n”,
argv[0]);
return EXIT_FAILURE;
}

/* initialize resource manager attributes */
memset(&resmgr_attr, 0, sizeof resmgr_attr);
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;

/* initialize functions for handling messages */
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

/* initialize attribute structure used by the device */
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

/* attach our device name /
id = resmgr_attach(dpp, /
dispatch handle /
&resmgr_attr, /
resource manager attrs /
“/dev/sample”, /
device name /
_FTYPE_ANY, /
open type /
0, /
flags /
&connect_funcs, /
connect routines /
&io_funcs, /
I/O routines /
&attr); /
handle */
if(id == -1) {
fprintf(stderr, “%s: Unable to attach name.\n”, argv[0]);
return EXIT_FAILURE;
}

/* allocate a context structure */
ctp = dispatch_context_alloc(dpp);

/* start the resource manager message loop */
while(1) {
if((ctp = dispatch_block(ctp)) == NULL) {
fprintf(stderr, “block error\n”);
return EXIT_FAILURE;
}
dispatch_handler(ctp);
}
}

Thanks for your help.

But I still got a problem.
I specified S_IFCHR instead of S_IFNAM, but a character device was not made.
The result is same as before. I think a character device has MAJOR and MINOR
number, but the device I made does not. Should do I do something more ?

Thanks in advance,
Hoon


“Rover Fan” <RoverFan@Chartermi.net> wrote in message
news:9ujav6$e1j$1@inn.qnx.com

The ‘n’ I believe indicates a ‘Special named file’ (see <sys/stat.h>). The
flag that you are passing into the iofunc_attr_init() function is S_IFNAM
which will result in a’Special named file’ device. To make a character
device, specify S_IFCHR instead of S_IFNAM.


“Hoon Jung” <> hjung@3ic.co.kr> > wrote in message
news:9uijmb$s4s$> 1@inn.qnx.com> …
Hi,
I want to make a character device.
The following code is example in QNX 6 Programmer’s Guide.
I expected the code makes a character device, but doesn’t so.
When I do ‘ls -l /dev/sample’, the result is

nrw-rw-rw- 1 root root 0 Dec 04 22:25 /dev/sample

,instead of

crw-rw-rw- 1 root root 0 Dec 04 22:25 /dev/sample

I know ‘c’ means character device, however what does mean ‘n’ ? network
?
And how do I modify the code for making a character device ?

Thanks in advance,
Hoon

#include <errno.h
#include <stdio.h
#include <stddef.h
#include <stdlib.h
#include <unistd.h
#include <sys/iofunc.h
#include <sys/dispatch.h

static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;

main(int argc, char *argv)
{
/
declare variables we’ll be using */
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
dispatch_context_t *ctp;
int id;

/* initialize dispatch interface */
if((dpp = dispatch_create()) == NULL) {
fprintf(stderr, “%s: Unable to allocate dispatch handle.\n”,
argv[0]);
return EXIT_FAILURE;
}

/* initialize resource manager attributes */
memset(&resmgr_attr, 0, sizeof resmgr_attr);
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;

/* initialize functions for handling messages */
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

/* initialize attribute structure used by the device */
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

/* attach our device name /
id = resmgr_attach(dpp, /
dispatch handle /
&resmgr_attr, /
resource manager attrs /
“/dev/sample”, /
device name /
_FTYPE_ANY, /
open type /
0, /
flags /
&connect_funcs, /
connect routines /
&io_funcs, /
I/O routines /
&attr); /
handle */
if(id == -1) {
fprintf(stderr, “%s: Unable to attach name.\n”, argv[0]);
return EXIT_FAILURE;
}

/* allocate a context structure */
ctp = dispatch_context_alloc(dpp);

/* start the resource manager message loop */
while(1) {
if((ctp = dispatch_block(ctp)) == NULL) {
fprintf(stderr, “block error\n”);
return EXIT_FAILURE;
}
dispatch_handler(ctp);
}
}
\

“Hoon Jung” <hjung@3ic.co.kr> wrote in message
news:9uijmb$s4s$1@inn.qnx.com

/* initialize attribute structure used by the device */
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);
snip

change this to use the flag for S_IFCHR for a character device. You have it
set to use as a [n]amed device.

-Adam

“Hoon Jung” <hjung@3ic.co.kr> wrote in message
news:9uk34s$sa2$1@inn.qnx.com

But I still got a problem.
I specified S_IFCHR instead of S_IFNAM, but a character device was not
made.
The result is same as before. I think a character device has MAJOR and
MINOR
number, but the device I made does not. Should do I do something more ?

That should be it - can you post your code in it’s entirity (io_read()
handlers etc) so that we can try it out and see if we see the same
behaviour?

-Adam



“Rover Fan” <> RoverFan@Chartermi.net> > wrote in message
news:9ujav6$e1j$> 1@inn.qnx.com> …
The ‘n’ I believe indicates a ‘Special named file’ (see <sys/stat.h>).
The
flag that you are passing into the iofunc_attr_init() function is
S_IFNAM
which will result in a’Special named file’ device. To make a character
device, specify S_IFCHR instead of S_IFNAM.


“Hoon Jung” <> hjung@3ic.co.kr> > wrote in message
news:9uijmb$s4s$> 1@inn.qnx.com> …
Hi,
I want to make a character device.
The following code is example in QNX 6 Programmer’s Guide.
I expected the code makes a character device, but doesn’t so.
When I do ‘ls -l /dev/sample’, the result is

nrw-rw-rw- 1 root root 0 Dec 04 22:25 /dev/sample

,instead of

crw-rw-rw- 1 root root 0 Dec 04 22:25 /dev/sample

I know ‘c’ means character device, however what does mean ‘n’ ?
network
?
And how do I modify the code for making a character device ?

Thanks in advance,
Hoon

#include <errno.h
#include <stdio.h
#include <stddef.h
#include <stdlib.h
#include <unistd.h
#include <sys/iofunc.h
#include <sys/dispatch.h

static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;

main(int argc, char *argv)
{
/
declare variables we’ll be using */
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
dispatch_context_t *ctp;
int id;

/* initialize dispatch interface */
if((dpp = dispatch_create()) == NULL) {
fprintf(stderr, “%s: Unable to allocate dispatch handle.\n”,
argv[0]);
return EXIT_FAILURE;
}

/* initialize resource manager attributes */
memset(&resmgr_attr, 0, sizeof resmgr_attr);
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;

/* initialize functions for handling messages */
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);

/* initialize attribute structure used by the device */
iofunc_attr_init(&attr, S_IFNAM | 0666, 0, 0);

/* attach our device name /
id = resmgr_attach(dpp, /
dispatch handle /
&resmgr_attr, /
resource manager attrs /
“/dev/sample”, /
device name /
_FTYPE_ANY, /
open type /
0, /
flags /
&connect_funcs, /
connect routines /
&io_funcs, /
I/O routines /
&attr); /
handle */
if(id == -1) {
fprintf(stderr, “%s: Unable to attach name.\n”, argv[0]);
return EXIT_FAILURE;
}

/* allocate a context structure */
ctp = dispatch_context_alloc(dpp);

/* start the resource manager message loop */
while(1) {
if((ctp = dispatch_block(ctp)) == NULL) {
fprintf(stderr, “block error\n”);
return EXIT_FAILURE;
}
dispatch_handler(ctp);
}
}


\

Hi,
Here is my sample code.
As I mentioned, I specified S_IFCHR, but it’s vain.

Thanks in advance,
Hoon

#include <errno.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>

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);
int io_open (resmgr_context_t *ctp, io_open_t *msg,
RESMGR_HANDLE_T *handle, void *extra);

static char *buffer = “Hello world\n”;

static resmgr_connect_funcs_t connect_funcs;
static resmgr_io_funcs_t io_funcs;
static iofunc_attr_t attr;
iofunc_mount_t mount1;

main(int argc, char *argv)
{
/
declare variables we’ll be using */
resmgr_attr_t resmgr_attr;
dispatch_t *dpp;
dispatch_context_t *ctp;
int id;
dev_t dev;

/* initialize dispatch interface */
if((dpp = dispatch_create()) == NULL) {
fprintf(stderr, “%s: Unable to allocate dispatch handle.\n”,
argv[0]);
return EXIT_FAILURE;
}

/* initialize resource manager attributes */
memset(&resmgr_attr, 0, sizeof resmgr_attr);
resmgr_attr.nparts_max = 1;
resmgr_attr.msg_max_size = 2048;

/* initialize functions for handling messages */
iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &connect_funcs,
_RESMGR_IO_NFUNCS, &io_funcs);
io_funcs.read = io_read;
io_funcs.write = io_write;
io_funcs.devctl = io_devctl;
connect_funcs.open = io_open;

/* initialize attribute structure used by the device */
iofunc_attr_init(&attr, S_IFCHR | 0666, 0, 0);
attr.nbytes = strlen(buffer)+1;

dev = rsrcdbmgr_devno_attach("/dev/sample", 0, 0);

/* attach our device name */
if((id = resmgr_attach(dpp, &resmgr_attr, “/dev/sample”, _FTYPE_ANY, 0,
&connect_funcs, &io_funcs, &attr)) == -1) {
fprintf(stderr, “%s: Unable to attach name.\n”, argv[0]);
return EXIT_FAILURE;
}

resmgr_devino(id, &mount1.dev, &attr.inode);

/* allocate a context structure */
ctp = dispatch_context_alloc(dpp);

/* start the resource manager message loop */
while(1) {
if((ctp = dispatch_block(ctp)) == NULL) {
fprintf(stderr, “block error\n”);
return EXIT_FAILURE;
}
dispatch_handler(ctp);
}
}

int
io_read (resmgr_context_t *ctp, io_read_t *msg, RESMGR_OCB_T *ocb)
{
int nleft;
int nbytes;
int nparts;
int status;


if ((status = iofunc_read_verify (ctp, msg, ocb, NULL)) != EOK)
return (status);

if (msg->i.nbytes == 0) {
return (EOK);
}

// If an xtype is specified make sure it is a readcond.
if((msg->i.xtype & _IO_XTYPE_MASK) && (msg->i.xtype &
_IO_XTYPE_MASK)
!= _IO_XTYPE_READCOND) {
return(EINVAL);
}

printf(“io_read, rcvid = %d, ctp = %X\n”, ctp->rcvid, ctp);
/*

  • on all reads (first and subsequent) calculate
  • how many bytes we can return to the client,
  • based upon the number of bytes available (nleft)
  • and the client’s buffer size
    */

nleft = ocb->attr->nbytes - ocb->offset;
nbytes = min (msg->i.nbytes, nleft);

if (nbytes > 0) {
/* set up the return data IOV */
SETIOV (ctp->iov, buffer + ocb->offset, nbytes);

/* set up the number of bytes (returned by client’s read()) */
_IO_SET_READ_NBYTES (ctp, nbytes);

/*

  • advance the offset by the number of bytes
  • returned to the client.
    */

ocb->offset += nbytes;

nparts = 1;
} else {
/*

  • they’ve asked for zero bytes or they’ve already previously
  • read everything
    */

_IO_SET_READ_NBYTES (ctp, 0);

nparts = 0;
}

/* mark the access time as invalid (we just accessed it) */

if (msg->i.nbytes > 0)
ocb->attr->flags |= IOFUNC_ATTR_ATIME;

return (_RESMGR_NPARTS (nparts));
}


int
io_write(resmgr_context_t *ctp, io_write_t *msg, RESMGR_OCB_T *ocb)
{
int status;

if ((status = iofunc_write_verify (ctp, msg, ocb, NULL)) != EOK)
return (status);

if (msg->i.nbytes == 0) {
return (EOK);
}

if (msg->i.xtype & _IO_XTYPE_MASK != _IO_XTYPE_NONE)
return (ENOSYS);

printf(“io_write, rcvid = %d\n”, ctp->rcvid);

return(EOK);
}

int io_open (resmgr_context_t *ctp, io_open_t *msg,
RESMGR_HANDLE_T *handle, void *extra)
{
printf(“io_open, rcvid = %d\n”, ctp->rcvid);
return (iofunc_open_default (ctp, msg, handle, extra));
}

Hoon Jung <hjung@3ic.co.kr> wrote:
: Here is my sample code.
: As I mentioned, I specified S_IFCHR, but it’s vain.

: /* initialize attribute structure used by the device */
: iofunc_attr_init(&attr, S_IFCHR | 0666, 0, 0);
: attr.nbytes = strlen(buffer)+1;

: dev = rsrcdbmgr_devno_attach("/dev/sample", 0, 0);

I don’t know what you’re doing here. The first parameter should be a
major device class name, try _MAJOR_DEV from <sys/ftype.h>. The
second parameter should probably be -1, to indicate you’ll accept any
free minor number within that class. And finally, you want to assign
the result into attr.rdev …

attr.rdev = rscdbmgr_devno_attach(_MAJOR_DEV, -1, 0);