public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* /dev/fd/N not synonymous with file descriptor N; it is on Linux
@ 2018-12-16 16:31 Houder
  2018-12-16 20:28 ` Corinna Vinschen
  2019-01-06 20:19 ` Corinna Vinschen
  0 siblings, 2 replies; 25+ messages in thread
From: Houder @ 2018-12-16 16:31 UTC (permalink / raw)
  To: cygwin

[-- Attachment #1: Type: text/plain, Size: 956 bytes --]

L.S.,

/dev/fd/N not synonymous with file descriptor N; it is on Linux

64-@@ cat /dev/fd/0 <<\EOF
> Hi
> EOF
cat: /dev/fd/0: No such file or directory

fails on Cygwin; not on Linux.

Also see:

     https://cygwin.com/ml/cygwin/2018-12/msg00028.html
     ( Bash heredoc on FD 3 )

Based on the output of strace on Linux, I composed an STC, that 
duplicates
the steps taken by bash (and cat).

This STC succeeds on Linux, but fails on Cygwin.

What does the STC do:

  - it creates a (temporary) file in the same way that bash does
  - the file is written to, the file descriptor is closed and the file 
unlinked
  - however, before the file is unlinked, it is opened a second time, 
like bash
    would do

Next
  - the file /dev/fd/N is opened, where N is the file descriptor that has 
been
    left open; this is what the "cat command" would do.

The "cat command" on Linux succeeds; it fails on Cygwin.

Regards,
Henri

STC attached (hopefully)

=====

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: stc.c --]
[-- Type: text/x-c; name=stc.c, Size: 3256 bytes --]

// gcc -Wall -o stc stc.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h> // strerror()
#include <errno.h>
#include <fcntl.h>

/*
 LPI, 5.11 The /dev/fd Directory (Linux Programming Interface, Michael Kerrisk)
 "For each process, the kernel provides the special virtual directory /dev/fd.
  This directory contains filenames of the form /dev/fd/n, where n is a number
  corresponding to one of the open file descriptors for the process."
 "... Opening one of the files in the /dev/fd directory is equivalent to duplicating
  the corresponding file descriptor. ..."
 "... The files in the /dev/fd directory are rarely used within programs. Their most
  common use is in the shell. Many user-level commands take filename arguments, and
  sometimes we would like to put them in a pipeline and have one of the arguments be
  standard input or output instead. ..."
 */

void
errExit(const char *str)
{
    printf("id = %s, errno = %d, errstr = %s\n", str, errno, strerror(errno));
    fflush(stdout);
    exit(EXIT_FAILURE);
}

int
main()
{
    int fd1, fd2, fd3;

    errno = 0;
    // create a tmpfile in the same way that bash would do ...
    fd1 = open("/tmp/stc.txt", O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
    if (fd1 == -1)
        errExit("openfd1");

    errno = 0;
    if (write(fd1, "Hello, world!\n", 14) == -1) errExit("writefd1");

    errno = 0;
    // also open this tmpfile for reading like bash would do ...
    fd2 = open("/tmp/stc.txt", O_RDONLY);
    if (fd2 == -1)
        errExit("openfd2");

    errno = 0;
    // close fd 1 like bash would do ...
    if (close(fd1) == -1) errExit("closefd1");

    errno = 0;
    // delete the tmpfile like bash would do ...
    if (unlink("/tmp/stc.txt") == -1) errExit("unlink");

    // kludge: compose a string (using fd2) representing "the device file"
    // in /dev/fd (a symlnk to /proc/self/fd) for the file descriptor fd 2
    // that is still open ...
    char devfile[12] = "/dev/fd/"; devfile[8] = fd2 + 0x30; devfile[9] = '\0';

    printf("devfile = %s\n", devfile);

    errno = 0;
    // open this device file; it succeeds on Linux, but fails on Cygwin ...
    fd3 = open(devfile, O_RDONLY);

    const char *id = "openfd3";
    if (fd3 == -1) {
#if 0
        errExit(id);
#else
	printf("%s: Cannot open!, id = %s, errno = %d, errmsg = %s\n", devfile,
            id, errno, strerror(errno));
        char buf[16] = { 0 };
        // however the file to which the symlnk refers, is still present ...
        // Q: does Cygwin attempt to read the /tmp directory? (an attempt that
        //    will fail, because the file has been unlinked)
        // it appears that a readlink of a file in /dev/fd must be diverted to
        // the open file descriptor of the process ...
        errno = 0;
        if (read(fd2, buf, sizeof(buf) ) == -1) errExit("readfd2");
        printf("buf = %s", buf);
        if (close(fd2) == -1) printf("closefd2 failed\n");
        exit(EXIT_FAILURE);
#endif
    }

    char buf[16] = { 0 };
    errno = 0;
    if (read(fd3, buf, sizeof(buf) ) == -1) errExit("readfd3");
    printf("buf = %s", buf);

    if (close(fd3) == -1) printf("closefd3 failed\n");
    if (close(fd2) == -1) printf("closefd2 failed\n");
}

//=====

[-- Attachment #3: Type: text/plain, Size: 219 bytes --]


--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2019-01-28 16:51 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-16 16:31 /dev/fd/N not synonymous with file descriptor N; it is on Linux Houder
2018-12-16 20:28 ` Corinna Vinschen
2018-12-16 20:31   ` Corinna Vinschen
2018-12-16 21:36   ` Wayne Davison
2018-12-16 21:55     ` Corinna Vinschen
2018-12-17  4:30       ` Houder
2018-12-17  9:25         ` Corinna Vinschen
2018-12-17 11:26           ` Corinna Vinschen
2019-01-02 13:56             ` Houder
2018-12-17  3:41   ` Houder
2019-01-06 20:19 ` Corinna Vinschen
2019-01-22  8:50   ` Houder
2019-01-22  8:57     ` Houder
2019-01-22  9:06       ` Corinna Vinschen
2019-01-22  9:25         ` Houder
2019-01-22  9:42           ` Corinna Vinschen
2019-01-22 10:20             ` Houder
2019-01-22 10:39               ` Corinna Vinschen
2019-01-27 18:39                 ` Houder
2019-01-27 21:57                   ` Corinna Vinschen
2019-01-27 22:12                     ` Corinna Vinschen
2019-01-28 14:15                     ` Houder
2019-01-28 16:51                       ` Corinna Vinschen
2019-01-22  9:02     ` Corinna Vinschen
2019-01-22  9:07       ` Corinna Vinschen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).