Linux – Can’t write to a file I own and marked as writable?

Can’t write to a file I own and marked as writable?… here is a solution to the problem.

Can’t write to a file I own and marked as writable?

I’m working on Debian Jessie. As user opuser I created a file and owned it:

opuser@mymachine: $ ls -lash /webapps/myapp/run/gunicorn.sock
0 srwxrwxrwx 1 opuser webapps 0 Sep  1 18:50 /webapps/myapp/run/gunicorn.sock

Now if I try to open the file write:

opuser@mymachine: $ vi /webapps/myapp/run/gunicorn.sock

vi displays the error at the bottom: “~/run/gunicorn.sock" [Permission Denied].

Why do I have a file but can’t open the write, and the file permissions show that it is globally writable?

Update:

The file was created by running gunicorn, and the reason I debug it is that gunicorn users can’t write to it either :

gunicorn openprescribing.wsgi:application --name myapp_prod --workers 3 --bind=unix:/webapps/webapps/run/gunicorn.sock --user opuser --group webapps --log-level=debug

Here is the complete error:

[2015-09-01 11:18:36 +0000] [9439] [DEBUG] Current configuration:
  proxy_protocol: False
  worker_connections: 1000
  statsd_host: None
  max_requests_jitter: 0
  post_fork: <function post_fork at 0x7efebefd2230>
  pythonpath: None
  enable_stdio_inheritance: False
  worker_class: sync
  ssl_version: 3
  suppress_ragged_eofs: True
  syslog: False
  syslog_facility: user
  when_ready: <function when_ready at 0x7efebefc6ed8>
  pre_fork: <function pre_fork at 0x7efebefd20c8>
  cert_reqs: 0
  preload_app: False
  keepalive: 2
  accesslog: None
  group: 999
  graceful_timeout: 30
  do_handshake_on_connect: False
  spew: False
  workers: 3
  proc_name: myapp_prod
  sendfile: True
  pidfile: None
  umask: 0
  on_reload: <function on_reload at 0x7efebefc6d70>
  pre_exec: <function pre_exec at 0x7efebefd27d0>
  worker_tmp_dir: None
  post_worker_init: <function post_worker_init at 0x7efebefd2398>
  limit_request_fields: 100
  on_exit: <function on_exit at 0x7efebefd2e60>
  config: None
  secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
  proxy_allow_ips: ['127.0.0.1']
  pre_request: <function pre_request at 0x7efebefd2938>
  post_request: <function post_request at 0x7efebefd2a28>
  user: 999
  forwarded_allow_ips: ['127.0.0.1']
  worker_int: <function worker_int at 0x7efebefd2500>
  threads: 1
  max_requests: 0
  limit_request_line: 4094
  access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
  certfile: None
  worker_exit: <function worker_exit at 0x7efebefd2b90>
  chdir: /webapps/myapp/myapp
  paste: None
  default_proc_name: myapp.wsgi:application
  errorlog: -
  loglevel: debug
  logconfig: None
  syslog_addr: udp://localhost:514
  syslog_prefix: None
  daemon: False
  ciphers: TLSv1
  on_starting: <function on_starting at 0x7efebefc6c08>
  worker_abort: <function worker_abort at 0x7efebefd2668>
  bind: ['unix:/webapps/myapp/run/gunicorn.sock']
  raw_env: []
  reload: False
  check_config: False
  limit_request_field_size: 8190
  nworkers_changed: <function nworkers_changed at 0x7efebefd2cf8>
  timeout: 30
  ca_certs: None
  django_settings: None
  tmp_upload_dir: None
  keyfile: None
  backlog: 2048
  logger_class: gunicorn.glogging.Logger
  statsd_prefix:
[2015-09-01 11:18:36 +0000] [9439] [INFO] Starting gunicorn 19.3.0
Traceback (most recent call last):
  File "/home/anna/.virtualenvs/myapp/bin/gunicorn", line 11, in <module>
    sys.exit(run())
  File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 74, in run
    WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
  File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 189, in run
    super(Application, self).run()
  File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 72, in run
    Arbiter(self).run()
  File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 171, in run
    self.start()
  File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 130, in start
    self. LISTENERS = create_sockets(self.cfg, self.log)
  File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/sock.py", line 211, in create_sockets
    sock = sock_type(addr, conf, log)
  File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/sock.py", line 104, in __init__
    os.remove(addr)
OSError: [Errno 13] Permission denied: '/webapps/myapp/run/gunicorn.sock'

Solution

The node you are trying to open is a socket. More precisely, a Unix domain socket (the s in the permission flag indicates this). Sockets are not open(2) normal way (this is why vi(1) fails.) They must be called via the socket(PF_UNIX, ...) system (see unix(7)) and then bind(2)ed to the correct path in the filesystem (this is what makes them appear in the filesystem’s hierarchy).

Once you have such a socket working, you must connect(2) it to another socket (

or accept(2) because it is already bound (bind) to the filesystem node) to allow communication to flow from one socket to another.

For an introduction to socket

API programming (and UNIX domain sockets), read the famous R.W. Stevens book Unix Network Programming, Volume 1: Socket Network APIs (3rd Edition).

Related Problems and Solutions