indexing
	description: "An unix socket."
	status: "See notice at end of class"
	date: "$Date$"
	revision: "$Revision$"

deferred class interface
	UNIX_SOCKET

feature -- Initialization

	create_from_descriptor (fd: INTEGER)
			-- Create socket from descriptor fd.
			-- (from SOCKET)
		ensure -- from SOCKET
			family_valid: family = address.family
			opened_all: is_open_write and is_open_read
	
feature -- Access

	retrieved: ANY
			-- Retrieved object structure
			-- To access resulting object under correct type,
			-- use assignment attempt.
			-- Will raise an exception (code Retrieve_exception)
			-- if content is not a stored Eiffel structure.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			exists: exists
			is_open_read: is_open_read
			support_storable: support_storable
		ensure -- from IO_MEDIUM
			result_exists: Result /= void
	
feature -- Status report

	address_in_use: BOOLEAN
			-- Address is in use by another socket.
			-- (from SOCKET_RESOURCES)

	address_not_readable: BOOLEAN
			-- Unreadable address
			-- (from SOCKET_RESOURCES)

	already_bound: BOOLEAN
			-- Socket has already been bound.
			-- (from SOCKET_RESOURCES)

	bad_socket_handle: BOOLEAN
			-- Socket descriptor is bad.
			-- (from SOCKET_RESOURCES)

	connect_in_progress: BOOLEAN
			-- Call to connect returned on a non-blocking socket.
			-- (from SOCKET_RESOURCES)

	connection_refused: BOOLEAN
			-- Connection is refused (possibly due to security).
			-- (from SOCKET_RESOURCES)

	dtable_full: BOOLEAN
			-- Descriptor table is full
			-- (from SOCKET_RESOURCES)

	error: STRING
			-- Output a related error message.
			-- (from SOCKET_RESOURCES)

	error_number: INTEGER
			-- Returned error number
			-- (from SOCKET_RESOURCES)

	expired_socket: BOOLEAN
			-- Socket connection has expired.
			-- (from SOCKET_RESOURCES)

	invalid_address: BOOLEAN
			-- Address is not valid.
			-- (from SOCKET_RESOURCES)

	invalid_socket_handle: BOOLEAN
			-- Socket descriptor is not valid.
			-- (from SOCKET_RESOURCES)

	is_plain_text: BOOLEAN
			-- Is file reserved for text (character sequences)?
			-- (from IO_MEDIUM)

	is_valid_peer_address (addr: SOCKET_ADDRESS): BOOLEAN
			-- Is addr a valid peer address?
			-- (from SOCKET)
		require -- from SOCKET
			address_exists: addr /= void

	last_character: CHARACTER
			-- Last character read by read_character
			-- (from IO_MEDIUM)

	last_double: DOUBLE
			-- Last double read by read_double
			-- (from IO_MEDIUM)

	last_integer: INTEGER
			-- Last integer read by read_integer
			-- (from IO_MEDIUM)

	last_real: REAL
			-- Last real read by read_real
			-- (from IO_MEDIUM)

	last_string: STRING
			-- Last string read
			-- (from IO_MEDIUM)

	network: BOOLEAN
			-- Socket failed due to network problems.
			-- (from SOCKET_RESOURCES)

	no_buffers: BOOLEAN
			-- No more buffers available
			-- (from SOCKET_RESOURCES)

	no_permission: BOOLEAN
			-- No permission is given to user for this socket.
			-- (from SOCKET_RESOURCES)

	not_connected: BOOLEAN
			-- Socket is not connect.
			-- (from SOCKET_RESOURCES)

	protected_address: BOOLEAN
			-- No access to this address is allowed.
			-- (from SOCKET_RESOURCES)

	protocol_not_supported: BOOLEAN
			-- Protocol is not supported on this platform.
			-- (from SOCKET_RESOURCES)

	socket_family_not_supported: BOOLEAN
			-- Requested family is not supported.
			-- (from SOCKET_RESOURCES)

	socket_in_use: BOOLEAN
			-- Socket is already in use.
			-- (from SOCKET_RESOURCES)

	socket_ok: BOOLEAN
			-- No error
			-- (from SOCKET_RESOURCES)

	socket_would_block: BOOLEAN
			-- Call to read, write, etc would have blocked.
			-- (from SOCKET_RESOURCES)

	support_storable: BOOLEAN
			-- Can medium be used to store an Eiffel structure?
			-- (from SOCKET)

	zero_option: BOOLEAN
			-- No options provided
			-- (from SOCKET_RESOURCES)
	
