Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 56ceb16

Browse files
authoredSep 8, 2018
Rollup merge of #54024 - alexcrichton:compile-to-wasm, r=petrochenkov
Fix compiling some rustc crates to wasm I was dabbling recently seeing what it would take to compile `rustfmt` to the `wasm32-unknown-unknown` target and it turns out not much effort is needed! Currently `rustfmt` depends on a few rustc crates published to crates.io, so this commit touches up those crates to compile for wasm themselves. Notably: * The `rustc_data_structures` crate's `flock` implementation is stubbed out to unconditionally return errors on unsupported platforms. * The `rustc_errors` crate is extended to not do any locking for all non-windows platforms. In both of these cases if we port the compiler to new platforms the functionality isn't critical but will be discovered over time as it comes up, so this hopefully doesn't make it too too hard to compile to new platforms!
2 parents 10418e8 + 0c89243 commit 56ceb16

File tree

2 files changed

+299
-293
lines changed

2 files changed

+299
-293
lines changed
 

‎src/librustc_data_structures/flock.rs

Lines changed: 298 additions & 292 deletions
Original file line numberDiff line numberDiff line change
@@ -15,345 +15,351 @@
1515
//! librustdoc, it is not production quality at all.
1616
1717
#![allow(non_camel_case_types)]
18-
use std::path::Path;
19-
20-
pub use self::imp::Lock;
18+
#![allow(nonstandard_style)]
2119

