Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Systems Programming - SoCoded 2013
Search
Andy Delcambre
September 20, 2013
Programming
200
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Systems Programming - SoCoded 2013
Andy Delcambre
September 20, 2013
More Decks by Andy Delcambre
See All by Andy Delcambre
Git and GitHub at YAPC:Asia
adelcambre
1
3.4k
Git, GitHub, Etc
adelcambre
3
260
Ruby Systems Programming
adelcambre
4
1.2k
Debugging Production Service Oriented Systems
adelcambre
3
450
Ruby, Rails and Engine Yard - Úll
adelcambre
1
340
SFRuby Nov 2011 - Release Early and Release Often
adelcambre
2
97
Release early and Release often
adelcambre
2
560
Other Decks in Programming
See All in Programming
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
5
1.9k
170k Jobs a Day on GKE: Scaling Mercari's CI Platform - and What's Next for AI-Native Development
junyaokabe
0
110
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
640
複数の Claude Code が"放置"されてしまう問題をCLI ダッシュボードを自作して解決した話
sumihiro3
1
700
変わらないものが、変わるものを決める — 意図駆動開発 × イベントソーシング × イミュータブル | What Doesn't Change Decides What Can — IDD × Event Sourcing × Immutability
tomohisa
0
1.8k
FDEが実現するAI駆動経営の現在地
gonta
2
290
20260722_microCMSで考える、AI時代のコンテンツ運用設計
yosh1
0
430
GDG Korea Android: 2026 I/O Extended ~ What's new in Android development tools
pluu
0
230
ソフトウェア設計に溶けるインフラ ― AWS CDK のインフラ認識論
konokenj
3
810
How I Won Prize Money at a Hackathon Using Codex and Symphony Alpha
yasei_no_otoko
0
110
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
790
yield再入門 #phpcon
o0h
PRO
0
1.2k
Featured
See All Featured
Writing Fast Ruby
sferik
630
63k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
390
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.8k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.5k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
490
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
250
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
500
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
VelocityConf: Rendering Performance Case Studies
addyosmani
332
25k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.2k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
73
41k
Un-Boring Meetings
codingconduct
0
390
Transcript
Systems Programming
operate and control the computer hardware and to provide a
platform for running application software http://en.wikipedia.org/wiki/System_software “
application software “
web software “
Building Blocks The Kernel System Calls Sockets File Descriptors HTTP
None
The Kernel
Your Code The Kernel Hardware
Your Code
Your Code User Mode
Your Code Math User Mode
Your Code Math Access Memory User Mode
The Kernel
The Kernel Anything
The Kernel Anything Everything
System Calls
User Mode Kernel Mode
User Mode Kernel Mode Your Program System Calls
$ strace -p <server pid>
None
120,602 Calls One Request
linux$ wc -l syscall_table.S 326
mov! eax, 5 mov! ebx, path mov! ecx, flags int!
80h open(path, flags)
linux$ cat syscall_table.S | grep -c sys_ni_syscal 65 Not Implemented
File Descriptors
Everything is a File
Things that are Files (Non Exhaustive)
Things that are Files (Non Exhaustive) Files
Things that are Files (Non Exhaustive) Links DVDs Hard Drives
USB Keys Sockets* Files Directories Sound Cards Graphics Cards Printers Pipes Terminals UNIX Sockets Shared Memory
read() write() close() lseek()* File API
0 -> /dev/null 1 -> unicorn.log 2 -> unicorn.log 3
-> pipe:[3753224456] 4 -> pipe:[3753224456] 5 -> socket:[19730] 6 -> pipe:[3753224457] 7 -> socket:[19731] 8 -> socket:[19732] 9 -> pipe:[3753224457] 10 -> production.log 11 -> socket:[3766066290] 12 -> socket:[3753228795] 13 -> socket:[3753229266] 14 -> socket:[3753229276] 15 -> socket:[3753229285] 16 -> socket:[3753229307] 17 -> socket:[3753235718] 18 -> socket:[3753235910] 19 -> socket:[3753242775] 20 -> socket:[3753242776] 21 -> socket:[3753242778] 22 -> socket:[3753239097] 23 -> socket:[3753242942] 24 -> socket:[3753242944] 25 -> socket:[3753239202] 26 -> socket:[3753239203] 27 -> socket:[3753239204] 28 -> socket:[3753242981] 29 -> socket:[3753242982] 30 -> socket:[3753243929] 31 -> socket:[3753240046] 32 -> socket:[3753245881] 33 -> socket:[3753248970] 34 -> socket:[3753253476] 35 -> pygments-ruby.log 36 -> /dev/null 37 -> pipe:[3753260503] 38 -> pipe:[3753260504] 39 -> socket:[3753344667] 40 -> pipe:[3753260505] 41 -> socket:[3765810413] 42 -> socket:[3765810440] 43 -> socket:[3765848228] $ ls -l /proc/32660/fd
BSD Sockets
1980 1970 1960 1990 Multics Unix (Unics) BSD BSD 4.2
TCP/IP
socket() bind() listen() accept() read() and write() close()
HTTP
HTTP Request GET /index.html HTTP/1.1 User-Agent: curl/7.24.0 Host: www.google.com Accept:
*/*
HTTP Response HTTP/1.1 200 OK Date: Tue, 05 Mar 2013
23:03:52 GMT Cache-Control: private, max-age=0 Content-Type: text/html Server: gws Transfer-Encoding: chunked <data>
There Will be Code
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end Require the socket lib
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end Some constants for later
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end socket = Socket.new(:INET, :STREAM)
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr)
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end socket.listen(5)
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end while client_socket = socket.accept[0]
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end path = client_socket.readline.split[1]
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end path = client_socket.readline.split[1] GET /index.html HTTP/1.1
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end filename = File.expand_path("../#{path}", __FILE__)
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end if File.file?(filename)
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}")
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") OK = "HTTP/1.1 200 OK\n"
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end client_socket.write(NOT_FOUND)
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end client_socket.write(NOT_FOUND) NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end client_socket.close
require 'socket' NOT_FOUND = "HTTP/1.1 404 Not Found\nContent-Length: 9\n\nNot Found"
OK = "HTTP/1.1 200 OK\n" socket = Socket.new(:INET, :STREAM) sockaddr = Socket.sockaddr_in(11080, '127.0.0.1') socket.bind(sockaddr) socket.listen(5) while client_socket = socket.accept[0] path = client_socket.readline.split[1] filename = File.expand_path("../#{path}", __FILE__) if File.file?(filename) contents = File.read(filename) client_socket.write(OK) client_socket.write("Content-Length: #{contents.size}\n\n") client_socket.write("#{contents}") else client_socket.write(NOT_FOUND) end client_socket.close end
def new_ipv6_server(addr, port, opt) opt.key?(:ipv6only) or return Kgio::TCPServer.new(addr, port) defined?(IPV6_V6ONLY)
or abort "Socket::IPV6_V6ONLY not defined, upgrade Ruby and/or your OS" sock = Socket.new(AF_INET6, SOCK_STREAM, 0) sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, opt[:ipv6only] ? 1 : 0) sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sock.bind(Socket.pack_sockaddr_in(port, addr)) IO_PURGATORY << sock Kgio::TCPServer.for_fd(sock.fileno) end ret = IO.select(l, nil, SELF_PIPE, @timeout) and ready = ret[0] Unicorn
def new_ipv6_server(addr, port, opt) opt.key?(:ipv6only) or return Kgio::TCPServer.new(addr, port) defined?(IPV6_V6ONLY)
or abort "Socket::IPV6_V6ONLY not defined, upgrade Ruby and/or your OS" sock = Socket.new(AF_INET6, SOCK_STREAM, 0) sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, opt[:ipv6only] ? 1 : 0) sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sock.bind(Socket.pack_sockaddr_in(port, addr)) IO_PURGATORY << sock Kgio::TCPServer.for_fd(sock.fileno) end ret = IO.select(l, nil, SELF_PIPE, @timeout) and ready = ret[0] Unicorn sock = Socket.new(AF_INET6, SOCK_STREAM, 0)
def new_ipv6_server(addr, port, opt) opt.key?(:ipv6only) or return Kgio::TCPServer.new(addr, port) defined?(IPV6_V6ONLY)
or abort "Socket::IPV6_V6ONLY not defined, upgrade Ruby and/or your OS" sock = Socket.new(AF_INET6, SOCK_STREAM, 0) sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, opt[:ipv6only] ? 1 : 0) sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sock.bind(Socket.pack_sockaddr_in(port, addr)) IO_PURGATORY << sock Kgio::TCPServer.for_fd(sock.fileno) end ret = IO.select(l, nil, SELF_PIPE, @timeout) and ready = ret[0] Unicorn sock.bind( Socket.pack_sockaddr_in(port, addr))
def new_ipv6_server(addr, port, opt) opt.key?(:ipv6only) or return Kgio::TCPServer.new(addr, port) defined?(IPV6_V6ONLY)
or abort "Socket::IPV6_V6ONLY not defined, upgrade Ruby and/or your OS" sock = Socket.new(AF_INET6, SOCK_STREAM, 0) sock.setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, opt[:ipv6only] ? 1 : 0) sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) sock.bind(Socket.pack_sockaddr_in(port, addr)) IO_PURGATORY << sock Kgio::TCPServer.for_fd(sock.fileno) end ret = IO.select(l, nil, SELF_PIPE, @timeout) and ready = ret[0] Unicorn IO.select(l, nil, SELF_PIPE, @timeout)
The Kernel System Calls Sockets File Descriptors HTTP
Further Reading Linux System Programming Robert Love
Further Reading Unix Network Programming Richard Stevens
Further Reading Advanced Programming in the UNIX Environment Richard Stevens
Andy Delcambre adelcambre @
None
Thanks! adelcambre @