{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/comments/42320749","id":42320749,"diff_hunk":"@@ -813,3 +814,36 @@ extern \"C\" int32_t GetWindowSize(WinSize* windowSize)\n     return -1;\n #endif\n }\n+\n+extern \"C\" int32_t ReadStdinUnbuffered(void* buffer, int32_t bufferSize)\n+{\n+    assert(buffer != nullptr || bufferSize == 0);\n+    assert(bufferSize >= 0);\n+\n+    if (bufferSize < 0)\n+    {\n+        errno = EINVAL;\n+        return -1;\n+    }\n+\n+#if HAVE_TCGETATTR && HAVE_TCSETATTR && HAVE_ECHO && HAVE_ICANON && HAVE_TCSANOW\n+    struct termios oldtermios = {};\n+    struct termios newtermios = {};\n+\n+    if (tcgetattr(0, &oldtermios) < 0) return -1;\n+\n+    newtermios = oldtermios;\n+    newtermios.c_lflag &= static_cast<uint32_t>(~ECHO);\n+    newtermios.c_lflag &= static_cast<uint32_t>(~ICANON);\n+    newtermios.c_cc[VMIN] = 1;\n+    newtermios.c_cc[VTIME] = 0;\n+    if (tcsetattr(0, TCSANOW, &newtermios) < 0) return -3;\n+    ssize_t count = read(0, buffer, UnsignedCast(bufferSize));\n+    tcsetattr(0, TCSANOW, &oldtermios);\n+    return static_cast<int32_t>(count);\n+#else\n+    return -1;","path":"src/Native/System.Native/pal_io.cpp","position":40,"original_position":40,"commit_id":"874a2f0fb7f39b716ffb5308f0e9e7135437a02c","original_commit_id":"874a2f0fb7f39b716ffb5308f0e9e7135437a02c","user":{"login":"stephentoub","id":2642209,"avatar_url":"https://avatars.githubusercontent.com/u/2642209?v=3","gravatar_id":"","url":"https://api.github.com/users/stephentoub","html_url":"https://github.com/stephentoub","followers_url":"https://api.github.com/users/stephentoub/followers","following_url":"https://api.github.com/users/stephentoub/following{/other_user}","gists_url":"https://api.github.com/users/stephentoub/gists{/gist_id}","starred_url":"https://api.github.com/users/stephentoub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephentoub/subscriptions","organizations_url":"https://api.github.com/users/stephentoub/orgs","repos_url":"https://api.github.com/users/stephentoub/repos","events_url":"https://api.github.com/users/stephentoub/events{/privacy}","received_events_url":"https://api.github.com/users/stephentoub/received_events","type":"User","site_admin":false},"body":"We should probably set errno to ENOTSUP.","created_at":"2015-10-18T13:11:17Z","updated_at":"2015-10-18T13:11:17Z","html_url":"https://github.com/dotnet/corefx/pull/3939#discussion_r42320749","pull_request_url":"https://api.github.com/repos/dotnet/corefx/pulls/3939","_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments/42320749"},"html":{"href":"https://github.com/dotnet/corefx/pull/3939#discussion_r42320749"},"pull_request":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3939"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/3939","id":47995711,"html_url":"https://github.com/dotnet/corefx/pull/3939","diff_url":"https://github.com/dotnet/corefx/pull/3939.diff","patch_url":"https://github.com/dotnet/corefx/pull/3939.patch","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/3939","number":3939,"state":"open","locked":false,"title":"Enable System.Console.ReadKey","user":{"login":"pallavit","id":10713359,"avatar_url":"https://avatars.githubusercontent.com/u/10713359?v=3","gravatar_id":"","url":"https://api.github.com/users/pallavit","html_url":"https://github.com/pallavit","followers_url":"https://api.github.com/users/pallavit/followers","following_url":"https://api.github.com/users/pallavit/following{/other_user}","gists_url":"https://api.github.com/users/pallavit/gists{/gist_id}","starred_url":"https://api.github.com/users/pallavit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pallavit/subscriptions","organizations_url":"https://api.github.com/users/pallavit/orgs","repos_url":"https://api.github.com/users/pallavit/repos","events_url":"https://api.github.com/users/pallavit/events{/privacy}","received_events_url":"https://api.github.com/users/pallavit/received_events","type":"User","site_admin":false},"body":"This change tries to enable #1153.\r\n\r\nOn Windows the implementation is pretty straight-forward. We have APIs to capture the standard input and APIs that tell us the kind of key and modifier is pressed. \r\n\r\nOn Unix, there is no concept of virtual key codes and so, the implementation is mostly best case effort. \r\n The current implementation works as follows.\r\n 1. Capture stdin in the raw mode and reads as much of buffer as possible (max = 255 bytes).\r\n 2. Try to match the buffer with any of the special keys which it maintains in the db from the static string capabilities from TermInfo.\r\n 3. If not, it simply tries to use the ASCII key chart and map it to an equivalent ConsoleKey.\r\n\r\nIt also tries to second guess the modifier keys as follows\r\n 1. Alt - This is captured as esc key, so, we try to check if at the time of processing we can a combination of ESC + known key and if so, we assume alt was pressed.\r\n 2. Ctrl - Other than the known keys like \\b \\t and \\n, the rest of the ASCII key charts from 1 to 26 are considered typed with Ctrl + the alphabet.\r\n 3. Shift - Any capital A to Z are assumed to be pressed with Shift key.\r\n\r\nNot all keys are captured by this logic. For example, on my keyboard, NumLock + No. key results in a byte sequence, that can't be mapped to the no. itself. So, Unix implementation can never return ConsoleKey.NumPadX, Similarly combinations of Alt+FunctionKeys can't be interpreted correctly and are interpreted as Esc + the individual keys. Since not all key presses can be mapped to the correct ConsoleKey, the implementation tries to ignore 1 byte in case it can't be mapped to anything and continue to interpret the next byte. This is done because (ConsoleKey)0 is invalid. So, even if we can get the int representation of the byte being processed, we can't really create a valid ConsoleKeyInfo from it.","created_at":"2015-10-17T21:27:00Z","updated_at":"2015-10-18T13:11:17Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/corefx/pulls/3939/commits","review_comments_url":"https://api.github.com/repos/dotnet/corefx/pulls/3939/comments","review_comment_url":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/3939/comments","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/874a2f0fb7f39b716ffb5308f0e9e7135437a02c","head":{"label":"pallavit:ConsoleReadKey","ref":"ConsoleReadKey","sha":"874a2f0fb7f39b716ffb5308f0e9e7135437a02c","user":{"login":"pallavit","id":10713359,"avatar_url":"https://avatars.githubusercontent.com/u/10713359?v=3","gravatar_id":"","url":"https://api.github.com/users/pallavit","html_url":"https://github.com/pallavit","followers_url":"https://api.github.com/users/pallavit/followers","following_url":"https://api.github.com/users/pallavit/following{/other_user}","gists_url":"https://api.github.com/users/pallavit/gists{/gist_id}","starred_url":"https://api.github.com/users/pallavit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pallavit/subscriptions","organizations_url":"https://api.github.com/users/pallavit/orgs","repos_url":"https://api.github.com/users/pallavit/repos","events_url":"https://api.github.com/users/pallavit/events{/privacy}","received_events_url":"https://api.github.com/users/pallavit/received_events","type":"User","site_admin":false},"repo":{"id":31432680,"name":"corefx","full_name":"pallavit/corefx","owner":{"login":"pallavit","id":10713359,"avatar_url":"https://avatars.githubusercontent.com/u/10713359?v=3","gravatar_id":"","url":"https://api.github.com/users/pallavit","html_url":"https://github.com/pallavit","followers_url":"https://api.github.com/users/pallavit/followers","following_url":"https://api.github.com/users/pallavit/following{/other_user}","gists_url":"https://api.github.com/users/pallavit/gists{/gist_id}","starred_url":"https://api.github.com/users/pallavit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pallavit/subscriptions","organizations_url":"https://api.github.com/users/pallavit/orgs","repos_url":"https://api.github.com/users/pallavit/repos","events_url":"https://api.github.com/users/pallavit/events{/privacy}","received_events_url":"https://api.github.com/users/pallavit/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/pallavit/corefx","description":"This repo contains the foundational libraries that make up the .NET Core development stack.","fork":true,"url":"https://api.github.com/repos/pallavit/corefx","forks_url":"https://api.github.com/repos/pallavit/corefx/forks","keys_url":"https://api.github.com/repos/pallavit/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pallavit/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pallavit/corefx/teams","hooks_url":"https://api.github.com/repos/pallavit/corefx/hooks","issue_events_url":"https://api.github.com/repos/pallavit/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/pallavit/corefx/events","assignees_url":"https://api.github.com/repos/pallavit/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/pallavit/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/pallavit/corefx/tags","blobs_url":"https://api.github.com/repos/pallavit/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pallavit/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pallavit/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/pallavit/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pallavit/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/pallavit/corefx/languages","stargazers_url":"https://api.github.com/repos/pallavit/corefx/stargazers","contributors_url":"https://api.github.com/repos/pallavit/corefx/contributors","subscribers_url":"https://api.github.com/repos/pallavit/corefx/subscribers","subscription_url":"https://api.github.com/repos/pallavit/corefx/subscription","commits_url":"https://api.github.com/repos/pallavit/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/pallavit/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/pallavit/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/pallavit/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/pallavit/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/pallavit/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pallavit/corefx/merges","archive_url":"https://api.github.com/repos/pallavit/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pallavit/corefx/downloads","issues_url":"https://api.github.com/repos/pallavit/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/pallavit/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/pallavit/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/pallavit/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pallavit/corefx/labels{/name}","releases_url":"https://api.github.com/repos/pallavit/corefx/releases{/id}","created_at":"2015-02-27T18:16:49Z","updated_at":"2015-03-05T19:20:13Z","pushed_at":"2015-10-17T21:24:16Z","git_url":"git://github.com/pallavit/corefx.git","ssh_url":"git@github.com:pallavit/corefx.git","clone_url":"https://github.com/pallavit/corefx.git","svn_url":"https://github.com/pallavit/corefx","homepage":"","size":35885,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:master","ref":"master","sha":"aa871b59c7d908c7442e0649449f89e818162c23","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":26295345,"name":"corefx","full_name":"dotnet/corefx","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dotnet/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":false,"url":"https://api.github.com/repos/dotnet/corefx","forks_url":"https://api.github.com/repos/dotnet/corefx/forks","keys_url":"https://api.github.com/repos/dotnet/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/corefx/teams","hooks_url":"https://api.github.com/repos/dotnet/corefx/hooks","issue_events_url":"https://api.github.com/repos/dotnet/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/corefx/events","assignees_url":"https://api.github.com/repos/dotnet/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/corefx/tags","blobs_url":"https://api.github.com/repos/dotnet/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/corefx/languages","stargazers_url":"https://api.github.com/repos/dotnet/corefx/stargazers","contributors_url":"https://api.github.com/repos/dotnet/corefx/contributors","subscribers_url":"https://api.github.com/repos/dotnet/corefx/subscribers","subscription_url":"https://api.github.com/repos/dotnet/corefx/subscription","commits_url":"https://api.github.com/repos/dotnet/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/corefx/merges","archive_url":"https://api.github.com/repos/dotnet/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/corefx/downloads","issues_url":"https://api.github.com/repos/dotnet/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/corefx/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/corefx/releases{/id}","created_at":"2014-11-06T23:42:48Z","updated_at":"2015-10-17T22:22:45Z","pushed_at":"2015-10-18T11:46:34Z","git_url":"git://github.com/dotnet/corefx.git","ssh_url":"git@github.com:dotnet/corefx.git","clone_url":"https://github.com/dotnet/corefx.git","svn_url":"https://github.com/dotnet/corefx","homepage":"http://dotnet.github.io/core/","size":82546,"stargazers_count":8456,"watchers_count":8456,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1849,"mirror_url":null,"open_issues_count":648,"forks":1849,"open_issues":648,"watchers":8456,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3939"},"html":{"href":"https://github.com/dotnet/corefx/pull/3939"},"issue":{"href":"https://api.github.com/repos/dotnet/corefx/issues/3939"},"comments":{"href":"https://api.github.com/repos/dotnet/corefx/issues/3939/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3939/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/3939/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/corefx/statuses/874a2f0fb7f39b716ffb5308f0e9e7135437a02c"}}}}