22-
#[cfg(unix)]
23-
mod imp {
24-
use std::ffi::{CString, OsStr};
25-
use std::os::unix::prelude::*;
26-
use std::path::Path;
27-
use std::io;
28-
use libc;
20+
use std::io;
21+
use std::path::Path;
2922

30-
#[cfg(any(target_os = "linux", target_os = "android"))]
31-
mod os {
23+
cfg_if! {
24+
if #[cfg(unix)] {
25+
use std::ffi::{CString, OsStr};
26+
use std::os::unix::prelude::*;
3227
use libc;
3328

34-
#[repr(C)]
35-
pub struct flock {
36-
pub l_type: libc::c_short,
37-
pub l_whence: libc::c_short,
38-
pub l_start: libc::off_t,
39-
pub l_len: libc::off_t,
40-
pub l_pid: libc::pid_t,
41-
42-
// not actually here, but brings in line with freebsd
43-
pub l_sysid: libc::c_int,
44-
}
29+
#[cfg(any(target_os = "linux", target_os = "android"))]
30+
mod os {
31+
use libc;
4532

46-
pub const F_RDLCK: libc::c_short = 0;
47-
pub const F_WRLCK: libc::c_short = 1;
48-
pub const F_UNLCK: libc::c_short = 2;
49-
pub const F_SETLK: libc::c_int = 6;
50-
pub const F_SETLKW: libc::c_int = 7;
51-
}
33+
#[repr(C)]
34+
pub struct flock {
35+
pub l_type: libc::c_short,
36+
pub l_whence: libc::c_short,
37+
pub l_start: libc::off_t,
38+
pub l_len: libc::off_t,
39+
pub l_pid: libc::pid_t,
5240

53-
#[cfg(target_os = "freebsd")]
54-
mod os {
55-
use libc;
41+
// not actually here, but brings in line with freebsd
42+
pub l_sysid: libc::c_int,
43+
}
5644

57-
#[repr(C)]
58-
pub struct flock {
59-
pub l_start: libc::off_t,
60-
pub l_len: libc::off_t,
61-
pub l_pid: libc::pid_t,
62-
pub l_type: libc::c_short,
63-
pub l_whence: libc::c_short,
64-
pub l_sysid: libc::c_int,
45+
pub const F_RDLCK: libc::c_short = 0;
46+
pub const F_WRLCK: libc::c_short = 1;
47+
pub const F_UNLCK: libc::c_short = 2;
48+
pub const F_SETLK: libc::c_int = 6;
49+
pub const F_SETLKW: libc::c_int = 7;
6550
}
6651

67-
pub const F_RDLCK: libc::c_short = 1;
68-
pub const F_UNLCK: libc::c_short = 2;
69-
pub const F_WRLCK: libc::c_short = 3;
70-
pub const F_SETLK: libc::c_int = 12;
71-
pub const F_SETLKW: libc::c_int = 13;
72-
}
73-
74-
#[cfg(any(target_os = "dragonfly",
75-
target_os = "bitrig",
76-
target_os = "netbsd",
77-
target_os = "openbsd"))]
78-
mod os {
79-
use libc;
52+
#[cfg(target_os = "freebsd")]
53+
mod os {
54+
use libc;
55+
56+
#[repr(C)]
57+
pub struct flock {
58+
pub l_start: libc::off_t,
59+
pub l_len: libc::off_t,
60+
pub l_pid: libc::pid_t,
61+
pub l_type: libc::c_short,
62+
pub l_whence: libc::c_short,
63+
pub l_sysid: libc::c_int,
64+
}
8065

81-
#[repr(C)]
82-
pub struct flock {
83-
pub l_start: libc::off_t,
84-
pub l_len: libc::off_t,
85-
pub l_pid: libc::pid_t,
86-
pub l_type: libc::c_short,
87-
pub l_whence: libc::c_short,
88-
89-
// not actually here, but brings in line with freebsd
90-
pub l_sysid: libc::c_int,
66+
pub const F_RDLCK: libc::c_short = 1;
67+
pub const F_UNLCK: libc::c_short = 2;
68+
pub const F_WRLCK: libc::c_short = 3;
69+
pub const F_SETLK: libc::c_int = 12;
70+
pub const F_SETLKW: libc::c_int = 13;
9171
}
9272

93-
pub const F_RDLCK: libc::c_short = 1;
94-
pub const F_UNLCK: libc::c_short = 2;
95-
pub const F_WRLCK: libc::c_short = 3;
96-
pub const F_SETLK: libc::c_int = 8;
97-
pub const F_SETLKW: libc::c_int = 9;
98-
}
99-
100-
#[cfg(target_os = "haiku")]
101-
mod os {
102-
use libc;
73+
#[cfg(any(target_os = "dragonfly",
74+
target_os = "bitrig",
75+
target_os = "netbsd",
76+
target_os = "openbsd"))]
77+
mod os {
78+
use libc;
79+
80+
#[repr(C)]
81+
pub struct flock {
82+
pub l_start: libc::off_t,
83+
pub l_len: libc::off_t,
84+
pub l_pid: libc::pid_t,
85+
pub l_type: libc::c_short,
86+
pub l_whence: libc::c_short,
87+
88+
// not actually here, but brings in line with freebsd
89+
pub l_sysid: libc::c_int,
90+
}
10391

104-
#[repr(C)]
105-
pub struct flock {
106-
pub l_type: libc::c_short,
107-
pub l_whence: libc::c_short,
108-
pub l_start: libc::off_t,
109-
pub l_len: libc::off_t,
110-
pub l_pid: libc::pid_t,
111-
112-
// not actually here, but brings in line with freebsd
113-
pub l_sysid: libc::c_int,
92+
pub const F_RDLCK: libc::c_short = 1;
93+
pub const F_UNLCK: libc::c_short = 2;
94+
pub const F_WRLCK: libc::c_short = 3;
95+
pub const F_SETLK: libc::c_int = 8;
96+
pub const F_SETLKW: libc::c_int = 9;
11497
}
11598

116-
pub const F_RDLCK: libc::c_short = 0x0040;
117-
pub const F_UNLCK: libc::c_short = 0x0200;
118-
pub const F_WRLCK: libc::c_short = 0x0400;
119-
pub const F_SETLK: libc::c_int = 0x0080;
120-
pub const F_SETLKW: libc::c_int = 0x0100;
121-
}
99+
#[cfg(target_os = "haiku")]
100+
mod os {
101+
use libc;
122102

123-
#[cfg(any(target_os = "macos", target_os = "ios"))]
124-
mod os {
125-
use libc;
103+
#[repr(C)]
104+
pub struct flock {
105+
pub l_type: libc::c_short,
106+
pub l_whence: libc::c_short,
107+
pub l_start: libc::off_t,
108+
pub l_len: libc::off_t,
109+
pub l_pid: libc::pid_t,
126110

127-
#[repr(C)]
128-
pub struct flock {
129-
pub l_start: libc::off_t,
130-
pub l_len: libc::off_t,
131-
pub l_pid: libc::pid_t,
132-
pub l_type: libc::c_short,
133-
pub l_whence: libc::c_short,
134-
135-
// not actually here, but brings in line with freebsd
136-
pub l_sysid: libc::c_int,
111+
// not actually here, but brings in line with freebsd
112+
pub l_sysid: libc::c_int,
113+
}
114+
115+
pub const F_RDLCK: libc::c_short = 0x0040;
116+
pub const F_UNLCK: libc::c_short = 0x0200;
117+
pub const F_WRLCK: libc::c_short = 0x0400;
118+
pub const F_SETLK: libc::c_int = 0x0080;
119+
pub const F_SETLKW: libc::c_int = 0x0100;
137120
}
138121

139-
pub const F_RDLCK: libc::c_short = 1;
140-
pub const F_UNLCK: libc::c_short = 2;
141-
pub const F_WRLCK: libc::c_short = 3;
142-
pub const F_SETLK: libc::c_int = 8;
143-
pub const F_SETLKW: libc::c_int = 9;
144-
}
122+
#[cfg(any(target_os = "macos", target_os = "ios"))]
123+
mod os {
124+
use libc;
145125

146-
#[cfg(target_os = "solaris")]
147-
mod os {
148-
use libc;
126+
#[repr(C)]
127+
pub struct flock {
128+
pub l_start: libc::off_t,
129+
pub l_len: libc::off_t,
130+
pub l_pid: libc::pid_t,
131+
pub l_type: libc::c_short,
132+
pub l_whence: libc::c_short,
149133

150-
#[repr(C)]
151-
pub struct flock {
152-
pub l_type: libc::c_short,
153-
pub l_whence: libc::c_short,
154-
pub l_start: libc::off_t,
155-
pub l_len: libc::off_t,
156-
pub l_sysid: libc::c_int,
157-
pub l_pid: libc::pid_t,
134+
// not actually here, but brings in line with freebsd
135+
pub l_sysid: libc::c_int,
136+
}
137+
138+
pub const F_RDLCK: libc::c_short = 1;
139+
pub const F_UNLCK: libc::c_short = 2;
140+
pub const F_WRLCK: libc::c_short = 3;
141+
pub const F_SETLK: libc::c_int = 8;
142+
pub const F_SETLKW: libc::c_int = 9;
158143
}
159144

160-
pub const F_RDLCK: libc::c_short = 1;
161-
pub const F_WRLCK: libc::c_short = 2;
162-
pub const F_UNLCK: libc::c_short = 3;
163-
pub const F_SETLK: libc::c_int = 6;
164-
pub const F_SETLKW: libc::c_int = 7;
165-
}
145+
#[cfg(target_os = "solaris")]
146+
mod os {
147+
use libc;
148+
149+
#[repr(C)]
150+
pub struct flock {
151+
pub l_type: libc::c_short,
152+
pub l_whence: libc::c_short,
153+
pub l_start: libc::off_t,
154+
pub l_len: libc::off_t,
155+
pub l_sysid: libc::c_int,
156+
pub l_pid: libc::pid_t,
157+
}
166158

167-
#[derive(Debug)]
168-
pub struct Lock {
169-
fd: libc::c_int,
170-
}
159+
pub const F_RDLCK: libc::c_short = 1;
160+
pub const F_WRLCK: libc::c_short = 2;
161+
pub const F_UNLCK: libc::c_short = 3;
162+
pub const F_SETLK: libc::c_int = 6;
163+
pub const F_SETLKW: libc::c_int = 7;
164+
}
171165

172-
impl Lock {
173-
pub fn new(p: &Path,
174-
wait: bool,
175-
create: bool,
176-
exclusive: bool)
177-
-> io::Result<Lock> {
178-
let os: &OsStr = p.as_ref();
179-
let buf = CString::new(os.as_bytes()).unwrap();
180-
let open_flags = if create {
181-
libc::O_RDWR | libc::O_CREAT
182-
} else {
183-
libc::O_RDWR
184-
};
185-
186-
let fd = unsafe {
187-
libc::open(buf.as_ptr(), open_flags,
188-
libc::S_IRWXU as libc::c_int)
189-
};
190-
191-
if fd < 0 {
192-
return Err(io::Error::last_os_error());
193-
}
166+
#[derive(Debug)]
167+
pub struct Lock {
168+
fd: libc::c_int,
169+
}
194170

195-
let lock_type = if exclusive {
196-
os::F_WRLCK
197-
} else {
198-
os::F_RDLCK
199-
};
200-
201-
let flock = os::flock {
202-
l_start: 0,
203-
l_len: 0,
204-
l_pid: 0,
205-
l_whence: libc::SEEK_SET as libc::c_short,
206-
l_type: lock_type,
207-
l_sysid: 0,
208-
};
209-
let cmd = if wait { os::F_SETLKW } else { os::F_SETLK };
210-
let ret = unsafe {
211-
libc::fcntl(fd, cmd, &flock)
212-
};
213-
if ret == -1 {
214-
let err = io::Error::last_os_error();
215-
unsafe { libc::close(fd); }
216-
Err(err)
217-
} else {
218-
Ok(Lock { fd: fd })
171+
impl Lock {
172+
pub fn new(p: &Path,
173+
wait: bool,
174+
create: bool,
175+
exclusive: bool)
176+
-> io::Result<Lock> {
177+
let os: &OsStr = p.as_ref();
178+
let buf = CString::new(os.as_bytes()).unwrap();
179+
let open_flags = if create {
180+
libc::O_RDWR | libc::O_CREAT
181+
} else {
182+
libc::O_RDWR
183+
};
184+
185+
let fd = unsafe {
186+
libc::open(buf.as_ptr(), open_flags,
187+
libc::S_IRWXU as libc::c_int)
188+
};
189+
190+
if fd < 0 {
191+
return Err(io::Error::last_os_error());
192+
}
193+
194+
let lock_type = if exclusive {
195+
os::F_WRLCK
196+
} else {
197+
os::F_RDLCK
198+
};
199+
200+
let flock = os::flock {
201+
l_start: 0,
202+
l_len: 0,
203+
l_pid: 0,
204+
l_whence: libc::SEEK_SET as libc::c_short,
205+
l_type: lock_type,
206+
l_sysid: 0,
207+
};
208+
let cmd = if wait { os::F_SETLKW } else { os::F_SETLK };
209+
let ret = unsafe {
210+
libc::fcntl(fd, cmd, &flock)
211+
};
212+
if ret == -1 {
213+
let err = io::Error::last_os_error();
214+
unsafe { libc::close(fd); }
215+
Err(err)
216+
} else {
217+
Ok(Lock { fd: fd })
218+
}
219219
}
220220
}
221-
}
222221

223-
impl Drop for Lock {
224-
fn drop(&mut self) {
225-
let flock = os::flock {
226-
l_start: 0,
227-
l_len: 0,
228-
l_pid: 0,
229-
l_whence: libc::SEEK_SET as libc::c_short,
230-
l_type: os::F_UNLCK,
231-
l_sysid: 0,
232-
};
233-
unsafe {
234-
libc::fcntl(self.fd, os::F_SETLK, &flock);
235-
libc::close(self.fd);
222+
impl Drop for Lock {
223+
fn drop(&mut self) {
224+
let flock = os::flock {
225+
l_start: 0,
226+
l_len: 0,
227+
l_pid: 0,
228+
l_whence: libc::SEEK_SET as libc::c_short,
229+
l_type: os::F_UNLCK,
230+
l_sysid: 0,
231+
};
232+
unsafe {
233+
libc::fcntl(self.fd, os::F_SETLK, &flock);
234+
libc::close(self.fd);
235+
}
236236
}
237237
}
238-
}
239-
}
238+
} else if #[cfg(windows)] {
239+
use std::mem;
240+
use std::os::windows::prelude::*;
241+
use std::os::windows::raw::HANDLE;
242+
use std::fs::{File, OpenOptions};
243+
use std::os::raw::{c_ulong, c_int};
240244

241-
#[cfg(windows)]
242-
#[allow(nonstandard_style)]
243-
mod imp {
244-
use std::io;
245-
use std::mem;
246-
use std::os::windows::prelude::*;
247-
use std::os::windows::raw::HANDLE;
248-
use std::path::Path;
249-
use std::fs::{File, OpenOptions};
250-
use std::os::raw::{c_ulong, c_int};
251-
252-
type DWORD = c_ulong;
253-
type BOOL = c_int;
254-
type ULONG_PTR = usize;
255-
256-
type LPOVERLAPPED = *mut OVERLAPPED;
257-
const LOCKFILE_EXCLUSIVE_LOCK: DWORD = 0x0000_0002;
258-
const LOCKFILE_FAIL_IMMEDIATELY: DWORD = 0x0000_0001;
259-
260-
const FILE_SHARE_DELETE: DWORD = 0x4;
261-
const FILE_SHARE_READ: DWORD = 0x1;
262-
const FILE_SHARE_WRITE: DWORD = 0x2;
263-
264-
#[repr(C)]
265-
struct OVERLAPPED {
266-
Internal: ULONG_PTR,
267-
InternalHigh: ULONG_PTR,
268-
Offset: DWORD,
269-
OffsetHigh: DWORD,
270-
hEvent: HANDLE,
271-
}
245+
type DWORD = c_ulong;
246+
type BOOL = c_int;
247+
type ULONG_PTR = usize;
272248

273-
extern "system" {
274-
fn LockFileEx(hFile: HANDLE,
275-
dwFlags: DWORD,
276-
dwReserved: DWORD,
277-
nNumberOfBytesToLockLow: DWORD,
278-
nNumberOfBytesToLockHigh: DWORD,
279-
lpOverlapped: LPOVERLAPPED) -> BOOL;
280-
}
249+
type LPOVERLAPPED = *mut OVERLAPPED;
250+
const LOCKFILE_EXCLUSIVE_LOCK: DWORD = 0x0000_0002;
251+
const LOCKFILE_FAIL_IMMEDIATELY: DWORD = 0x0000_0001;
281252

282-
#[derive(Debug)]
283-
pub struct Lock {
284-
_file: File,
285-
}
253+
const FILE_SHARE_DELETE: DWORD = 0x4;
254+
const FILE_SHARE_READ: DWORD = 0x1;
255+
const FILE_SHARE_WRITE: DWORD = 0x2;
286256

287-
impl Lock {
288-
pub fn new(p: &Path,
289-
wait: bool,
290-
create: bool,
291-
exclusive: bool)
292-
-> io::Result<Lock> {
293-
assert!(p.parent().unwrap().exists(),
294-
"Parent directory of lock-file must exist: {}",
295-
p.display());
296-
297-
let share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
298-
299-
let mut open_options = OpenOptions::new();
300-
open_options.read(true)
301-
.share_mode(share_mode);
302-
303-
if create {
304-
open_options.create(true)
305-
.write(true);
306-
}
257+
#[repr(C)]
258+
struct OVERLAPPED {
259+
Internal: ULONG_PTR,
260+
InternalHigh: ULONG_PTR,
261+
Offset: DWORD,
262+
OffsetHigh: DWORD,
263+
hEvent: HANDLE,
264+
}
307265

308-
debug!("Attempting to open lock file `{}`", p.display());
309-
let file = match open_options.open(p) {
310-
Ok(file) => {
311-
debug!("Lock file opened successfully");
312-
file
313-
}
314-
Err(err) => {
315-
debug!("Error opening lock file: {}", err);
316-
return Err(err)
317-
}
318-
};
266+
extern "system" {
267+
fn LockFileEx(hFile: HANDLE,
268+
dwFlags: DWORD,
269+
dwReserved: DWORD,
270+
nNumberOfBytesToLockLow: DWORD,
271+
nNumberOfBytesToLockHigh: DWORD,
272+
lpOverlapped: LPOVERLAPPED) -> BOOL;
273+
}
319274

320-
let ret = unsafe {
321-
let mut overlapped: OVERLAPPED = mem::zeroed();
275+
#[derive(Debug)]
276+
pub struct Lock {
277+
_file: File,
278+
}
322279

323-
let mut dwFlags = 0;
324-
if !wait {
325-
dwFlags |= LOCKFILE_FAIL_IMMEDIATELY;
280+
impl Lock {
281+
pub fn new(p: &Path,
282+
wait: bool,
283+
create: bool,
284+
exclusive: bool)
285+
-> io::Result<Lock> {
286+
assert!(p.parent().unwrap().exists(),
287+
"Parent directory of lock-file must exist: {}",
288+
p.display());
289+
290+
let share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
291+
292+
let mut open_options = OpenOptions::new();
293+
open_options.read(true)
294+
.share_mode(share_mode);
295+
296+
if create {
297+
open_options.create(true)
298+
.write(true);
326299
}
327300

328-
if exclusive {
329-
dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
301+
debug!("Attempting to open lock file `{}`", p.display());
302+
let file = match open_options.open(p) {
303+
Ok(file) => {
304+
debug!("Lock file opened successfully");
305+
file
306+
}
307+
Err(err) => {
308+
debug!("Error opening lock file: {}", err);
309+
return Err(err)
310+
}
311+
};
312+
313+
let ret = unsafe {
314+
let mut overlapped: OVERLAPPED = mem::zeroed();
315+
316+
let mut dwFlags = 0;
317+
if !wait {
318+
dwFlags |= LOCKFILE_FAIL_IMMEDIATELY;
319+
}
320+
321+
if exclusive {
322+
dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
323+
}
324+
325+
debug!("Attempting to acquire lock on lock file `{}`",
326+
p.display());
327+
LockFileEx(file.as_raw_handle(),
328+
dwFlags,
329+
0,
330+
0xFFFF_FFFF,
331+
0xFFFF_FFFF,
332+
&mut overlapped)
333+
};
334+
if ret == 0 {
335+
let err = io::Error::last_os_error();
336+
debug!("Failed acquiring file lock: {}", err);
337+
Err(err)
338+
} else {
339+
debug!("Successfully acquired lock.");
340+
Ok(Lock { _file: file })
330341
}
342+
}
343+
}
331344

332-
debug!("Attempting to acquire lock on lock file `{}`",
333-
p.display());
334-
LockFileEx(file.as_raw_handle(),
335-
dwFlags,
336-
0,
337-
0xFFFF_FFFF,
338-
0xFFFF_FFFF,
339-
&mut overlapped)
340-
};
341-
if ret == 0 {
342-
let err = io::Error::last_os_error();
343-
debug!("Failed acquiring file lock: {}", err);
344-
Err(err)
345-
} else {
346-
debug!("Successfully acquired lock.");
347-
Ok(Lock { _file: file })
345+
// Note that we don't need a Drop impl on the Windows: The file is unlocked
346+
// automatically when it's closed.
347+
} else {
348+
#[derive(Debug)]
349+
pub struct Lock(());
350+
351+
impl Lock {
352+
pub fn new(_p: &Path, _wait: bool, _create: bool, _exclusive: bool)
353+
-> io::Result<Lock>
354+
{
355+
let msg = "file locks not supported on this platform";
356+
Err(io::Error::new(io::ErrorKind::Other, msg))
348357
}
349358
}
350359
}
351-
352-
// Note that we don't need a Drop impl on the Windows: The file is unlocked
353-
// automatically when it's closed.
354360
}
355361

356-
impl imp::Lock {
362+
impl Lock {
357363
pub fn panicking_new(p: &Path,
358364
wait: bool,
359365
create: bool,

‎src/librustc_errors/lock.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ pub fn acquire_global_lock(name: &str) -> Box<dyn Any> {
109109
}
110110
}
111111

112-
#[cfg(unix)]
112+
#[cfg(not(windows))]
113113
pub fn acquire_global_lock(_name: &str) -> Box<dyn Any> {
114114
Box::new(())
115115
}

0 commit comments

Comments
 (0)
Please sign in to comment.