2

I'd like to create a character device which has the same properties as a standard pseudo-terminal, but that can be named in a specific name.

Basically I'd like to have /dev/pts/my-unique-name instead of the numbers which can be reused. Is there a way to do that? Can mknod for example create arbitrarily connected char-devices?

viraptor
  • 1,296
  • 6
  • 21
  • 41
  • If you can't use a symlink, then I think you need to click the `flag` link and ask a moderator to move this question to Stack Overflow since I believe this will involve writing a program to create such a device. `mknod` can't do it, as far as I know. – Dennis Williamson Mar 17 '11 at 15:37

2 Answers2

1

mknod will work, with some exceptions. The syntax is:

mknod /path/to/new/dev c major minor

So, for example, you should likely be able to create a new pts type device with

mknod /tmp/mypts c 136 0

What I've found, however, is that if you try to do this in /dev/pts, you will get an access denied message. I can do it in /dev, just not /dev/pts. I'm on a Centos 5.5 box. YMMV.

This is because /dev/pts is mounted by the kernel (from my /etc/fstab file):

devpts                  /dev/pts                devpts  gid=5,mode=620  0 0

This is a kernel-managed pseudo filesystem, and I wouldn't think that screwing around with it is a good idea. The standard way to get a new file created in there is by open()ing /dev/ptmx; that will get the calling process the fd of the master terminal assigned, and a new device will be created as /dev/pts/X where X is dynamically allocated by ptmx as the slave. This would then be opened itself, usually by a forked process from the original one.

There's likely a good reason why it's done this way. I'm not sure what it is, but I would avoid trying to break it, if system stability is something you value.

That all being said, the first command line with real options I presented would allow you to make your own pts device anywhere but /dev/pts, and depending on what you're intending to do with it, maybe that's enough to get you where you're going.

malcolmpdx
  • 2,300
  • 1
  • 16
  • 12
  • Ok - I can create such device, but how do I get "the other end" of that terminal - as in the provider, not the client? ptmx does it by making one master, the other one slave. I can't use `/dev/ptmx` because I need unique name that will not change when the device is not used anymore. (`/dev/pts/...` devices can get a "reused" number) – viraptor Mar 24 '11 at 20:20
  • 1
    Might help if you could describe what you're attempting to do. Drive a co-process? something like the script command? I will edit my response to be accurate (the value from the open() on /dev/ptmx is the master, and then you fork another process, open the slave, and then exec() to use the slave). – malcolmpdx Mar 24 '11 at 21:17
  • I need to query a couple of hosts for the location of that pts and I need it to be there after I ssh to the host. With ptmx, if something releases /dev/pts/10, another ptmx user can get the same device - race condition with my connection - not good. I need that device to be provided on the host by a device mapped from a KVM VM. – viraptor Mar 24 '11 at 22:26
  • @viraptor - KVM is beyond my experience, but I'll ask what you're going to do with the device once it's there (maybe I'll learn something about KVM). Do you want your ssh connection to use it? – malcolmpdx Mar 29 '11 at 04:03
  • Cant you use another well-named IPC mechanism like a unix socket and manage the connection to that to whatever the pty ends up being? – Matthew Ife Dec 07 '13 at 08:53
1

What you are asking for is essentially a use case for using BSD pseudoterminals. The BSD pseudoterminal device driver had 256 pairs of inode numbers (with each pair consisting of a master and a slave), and the corresponding inodes were created in /dev at install and left that way.

Nothing in the kernel enforced any particular naming, but an application needing to search for an unused pair would usually have some expectations about the naming.

Most people consider BSD pseudoterminals to have become obsolete with the introduction of Unix 98 pseoduterminals. And it appears multiple Linux distributions have dropped support for BSD pseudoterminals. However if you can find a kernel which still has support for BSD pseudoterminals, then you can use that support to create a pair of device inodes exactly like you are asking for.

mknod /dev/my-master c 2 42
mknod /dev/my-slave c 3 42

Notice that those have to remain outside of /dev/pts, as /dev/pts is for Unix 98 pseudoterminals.

If you just need to transfer a stream of characters and don't need all the other features a pseudoterminal has to offer, then it may be easier to use a named pipe.

kasperd
  • 30,455
  • 17
  • 76
  • 124