add getprotobyname and associated functions from netdb.h. Add test_getprotobyname.c test suite and update test_sockets.py to include test_getprotobyname. ./runner.py sockets.test_getprotobyname completes successfully
This commit is contained in:
Родитель
b988457c13
Коммит
3e4a22b4a9
|
@ -7682,6 +7682,89 @@ LibraryManager.library = {
|
||||||
return _gai_strerror.buffer;
|
return _gai_strerror.buffer;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Implement netdb.h protocol entry (getprotoent, getprotobyname, getprotobynumber, setprotoent, endprotoent)
|
||||||
|
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/getprotobyname.html
|
||||||
|
$PROTOCOL_LIST: [],
|
||||||
|
$PROTOCOL_MAP: {},
|
||||||
|
setprotoent__deps: ['$PROTOCOL_LIST', '$PROTOCOL_MAP'],
|
||||||
|
setprotoent: function(stayopen) {
|
||||||
|
// void setprotoent(int stayopen);
|
||||||
|
|
||||||
|
// Allocate and populate a protoent structure given a name, protocol number and array of aliases
|
||||||
|
function allocprotoent(name, proto, aliases) {
|
||||||
|
// write name into buffer
|
||||||
|
var nameBuf = _malloc(name.length + 1);
|
||||||
|
writeAsciiToMemory(name, nameBuf);
|
||||||
|
|
||||||
|
// write aliases into buffer
|
||||||
|
var j = 0;
|
||||||
|
var length = aliases.length;
|
||||||
|
var aliasListBuf = _malloc((length + 1) * 4); // Use length + 1 so we have space for the terminating NULL ptr.
|
||||||
|
|
||||||
|
for (var i = 0; i < length; i++, j += 4) {
|
||||||
|
var alias = aliases[i];
|
||||||
|
var aliasBuf = _malloc(alias.length + 1);
|
||||||
|
writeAsciiToMemory(alias, aliasBuf);
|
||||||
|
{{{ makeSetValue('aliasListBuf', 'j', 'aliasBuf', 'i8*') }}};
|
||||||
|
}
|
||||||
|
{{{ makeSetValue('aliasListBuf', 'j', '0', 'i8*') }}}; // Terminating NULL pointer.
|
||||||
|
|
||||||
|
// generate protoent
|
||||||
|
var pe = _malloc({{{ C_STRUCTS.protoent.__size__ }}});
|
||||||
|
{{{ makeSetValue('pe', C_STRUCTS.protoent.p_name, 'nameBuf', 'i8*') }}};
|
||||||
|
{{{ makeSetValue('pe', C_STRUCTS.protoent.p_aliases, 'aliasListBuf', 'i8**') }}};
|
||||||
|
{{{ makeSetValue('pe', C_STRUCTS.protoent.p_proto, 'proto', 'i32') }}};
|
||||||
|
return pe;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Populate the protocol 'database'. The entries are limited to tcp and udp, though it is fairly trivial
|
||||||
|
// to add extra entries from /etc/protocols if desired - though not sure if that'd actually be useful.
|
||||||
|
if (PROTOCOL_LIST.length === 0) {
|
||||||
|
var entry = allocprotoent('tcp', 6, ['TCP']);
|
||||||
|
PROTOCOL_LIST.push(entry);
|
||||||
|
PROTOCOL_MAP['tcp'] = PROTOCOL_MAP['6'] = entry;
|
||||||
|
entry = allocprotoent('udp', 17, ['UDP']);
|
||||||
|
PROTOCOL_LIST.push(entry);
|
||||||
|
PROTOCOL_MAP['udp'] = PROTOCOL_MAP['17'] = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
_setprotoent.index = 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
endprotoent: function() {
|
||||||
|
// void endprotoent(void);
|
||||||
|
// We're not using a real protocol database so we don't do a real close.
|
||||||
|
},
|
||||||
|
|
||||||
|
getprotoent__deps: ['setprotoent', '$PROTOCOL_LIST'],
|
||||||
|
getprotoent: function(number) {
|
||||||
|
// struct protoent *getprotoent(void);
|
||||||
|
// reads the next entry from the protocols 'database' or return NULL if 'eof'
|
||||||
|
if (_setprotoent.index === PROTOCOL_LIST.length) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
var result = PROTOCOL_LIST[_setprotoent.index++];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getprotobyname__deps: ['setprotoent', '$PROTOCOL_MAP'],
|
||||||
|
getprotobyname: function(name) {
|
||||||
|
// struct protoent *getprotobyname(const char *);
|
||||||
|
name = Pointer_stringify(name);
|
||||||
|
_setprotoent(true);
|
||||||
|
var result = PROTOCOL_MAP[name];
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
getprotobynumber__deps: ['setprotoent', '$PROTOCOL_MAP'],
|
||||||
|
getprotobynumber: function(number) {
|
||||||
|
// struct protoent *getprotobynumber(int proto);
|
||||||
|
_setprotoent(true);
|
||||||
|
var result = PROTOCOL_MAP[number];
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// sockets. Note that the implementation assumes all sockets are always
|
// sockets. Note that the implementation assumes all sockets are always
|
||||||
// nonblocking
|
// nonblocking
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void checkEntryByValue(char* name, int port, char** aliasArray) {
|
||||||
|
struct protoent* entry;
|
||||||
|
char** aliases;
|
||||||
|
|
||||||
|
// Perform a protocol look up by name
|
||||||
|
entry = getprotobyname(name);
|
||||||
|
assert(entry != NULL);
|
||||||
|
|
||||||
|
// Check results
|
||||||
|
assert(strcmp(name, entry->p_name) == 0);
|
||||||
|
assert(port == entry->p_proto);
|
||||||
|
|
||||||
|
aliases = entry->p_aliases;
|
||||||
|
for (int i = 0; aliases[i] != NULL; i++) {
|
||||||
|
assert(strcmp(aliases[i], aliasArray[i]) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform a protocol look up by number
|
||||||
|
entry = getprotobynumber(port);
|
||||||
|
assert(entry != NULL);
|
||||||
|
|
||||||
|
// Check results
|
||||||
|
assert(strcmp(name, entry->p_name) == 0);
|
||||||
|
assert(port == entry->p_proto);
|
||||||
|
|
||||||
|
aliases = entry->p_aliases;
|
||||||
|
for (int i = 0; aliases[i] != NULL; i++) {
|
||||||
|
assert(strcmp(aliases[i], aliasArray[i]) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkEntryDatabase() {
|
||||||
|
struct protoent* entry;
|
||||||
|
|
||||||
|
// Don't call setprotoent() initially as getprotoent() should open the "database" if necessary.
|
||||||
|
entry = getprotoent();
|
||||||
|
assert(entry != NULL);
|
||||||
|
assert(strcmp("tcp", entry->p_name) == 0);
|
||||||
|
|
||||||
|
entry = getprotoent();
|
||||||
|
assert(entry != NULL);
|
||||||
|
assert(strcmp("udp", entry->p_name) == 0);
|
||||||
|
|
||||||
|
// Check that setprotoent() correctly sets the next entry to the first entry
|
||||||
|
setprotoent(1);
|
||||||
|
|
||||||
|
entry = getprotoent();
|
||||||
|
assert(entry != NULL);
|
||||||
|
assert(strcmp("tcp", entry->p_name) == 0);
|
||||||
|
|
||||||
|
entry = getprotoent();
|
||||||
|
assert(entry != NULL);
|
||||||
|
assert(strcmp("udp", entry->p_name) == 0);
|
||||||
|
|
||||||
|
// If we do a getprotoent() that goes past the end of the 'database' check that it returns NULL.
|
||||||
|
entry = getprotoent();
|
||||||
|
assert(entry == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// First check getprotobyname() and getprotobynumber()
|
||||||
|
char* aliases[] = {"TCP"};
|
||||||
|
checkEntryByValue("tcp", 6, aliases);
|
||||||
|
|
||||||
|
aliases[0] = "UDP";
|
||||||
|
checkEntryByValue("udp", 17, aliases);
|
||||||
|
|
||||||
|
// Check that the doomsday protocol hasn't been implemented :-) ......
|
||||||
|
assert(getprotobyname("doomsday") == NULL);
|
||||||
|
|
||||||
|
// Now check setprotoent() and getprotoent()
|
||||||
|
checkEntryDatabase();
|
||||||
|
|
||||||
|
endprotoent();
|
||||||
|
|
||||||
|
puts("success");
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
|
@ -228,6 +228,9 @@ class sockets(BrowserCore):
|
||||||
def test_gethostbyname(self):
|
def test_gethostbyname(self):
|
||||||
self.do_run(open(path_from_root('tests', 'sockets', 'test_gethostbyname.c')).read(), 'success')
|
self.do_run(open(path_from_root('tests', 'sockets', 'test_gethostbyname.c')).read(), 'success')
|
||||||
|
|
||||||
|
def test_getprotobyname(self):
|
||||||
|
self.do_run(open(path_from_root('tests', 'sockets', 'test_getprotobyname.c')).read(), 'success')
|
||||||
|
|
||||||
def test_sockets_echo(self):
|
def test_sockets_echo(self):
|
||||||
sockets_include = '-I'+path_from_root('tests', 'sockets')
|
sockets_include = '-I'+path_from_root('tests', 'sockets')
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче