Skip to content

Commit

Permalink
Identify sockets
Browse files Browse the repository at this point in the history
  • Loading branch information
mxr committed Mar 2, 2021
1 parent 6904105 commit 645f876
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ If you have an actual file on disk, you can get the most information possible

When using a file on disk, the checks performed are:

* File type (file, symlink, directory)
* File type (file, symlink, directory, socket)
* Mode (is it executable?)
* File name (mostly based on extension)
* If executable, the shebang is read and the interpreter interpreted
Expand Down
6 changes: 5 additions & 1 deletion identify/identify.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os.path
import re
import shlex
import stat
import string
import sys
from typing import IO
Expand All @@ -18,13 +19,14 @@

DIRECTORY = 'directory'
SYMLINK = 'symlink'
SOCKET = 'socket'
FILE = 'file'
EXECUTABLE = 'executable'
NON_EXECUTABLE = 'non-executable'
TEXT = 'text'
BINARY = 'binary'

TYPE_TAGS = frozenset((DIRECTORY, FILE, SYMLINK))
TYPE_TAGS = frozenset((DIRECTORY, FILE, SYMLINK, SOCKET))
MODE_TAGS = frozenset((EXECUTABLE, NON_EXECUTABLE))
ENCODING_TAGS = frozenset((BINARY, TEXT))
_ALL_TAGS = {*TYPE_TAGS, *MODE_TAGS, *ENCODING_TAGS}
Expand All @@ -42,6 +44,8 @@ def tags_from_path(path: str) -> Set[str]:
return {DIRECTORY}
if os.path.islink(path):
return {SYMLINK}
if stat.S_ISSOCK(os.stat(path).st_mode):
return {SOCKET}

tags = {FILE}

Expand Down
14 changes: 14 additions & 0 deletions tests/identify_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import io
import os
import socket
import stat
from tempfile import TemporaryDirectory

import pytest

Expand All @@ -12,6 +14,7 @@ def test_all_tags_includes_basic_ones():
assert 'directory' in identify.ALL_TAGS
assert 'executable' in identify.ALL_TAGS
assert 'text' in identify.ALL_TAGS
assert 'socket' in identify.ALL_TAGS


@pytest.mark.parametrize(
Expand Down Expand Up @@ -51,6 +54,17 @@ def test_tags_from_path_symlink(tmpdir):
assert identify.tags_from_path(x.strpath) == {'symlink'}


def test_tags_from_path_socket():
tmproot = '/tmp' # short path avoids `OSError: AF_UNIX path too long`
with TemporaryDirectory(dir=tmproot) as tmpdir:
socket_path = os.path.join(tmpdir, 'socket')
with socket.socket(socket.AF_UNIX) as sock:
sock.bind(socket_path)
tags = identify.tags_from_path(socket_path)

assert tags == {'socket'}


def test_tags_from_path_broken_symlink(tmpdir):
x = tmpdir.join('foo')
x.mksymlinkto(tmpdir.join('lol'))
Expand Down

0 comments on commit 645f876

Please sign in to comment.