X-Recipient: archive-cygwin AT delorie DOT com DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:message-id:from:reply-to:to:subject :references:in-reply-to:content-type; q=dns; s=default; b=xgNSFe QAKl/p2BRpAESpaX7hC7tYHRdTzVbAjKetB9bxPV2U8LcYeJtQOzyBIYCHdHn6Hw QE5+Krpj47YjcJa59HeUDGnE3gqcqtYew0/3lHhJ8XLpqwY0ha3tyd1Fgbr0Mbox ow3jnOYfT8ZZ7wwf6O1zwSNC6WDA2b/ToR7Q4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:date:message-id:from:reply-to:to:subject :references:in-reply-to:content-type; s=default; bh=DKpEGxUGXB8q N2a2c5euj6aXwFA=; b=Z6+tICcZheXWsx116VE4q/7hKwq19jPhx3ax3doLAzGo AoyAX7vKKcxAkCW11KWRKGB1Xf4+J+ms4nz2vyoGVO012aZ097UCPhpTZFztf7hI 7b+MYHx+OFtWt1j7b4J5Lp0oljrz1cTXcu3ZHpqiRuSU7fXlFVqSohqrNc2ZMu8= Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-7.6 required=5.0 tests=BAYES_00,GIT_PATCH_2,NORMAL_HTTP_TO_IP,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=authority, H*M:smtp, Administrators, corinna X-HELO: lb1-smtp-cloud7.xs4all.net Date: Sun, 27 Jan 2019 19:39:15 +0100 Message-ID: <6132284bb44434a89381a695fdd86c7d@smtp-cloud7.xs4all.net> From: Houder Reply-To: cygwin AT cygwin DOT com To: cygwin AT cygwin DOT com Subject: Re: /dev/fd/N not synonymous with file descriptor N; it is on Linux References: <0f030e809f063f5a5e64ff7a7a0c3227 AT xs4all DOT nl> <20190106201950 DOT GC4430 AT calimero DOT vinschen DOT de> <1c60402837d6510667357257b5e96e88 AT xs4all DOT nl> <20190122090633 DOT GK2802 AT calimero DOT vinschen DOT de> <151898514e462bd76cda8a227d4baa16 AT xs4all DOT nl> <20190122094157 DOT GN2802 AT calimero DOT vinschen DOT de> <45382f09a86b6cf3bcabd82adb593622 AT smtp-cloud8 DOT xs4all DOT net> <20190122103928 DOT GO2802 AT calimero DOT vinschen DOT de> In-Reply-to: <20190122103928.GO2802@calimero.vinschen.de> Content-Type: text/plain; charset=UTF-8; format=fixed User-Agent: mua.awk 0.99 On Tue, 22 Jan 2019 11:39:28, Corinna Vinschen wrote: > > On Jan 22 11:20, Houder wrote: > > On Tue, 22 Jan 2019 10:41:57, Corinna Vinschen wrote: > > > On Jan 22 10:25, Houder wrote: > > [snip] > > > > > > Curious! It fails (for me) on W7 ... > > > > > > It works for me just as well on W7: [snip] > Maybe you should run the above shell session under strace and see if > something unusual crops up. BLODA? NO BLODA. Ok, for the record (as this is W7, i.e. pre-pre-W10 :-) Using my original STC again: (source code included below) - create file (in /tmp) write-only, write "Hello, world!" to file, close fd - open file once more read-only - unlink file - open file, using /dev/fd/N, read-write <==== succeeds (and the handle shown by fcntl is read-write) - write "*****" to file (using the fd obtained in the previous line), lseek to begin of file - write fails w/ "Permission denied" <==== so ... the file cannot be written to? - read file (using the same fd) Regards, Henri 64-@@ uname -a CYGWIN_NT-6.1 Seven 2.12.0s(0.333/5/3) 2019-01-21 10:25 x86_64 Cygwin ----- From the output of strace: ----- # write ... fails 74 25044 [main] stc 1368 write: write(4, 0x100403117, 14) 31 25075 [main] stc 1368 seterrno_from_nt_status: /ext/build/mknetrel/src/cygwin-snapshot-20190121-1/winsup/cygwin/fhandler.cc:294 status 0xC0000022 -> windows error 5 29 25104 [main] stc 1368 geterrno_from_win_error: windows error 5 == errno 13 27 25131 [main] stc 1368 write: -1 = write(4, 0x100403117, 14), errno 13 i.e. the STC fails in fhandler_base::raw_write() in winsup/cygwin/fhandler.cc, right after NtWriteFile() ... Btw, earlier on, when /tmp/stc.txt is unlinked, an "Sharing violation" occurs: 32 21456 [main] stc 1368 unlink_nt: Trying to delete \??\E:\Cygwin64\tmp\stc.txt, isdir = 0 ----- # Sharing violation? in unlink_nt() in winsup/cygwin/syscalls.cc, after the 3rd call to NtOpenfile() 50 21506 [main] stc 1368 unlink_nt: Sharing violation when opening \??\E:\Cygwin64\tmp\stc.txt 443 21949 [main] stc 1368 try_to_bin: \??\E:\Cygwin64\tmp\stc.txt, return bin_status 2 ### "has been moved"? 35 21984 [main] stc 1368 unlink_nt: \??\E:\Cygwin64\tmp\stc.txt, return status = 0x0 28 22012 [main] stc 1368 unlink: 0 = unlink(/tmp/stc.txt) ----- Output of the STC: 64-@@ ./stc # source code included below ... Invoked from: /usr/bin/bash (parent process) flagsfl2 = 0x118000 devfile = /dev/fd/3 flagsfl3 = 0x118002 /dev/fd/3: Cannot write!, id = openfd3, errno = 13, errstr = Permission denied buf = Hello, world! 64-@@ # this is odd: open("/dev/fd/3", O_RDWR) succeeds ... write(4, ...) does not # fail w/ "Bad file descriptor", but w/ "Permission denied"! ----- If the STC is put "on hold" right before termination (before closing the file descriptors), the "bin" shows: 64-@@ pwd /drv/e/$RECYCLE.BIN/S-1-5-21-91509220-1575020443-2714799223-1000 64-@@ ls -al total 6 drwx------+ 1 Henri None 0 Jan 27 17:27 . drwxrwx---+ 1 Henri None 0 Jan 27 08:47 .. -rw-r----- 1 Unknown+User Unknown+Group 14 Jan 27 17:27 .???017d00000001f91f4e494283f3b8a953 -rwx------+ 1 Henri None 129 Jan 27 08:33 desktop.ini This file cannot be accessed (read) ... (can be read by STC, but NOT written to!). 64-@@ icacls . . BUILTIN\Administrators:(OI)(CI)(F) NT AUTHORITY\SYSTEM:(OI)(CI)(F) Seven\Henri:(OI)(CI)(F) Mandatory Label\Low Mandatory Level:(OI)(CI)(IO)(NW) Successfully processed 1 files; Failed processing 0 files 64-@@ getfacl . # file: . # owner: Henri # group: None user::rwx group::--- group:SYSTEM:rwx #effective:--- group:Administrators:rwx #effective:--- mask::--- other::--- default:user::rwx default:group::--- default:group:SYSTEM:rwx #effective:--- default:group:Administrators:rwx #effective:--- default:mask::--- default:other::--- ----- source code of STC: // gcc -Wall -o stc stc.c #include #include #include #include // strerror() #include #include // NOTE: my text uses "fd 2" for a file descriptor that equals 2; and fd2 for variable fd2 /* LPI, 5.11 The /dev/fd Directory (Linux Programming Interface, Michael Kerrisk) ... FIXME: No, on Linux the file is "reopened": a new open file description is created! Cygwin/ W7 file deleted: (fd2 is opened before file deletion) - file can be written to via fd3 iff fd2 has been opened read-write file NOT deleted: - file can be written to via fd3, even if fd2 has been opened read-only */ /* - create file (in /tmp) write-only, write "Hello, world!" to file, close fd - open file once more read-only (or read-write) - unlink file - open file, using /dev/fd/N (or /proc//fd/N), read-write - write "*****" to file (using the fd obtained in the previous line), lseek to begin of file - read file (using the same fd) */ void errExit(const char *str) { fprintf(stderr, "id = %s, errno = %d, errstr = %s\n", str, errno, strerror(errno)); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { #if 1 { char tmp0[30] = { 0 }; char tmp1[30] = { 0 }; if (snprintf(tmp0, sizeof(tmp0), "/proc/%u/exe", (unsigned int)getppid() ) == -1 ) errExit("sprintf-tmp0"); //printf("tmp0 = %s\n", tmp0); if (strlen(tmp0) == sizeof(tmp0) ) errExit("strlen-tmp0"); if (readlink(tmp0, tmp1, sizeof(tmp1) - 1) == -1) errExit("readlink-tmp1"); //printf("tmp1 = %s\n", tmp1); if (strlen(tmp1) == sizeof(tmp1) ) errExit("strlen-tmp1"); fprintf(stderr, "Invoked from: %s (parent process)\n", tmp1); } #endif int fd1, fd2, fd3; errno = 0; // kludge (ignore error if file does not exist) ... if (unlink("/tmp/stc.txt") == -1) { if (errno != 2) errExit("unlink"); else 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"); if (write(fd1, "Hello, world!\n", 14) == -1) errExit("writefd1"); // close fd1 like bash would do ... if (close(fd1) == -1) errExit("closefd1"); // also open this tmpfile for reading like bash would do ... fd2 = open("/tmp/stc.txt", O_RDONLY); //fd2 = open("/tmp/stc.txt", O_RDWR); if (fd2 == -1) errExit("openfd2"); #if 1 int flagsfl2; if ( (flagsfl2 = fcntl(fd2, F_GETFL)) == -1) errExit("fcntlfd1-getfl2"); fprintf(stderr, "flagsfl2 = 0x%x\n", flagsfl2); // Linux: /usr/include/bits/fcntl-linux.h // Cygwin: /usr/include/sys/_default_fcntl.h #endif // 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 file descriptor fd2 which // is still open ... char devfile[16] = "/dev/fd/"; devfile[8] = fd2 + 0x30; devfile[9] = '\0'; //char devfile[16] = "/proc/self/fd/"; devfile[14] = fd2 + 0x30; devfile[15] = '\0'; fprintf(stderr, "devfile = %s\n", devfile); // open this device file; it succeeds on Linux, but fails on Cygwin (that // is, it failed before 20190107?) //fd3 = open(devfile, O_RDONLY); // this failed before 20190107? fd3 = open(devfile, O_RDWR); // odd: succeeds on W7 (fd2 is read-only!) if (fd3 == -1) { // does not happen beyond 20190106 const char *id = "openfd3"; #if 1 fprintf(stderr, "%s: Cannot open!, id = %s, errno = %d, errstr = %s\n", devfile, id, errno, strerror(errno)); /* previously, (before 20190107?) it was not even possible to open the file, using either "/dev/fd/N" or "/proc/self/fd/N" if the target had been unlink'ed ... Now it is possible to open the file as indicated, but it can only be read. On Linux however, it is even possible to open it "read-write" ... (where fd3 will point to a brand-new open file handle) */ errno = 0; char buf[16] = { 0 }; if (read(fd2, buf, sizeof(buf) ) == -1) errExit("readfd2"); fprintf(stderr, "buf = %s", buf); if (close(fd2) == -1) fprintf(stderr, "closefd2 failed\n"); exit(EXIT_FAILURE); #else errExit(id); #endif } #if 0 { char buf[16] = { 0 }; if (read(fd2, buf, sizeof(buf) ) == -1) errExit("readfd2"); fprintf(stderr, "buf = %s", buf); } #endif #if 1 int flagsfl3; if ( (flagsfl3 = fcntl(fd3, F_GETFL)) == -1) errExit("fcntlfd3-getfl3"); fprintf(stderr, "flagsfl3 = 0x%x\n", flagsfl3); // Linux: /usr/include/bits/fcntl-linux.h // Cygwin: /usr/include/sys/_default_fcntl.h #endif // option: write using fd3 #if 1 // failure unless fd2 has been opened read-write (and file has been deleted) // W7: fd3 will be a duplicate of fd2 in that case ... if (write(fd3, "*****\n", 14) == -1) { const char *id = "openfd3"; #if 1 fprintf(stderr, "%s: Cannot write!, id = %s, errno = %d, errstr = %s\n", devfile, id, errno, strerror(errno)); errno = 0; #else errExit(id); #endif } // required because of write() -- reset file offset if (lseek(fd3, 0, SEEK_SET) == -1) errExit("lseekfd3"); #endif // end - option: write using fd3 char buf[16] = { 0 }; if (read(fd3, buf, sizeof(buf) ) == -1) errExit("readfd3"); fprintf(stderr, "buf = %s", buf); //sleep(30); if (close(fd3) == -1) fprintf(stderr, "closefd3 failed\n"); if (close(fd2) == -1) fprintf(stderr, "closefd2 failed\n"); } //===== -- 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