grim/guifications3
Clone
Summary
Browse
Changes
Graph
bumped the glib dependency to >=2.26.0
2011-05-17, Gary Kramlich
2e22ea40b80f
bumped the glib dependency to >=2.26.0
added a dep on GIO
/*
* Guifications - The end-all, be-all notification framework
* Copyright (C) 2003-2009 Gary Kramlich <grim@reaperworld.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if HAVE_CONFIG_H
#
include
<config.h>
#endif
#include
<gflib/gf_intl.h>
#include
<gflib/gf_log.h>
#include
"gf_unix_errors.h"
#include
"gf_unix_server_connection.h"
#include
"gf_unix_utils.h"
#include
<sys/socket.h>
#include
<sys/types.h>
#include
<sys/un.h>
#include
<unistd.h>
#define GF_UNIX_SERVER_CONNECTION_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), GF_TYPE_UNIX_SERVER_CONNECTION, GfUnixServerConnectionPrivate))
/******************************************************************************
* Structs
*****************************************************************************/
typedef
struct
{
gint
fd
;
gchar
*
path
;
}
GfUnixServerConnectionPrivate
;
/******************************************************************************
* Globals
*****************************************************************************/
static
GfServerConnectionClass
*
parent_class
=
NULL
;
static
GType
type
=
0
;
/******************************************************************************
* Connection Stuff
*****************************************************************************/
static
gboolean
gf_unix_server_connection_listen
(
GfServerConnection
*
connection
,
GError
**
error
)
{
struct
sockaddr_un
saddr
;
GfUnixServerConnectionPrivate
*
priv
=
GF_UNIX_SERVER_CONNECTION_GET_PRIVATE
(
connection
);
gf_connection_set_state
(
GF_CONNECTION
(
connection
),
GF_CONNECTION_STATE_CONNECTING
);
priv
->
fd
=
socket
(
AF_UNIX
,
SOCK_STREAM
,
0
);
if
(
priv
->
fd
==
-1
)
{
*
error
=
g_error_new
(
GF_UNIX_ERRORS
,
FailedToCreateSocket
,
"Failed to create socket"
);
return
FALSE
;
}
saddr
.
sun_family
=
AF_UNIX
;
priv
->
path
=
gf_unix_get_socket_path
();
g_snprintf
(
saddr
.
sun_path
,
108
,
"%s"
,
priv
->
path
);
if
(
access
(
saddr
.
sun_path
,
F_OK
)
==
0
)
{
if
(
connect
(
priv
->
fd
,
(
struct
sockaddr
*
)
&
saddr
,
sizeof
(
saddr
))
!=
-1
)
{
/* the socket is already in use */
close
(
priv
->
fd
);
priv
->
fd
=
-1
;
gf_connection_set_state
(
GF_CONNECTION
(
connection
),
GF_CONNECTION_STATE_DISCONNECTED
);
*
error
=
g_error_new
(
GF_UNIX_ERRORS
,
SocketInUse
,
"Socket is already in use!"
);
return
FALSE
;
}
unlink
(
saddr
.
sun_path
);
}
if
(
bind
(
priv
->
fd
,
(
struct
sockaddr
*
)
&
saddr
,
sizeof
(
saddr
))
==
-1
)
{
close
(
priv
->
fd
);
priv
->
fd
=
-1
;
gf_connection_set_state
(
GF_CONNECTION
(
connection
),
GF_CONNECTION_STATE_DISCONNECTED
);
*
error
=
g_error_new
(
GF_UNIX_ERRORS
,
FailedToBindToSocket
,
"Failed to bind to the socket"
);
return
FALSE
;
}
listen
(
priv
->
fd
,
5
);
if
(
!
gf_unix_fd_make_nonblocking
(
priv
->
fd
))
{
close
(
priv
->
fd
);
priv
->
fd
=
-1
;
gf_connection_set_state
(
GF_CONNECTION
(
connection
),
GF_CONNECTION_STATE_DISCONNECTED
);
*
error
=
g_error_new
(
GF_UNIX_ERRORS
,
FailedToMakeNonBlocking
,
"Failed to make the socket nonblocking"
);
return
FALSE
;
}
gf_connection_set_state
(
GF_CONNECTION
(
connection
),
GF_CONNECTION_STATE_CONNECTED
);
return
TRUE
;
}
static
gboolean
gf_unix_server_connection_disconnect
(
GfConnection
*
connection
,
GError
**
error
)
{
return
FALSE
;
}
/******************************************************************************
* Object Stuff
*****************************************************************************/
static
void
gf_unix_server_connection_finalize
(
GObject
*
obj
)
{
GfUnixServerConnectionPrivate
*
priv
=
NULL
;
priv
=
GF_UNIX_SERVER_CONNECTION_GET_PRIVATE
(
obj
);
G_OBJECT_CLASS
(
parent_class
)
->
finalize
(
obj
);
}
static
void
gf_unix_server_connection_class_init
(
GfUnixServerConnectionClass
*
klass
)
{
GObjectClass
*
obj_class
=
G_OBJECT_CLASS
(
klass
);
GfNamedObjectClass
*
gfno_class
=
GF_NAMED_OBJECT_CLASS
(
klass
);
GfConnectionClass
*
conn_class
=
GF_CONNECTION_CLASS
(
klass
);
GfServerConnectionClass
*
server_class
=
GF_SERVER_CONNECTION_CLASS
(
klass
);
parent_class
=
g_type_class_peek_parent
(
klass
);
obj_class
->
finalize
=
gf_unix_server_connection_finalize
;
g_type_class_add_private
(
klass
,
sizeof
(
GfUnixServerConnectionPrivate
));
gfno_class
->
name
=
_
(
"UNIX"
);
server_class
->
listen
=
gf_unix_server_connection_listen
;
conn_class
->
disconnect
=
gf_unix_server_connection_disconnect
;
}
/******************************************************************************
* Connection API
*****************************************************************************/
void
gf_unix_server_connection_register_type
(
GfNativePlugin
*
plugin
)
{
if
(
type
==
0
)
{
static
const
GTypeInfo
info
=
{
sizeof
(
GfUnixServerConnectionClass
),
NULL
,
NULL
,
(
GClassInitFunc
)
gf_unix_server_connection_class_init
,
NULL
,
NULL
,
sizeof
(
GfUnixServerConnection
),
0
,
NULL
,
};
type
=
gf_native_plugin_register_type
(
plugin
,
GF_TYPE_SERVER_CONNECTION
,
"GfUnixServerConnection"
,
&
info
,
0
);
}
}
GType
gf_unix_server_connection_get_type
(
void
)
{
if
(
type
==
0
)
{
gf_log_warning
(
"GfUnixServerConnection"
,
"gf_unix_server_connection_get_type called before the "
"type was registered!
\n
"
);
}
return
type
;
}