3 * Copyright (c) 2013 Luca Barbato
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 * Unix socket url_protocol
29 #include "libavutil/avstring.h"
30 #include "libavutil/opt.h"
31 #include "os_support.h"
36 typedef struct UnixContext
{
38 struct sockaddr_un addr
;
45 #define OFFSET(x) offsetof(UnixContext, x)
46 #define ED AV_OPT_FLAG_DECODING_PARAM|AV_OPT_FLAG_ENCODING_PARAM
47 static const AVOption unix_options
[] = {
48 { "listen", "Open socket for listening", OFFSET(listen
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, ED
},
49 { "timeout", "Timeout in ms", OFFSET(timeout
), AV_OPT_TYPE_INT
, { .i64
= -1 }, -1, INT_MAX
, ED
},
50 { "type", "Socket type", OFFSET(type
), AV_OPT_TYPE_INT
, { .i64
= SOCK_STREAM
}, INT_MIN
, INT_MAX
, ED
, "type" },
51 { "stream", "Stream (reliable stream-oriented)", 0, AV_OPT_TYPE_CONST
, { .i64
= SOCK_STREAM
}, INT_MIN
, INT_MAX
, ED
, "type" },
52 { "datagram", "Datagram (unreliable packet-oriented)", 0, AV_OPT_TYPE_CONST
, { .i64
= SOCK_DGRAM
}, INT_MIN
, INT_MAX
, ED
, "type" },
53 { "seqpacket", "Seqpacket (reliable packet-oriented", 0, AV_OPT_TYPE_CONST
, { .i64
= SOCK_SEQPACKET
}, INT_MIN
, INT_MAX
, ED
, "type" },
57 static const AVClass unix_class
= {
59 .item_name
= av_default_item_name
,
60 .option
= unix_options
,
61 .version
= LIBAVUTIL_VERSION_INT
,
64 static int unix_open(URLContext
*h
, const char *filename
, int flags
)
66 UnixContext
*s
= h
->priv_data
;
69 av_strstart(filename
, "unix:", &filename
);
70 s
->addr
.sun_family
= AF_UNIX
;
71 av_strlcpy(s
->addr
.sun_path
, filename
, sizeof(s
->addr
.sun_path
));
73 if ((fd
= ff_socket(AF_UNIX
, s
->type
, 0)) < 0)
77 fd
= ff_listen_bind(fd
, (struct sockaddr
*)&s
->addr
,
78 sizeof(s
->addr
), s
->timeout
, h
);
84 ret
= ff_listen_connect(fd
, (struct sockaddr
*)&s
->addr
,
85 sizeof(s
->addr
), s
->timeout
, h
, 0);
95 if (s
->listen
&& AVUNERROR(ret
) != EADDRINUSE
)
96 unlink(s
->addr
.sun_path
);
102 static int unix_read(URLContext
*h
, uint8_t *buf
, int size
)
104 UnixContext
*s
= h
->priv_data
;
107 if (!(h
->flags
& AVIO_FLAG_NONBLOCK
)) {
108 ret
= ff_network_wait_fd(s
->fd
, 0);
112 ret
= recv(s
->fd
, buf
, size
, 0);
113 return ret
< 0 ? ff_neterrno() : ret
;
116 static int unix_write(URLContext
*h
, const uint8_t *buf
, int size
)
118 UnixContext
*s
= h
->priv_data
;
121 if (!(h
->flags
& AVIO_FLAG_NONBLOCK
)) {
122 ret
= ff_network_wait_fd(s
->fd
, 1);
126 ret
= send(s
->fd
, buf
, size
, MSG_NOSIGNAL
);
127 return ret
< 0 ? ff_neterrno() : ret
;
130 static int unix_close(URLContext
*h
)
132 UnixContext
*s
= h
->priv_data
;
134 unlink(s
->addr
.sun_path
);
139 static int unix_get_file_handle(URLContext
*h
)
141 UnixContext
*s
= h
->priv_data
;
145 URLProtocol ff_unix_protocol
= {
147 .url_open
= unix_open
,
148 .url_read
= unix_read
,
149 .url_write
= unix_write
,
150 .url_close
= unix_close
,
151 .url_get_file_handle
= unix_get_file_handle
,
152 .priv_data_size
= sizeof(UnixContext
),
153 .priv_data_class
= &unix_class
,
154 .flags
= URL_PROTOCOL_FLAG_NETWORK
,