「フリトスのようなコードモンキー
タブとマウンテンデューのようなコードモンキー
コードモンキー非常に単純な男
大きな暖かいファジーな秘密の心で:
あなたのようなコードモンキー
あなたのようなコードモンキー»
-ジョナサンコールトン-コードモンキー
多くの人がジョナサンコールトンのこのシックな歌に精通しており、「ロブはコードモンキーは非常に勤勉だ」と言うが、「彼の出力は悪臭を放ち」、「彼のコードは「機能的」でも「エレガント」でもない」という状況を知っています。
非常に便利なソフトウェアを提供してくれたC言語は、JavaやC#などの高レベルの巨人によってデスクトップとエンタープライズから徐々に絞り出され、システムプログラミングのニッチを占めました。 そして、すべてがうまくいくだろうが、システムエンジニアは非常に
退屈な種類の男です。 言葉遣いがあっても彼らの前で時々起こるタスクは、普通の人間を恐怖に追い込むことができます。 実際、いくつかのソリューションと同じです。
今日は、Cシステムプログラミングの奥深さから学んだいくつかの優れた実践についてお話します。 行こう
項目は、最も基本的で明白な(C言語の初心者向け)から、最も具体的で有用なものまであります。 あなたがそれを知っていると感じたら-スクロールしてください。
実践I:統一されたコードスタイルと「良いトーン」の基本原則を順守する
関数は引数としてINPUT変数を受け取り、それをIncomingValues配列に解析し、result_to_return?を返しますか? バイコードは取っておきましょう!
初心者が最初に与えることは、特定のアプリケーション内でコードを記述する単一のスタイルを守らないことです。 次は「マナー」のルールを無視します。
Cコードを記述するための最も一般的なガイドラインの一部を次に示します。
- マクロとマクロ関数の名前は大文字で表記され、名前の単語は下線で互いに区切られています。
#define MAX_ARRAY_SIZE 32
#define INCORRECT_VALUE -1
#define IPC_FIND_NODE(x) ipc_find_node(config.x)
- ,
int my_int_variable = 0;
char *hello_str = "hello_habrahabr";
pid_t current_pid = fork();
, . , camelCase PascalCase .
UPD: fogree , PascalCase camelCase.
- , , — .
, , . .
— a, b, c — ( ). — .
- ( - ) , , .
, : PascalCase under_score, .
static void dgtprint(char *str) {
int i;
for (i = 0; i < strlen(str); i++) {
if (isdigit(str[i]))
printf("%c", str[i]);
else
print("_");
}
}
void EnableAllVlans(struct vlan_cfg *vp) {
int i;
for (i = 0; i < VLAN_COUNT; i++) {
EnableVlanByProto(vp.vlan[i]);
}
}
void enable_all_vlans(struct vlan_cfg *vp) {
int i;
for (i = 0; i < VLAN_COUNT; i++) {
enable_vlan_by_proto(vp.vlan[i]);
}
}
- i, j, k —
int array[MAX_ARRAY_SIZE] = arrinit();
register int i, j, k;
for (i = 0; i < MAX_ARRAY_SIZE; i++)
for (j = 0; j < MAX_ARRAY_SIZE; j++)
for (k = MAX_ARRAY_SIZE; k >= 0; k--)
dosmthng(i, j, k, array[i]);
if (condition) { dosmthng(); } else
{
dont_do_something();
}
if (condition) {
dosmthng();
} else {
dont_do_something();
}
if (condition)
{
dosmthng();
}
else
{
dont_do_something();
}
if (condition) { dosmthng(); } else { dont_do_something(); }
- . , .
. , — NULL:
int counter = 0, start_position = 0, unknown_position = 0;
struct dhcp_header * dhcp = NULL, * dhcp_temp = NULL;
char input_string[32] = { 0 };
, ?
. ( ) ( gdb), . (, « »). .
- .
— , .
— , . — , - , .
, — , , , , , .
static int CheckModemConnection()
{
int i = 0;
if (CHECK_CFG_STR(Network.LanIpAddress) || CHECK_CFG_STR(Network.LanNetmask))
return 1;
for(i = 0; i < MAX_MODEM_IDX; i++)
{
if (CHECK_CFG_INT(Modems.Modem[i].Proto) || CHECK_CFG_INT(Modems.Modem[i].MTU) ||
CHECK_CFG_STR(Modems.Modem[i].Username) || CHECK_CFG_STR(Modems.Modem[i].Password) ||
CHECK_CFG_STR(Modems.Modem[i].Number) || CHECK_CFG_STR(Modems.Modem[i].AdditionalParams) ||
CHECK_CFG_STR(Modems.Modem[i].PIN) || CHECK_CFG_STR(Modems.Modem[i].MRU) ||
CHECK_CFG_STR(Modems.Modem[i].PppoeIdle) || CHECK_CFG_STR(Modems.Modem[i].USBPort) ||
CHECK_CFG_STR(Reservation.Prefer) || CHECK_CFG_STR(Modems.Modem[i].PppoeConnectType) ||
CHECK_CFG_INT(Modems.Mode) || CHECK_CFG_INT(Aggregation.usb1) || CHECK_CFG_INT(Aggregation.usb2))
return 1;
}
return 0;
}
( RedMine), , . - - « ?», . , , .
/* Muraviyov: #66770 */
P.S. : , , , Code Style, . - .II:
— .
, , , , :
- , , .
file1.c, mySUPER_COOL_header.h ..
main.c — , graph_const.h — .
- include.
:
- project/
- common.c
- common.h
- main.c
- network.h
- networking.c
- networking_v6.c
- packet.c
- packet.h
- Makefile
, . , 9 , , , 39. - . , — , GUI, , , Github/Gitlab/Bitbucket?
, ? , :
- project/
- include/
- common.h
- network.h
- packet.h
- common.c
- main.c
- networking.c
- networking_v6.c
- packet.c
- Makefile
, include . Makefile (include , Makefile):
@$(CC) $(OBJS) -o networkd -L$(ROMFS)/lib -linteraction -Wall -lpthread -I ./include
- .c .
, , // — . , — .
- — , . Makefile :
.PHONY clean build
build:
cd sound/ && make clean && make
cd graphics/ && make clean && make
cd engine/ && make clean && make
sound:
cd sound/ && make clean && make
graphics:
cd graphics/ && make clean && make
engine:
cd engine/ && make clean && make
clean:
cd sound/ && make clean
cd engine/ && make clean
cd greaphics/ && make clean
III: -
- (-) . , , , errno .
( — ), , «» . -, , , .
— . , (+ ) .
. — :
int sock_one = 0, sock_two = 0, sock_three = 0;
if ((socket_one = socket(AF_INET , SOCK_STREAM , 0)) <= 0) {
perror("socket one");
exit(EXIT_ERROR_CODE);
}
if ((socket_two = socket(AF_INET , SOCK_DGRAM , 0)) <= 0) {
perror("socket two");
exit(EXIT_ERROR_CODE);
}
if ((socket_three = socket(PF_INET , SOCK_RAW , 0)) <= 0) {
perror("socket three");
exit(EXIT_ERROR_CODE);
}
, , ? .
int Socket(int domain, int type, int proto) {
int desk = socket(domain, type, proto);
if (desk <= 0) {
perror("socket");
exit(EXIT_ERROR_CODE);
}
return desk;
}
int socket_one = 0, socket_two = 0, soket_three = 0;
socket_one = Socket(AF_INET , SOCK_STREAM , 0);
socket_two = Socket(AF_INET , SOCK_DGRAM , 0);
socket_three = Socket(PF_INET , SOCK_RAW , 0);
, - ( «» ), .
, . , .
, , , . — :)
IV: keywords
keywords . , , . , — , .
, , . , , . :
- register — , . register - .
register byte i = 0;
for (i; i < 256; i++)
check_value(i);
- restrict — (, , ), , . , , - . — , .
void updatePtrs(size_t *restrict ptrA, size_t *restrict ptrB, size_t *restrict val);
- volatile — , . , , dead code (, ), , .
int var = 1;
if (!var)
dosmthng();
volatile int var = 1;
if (!var)
dosmthng();
. —
.
V: . valgrind.
, , , .
Valgrind — , , . , , , , , , . .
+ .
.
VI: ,
busybox 1.21. , busybox,
-.
UPD: «» busybox.
themiron , , — , . «» busybox, .
, busybox.
busybox , . , —
.
busybox. udhcpc —
DHCP :
- , .
DHCP RFC, dhcp-. , , . — , , (DHCP- <-> DHCP-).
( networking/udhcp/common.h)
struct dhcp_packet {
uint8_t op;
uint8_t htype;
uint8_t hlen;
uint8_t hops;
uint32_t xid;
uint16_t secs;
uint16_t flags;
#define BROADCAST_FLAG 0x8000
uint32_t ciaddr;
uint32_t yiaddr;
uint32_t siaddr_nip;
uint32_t gateway_nip;
uint8_t chaddr[16];
uint8_t sname[64];
uint8_t file[128];
uint32_t cookie;
uint8_t options[DHCP_OPTIONS_BUFSIZE + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS];
} PACKED;
- .
, .. .
: , .
( networking/udhcp/common.h)
struct dhcp_packet {
uint8_t op;
uint8_t htype;
uint8_t hlen;
uint8_t hops;
uint32_t xid;
uint16_t secs;
uint16_t flags;
#define BROADCAST_FLAG 0x8000
uint32_t ciaddr;
uint32_t yiaddr;
uint32_t siaddr_nip;
uint32_t gateway_nip;
uint8_t chaddr[16];
uint8_t sname[64];
uint8_t file[128];
uint32_t cookie;
uint8_t options[DHCP_OPTIONS_BUFSIZE + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS];
} PACKED;
#define DHCP_PKT_SNAME_LEN 64
#define DHCP_PKT_FILE_LEN 128
#define DHCP_PKT_SNAME_LEN_STR "64"
#define DHCP_PKT_FILE_LEN_STR "128"
struct ip_udp_dhcp_packet {
struct iphdr ip;
struct udphdr udp;
struct dhcp_packet data;
} PACKED;
struct udp_dhcp_packet {
struct udphdr udp;
struct dhcp_packet data;
} PACKED;
enum {
IP_UDP_DHCP_SIZE = sizeof(struct ip_udp_dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS,
UDP_DHCP_SIZE = sizeof(struct udp_dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS,
DHCP_SIZE = sizeof(struct dhcp_packet) - CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS,
};
, , :
( networking/udhcp/common.h)
unsigned FAST_FUNC udhcp_option_idx(const char *name);
uint8_t *udhcp_get_option(struct dhcp_packet *packet, int code) FAST_FUNC;
int udhcp_end_option(uint8_t *optionptr) FAST_FUNC;
void udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt) FAST_FUNC;
void udhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code, uint32_t data) FAST_FUNC;
#if ENABLE_FEATURE_UDHCP_RFC3397
char *dname_dec(const uint8_t *cstr, int clen, const char *pre) FAST_FUNC;
uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen) FAST_FUNC;
#endif
struct option_set *udhcp_find_option(struct option_set *opt_list, uint8_t code) FAST_FUNC;
udhcpc , . , .
— , . , « ?» . .
— , , .
( networking/udhcp/common.h)
#define DHCP_PADDING 0x00
#define DHCP_SUBNET 0x01
#define DHCP_HOST_NAME 0x0c
#define DHCP_REQUESTED_IP 0x32
#define DHCP_LEASE_TIME 0x33
#define DHCP_OPTION_OVERLOAD 0x34
#define DHCP_MESSAGE_TYPE 0x35
#define DHCP_SERVER_ID 0x36
#define DHCP_PARAM_REQ 0x37
#define DHCP_MAX_SIZE 0x39
#define DHCP_VENDOR 0x3c
#define DHCP_CLIENT_ID 0x3d
#define DHCP_FQDN 0x51
#define DHCP_VLAN_ID 0x84
#define DHCP_VLAN_PRIORITY 0x85
#define DHCP_END 0xff
- .
, . : , n ( n — ), , , , . . , :
( networking/udhcp/packet.c)
int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
uint32_t source_nip, int source_port,
uint32_t dest_nip, int dest_port, const uint8_t *dest_arp,
int ifindex)
{
struct sockaddr_ll dest_sll;
struct ip_udp_dhcp_packet packet;
unsigned padding;
int fd;
int result = -1;
const char *msg;
fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
if (fd < 0) {
msg = "socket(%s)";
goto ret_msg;
}
memset(&dest_sll, 0, sizeof(dest_sll));
memset(&packet, 0, offsetof(struct ip_udp_dhcp_packet, data));
packet.data = *dhcp_pkt;
dest_sll.sll_family = AF_PACKET;
dest_sll.sll_protocol = htons(ETH_P_IP);
dest_sll.sll_ifindex = ifindex;
dest_sll.sll_halen = 6;
memcpy(dest_sll.sll_addr, dest_arp, 6);
if (bind(fd, (struct sockaddr *)&dest_sll, sizeof(dest_sll)) < 0) {
msg = "bind(%s)";
goto ret_close;
}
padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(packet.data.options);
packet.ip.protocol = IPPROTO_UDP;
packet.ip.saddr = source_nip;
packet.ip.daddr = dest_nip;
packet.udp.source = htons(source_port);
packet.udp.dest = htons(dest_port);
packet.udp.len = htons(UDP_DHCP_SIZE - padding);
packet.ip.tot_len = packet.udp.len;
packet.udp.check = inet_cksum((uint16_t *)&packet,
IP_UDP_DHCP_SIZE - padding);
packet.ip.tot_len = htons(IP_UDP_DHCP_SIZE - padding);
packet.ip.ihl = sizeof(packet.ip) >> 2;
packet.ip.version = IPVERSION;
packet.ip.ttl = IPDEFTTL;
packet.ip.check = inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip));
udhcp_dump_packet(dhcp_pkt);
result = sendto(fd, &packet, IP_UDP_DHCP_SIZE - padding, 0,
(struct sockaddr *) &dest_sll, sizeof(dest_sll));
msg = "sendto";
ret_close:
close(fd);
if (result < 0) {
ret_msg:
bb_perror_msg(msg, "PACKET");
}
return result;
}
dhcp IP . (BROADCAST) .
— , broadcast. , , , , , . :
( networking/udhcp/dhcpc.c)
static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet)
{
return udhcp_send_raw_packet(packet,
INADDR_ANY, CLIENT_PORT,
INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR,
client_config.ifindex);
}
, , , , . udhcp_send_raw_packet, .
, , , . .
, . , . . .
., !