feature -- Status setting

	unlink
			-- Remove associate name from file system.
		require else
			name_address: address /= void
	
feature -- Element change

	basic_store (object: ANY)
			-- Produce an external representation of the
			-- entire object structure reachable from object.
			-- Retrievable within current system only.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			object_not_void: object /= void
			exists: exists
			is_open_write: is_open_write
			support_storable: support_storable

	general_store (object: ANY)
			-- Produce an external representation of the
			-- entire object structure reachable from object.
			-- Retrievable from other systems for same platform
			-- (machine architecture).
			-- (from SOCKET)
		require -- from IO_MEDIUM
			object_not_void: object /= void
			exists: exists
			is_open_write: is_open_write
			support_storable: support_storable

	independent_store (object: ANY)
			-- Produce an external representation of the
			-- entire object structure reachable from object.
			-- Retrievable from other systems for the same or other
			-- platform (machine architecture).
			-- (from SOCKET)
		require -- from IO_MEDIUM
			object_not_void: object /= void
			exists: exists
			is_open_write: is_open_write
			support_storable: support_storable
	
feature -- Removal

	dispose
			-- Ensure this medium is closed when garbage collected.
			-- (from IO_MEDIUM)
	
feature -- Obsolete

	lastchar: CHARACTER
			-- Last character read by read_character
			-- (from IO_MEDIUM)

	lastdouble: DOUBLE
			-- Last double read by read_double
			-- (from IO_MEDIUM)

	lastint: INTEGER
			-- Last integer read by read_integer
			-- (from IO_MEDIUM)

	lastreal: REAL
			-- Last real read by read_real
			-- (from IO_MEDIUM)

	laststring: STRING
			-- Last string read
			-- (from IO_MEDIUM)
	
feature -- Basic commands

	bind
			-- Bind socket to local address in address.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
			valid_local_address: address /= void

	close
			-- Close socket.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			medium_is_open: not is_closed
		require else -- from SOCKET
			socket_exists: exists

	connect
			-- Connect socket to peer address.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
			valid_peer_address: peer_address /= void

	descriptor: INTEGER
			-- Socket descriptor of current socket
			-- (from SOCKET)

	descriptor_available: BOOLEAN
			-- Is descriptor available?
			-- (from SOCKET)

	family: INTEGER
			-- Socket family eg. af_inet, af_unix
			-- (from SOCKET)

	is_closed: BOOLEAN
			-- Is socket closed?
			-- (from SOCKET)

	make_socket
			-- Create socket descriptor.
			-- (from SOCKET)
		require -- from SOCKET
			valid_family: family >= 0
			valid_type: type >= 0
			valid_protocol: protocol >= 0

	peer_address: like address
			-- Peer address of socket
			-- (from SOCKET)

	protocol: INTEGER
			-- Protocol of the socket. default 0
			-- means for the system to chose the default
			-- protocol for the family chosen. eg. udp, tcp.
			-- (from SOCKET)

	set_address (addr: like address)
			-- Set local address to addr.
			-- (from SOCKET)
		require -- from SOCKET
			same_type: addr.family = family
		ensure -- from SOCKET
			address_set: address = addr

	set_peer_address (addr: like address)
			-- Set peer address to addr.
			-- (from SOCKET)
		require -- from SOCKET
			address_exists: addr /= void
			address_valid: is_valid_peer_address (addr)
		ensure -- from SOCKET
			address_set: peer_address = addr

	type: INTEGER
			-- Type of socket. eg stream, datagram
			-- (from SOCKET)
	
feature -- Externals: flags for send, sendto recv and recvfrom socket calls

	c_msgdontroute: INTEGER
			-- Do not route message
			-- (from SOCKET_RESOURCES)

	c_oobmsg: INTEGER
			-- Out of bound message
			-- (from SOCKET_RESOURCES)

	c_peekmsg: INTEGER
			-- Peek message
			-- (from SOCKET_RESOURCES)
	
