Запись в файловый дескриптор 3 в узле - PullRequest
2 голосов
/ 26 апреля 2020

console.log использует process.stdout.write для записи в дескриптор файла (fd) 1

и

console.error использует process.stderr.write для записи в дескриптор файла (fd) 2

Как я могу создать новый дескриптор файла 3? и напишите что?

Обновление: использование net

import net from 'net'

const example = new net.Socket({ fd: 3, writable: true })

const buffBaby = Buffer.from('meow', 'utf8')

example.write(buffBaby)

Я получаю эту ошибку:

Ошибка: ENOTTY: неподходящий ioctl для устройства, uv_pipe_open

И я пробовал это:

const fs = require('fs');
const fd3 = fs.createWriteStream(null, {fd: 3});
fd3.write("Hello to FD 3!\n");

Ошибка: ENXIO: нет такого устройства или адреса, напишите

Ответы [ 2 ]

1 голос
/ 26 апреля 2020

этот вопрос остановил меня, так как я не видел ни POSIX, ни других системных вызовов, чтобы вы могли выбрать, какой номер fd вы хотите создать, например socket и open - пожалуйста, исправьте мне, если я не прав, я хотел уточнить параметры net .Socket из nodejs документы и там написано:

fd: (число) Если указано, обернуть вокруг существующего сокета с заданным файловым дескриптором, в противном случае будет создан новый сокет.

это означает, что он не создает сокет на выбранном вами fd, вместо этого он повторно использует существующий Во-первых, я предполагаю избегать создания нового соединения по причинам производительности или совместного использования соединения с другим потоком или потребителем.

Наконец, имейте в виду, что номер fd уникален для каждой области процесса или (блок управления процессом), при этом создание fd является инкрементным, начиная с 3, поскольку 0, 1 и 2 зарезервированы, исходя из этого, вы можете ожидать число fd, если точно знаете правильную последовательность открытий соединения, поскольку каждое открытое соединение, сокет или файл создадут его - если вы не закроете их

1 голос
/ 26 апреля 2020

Я предполагаю, что ваш процесс уже имеет в виду такой FD, иначе вы бы спросили, как записать файл или сокет, а не FD. При условии, что это будет работать:

const fs = require('fs');
const fd3 = fs.createWriteStream(null, {fd: 3});
fd3.write("Hello to FD 3!\n");

Это создает новый поток, связанный с FD 3, так же, как process.stdout связан с FD 1, а process.stderr связан с FD 2.

Я предполагаю, что ваш FD блокируется (по умолчанию для FD в Linux). Если он по какой-то причине неблокирует, вам нужно либо изменить его обратно на блокировку, либо использовать вместо него net.Socket.

Если вы запускаете этот код, когда вы этого не сделали дайте ему FD для записи, тогда, вероятно, произойдет что-то плохое:

events.js:292
      throw er; // Unhandled 'error' event
      ^

Error: EINVAL: invalid argument, write
Emitted 'error' event on WriteStream instance at:
    at emitErrorNT (internal/streams/destroy.js:96:8)
    at emitErrorCloseNT (internal/streams/destroy.js:68:3)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  errno: -22,
  code: 'EINVAL',
  syscall: 'write'
}
Aborted (core dumped)

Или, может быть, это:

events.js:292
      throw er; // Unhandled 'error' event
      ^

Error: EBADF: bad file descriptor, close
Emitted 'error' event on WriteStream instance at:
    at emitErrorNT (internal/streams/destroy.js:96:8)
    at emitErrorCloseNT (internal/streams/destroy.js:68:3)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  errno: -9,
  code: 'EBADF',
  syscall: 'close'
}

Если вы действительно хотите открыть FD с узла , тогда вы можете использовать любые обычные способы открытия файла, чтобы сделать это. Однако вы не можете гарантировать FD 3 в этом случае, поскольку есть большая вероятность, что что-то внутреннее для Node уже использует FD 3, и вы не можете просто выкрасть его из-под него.

...