Corinna Vinschen <corinna-cygwin <at> cygwin.com> writes: > Can you please provide the socket testcase?
Trying to send you what you ask for (using gmane.org, I have to copy/paste) ----- t_stat3.c: /*************************************************************************\ * Copyright (C) Michael Kerrisk, 2014. * * * * This program is free software. You may use, modify, and redistribute it * * under the terms of the GNU Affero General Public License as published * * by the Free Software Foundation, either version 3 or (at your option) * * any later version. This program is distributed without any warranty. * * See the file COPYING.agpl-v3 for details. * \*************************************************************************/ /* Listing 15-1 */ // t_stat.c -- heavily modified #define _BSD_SOURCE /* Get major() and minor() from <sys/types.h> */ #include <sys/types.h> #include <sys/stat.h> #include <time.h> //#include "file_perms.h" //#include "tlpi_hdr.h" #include <stdio.h> /* Standard I/O functions */ #include <stdlib.h> /* Prototypes of commonly used library functions, plus EXIT_SUCCESS and EXIT_FAILURE constants */ #include <unistd.h> /* Prototypes for many system calls */ #include <string.h> /* Commonly used string-handling functions */ static void displayStatInfo(const struct stat *sb) { printf("File type: "); switch (sb->st_mode & S_IFMT) { case S_IFREG: printf("regular file\n"); break; case S_IFDIR: printf("directory\n"); break; case S_IFCHR: printf("character device\n"); break; case S_IFBLK: printf("block device\n"); break; case S_IFLNK: printf("symbolic (soft) link\n"); break; case S_IFIFO: printf("FIFO or pipe\n"); break; case S_IFSOCK: printf("socket\n"); break; default: printf("unknown file type?\n"); break; } printf("Device containing i-node: (%lx) major=%lu minor=%lu\n", (long) sb->st_dev, (long) major(sb->st_dev), (long) minor(sb->st_dev)); printf("I-node number: %llx - decimal: %llu\n", sb->st_ino, sb->st_ino); if (S_ISCHR(sb->st_mode) || S_ISBLK(sb->st_mode)) printf(" **** Device number (st_rdev): major=%ld; minor=%ld\n", (long) major(sb->st_rdev), (long) minor(sb->st_rdev)); printf("File size: %lld bytes\n", (long long) sb->st_size); } void errExit(const char *format, ...); #include <sys/un.h> #include <sys/socket.h> int main() { char symlnk[64]; pid_t pid = getpid(); int sfd[2]; for (int f = 0; f < 2; f++) // step over the 1st and 2nd socket { if (!f) { sfd[f] = socket(AF_UNIX, SOCK_STREAM, 0); //sfd[f] = socket(AF_INET, SOCK_STREAM, 0); if (sfd[f] == -1) errExit("socket"); } else { sfd[f] = socket(AF_UNIX, SOCK_STREAM, 0); //sfd[f] = socket(AF_INET, SOCK_STREAM, 0); if (sfd[f] == -1) errExit("socket"); } } struct stat sb[2]; // one buffer for the 1st socket, one for the 2nd int f; char target[128]; ssize_t num; printf("1st socket\n"); f = 0; if (sprintf(symlnk, "/proc/%d/fd/%d", pid, sfd[f]) <= 0) errExit("sprintf"); printf("... %s (symbolic link to the socket)\n", symlnk); if ( (num = readlink( (const char *)symlnk, target, 128) ) == -1) errExit("readlink"); if (num < 128) { target[num] = '\0'; printf("... %s (target of symbolic link to the socket)\n", target); printf("... using stat() on symbolic link: %s\n", symlnk); //if (stat(target, sb + f) != 0) // not possible: target is NOT a filename ... if (stat(symlnk, sb + f) != 0) errExit("stat"); displayStatInfo(sb + f); printf("... using fstat()\n"); memset(sb + f, 0, sizeof(struct stat) ); // CLEAR if (fstat(sfd[f], sb + f) != 0) errExit("fstat"); displayStatInfo(sb + f); } #if 1 printf("\n2nd socket\n"); f = 1; if (sprintf(symlnk, "/proc/%d/fd/%d", pid, sfd[f]) <= 0) errExit("sprintf"); printf("... %s (symbolic link to the socket)\n", symlnk); if ( (num = readlink( (const char *)symlnk, target, 128) ) == -1) errExit("readlink"); if (num < 128) { target[num] = '\0'; printf("... %s (target of symbolic link to the socket)\n", target); printf("... using stat() on symbolic link: %s\n", symlnk); //if (stat(target, sb + f) != 0) // not possible: target is NOT a filename ... if (stat(symlnk, sb + f) != 0) errExit("stat"); displayStatInfo(sb + f); printf("... using fstat()\n"); memset(sb + f, 0, sizeof(struct stat) ); // CLEAR if (fstat(sfd[f], sb + f) != 0) errExit("fstat"); displayStatInfo(sb + f); } #endif close(sfd[0]); close(sfd[1]); exit(EXIT_SUCCESS); } #include <errno.h> /* Declares errno and defines error constants */ #include <stdarg.h> #ifdef TRUE #undef TRUE #endif #ifdef FALSE #undef FALSE #endif typedef enum { FALSE, TRUE } Boolean; static char *ename[] = { /* 0 */ "", /* 1 */ "EPERM", "ENOENT", "ESRCH", "EINTR", "EIO", "ENXIO", /* 7 */ "E2BIG", "ENOEXEC", "EBADF", "ECHILD", /* 11 */ "EAGAIN/EWOULDBLOCK", "ENOMEM", "EACCES", "EFAULT", /* 15 */ "ENOTBLK", "EBUSY", "EEXIST", "EXDEV", "ENODEV", /* 20 */ "ENOTDIR", "EISDIR", "EINVAL", "ENFILE", "EMFILE", /* 25 */ "ENOTTY", "ETXTBSY", "EFBIG", "ENOSPC", "ESPIPE", /* 30 */ "EROFS", "EMLINK", "EPIPE", "EDOM", "ERANGE", "ENOMSG", /* 36 */ "EIDRM", "ECHRNG", "EL2NSYNC", "EL3HLT", "EL3RST", /* 41 */ "ELNRNG", "EUNATCH", "ENOCSI", "EL2HLT", "EDEADLK", /* 46 */ "ENOLCK", "", "", "", "EBADE", "EBADR", "EXFULL", /* 53 */ "ENOANO", "EBADRQC", "EBADSLT", "EDEADLOCK", "EBFONT", /* 58 */ "", "", "ENOSTR", "ENODATA", "ETIME", "ENOSR", "ENONET", /* 65 */ "ENOPKG", "EREMOTE", "ENOLINK", "EADV", "ESRMNT", /* 70 */ "ECOMM", "EPROTO", "", "", "EMULTIHOP", "ELBIN", /* 76 */ "EDOTDOT", "EBADMSG", "", "EFTYPE", "ENOTUNIQ", "EBADFD", /* 82 */ "EREMCHG", "ELIBACC", "ELIBBAD", "ELIBSCN", "ELIBMAX", /* 87 */ "ELIBEXEC", "ENOSYS", "ENMFILE", "ENOTEMPTY", /* 91 */ "ENAMETOOLONG", "ELOOP", "", "", "EOPNOTSUPP", /* 96 */ "EPFNOSUPPORT", "", "", "", "", "", "", "", "ECONNRESET", /* 105 */ "ENOBUFS", "EAFNOSUPPORT", "EPROTOTYPE", "ENOTSOCK", /* 109 */ "ENOPROTOOPT", "ESHUTDOWN", "ECONNREFUSED", "EADDRINUSE", /* 113 */ "ECONNABORTED", "ENETUNREACH", "ENETDOWN", "ETIMEDOUT", /* 117 */ "EHOSTDOWN", "EHOSTUNREACH", "EINPROGRESS", "EALREADY", /* 121 */ "EDESTADDRREQ", "EMSGSIZE", "EPROTONOSUPPORT", /* 124 */ "ESOCKTNOSUPPORT", "EADDRNOTAVAIL", "ENETRESET", /* 127 */ "EISCONN", "ENOTCONN", "ETOOMANYREFS", "EPROCLIM", /* 131 */ "EUSERS", "EDQUOT", "ESTALE", "ENOTSUP", "ENOMEDIUM", /* 136 */ "ENOSHARE", "ECASECLASH", "EILSEQ", "EOVERFLOW", /* 140 */ "ECANCELED", "ENOTRECOVERABLE", "EOWNERDEAD", "ESTRPIPE" }; #define MAX_ENAME 143 static void terminate(Boolean useExit3) { char *s; /* Dump core if EF_DUMPCORE environment variable is defined and is a nonempty string; otherwise call exit(3) or _exit(2), depending on the value of 'useExit3'. */ s = getenv("EF_DUMPCORE"); if (s != NULL && *s != '\0') abort(); else if (useExit3) exit(EXIT_FAILURE); else _exit(EXIT_FAILURE); } static void outputError(Boolean useErr, int err, Boolean flushStdout, const char *format, va_list ap) { #define BUF_SIZE 500 char buf[BUF_SIZE], userMsg[BUF_SIZE], errText[BUF_SIZE]; vsnprintf(userMsg, BUF_SIZE, format, ap); if (useErr) snprintf(errText, BUF_SIZE, " [%s %s]", (err > 0 && err <= MAX_ENAME) ? ename[err] : "?UNKNOWN?", strerror(err)); else snprintf(errText, BUF_SIZE, ":"); snprintf(buf, BUF_SIZE, "ERROR%s %s\n", errText, userMsg); if (flushStdout) fflush(stdout); /* Flush any pending stdout */ fputs(buf, stderr); fflush(stderr); /* In case stderr is not line-buffered */ } void errExit(const char *format, ...) { va_list argList; va_start(argList, format); outputError(TRUE, errno, TRUE, format, argList); va_end(argList); terminate(TRUE); } //===== -- 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