feature -- Input

	last_boolean: BOOLEAN
			-- Last boolean read by read_boolean
			-- (from SOCKET)

	read (size: INTEGER): PACKET
			-- Read a packet of data of maximum size size.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	read_boolean
			-- Read a new boolean.
			-- Maker result available in last_boolean.
			-- Was declared in SOCKET as synonym of readbool.
			-- (from SOCKET)
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	read_character
			-- Read a new character.
			-- Make result available in last_character.
			-- Was declared in SOCKET as synonym of readchar.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			is_readable: readable
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	read_double
			-- Read a new double.
			-- Make result available in last_double.
			-- Was declared in SOCKET as synonym of readdouble.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			is_readable: readable
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	read_integer
			-- Read a new integer.
			-- Make result available in last_integer.
			-- Was declared in SOCKET as synonym of readint.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			is_readable: readable
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	read_line
			-- Read a line of characters (ended by a new_line).
			-- Was declared in SOCKET as synonym of readline.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			is_readable: readable
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	read_real
			-- Read a new real.
			-- Make result available in last_real.
			-- Was declared in SOCKET as synonym of readreal.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			is_readable: readable
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	read_stream (nb_char: INTEGER)
			-- Read a string of at most nb_char characters.
			-- Make result available in last_string.
			-- Was declared in SOCKET as synonym of readstream.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			is_readable: readable
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	readbool
			-- Read a new boolean.
			-- Maker result available in last_boolean.
			-- Was declared in SOCKET as synonym of read_boolean.
			-- (from SOCKET)
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	readchar
			-- Read a new character.
			-- Make result available in last_character.
			-- Was declared in SOCKET as synonym of read_character.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			is_readable: readable
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	readdouble
			-- Read a new double.
			-- Make result available in last_double.
			-- Was declared in SOCKET as synonym of read_double.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			is_readable: readable
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	readint
			-- Read a new integer.
			-- Make result available in last_integer.
			-- Was declared in SOCKET as synonym of read_integer.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			is_readable: readable
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	readline
			-- Read a line of characters (ended by a new_line).
			-- Was declared in SOCKET as synonym of read_line.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			is_readable: readable
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	readreal
			-- Read a new real.
			-- Make result available in last_real.
			-- Was declared in SOCKET as synonym of read_real.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			is_readable: readable
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	readstream (nb_char: INTEGER)
			-- Read a string of at most nb_char characters.
			-- Make result available in last_string.
			-- Was declared in SOCKET as synonym of read_stream.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			is_readable: readable
		require else -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read

	receive (size, flags: INTEGER): PACKET
			-- Receive a packet of maximum size size.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
			opened_for_read: is_open_read
	
