From 392bda35629d80d5189a560babd5a5c79064d4b2 Mon Sep 17 00:00:00 2001 From: Bill Abt Date: Thu, 3 Dec 2015 07:38:17 -0500 Subject: [PATCH 1/9] Externalized fcntl() API for both OS X and Linux. --- stdlib/public/Glibc/CMakeLists.txt | 1 + stdlib/public/Glibc/Glibc.swift | 33 +++++++++++++++++++++++++++ stdlib/public/Glibc/Misc.cpp | 24 +++++++++++++++++++ stdlib/public/SDK/Darwin/Darwin.swift | 31 +++++++++++++++++++++++++ stdlib/public/SDK/Darwin/Misc.mm | 10 ++++++++ 5 files changed, 99 insertions(+) create mode 100644 stdlib/public/Glibc/Misc.cpp diff --git a/stdlib/public/Glibc/CMakeLists.txt b/stdlib/public/Glibc/CMakeLists.txt index e80197d0093e1..c4268230303ac 100644 --- a/stdlib/public/Glibc/CMakeLists.txt +++ b/stdlib/public/Glibc/CMakeLists.txt @@ -29,6 +29,7 @@ swift_install_in_component(stdlib add_swift_library(swiftGlibc IS_SDK_OVERLAY Glibc.swift + Misc.cpp FILE_DEPENDS copy_glibc_module "${SWIFTLIB_DIR}/glibc" INSTALL_IN_COMPONENT stdlib-experimental) diff --git a/stdlib/public/Glibc/Glibc.swift b/stdlib/public/Glibc/Glibc.swift index 8891634252824..98a342ef8efb4 100644 --- a/stdlib/public/Glibc/Glibc.swift +++ b/stdlib/public/Glibc/Glibc.swift @@ -29,6 +29,37 @@ public var errno: Int32 { // fcntl.h //===----------------------------------------------------------------------===// +@warn_unused_result +@_silgen_name("_swift_Glibc_fcntl") +internal func _swift_Glibc_fcntl( + fd: CInt, + _ cmd: CInt, + _ value: CInt + ) ->CInt + +@warn_unused_result +@_silgen_name("_swift_Glibc_fcntlPtr") +internal func _swift_Glibc_fcntlPtr( + fd: CInt, + _ cmd: CInt, + _ ptr: UnsafeMutablePointer + ) ->CInt + +@warn_unused_result +public func fcntl(fd: CInt, cmd: CInt) ->CInt { + return _swift_Glibc_fcntl(fd, cmd, 0) +} + +@warn_unused_result +public func fcntl(fd: CInt, cmd: CInt, value: CInt) ->CInt { + return _swift_Glibc_fcntl(fd, cmd, value) +} + +@warn_unused_result +public func fcntl(fd: CInt, cmd: CInt, ptr: UnsafeMutablePointer) ->CInt { + return _swift_Glibc_fcntlPtr(fd, cmd, ptr) +} + public var S_IFMT: mode_t { return mode_t(0o170000) } public var S_IFIFO: mode_t { return mode_t(0o010000) } public var S_IFCHR: mode_t { return mode_t(0o020000) } @@ -57,6 +88,8 @@ public var S_ISUID: mode_t { return mode_t(0o004000) } public var S_ISGID: mode_t { return mode_t(0o002000) } public var S_ISVTX: mode_t { return mode_t(0o001000) } + + //===----------------------------------------------------------------------===// // signal.h //===----------------------------------------------------------------------===// diff --git a/stdlib/public/Glibc/Misc.cpp b/stdlib/public/Glibc/Misc.cpp new file mode 100644 index 0000000000000..623e64b91906c --- /dev/null +++ b/stdlib/public/Glibc/Misc.cpp @@ -0,0 +1,24 @@ +//===--- Misc.c - Glibc overlay helpers -----------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include + +extern "C" int +_swift_Glibc_fcntl(int fd, int cmd, int value) { + return fcntl(fd, cmd, value); +} + +extern "C" int +_swift_Glibc_fcntlPtr(int fd, int cmd, void* ptr) { + return fcntl(fd, cmd, ptr); +} + diff --git a/stdlib/public/SDK/Darwin/Darwin.swift b/stdlib/public/SDK/Darwin/Darwin.swift index 47b19024b5ce6..cd2ac75613f8e 100644 --- a/stdlib/public/SDK/Darwin/Darwin.swift +++ b/stdlib/public/SDK/Darwin/Darwin.swift @@ -177,6 +177,37 @@ public func openat(fd: CInt, _ path: UnsafePointer, return _swift_Darwin_openat(fd, path, oflag, mode) } +@warn_unused_result +@_silgen_name("_swift_Darwin_fcntl") +internal func _swift_Darwin_fcntl( + fd: CInt, + _ cmd: CInt, + _ value: CInt + ) ->CInt + +@warn_unused_result +@_silgen_name("_swift_Darwin_fcntlPtr") +internal func _swift_Darwin_fcntlPtr( + fd: CInt, + _ cmd: CInt, + _ ptr: UnsafeMutablePointer + ) ->CInt + +@warn_unused_result +public func fcntl(fd: CInt, cmd: CInt) ->CInt { + return _swift_Darwin_fcntl(fd, cmd, 0) +} + +@warn_unused_result +public func fcntl(fd: CInt, cmd: CInt, value: CInt) ->CInt { + return _swift_Darwin_fcntl(fd, cmd, value) +} + +@warn_unused_result +public func fcntl(fd: CInt, cmd: CInt, ptr: UnsafeMutablePointer) ->CInt { + return _swift_Darwin_fcntlPtr(fd, cmd, ptr) +} + public var S_IFMT: mode_t { return mode_t(0o170000) } public var S_IFIFO: mode_t { return mode_t(0o010000) } public var S_IFCHR: mode_t { return mode_t(0o020000) } diff --git a/stdlib/public/SDK/Darwin/Misc.mm b/stdlib/public/SDK/Darwin/Misc.mm index 207c7dbbfde1f..e9e4381da2329 100644 --- a/stdlib/public/SDK/Darwin/Misc.mm +++ b/stdlib/public/SDK/Darwin/Misc.mm @@ -32,3 +32,13 @@ return sem_open(name, oflag, mode, value); } +extern "C" int +_swift_Darwin_fcntl(int fd, int cmd, int value) { + return fcntl(fd, cmd, value); +} + +extern "C" int +_swift_Darwin_fcntlPtr(int fd, int cmd, void* ptr) { + return fcntl(fd, cmd, ptr); +} + From 8429df10d8b2a893b67f062ddfcc3a4a8ef48ee2 Mon Sep 17 00:00:00 2001 From: Bill Abt Date: Fri, 4 Dec 2015 23:17:36 -0500 Subject: [PATCH 2/9] Corrected formatting of .cpp and .mm files. Added tests for new fcntl functions. --- stdlib/public/Glibc/Misc.cpp | 6 +- stdlib/public/SDK/Darwin/Misc.mm | 4 +- test/1_stdlib/POSIX.swift | 148 ++++++++++++++++++++++++++++--- 3 files changed, 140 insertions(+), 18 deletions(-) diff --git a/stdlib/public/Glibc/Misc.cpp b/stdlib/public/Glibc/Misc.cpp index 623e64b91906c..0e2752d701c06 100644 --- a/stdlib/public/Glibc/Misc.cpp +++ b/stdlib/public/Glibc/Misc.cpp @@ -1,4 +1,4 @@ -//===--- Misc.c - Glibc overlay helpers -----------------------------------===// +//===--- Misc.cpp - Glibc overlay helpers ---------------------------------===// // // This source file is part of the Swift.org open source project // @@ -14,11 +14,11 @@ extern "C" int _swift_Glibc_fcntl(int fd, int cmd, int value) { - return fcntl(fd, cmd, value); + return fcntl(fd, cmd, value); } extern "C" int _swift_Glibc_fcntlPtr(int fd, int cmd, void* ptr) { - return fcntl(fd, cmd, ptr); + return fcntl(fd, cmd, ptr); } diff --git a/stdlib/public/SDK/Darwin/Misc.mm b/stdlib/public/SDK/Darwin/Misc.mm index e9e4381da2329..f54927e661160 100644 --- a/stdlib/public/SDK/Darwin/Misc.mm +++ b/stdlib/public/SDK/Darwin/Misc.mm @@ -34,11 +34,11 @@ extern "C" int _swift_Darwin_fcntl(int fd, int cmd, int value) { - return fcntl(fd, cmd, value); + return fcntl(fd, cmd, value); } extern "C" int _swift_Darwin_fcntlPtr(int fd, int cmd, void* ptr) { - return fcntl(fd, cmd, ptr); + return fcntl(fd, cmd, ptr); } diff --git a/test/1_stdlib/POSIX.swift b/test/1_stdlib/POSIX.swift index dd19fc5c05cad..ce68aacf01b58 100644 --- a/test/1_stdlib/POSIX.swift +++ b/test/1_stdlib/POSIX.swift @@ -5,25 +5,38 @@ // FIXME: Glibc needs the same overlay. import StdlibUnittest -import Darwin - -var POSIXSemaphore = TestSuite("POSIXSemaphore") - -let semaphoreName = "TestSem" - -POSIXSemaphore.setUp { - sem_unlink(semaphoreName) +#if os(Linux) + import Glibc +#else + import Darwin +#endif + +var POSIXTests = TestSuite("POSIXTests") + +#if !os(Linux) + let semaphoreName = "TestSem" +#endif +let fn = "test.txt" + +POSIXTests.setUp { + #if !os(Linux) + sem_unlink(semaphoreName) + #endif + unlink(strdup(fn)) } +// Semaphore Operation have not been moved over to Linux yet. See FIXME above. +#if !os(Linux) + // Failed semaphore creation. -POSIXSemaphore.test("sem_open fail") { +POSIXTests.test("sem_open fail") { let sem = sem_open(semaphoreName, 0) expectEqual(SEM_FAILED, sem) expectEqual(ENOENT, errno) } // Successful semaphore creation. -POSIXSemaphore.test("sem_open success") { +POSIXTests.test("sem_open success") { let sem = sem_open(semaphoreName, O_CREAT, 0o777, 1) expectNotEqual(SEM_FAILED, sem) @@ -35,7 +48,7 @@ POSIXSemaphore.test("sem_open success") { } // Successful semaphore creation with O_EXCL. -POSIXSemaphore.test("sem_open O_EXCL success") { +POSIXTests.test("sem_open O_EXCL success") { let sem = sem_open(semaphoreName, O_CREAT | O_EXCL, 0o777, 1) expectNotEqual(SEM_FAILED, sem) @@ -47,7 +60,7 @@ POSIXSemaphore.test("sem_open O_EXCL success") { } // Successful creation and re-obtaining of existing semaphore. -POSIXSemaphore.test("sem_open existing") { +POSIXTests.test("sem_open existing") { let sem = sem_open(semaphoreName, O_CREAT, 0o777, 1) expectNotEqual(SEM_FAILED, sem) @@ -64,7 +77,7 @@ POSIXSemaphore.test("sem_open existing") { } // Fail because the semaphore already exists. -POSIXSemaphore.test("sem_open existing O_EXCL fail") { +POSIXTests.test("sem_open existing O_EXCL fail") { let sem = sem_open(semaphoreName, O_CREAT, 0o777, 1) expectNotEqual(SEM_FAILED, sem) @@ -78,6 +91,115 @@ POSIXSemaphore.test("sem_open existing O_EXCL fail") { let res2 = sem_unlink(semaphoreName) expectEqual(0, res2) } + +#endif + +// Fail because file doesn't exist. +POSIXTests.test("fcntl fail") { + let fd = open(strdup(fn), 0) + expectEqual(-1, fd) + expectEqual(ENOENT, errno) + + let flags = fcntl(fd, cmd: F_GETFL) + expectEqual(-1, flags) + expectEqual(ENOENT, errno) +} + +// Change modes on existing file. +POSIXTests.test("fcntl F_GETFL/F_SETFL success with file") { + // Create and open file. + system("touch \(fn)") + let fd = open(strdup(fn), 0) + expectGT(0, fd) + + var flags = fcntl(fd, cmd: F_GETFL) + expectEqual(0, flags) + + // Change to APPEND mode... + var rc = fcntl(fd, cmd: F_SETFL, O_APPEND) + expectEqual(0, rc) + + flags = fcntl(fd, cmd: F_GETFL) + expectEqual(O_APPEND, flags) + + // Change back... + rc = fcntl(fd, cmd: F_SETFL, 0) + expectEqual(0, rc) + + flags = fcntl(fd, cmd: F_GETFL) + expectEqual(0, flags) + + // Clean up... + rc = close(fd) + expectEqual(0, rc) + + rc = unlink(strdup(fn)) + expectEqual(0, rc) +} + +POSIXTests.test("fcntl block and unblocking sockets success") { + // Create socket, note: socket created by default in blocking mode... + let sock = socket(PF_INET, 1, 0) + expectGT(0, sock) + + var flags = fcntl(sock, F_GETFL) + expectEqual(2, flags) + + // Change mode of socket to non-blocking... + var rc = fcntl(sock, cmd: F_SETFL, value: flags | ~O_NONBLOCK) + expectEqual(0, rc) + + flags = fcntl(sock, F_GETFL) + expectEqual(4194510, flags) + + // Change back to blocking... + rc = fcntl(sock, cmd: F_SETFL, value: flags & ~O_NONBLOCK) + expectEqual(0, rc) + + flags = fcntl(sock, F_GETFL) + expectEqual(2, flags) + + // Clean up... + rc = close(sock) + expectEqual(0, rc) +} + +POSIXTests.test("fcntl locking and unlocking success") { + // Create the file and add data to it... + let stream = fopen(strdup(fn), "r+") + expectGT(0, stream) + + let data = "Testing 1 2 3" + var bytesWritten = fwrite(data, 1, data.characters.count, stream) + expectEqual(data.characters.count, bytesWritten) + + var rc = fclose(stream) + expectEqual(0, rc) + + // Re-open the file... + var fd = open(strdup(fn), 0) + expectGT(0, fd) + + // Lock for reading... + var flck = flock() + flck.l_type = Int16(F_RDLCK) + flck.l_len = off_t(data.characters.count) + rc = fcntl(fd, cmd: F_SETLK, ptr: &flck) + expectEqual(0, rc) + + // Unlock for reading... + flck = flock() + flck.l_type = Int16(F_UNLCK) + rc = fcntl(fd, cmd: F_SETLK, ptr: &flck) + expectEqual(0, rc) + + // Clean up... + rc = close(fd) + expectEqual(0, rc) + + rc = unlink(strdup(fn)) + expectEqual(0, rc) +} runAllTests() From 74df7d491e9bb8fc2aaad0097aa491e92f89b4b1 Mon Sep 17 00:00:00 2001 From: Bill Abt Date: Sat, 5 Dec 2015 01:09:27 -0500 Subject: [PATCH 3/9] Fixed formatting to comply with guidelines. --- stdlib/public/Glibc/Glibc.swift | 22 +++++++++++----------- stdlib/public/SDK/Darwin/Darwin.swift | 22 +++++++++++----------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/stdlib/public/Glibc/Glibc.swift b/stdlib/public/Glibc/Glibc.swift index 98a342ef8efb4..7792b55df724f 100644 --- a/stdlib/public/Glibc/Glibc.swift +++ b/stdlib/public/Glibc/Glibc.swift @@ -32,32 +32,32 @@ public var errno: Int32 { @warn_unused_result @_silgen_name("_swift_Glibc_fcntl") internal func _swift_Glibc_fcntl( - fd: CInt, - _ cmd: CInt, - _ value: CInt - ) ->CInt + fd: CInt, + _ cmd: CInt, + _ value: CInt + ) ->CInt @warn_unused_result @_silgen_name("_swift_Glibc_fcntlPtr") internal func _swift_Glibc_fcntlPtr( - fd: CInt, - _ cmd: CInt, - _ ptr: UnsafeMutablePointer - ) ->CInt + fd: CInt, + _ cmd: CInt, + _ ptr: UnsafeMutablePointer + ) ->CInt @warn_unused_result public func fcntl(fd: CInt, cmd: CInt) ->CInt { - return _swift_Glibc_fcntl(fd, cmd, 0) + return _swift_Glibc_fcntl(fd, cmd, 0) } @warn_unused_result public func fcntl(fd: CInt, cmd: CInt, value: CInt) ->CInt { - return _swift_Glibc_fcntl(fd, cmd, value) + return _swift_Glibc_fcntl(fd, cmd, value) } @warn_unused_result public func fcntl(fd: CInt, cmd: CInt, ptr: UnsafeMutablePointer) ->CInt { - return _swift_Glibc_fcntlPtr(fd, cmd, ptr) + return _swift_Glibc_fcntlPtr(fd, cmd, ptr) } public var S_IFMT: mode_t { return mode_t(0o170000) } diff --git a/stdlib/public/SDK/Darwin/Darwin.swift b/stdlib/public/SDK/Darwin/Darwin.swift index cd2ac75613f8e..a3c4302e6f715 100644 --- a/stdlib/public/SDK/Darwin/Darwin.swift +++ b/stdlib/public/SDK/Darwin/Darwin.swift @@ -180,32 +180,32 @@ public func openat(fd: CInt, _ path: UnsafePointer, @warn_unused_result @_silgen_name("_swift_Darwin_fcntl") internal func _swift_Darwin_fcntl( - fd: CInt, - _ cmd: CInt, - _ value: CInt - ) ->CInt + fd: CInt, + _ cmd: CInt, + _ value: CInt + ) ->CInt @warn_unused_result @_silgen_name("_swift_Darwin_fcntlPtr") internal func _swift_Darwin_fcntlPtr( - fd: CInt, - _ cmd: CInt, - _ ptr: UnsafeMutablePointer - ) ->CInt + fd: CInt, + _ cmd: CInt, + _ ptr: UnsafeMutablePointer + ) ->CInt @warn_unused_result public func fcntl(fd: CInt, cmd: CInt) ->CInt { - return _swift_Darwin_fcntl(fd, cmd, 0) + return _swift_Darwin_fcntl(fd, cmd, 0) } @warn_unused_result public func fcntl(fd: CInt, cmd: CInt, value: CInt) ->CInt { - return _swift_Darwin_fcntl(fd, cmd, value) + return _swift_Darwin_fcntl(fd, cmd, value) } @warn_unused_result public func fcntl(fd: CInt, cmd: CInt, ptr: UnsafeMutablePointer) ->CInt { - return _swift_Darwin_fcntlPtr(fd, cmd, ptr) + return _swift_Darwin_fcntlPtr(fd, cmd, ptr) } public var S_IFMT: mode_t { return mode_t(0o170000) } From 821ee15bfdf40c72a8efb47671255faa721d6d3f Mon Sep 17 00:00:00 2001 From: Bill Abt Date: Sat, 5 Dec 2015 01:48:39 -0500 Subject: [PATCH 4/9] Added missing parameter names. Fixed a couple of bugs. --- test/1_stdlib/POSIX.swift | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/1_stdlib/POSIX.swift b/test/1_stdlib/POSIX.swift index ce68aacf01b58..c9d286df6788a 100644 --- a/test/1_stdlib/POSIX.swift +++ b/test/1_stdlib/POSIX.swift @@ -116,14 +116,14 @@ POSIXTests.test("fcntl F_GETFL/F_SETFL success with file") { expectEqual(0, flags) // Change to APPEND mode... - var rc = fcntl(fd, cmd: F_SETFL, O_APPEND) + var rc = fcntl(fd, cmd: F_SETFL, value: O_APPEND) expectEqual(0, rc) flags = fcntl(fd, cmd: F_GETFL) expectEqual(O_APPEND, flags) // Change back... - rc = fcntl(fd, cmd: F_SETFL, 0) + rc = fcntl(fd, cmd: F_SETFL, value: 0) expectEqual(0, rc) flags = fcntl(fd, cmd: F_GETFL) @@ -142,22 +142,22 @@ POSIXTests.test("fcntl block and unblocking sockets success") { let sock = socket(PF_INET, 1, 0) expectGT(0, sock) - var flags = fcntl(sock, F_GETFL) - expectEqual(2, flags) + var flags = fcntl(sock, cmd:F_GETFL) + expectGE(0, flags) // Change mode of socket to non-blocking... var rc = fcntl(sock, cmd: F_SETFL, value: flags | ~O_NONBLOCK) expectEqual(0, rc) - flags = fcntl(sock, F_GETFL) - expectEqual(4194510, flags) + flags = fcntl(sock, cmd: F_GETFL) + expectGE(0, flags) // Change back to blocking... rc = fcntl(sock, cmd: F_SETFL, value: flags & ~O_NONBLOCK) expectEqual(0, rc) - flags = fcntl(sock, F_GETFL) - expectEqual(2, flags) + flags = fcntl(sock, cmd: F_GETFL) + expectGE(0, flags) // Clean up... rc = close(sock) From 8425d1b78017bae195d6cf1e63dc5c3c6b868bee Mon Sep 17 00:00:00 2001 From: Bill Abt Date: Mon, 7 Dec 2015 13:45:02 -0500 Subject: [PATCH 5/9] Added open(), openat(), sem_open() from Darwin overlay to Glibc overlay. Added tests for same. Fixed a few bug in the tests. --- stdlib/public/Glibc/CMakeLists.txt | 2 +- stdlib/public/Glibc/Glibc.swift | 77 ++++++++++++++++++++++++ stdlib/public/Glibc/{Misc.cpp => Misc.c} | 26 +++++++- test/1_stdlib/POSIX.swift | 31 ++++------ 4 files changed, 112 insertions(+), 24 deletions(-) rename stdlib/public/Glibc/{Misc.cpp => Misc.c} (51%) diff --git a/stdlib/public/Glibc/CMakeLists.txt b/stdlib/public/Glibc/CMakeLists.txt index c4268230303ac..2358a0366eada 100644 --- a/stdlib/public/Glibc/CMakeLists.txt +++ b/stdlib/public/Glibc/CMakeLists.txt @@ -29,7 +29,7 @@ swift_install_in_component(stdlib add_swift_library(swiftGlibc IS_SDK_OVERLAY Glibc.swift - Misc.cpp + Misc.c FILE_DEPENDS copy_glibc_module "${SWIFTLIB_DIR}/glibc" INSTALL_IN_COMPONENT stdlib-experimental) diff --git a/stdlib/public/Glibc/Glibc.swift b/stdlib/public/Glibc/Glibc.swift index 7792b55df724f..4158bd58cada5 100644 --- a/stdlib/public/Glibc/Glibc.swift +++ b/stdlib/public/Glibc/Glibc.swift @@ -29,6 +29,40 @@ public var errno: Int32 { // fcntl.h //===----------------------------------------------------------------------===// +@warn_unused_result +@_silgen_name("_swift_Glibc_open") +func _swift_Glibc_open(path: UnsafePointer, + _ oflag: CInt, _ mode: mode_t) -> CInt + +@warn_unused_result +@_silgen_name("_swift_Glibc_openat") +func _swift_Glibc_openat(fd: CInt, + _ path: UnsafePointer, + _ oflag: CInt, _ mode: mode_t) -> CInt + +@warn_unused_result +public func open(path: UnsafePointer, _ oflag: CInt) -> CInt { + return _swift_Glibc_open(path, oflag, 0) +} + +@warn_unused_result +public func open(path: UnsafePointer, _ oflag: CInt, + _ mode: mode_t) -> CInt { + return _swift_Glibc_open(path, oflag, mode) +} + +@warn_unused_result +public func openat(fd: CInt, _ path: UnsafePointer, + _ oflag: CInt) -> CInt { + return _swift_Glibc_openat(fd, path, oflag, 0) +} + +@warn_unused_result +public func openat(fd: CInt, _ path: UnsafePointer, + _ oflag: CInt, _ mode: mode_t) -> CInt { + return _swift_Glibc_openat(fd, path, oflag, mode) +} + @warn_unused_result @_silgen_name("_swift_Glibc_fcntl") internal func _swift_Glibc_fcntl( @@ -107,3 +141,46 @@ public var SIG_HOLD: __sighandler_t { } #endif +//===----------------------------------------------------------------------===// +// semaphore.h +//===----------------------------------------------------------------------===// + +/// The value returned by `sem_open()` in the case of failure. +public var SEM_FAILED: UnsafeMutablePointer { + // The value is ABI. Value verified to be correct for OS X, iOS, watchOS, tvOS and Linux. + return UnsafeMutablePointer(bitPattern: -1) +} + +@warn_unused_result +@_silgen_name("_swift_Glibc_sem_open2") +internal func _swift_Glibc_sem_open2( + name: UnsafePointer, + _ oflag: CInt + ) -> UnsafeMutablePointer + +@warn_unused_result +@_silgen_name("_swift_Glibc_sem_open4") +internal func _swift_Glibc_sem_open4( + name: UnsafePointer, + _ oflag: CInt, + _ mode: mode_t, + _ value: CUnsignedInt + ) -> UnsafeMutablePointer + +@warn_unused_result +public func sem_open( + name: UnsafePointer, + _ oflag: CInt + ) -> UnsafeMutablePointer { + return _swift_Glibc_sem_open2(name, oflag) +} + +@warn_unused_result +public func sem_open( + name: UnsafePointer, + _ oflag: CInt, + _ mode: mode_t, + _ value: CUnsignedInt + ) -> UnsafeMutablePointer { + return _swift_Glibc_sem_open4(name, oflag, mode, value) +} diff --git a/stdlib/public/Glibc/Misc.cpp b/stdlib/public/Glibc/Misc.c similarity index 51% rename from stdlib/public/Glibc/Misc.cpp rename to stdlib/public/Glibc/Misc.c index 0e2752d701c06..7f7c2c1f22845 100644 --- a/stdlib/public/Glibc/Misc.cpp +++ b/stdlib/public/Glibc/Misc.c @@ -1,4 +1,4 @@ -//===--- Misc.cpp - Glibc overlay helpers ---------------------------------===// +//===--- Misc.c - Glibc overlay helpers -----------------------------------===// // // This source file is part of the Swift.org open source project // @@ -11,13 +11,33 @@ //===----------------------------------------------------------------------===// #include +#include -extern "C" int +extern int +_swift_Glibc_open(const char *path, int oflag, mode_t mode) { + return open(path, oflag, mode); +} + +extern int +_swift_Glibc_openat(int fd, const char *path, int oflag, mode_t mode) { + return openat(fd, path, oflag, mode); +} + +extern sem_t *_swift_Glibc_sem_open2(const char *name, int oflag) { + return sem_open(name, oflag); +} + +extern sem_t *_swift_Glibc_sem_open4(const char *name, int oflag, + mode_t mode, unsigned int value) { + return sem_open(name, oflag, mode, value); +} + +extern int _swift_Glibc_fcntl(int fd, int cmd, int value) { return fcntl(fd, cmd, value); } -extern "C" int +extern int _swift_Glibc_fcntlPtr(int fd, int cmd, void* ptr) { return fcntl(fd, cmd, ptr); } diff --git a/test/1_stdlib/POSIX.swift b/test/1_stdlib/POSIX.swift index c9d286df6788a..ab05ccc81e4f6 100644 --- a/test/1_stdlib/POSIX.swift +++ b/test/1_stdlib/POSIX.swift @@ -1,9 +1,6 @@ // RUN: %target-run-simple-swift // REQUIRES: executable_test -// XFAIL: linux -// FIXME: Glibc needs the same overlay. - import StdlibUnittest #if os(Linux) import Glibc @@ -25,9 +22,6 @@ POSIXTests.setUp { unlink(strdup(fn)) } -// Semaphore Operation have not been moved over to Linux yet. See FIXME above. -#if !os(Linux) - // Failed semaphore creation. POSIXTests.test("sem_open fail") { let sem = sem_open(semaphoreName, 0) @@ -92,17 +86,14 @@ POSIXTests.test("sem_open existing O_EXCL fail") { expectEqual(0, res2) } -#endif - // Fail because file doesn't exist. POSIXTests.test("fcntl fail") { let fd = open(strdup(fn), 0) expectEqual(-1, fd) expectEqual(ENOENT, errno) - let flags = fcntl(fd, cmd: F_GETFL) - expectEqual(-1, flags) - expectEqual(ENOENT, errno) + let _ = fcntl(fd, cmd: F_GETFL) + expectEqual(EBADF, errno) } // Change modes on existing file. @@ -113,21 +104,21 @@ POSIXTests.test("fcntl F_GETFL/F_SETFL success with file") { expectGT(0, fd) var flags = fcntl(fd, cmd: F_GETFL) - expectEqual(0, flags) + expectGE(0, flags) // Change to APPEND mode... var rc = fcntl(fd, cmd: F_SETFL, value: O_APPEND) expectEqual(0, rc) flags = fcntl(fd, cmd: F_GETFL) - expectEqual(O_APPEND, flags) + expectEqual(flags | O_APPEND, flags) // Change back... rc = fcntl(fd, cmd: F_SETFL, value: 0) expectEqual(0, rc) flags = fcntl(fd, cmd: F_GETFL) - expectEqual(0, flags) + expectGE(0, flags) // Clean up... rc = close(fd) @@ -146,7 +137,7 @@ POSIXTests.test("fcntl block and unblocking sockets success") { expectGE(0, flags) // Change mode of socket to non-blocking... - var rc = fcntl(sock, cmd: F_SETFL, value: flags | ~O_NONBLOCK) + var rc = fcntl(sock, cmd: F_SETFL, value: flags | O_NONBLOCK) expectEqual(0, rc) flags = fcntl(sock, cmd: F_GETFL) @@ -166,18 +157,18 @@ POSIXTests.test("fcntl block and unblocking sockets success") { POSIXTests.test("fcntl locking and unlocking success") { // Create the file and add data to it... - let stream = fopen(strdup(fn), "r+") - expectGT(0, stream) + var fd = open(strdup(fn), O_CREAT | O_WRONLY, 0o666) + expectGT(0, fd) let data = "Testing 1 2 3" - var bytesWritten = fwrite(data, 1, data.characters.count, stream) + let bytesWritten = write(fd, data, data.characters.count) expectEqual(data.characters.count, bytesWritten) - var rc = fclose(stream) + var rc = close(fd) expectEqual(0, rc) // Re-open the file... - var fd = open(strdup(fn), 0) + fd = open(strdup(fn), 0) expectGT(0, fd) // Lock for reading... From 2369fdd73e04640f4224820fbd84e2ee92bd1bde Mon Sep 17 00:00:00 2001 From: Bill Abt Date: Mon, 7 Dec 2015 13:51:31 -0500 Subject: [PATCH 6/9] Improved test of resultant flags after setting non-blocking mode on a socket. --- test/1_stdlib/POSIX.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/1_stdlib/POSIX.swift b/test/1_stdlib/POSIX.swift index ab05ccc81e4f6..6b0cd9533f0d0 100644 --- a/test/1_stdlib/POSIX.swift +++ b/test/1_stdlib/POSIX.swift @@ -141,7 +141,7 @@ POSIXTests.test("fcntl block and unblocking sockets success") { expectEqual(0, rc) flags = fcntl(sock, cmd: F_GETFL) - expectGE(0, flags) + expectGE(flags | O_NONBLOCK, flags) // Change back to blocking... rc = fcntl(sock, cmd: F_SETFL, value: flags & ~O_NONBLOCK) From daa3682d3b957d2ef2ee0c1c8558d1cb202f08b7 Mon Sep 17 00:00:00 2001 From: Bill Abt Date: Tue, 8 Dec 2015 09:50:20 -0500 Subject: [PATCH 7/9] Enable the semaphore tests for Linux. SEM_FAILED on Linux is zero whereas on Apple OS's it's -1. Had logic reversed in new fcntl() expectXXXX() functions. --- stdlib/public/Glibc/Glibc.swift | 4 ++-- test/1_stdlib/POSIX.swift | 26 +++++++++++--------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/stdlib/public/Glibc/Glibc.swift b/stdlib/public/Glibc/Glibc.swift index 4158bd58cada5..6d33cd19ff1e2 100644 --- a/stdlib/public/Glibc/Glibc.swift +++ b/stdlib/public/Glibc/Glibc.swift @@ -147,8 +147,8 @@ public var SIG_HOLD: __sighandler_t { /// The value returned by `sem_open()` in the case of failure. public var SEM_FAILED: UnsafeMutablePointer { - // The value is ABI. Value verified to be correct for OS X, iOS, watchOS, tvOS and Linux. - return UnsafeMutablePointer(bitPattern: -1) + // The value is ABI. Value verified to be correct on Linux. + return UnsafeMutablePointer(bitPattern: 0) } @warn_unused_result diff --git a/test/1_stdlib/POSIX.swift b/test/1_stdlib/POSIX.swift index 6b0cd9533f0d0..9a33feb9e5c86 100644 --- a/test/1_stdlib/POSIX.swift +++ b/test/1_stdlib/POSIX.swift @@ -10,15 +10,11 @@ import StdlibUnittest var POSIXTests = TestSuite("POSIXTests") -#if !os(Linux) - let semaphoreName = "TestSem" -#endif +let semaphoreName = "TestSem" let fn = "test.txt" POSIXTests.setUp { - #if !os(Linux) - sem_unlink(semaphoreName) - #endif + sem_unlink(semaphoreName) unlink(strdup(fn)) } @@ -101,10 +97,10 @@ POSIXTests.test("fcntl F_GETFL/F_SETFL success with file") { // Create and open file. system("touch \(fn)") let fd = open(strdup(fn), 0) - expectGT(0, fd) + expectGT(Int(fd), 0) var flags = fcntl(fd, cmd: F_GETFL) - expectGE(0, flags) + expectGE(Int(flags), 0) // Change to APPEND mode... var rc = fcntl(fd, cmd: F_SETFL, value: O_APPEND) @@ -118,7 +114,7 @@ POSIXTests.test("fcntl F_GETFL/F_SETFL success with file") { expectEqual(0, rc) flags = fcntl(fd, cmd: F_GETFL) - expectGE(0, flags) + expectGE(Int(flags), 0) // Clean up... rc = close(fd) @@ -131,24 +127,24 @@ POSIXTests.test("fcntl F_GETFL/F_SETFL success with file") { POSIXTests.test("fcntl block and unblocking sockets success") { // Create socket, note: socket created by default in blocking mode... let sock = socket(PF_INET, 1, 0) - expectGT(0, sock) + expectGT(Int(sock), 0) var flags = fcntl(sock, cmd:F_GETFL) - expectGE(0, flags) + expectGE(Int(flags), 0) // Change mode of socket to non-blocking... var rc = fcntl(sock, cmd: F_SETFL, value: flags | O_NONBLOCK) expectEqual(0, rc) flags = fcntl(sock, cmd: F_GETFL) - expectGE(flags | O_NONBLOCK, flags) + expectEqual((flags | O_NONBLOCK), flags) // Change back to blocking... rc = fcntl(sock, cmd: F_SETFL, value: flags & ~O_NONBLOCK) expectEqual(0, rc) flags = fcntl(sock, cmd: F_GETFL) - expectGE(0, flags) + expectGE(Int(flags), 0) // Clean up... rc = close(sock) @@ -158,7 +154,7 @@ POSIXTests.test("fcntl block and unblocking sockets success") { POSIXTests.test("fcntl locking and unlocking success") { // Create the file and add data to it... var fd = open(strdup(fn), O_CREAT | O_WRONLY, 0o666) - expectGT(0, fd) + expectGT(Int(fd), 0) let data = "Testing 1 2 3" let bytesWritten = write(fd, data, data.characters.count) @@ -169,7 +165,7 @@ POSIXTests.test("fcntl locking and unlocking success") { // Re-open the file... fd = open(strdup(fn), 0) - expectGT(0, fd) + expectGT(Int(fd), 0) // Lock for reading... var flck = flock() From a623e583676de2c231262b515abb42713dba9168 Mon Sep 17 00:00:00 2001 From: Bill Abt Date: Wed, 9 Dec 2015 08:56:58 -0500 Subject: [PATCH 8/9] Updated the implementation and tests to make the parameter names optional to conform with other "C" library APIs. --- stdlib/public/Glibc/Glibc.swift | 17 ++++++++++++++--- stdlib/public/SDK/Darwin/Darwin.swift | 17 ++++++++++++++--- test/1_stdlib/POSIX.swift | 26 +++++++++++++------------- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/stdlib/public/Glibc/Glibc.swift b/stdlib/public/Glibc/Glibc.swift index 6d33cd19ff1e2..745f63a476cbf 100644 --- a/stdlib/public/Glibc/Glibc.swift +++ b/stdlib/public/Glibc/Glibc.swift @@ -80,17 +80,28 @@ internal func _swift_Glibc_fcntlPtr( ) ->CInt @warn_unused_result -public func fcntl(fd: CInt, cmd: CInt) ->CInt { +public func fcntl( + fd: CInt, + _ cmd: CInt + ) ->CInt { return _swift_Glibc_fcntl(fd, cmd, 0) } @warn_unused_result -public func fcntl(fd: CInt, cmd: CInt, value: CInt) ->CInt { +public func fcntl( + fd: CInt, + _ cmd: CInt, + _ value: CInt + ) ->CInt { return _swift_Glibc_fcntl(fd, cmd, value) } @warn_unused_result -public func fcntl(fd: CInt, cmd: CInt, ptr: UnsafeMutablePointer) ->CInt { +public func fcntl( + fd: CInt, + _ cmd: CInt, + _ ptr: UnsafeMutablePointer + ) ->CInt { return _swift_Glibc_fcntlPtr(fd, cmd, ptr) } diff --git a/stdlib/public/SDK/Darwin/Darwin.swift b/stdlib/public/SDK/Darwin/Darwin.swift index a3c4302e6f715..f7fe33900617c 100644 --- a/stdlib/public/SDK/Darwin/Darwin.swift +++ b/stdlib/public/SDK/Darwin/Darwin.swift @@ -194,17 +194,28 @@ internal func _swift_Darwin_fcntlPtr( ) ->CInt @warn_unused_result -public func fcntl(fd: CInt, cmd: CInt) ->CInt { +public func fcntl( + fd: CInt, + _ cmd: CInt + ) ->CInt { return _swift_Darwin_fcntl(fd, cmd, 0) } @warn_unused_result -public func fcntl(fd: CInt, cmd: CInt, value: CInt) ->CInt { +public func fcntl( + fd: CInt, + _ cmd: CInt, + _ value: CInt + ) ->CInt { return _swift_Darwin_fcntl(fd, cmd, value) } @warn_unused_result -public func fcntl(fd: CInt, cmd: CInt, ptr: UnsafeMutablePointer) ->CInt { +public func fcntl( + fd: CInt, + _ cmd: CInt, + _ ptr: UnsafeMutablePointer + ) ->CInt { return _swift_Darwin_fcntlPtr(fd, cmd, ptr) } diff --git a/test/1_stdlib/POSIX.swift b/test/1_stdlib/POSIX.swift index 9a33feb9e5c86..981c68b714e1c 100644 --- a/test/1_stdlib/POSIX.swift +++ b/test/1_stdlib/POSIX.swift @@ -88,7 +88,7 @@ POSIXTests.test("fcntl fail") { expectEqual(-1, fd) expectEqual(ENOENT, errno) - let _ = fcntl(fd, cmd: F_GETFL) + let _ = fcntl(fd, F_GETFL) expectEqual(EBADF, errno) } @@ -99,21 +99,21 @@ POSIXTests.test("fcntl F_GETFL/F_SETFL success with file") { let fd = open(strdup(fn), 0) expectGT(Int(fd), 0) - var flags = fcntl(fd, cmd: F_GETFL) + var flags = fcntl(fd, F_GETFL) expectGE(Int(flags), 0) // Change to APPEND mode... - var rc = fcntl(fd, cmd: F_SETFL, value: O_APPEND) + var rc = fcntl(fd, F_SETFL, O_APPEND) expectEqual(0, rc) - flags = fcntl(fd, cmd: F_GETFL) + flags = fcntl(fd, F_GETFL) expectEqual(flags | O_APPEND, flags) // Change back... - rc = fcntl(fd, cmd: F_SETFL, value: 0) + rc = fcntl(fd, F_SETFL, 0) expectEqual(0, rc) - flags = fcntl(fd, cmd: F_GETFL) + flags = fcntl(fd, F_GETFL) expectGE(Int(flags), 0) // Clean up... @@ -129,21 +129,21 @@ POSIXTests.test("fcntl block and unblocking sockets success") { let sock = socket(PF_INET, 1, 0) expectGT(Int(sock), 0) - var flags = fcntl(sock, cmd:F_GETFL) + var flags = fcntl(sock, F_GETFL) expectGE(Int(flags), 0) // Change mode of socket to non-blocking... - var rc = fcntl(sock, cmd: F_SETFL, value: flags | O_NONBLOCK) + var rc = fcntl(sock, F_SETFL, flags | O_NONBLOCK) expectEqual(0, rc) - flags = fcntl(sock, cmd: F_GETFL) + flags = fcntl(sock, F_GETFL) expectEqual((flags | O_NONBLOCK), flags) // Change back to blocking... - rc = fcntl(sock, cmd: F_SETFL, value: flags & ~O_NONBLOCK) + rc = fcntl(sock, F_SETFL, flags & ~O_NONBLOCK) expectEqual(0, rc) - flags = fcntl(sock, cmd: F_GETFL) + flags = fcntl(sock, F_GETFL) expectGE(Int(flags), 0) // Clean up... @@ -171,13 +171,13 @@ POSIXTests.test("fcntl locking and unlocking success") { var flck = flock() flck.l_type = Int16(F_RDLCK) flck.l_len = off_t(data.characters.count) - rc = fcntl(fd, cmd: F_SETLK, ptr: &flck) + rc = fcntl(fd, F_SETLK, &flck) expectEqual(0, rc) // Unlock for reading... flck = flock() flck.l_type = Int16(F_UNLCK) - rc = fcntl(fd, cmd: F_SETLK, ptr: &flck) + rc = fcntl(fd, F_SETLK, &flck) expectEqual(0, rc) // Clean up... From 3c9d0495b51173a7c90143ed27083b69742c9702 Mon Sep 17 00:00:00 2001 From: Bill Abt Date: Thu, 10 Dec 2015 14:23:46 -0500 Subject: [PATCH 9/9] Format and code changes due to recommendations from Dmitri. Removed the strdup() call that left over from earlier debugging. --- stdlib/public/Glibc/Glibc.swift | 10 ++++----- stdlib/public/SDK/Darwin/Darwin.swift | 10 ++++----- test/1_stdlib/POSIX.swift | 29 +++++++++++++-------------- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/stdlib/public/Glibc/Glibc.swift b/stdlib/public/Glibc/Glibc.swift index 745f63a476cbf..6a38eed6c529a 100644 --- a/stdlib/public/Glibc/Glibc.swift +++ b/stdlib/public/Glibc/Glibc.swift @@ -69,7 +69,7 @@ internal func _swift_Glibc_fcntl( fd: CInt, _ cmd: CInt, _ value: CInt - ) ->CInt + ) -> CInt @warn_unused_result @_silgen_name("_swift_Glibc_fcntlPtr") @@ -77,13 +77,13 @@ internal func _swift_Glibc_fcntlPtr( fd: CInt, _ cmd: CInt, _ ptr: UnsafeMutablePointer - ) ->CInt + ) -> CInt @warn_unused_result public func fcntl( fd: CInt, _ cmd: CInt - ) ->CInt { + ) -> CInt { return _swift_Glibc_fcntl(fd, cmd, 0) } @@ -92,7 +92,7 @@ public func fcntl( fd: CInt, _ cmd: CInt, _ value: CInt - ) ->CInt { + ) -> CInt { return _swift_Glibc_fcntl(fd, cmd, value) } @@ -101,7 +101,7 @@ public func fcntl( fd: CInt, _ cmd: CInt, _ ptr: UnsafeMutablePointer - ) ->CInt { + ) -> CInt { return _swift_Glibc_fcntlPtr(fd, cmd, ptr) } diff --git a/stdlib/public/SDK/Darwin/Darwin.swift b/stdlib/public/SDK/Darwin/Darwin.swift index f7fe33900617c..31cfe96ef243a 100644 --- a/stdlib/public/SDK/Darwin/Darwin.swift +++ b/stdlib/public/SDK/Darwin/Darwin.swift @@ -183,7 +183,7 @@ internal func _swift_Darwin_fcntl( fd: CInt, _ cmd: CInt, _ value: CInt - ) ->CInt + ) -> CInt @warn_unused_result @_silgen_name("_swift_Darwin_fcntlPtr") @@ -191,13 +191,13 @@ internal func _swift_Darwin_fcntlPtr( fd: CInt, _ cmd: CInt, _ ptr: UnsafeMutablePointer - ) ->CInt + ) -> CInt @warn_unused_result public func fcntl( fd: CInt, _ cmd: CInt - ) ->CInt { + ) -> CInt { return _swift_Darwin_fcntl(fd, cmd, 0) } @@ -206,7 +206,7 @@ public func fcntl( fd: CInt, _ cmd: CInt, _ value: CInt - ) ->CInt { + ) -> CInt { return _swift_Darwin_fcntl(fd, cmd, value) } @@ -215,7 +215,7 @@ public func fcntl( fd: CInt, _ cmd: CInt, _ ptr: UnsafeMutablePointer - ) ->CInt { + ) -> CInt { return _swift_Darwin_fcntlPtr(fd, cmd, ptr) } diff --git a/test/1_stdlib/POSIX.swift b/test/1_stdlib/POSIX.swift index 981c68b714e1c..e18efbc127828 100644 --- a/test/1_stdlib/POSIX.swift +++ b/test/1_stdlib/POSIX.swift @@ -15,7 +15,7 @@ let fn = "test.txt" POSIXTests.setUp { sem_unlink(semaphoreName) - unlink(strdup(fn)) + unlink(fn) } // Failed semaphore creation. @@ -83,8 +83,8 @@ POSIXTests.test("sem_open existing O_EXCL fail") { } // Fail because file doesn't exist. -POSIXTests.test("fcntl fail") { - let fd = open(strdup(fn), 0) +POSIXTests.test("fcntl(CInt, CInt): fail") { + let fd = open(fn, 0) expectEqual(-1, fd) expectEqual(ENOENT, errno) @@ -93,10 +93,9 @@ POSIXTests.test("fcntl fail") { } // Change modes on existing file. -POSIXTests.test("fcntl F_GETFL/F_SETFL success with file") { +POSIXTests.test("fcntl(CInt, CInt): F_GETFL/F_SETFL success with file") { // Create and open file. - system("touch \(fn)") - let fd = open(strdup(fn), 0) + let fd = open(fn, O_CREAT, 0o666) expectGT(Int(fd), 0) var flags = fcntl(fd, F_GETFL) @@ -120,11 +119,11 @@ POSIXTests.test("fcntl F_GETFL/F_SETFL success with file") { rc = close(fd) expectEqual(0, rc) - rc = unlink(strdup(fn)) + rc = unlink(fn) expectEqual(0, rc) } -POSIXTests.test("fcntl block and unblocking sockets success") { +POSIXTests.test("fcntl(CInt, CInt, CInt): block and unblocking sockets success") { // Create socket, note: socket created by default in blocking mode... let sock = socket(PF_INET, 1, 0) expectGT(Int(sock), 0) @@ -151,26 +150,26 @@ POSIXTests.test("fcntl block and unblocking sockets success") { expectEqual(0, rc) } -POSIXTests.test("fcntl locking and unlocking success") { +POSIXTests.test("fcntl(CInt, CInt, UnsafeMutablePointer): locking and unlocking success") { // Create the file and add data to it... - var fd = open(strdup(fn), O_CREAT | O_WRONLY, 0o666) + var fd = open(fn, O_CREAT | O_WRONLY, 0o666) expectGT(Int(fd), 0) let data = "Testing 1 2 3" - let bytesWritten = write(fd, data, data.characters.count) - expectEqual(data.characters.count, bytesWritten) + let bytesWritten = write(fd, data, data.utf8.count) + expectEqual(data.utf8.count, bytesWritten) var rc = close(fd) expectEqual(0, rc) // Re-open the file... - fd = open(strdup(fn), 0) + fd = open(fn, 0) expectGT(Int(fd), 0) // Lock for reading... var flck = flock() flck.l_type = Int16(F_RDLCK) - flck.l_len = off_t(data.characters.count) + flck.l_len = off_t(data.utf8.count) rc = fcntl(fd, F_SETLK, &flck) expectEqual(0, rc) @@ -184,7 +183,7 @@ POSIXTests.test("fcntl locking and unlocking success") { rc = close(fd) expectEqual(0, rc) - rc = unlink(strdup(fn)) + rc = unlink(fn) expectEqual(0, rc) }