feature -- Output

	exists: BOOLEAN
			-- Does socket exist?
			-- (from SOCKET)

	extendible: BOOLEAN
			-- May new items be added?
			-- (from SOCKET)

	is_executable: BOOLEAN
			-- Is socket an executable?
			-- (from SOCKET)
		require -- from IO_MEDIUM
			handle_exists: exists

	is_open_read: BOOLEAN
			-- Is socket opened for reading?
			-- (from SOCKET)

	is_open_write: BOOLEAN
			-- Is socket opened for writing?
			-- (from SOCKET)

	is_readable: BOOLEAN
			-- Is socket a readable medium?
			-- (from SOCKET)
		require -- from IO_MEDIUM
			handle_exists: exists

	is_writable: BOOLEAN
			-- Is socket a writable medium?
			-- (from SOCKET)
		require -- from IO_MEDIUM
			handle_exists: exists

	new_line
			-- Write a "new_line" character to socket.
			-- Was declared in SOCKET as synonym of put_new_line.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	put_boolean (b: BOOLEAN)
			-- Write boolean b to socket.
			-- Was declared in SOCKET as synonym of putbool.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	put_character (c: CHARACTER)
			-- Write character c to socket.
			-- Was declared in SOCKET as synonym of putchar.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	put_double (d: DOUBLE)
			-- Write double d to socket.
			-- Was declared in SOCKET as synonym of putdouble.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	put_integer (i: INTEGER)
			-- Write integer i to socket.
			-- Was declared in SOCKET as synonym of putint.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	put_new_line
			-- Write a "new_line" character to socket.
			-- Was declared in SOCKET as synonym of new_line.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	put_real (r: REAL)
			-- Write real r to socket.
			-- Was declared in SOCKET as synonym of putreal.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	put_string (s: STRING)
			-- Write string s to socket.
			-- Was declared in SOCKET as synonym of putstring.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
			non_void: s /= void
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	putbool (b: BOOLEAN)
			-- Write boolean b to socket.
			-- Was declared in SOCKET as synonym of put_boolean.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	putchar (c: CHARACTER)
			-- Write character c to socket.
			-- Was declared in SOCKET as synonym of put_character.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	putdouble (d: DOUBLE)
			-- Write double d to socket.
			-- Was declared in SOCKET as synonym of put_double.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	putint (i: INTEGER)
			-- Write integer i to socket.
			-- Was declared in SOCKET as synonym of put_integer.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	putreal (r: REAL)
			-- Write real r to socket.
			-- Was declared in SOCKET as synonym of put_real.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	putstring (s: STRING)
			-- Write string s to socket.
			-- Was declared in SOCKET as synonym of put_string.
			-- (from SOCKET)
		require -- from IO_MEDIUM
			extendible: extendible
			non_void: s /= void
		require else -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write

	readable: BOOLEAN
			-- Is there currently any data available on socket?
			-- (from SOCKET)
		require -- from IO_MEDIUM
			handle_exists: exists

	send (a_packet: PACKET; flags: INTEGER)
			-- Send a packet a_packet of data to socket.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write
			valid_packet: a_packet /= void

	write (a_packet: PACKET)
			-- Write packet a_packet to socket.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
			opened_for_write: is_open_write
	
feature -- Status Report

	address: UNIX_SOCKET_ADDRESS
			-- Local address of socket

	cleanup
			-- Close socket and unlink it from file system.

	name: STRING
			-- Socket name
		require -- from  IO_MEDIUM
			True
		require else -- from SOCKET
			socket_exists: exists
		require else
			valid_address: address /= void
	
feature -- socket options

	debug_enabled: BOOLEAN
			-- Is socket system debugging enabled?
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists

	disable_debug
			-- Disable socket system debugging.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists

	do_not_route
			-- Set socket to non-routing.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists

	enable_debug
			-- Enable socket system debugging.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists

	group_id: INTEGER
			-- Group id of socket
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
			group_set: is_group_id

	is_blocking: BOOLEAN
			-- Is the socket blocking?
			-- (from SOCKET)

	is_group_id: BOOLEAN
			-- Is the owner id the socket group id?
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists

	is_process_id: BOOLEAN
			-- Is the owner id the socket process id?
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists

	is_socket_stream: BOOLEAN
			-- Is the socket a stream?
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists

	process_id: INTEGER
			-- Process id of socket
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
			process_set: is_process_id

	receive_buf_size: INTEGER
			-- Size of receive buffer.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists

	route
			-- Set socket to routing.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists

	route_enabled: BOOLEAN
			-- Is routing enabled?
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists

	send_buf_size: INTEGER
			-- Size of send buffer.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists

	set_blocking
			-- Set socket to blocking mode.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
		ensure -- from SOCKET
			is_blocking

	set_non_blocking
			-- Set socket to non-blocking mode.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
		ensure -- from SOCKET
			not is_blocking

	set_owner (own: INTEGER)
			-- Negative value sets group process id.
			-- positive value sets process id.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
			valid_owner: own /= 0 and own /= - 1
		ensure -- from SOCKET
			set_id: own < - 1 implies own = group_id or else own > 0 implies own = process_id

	set_receive_buf_size (s: INTEGER)
			-- Set receive buffer size.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
		ensure -- from SOCKET
			size_set: s = receive_buf_size

	set_send_buf_size (s: INTEGER)
			-- Set the send buffer to size s.
			-- (from SOCKET)
		require -- from SOCKET
			socket_exists: exists
		ensure -- from SOCKET
			size_set: s = send_buf_size
	
invariant

		-- from ANY
	reflexive_equality: standard_is_equal (Current)
	reflexive_conformance: conforms_to (Current)

end -- class UNIX_SOCKET