HDFS-15843. Make write cross-platform (#2710)
This commit is contained in:
parent
73394fabc7
commit
47620f8821
@ -23,5 +23,6 @@ set(LIBHDFSPP_DIR CACHE STRING ${CMAKE_INSTALL_PREFIX})
|
|||||||
include_directories( ${LIBHDFSPP_DIR}/include )
|
include_directories( ${LIBHDFSPP_DIR}/include )
|
||||||
link_directories( ${LIBHDFSPP_DIR}/lib )
|
link_directories( ${LIBHDFSPP_DIR}/lib )
|
||||||
|
|
||||||
add_executable(connect_cancel_c connect_cancel.c)
|
add_executable(connect_cancel_c $<TARGET_OBJECTS:x_platform_utils_obj_c_api> connect_cancel.c)
|
||||||
target_link_libraries(connect_cancel_c hdfspp_static uriparser2)
|
target_link_libraries(connect_cancel_c hdfspp_static uriparser2)
|
||||||
|
target_include_directories(connect_cancel_c PRIVATE ../../lib)
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "hdfspp/hdfs_ext.h"
|
#include "hdfspp/hdfs_ext.h"
|
||||||
#include "common/util_c.h"
|
#include "common/util_c.h"
|
||||||
|
#include "x-platform/c_api.h"
|
||||||
|
|
||||||
#define ERROR_BUFFER_SIZE 1024
|
#define ERROR_BUFFER_SIZE 1024
|
||||||
|
|
||||||
@ -43,10 +43,10 @@ const char *catch_exit = "Exiting the signal handler.\n";
|
|||||||
// Print to stdout without calling malloc or otherwise indirectly modify userspace state.
|
// Print to stdout without calling malloc or otherwise indirectly modify userspace state.
|
||||||
// Write calls to stdout may still interleave with stuff coming from elsewhere.
|
// Write calls to stdout may still interleave with stuff coming from elsewhere.
|
||||||
static void sighandler_direct_stdout(const char *msg) {
|
static void sighandler_direct_stdout(const char *msg) {
|
||||||
if(!msg)
|
if(!msg) {
|
||||||
return;
|
return;
|
||||||
ssize_t res = write(1 /*posix stdout fd*/, msg, strlen(msg));
|
}
|
||||||
(void)res;
|
x_platform_syscall_write_to_stdout(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sig_catch(int val) {
|
static void sig_catch(int val) {
|
||||||
|
@ -23,5 +23,6 @@ set(LIBHDFSPP_DIR CACHE STRING ${CMAKE_INSTALL_PREFIX})
|
|||||||
include_directories( ${LIBHDFSPP_DIR}/include )
|
include_directories( ${LIBHDFSPP_DIR}/include )
|
||||||
link_directories( ${LIBHDFSPP_DIR}/lib )
|
link_directories( ${LIBHDFSPP_DIR}/lib )
|
||||||
|
|
||||||
add_executable(connect_cancel connect_cancel.cc)
|
add_executable(connect_cancel $<TARGET_OBJECTS:x_platform_utils_obj> connect_cancel.cc)
|
||||||
target_link_libraries(connect_cancel hdfspp_static)
|
target_link_libraries(connect_cancel hdfspp_static)
|
||||||
|
target_include_directories(connect_cancel PRIVATE ../../lib)
|
||||||
|
@ -25,11 +25,12 @@
|
|||||||
#include <google/protobuf/stubs/common.h>
|
#include <google/protobuf/stubs/common.h>
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "x-platform/syscall.h"
|
||||||
|
|
||||||
// Simple example of how to cancel an async connect call.
|
// Simple example of how to cancel an async connect call.
|
||||||
// Here Control-C (SIGINT) is caught in order to invoke the FS level cancel and
|
// Here Control-C (SIGINT) is caught in order to invoke the FS level cancel and
|
||||||
// properly tear down the process. Valgrind should show no leaked memory on exit
|
// properly tear down the process. Valgrind should show no leaked memory on exit
|
||||||
@ -47,11 +48,10 @@ const std::string catch_exit("Exiting the signal handler.\n");
|
|||||||
// It's possible that the write interleaves with another write call,
|
// It's possible that the write interleaves with another write call,
|
||||||
// but it won't corrupt the stack or heap.
|
// but it won't corrupt the stack or heap.
|
||||||
static void sighandler_direct_stdout(const std::string &msg) {
|
static void sighandler_direct_stdout(const std::string &msg) {
|
||||||
ssize_t res = ::write(1 /*posix stdout FD*/, msg.data(), msg.size());
|
XPlatform::Syscall::WriteToStdout(msg);
|
||||||
// In production you'd want to check res, but error handling code will
|
// In production you'd want to check the result of the above call,
|
||||||
// need to be fairly application specific if it's going to properly
|
// but error handling code will need to be fairly application
|
||||||
// avoid reentrant calls to malloc.
|
// specific if it's going to properly avoid reentrant calls to malloc.
|
||||||
(void)res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signal handler to make a SIGINT call cancel rather than exit().
|
// Signal handler to make a SIGINT call cancel rather than exit().
|
||||||
|
@ -16,4 +16,11 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
add_library(x_platform_utils_obj OBJECT utils.cc)
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
||||||
|
set(SYSCALL_SRC syscall_windows.cc)
|
||||||
|
else()
|
||||||
|
set(SYSCALL_SRC syscall_linux.cc)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(x_platform_utils_obj OBJECT ${SYSCALL_SRC} utils.cc)
|
||||||
|
add_library(x_platform_utils_obj_c_api OBJECT $<TARGET_OBJECTS:x_platform_utils_obj> c_api.cc)
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "syscall.h"
|
||||||
|
|
||||||
|
extern "C" int x_platform_syscall_write_to_stdout(const char* msg) {
|
||||||
|
return XPlatform::Syscall::WriteToStdout(msg) ? 1 : 0;
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NATIVE_LIBHDFSPP_LIB_CROSS_PLATFORM_C_API_H
|
||||||
|
#define NATIVE_LIBHDFSPP_LIB_CROSS_PLATFORM_C_API_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* C APIs for accessing XPlatform
|
||||||
|
*/
|
||||||
|
|
||||||
|
int x_platform_syscall_write_to_stdout(const char* msg);
|
||||||
|
|
||||||
|
#endif // NATIVE_LIBHDFSPP_LIB_CROSS_PLATFORM_C_API_H
|
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NATIVE_LIBHDFSPP_LIB_CROSS_PLATFORM_SYSCALL
|
||||||
|
#define NATIVE_LIBHDFSPP_LIB_CROSS_PLATFORM_SYSCALL
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link XPlatform} namespace contains components that
|
||||||
|
* aid in writing cross-platform code.
|
||||||
|
*/
|
||||||
|
namespace XPlatform {
|
||||||
|
class Syscall {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Writes the given string to the application's
|
||||||
|
* standard output stream.
|
||||||
|
*
|
||||||
|
* @param message The string to write to stdout.
|
||||||
|
* @returns A boolean indicating whether the write
|
||||||
|
* was successful.
|
||||||
|
*/
|
||||||
|
static bool WriteToStdout(const std::string& message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the given char pointer to the application's
|
||||||
|
* standard output stream.
|
||||||
|
*
|
||||||
|
* @param message The char pointer to write to stdout.
|
||||||
|
* @returns A boolean indicating whether the write
|
||||||
|
* was successful.
|
||||||
|
*/
|
||||||
|
static int WriteToStdout(const char* message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool WriteToStdoutImpl(const char* message);
|
||||||
|
};
|
||||||
|
} // namespace XPlatform
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "syscall.h"
|
||||||
|
|
||||||
|
bool XPlatform::Syscall::WriteToStdout(const std::string& message) {
|
||||||
|
return WriteToStdoutImpl(message.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
int XPlatform::Syscall::WriteToStdout(const char* message) {
|
||||||
|
return WriteToStdoutImpl(message) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XPlatform::Syscall::WriteToStdoutImpl(const char* message) {
|
||||||
|
const auto message_len = strlen(message);
|
||||||
|
const auto result = write(1, message, message_len);
|
||||||
|
return result == static_cast<ssize_t>(message_len);
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#include "syscall.h"
|
||||||
|
|
||||||
|
bool XPlatform::Syscall::WriteToStdout(const std::string& message) {
|
||||||
|
return WriteToStdoutImpl(message.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
int XPlatform::Syscall::WriteToStdout(const char* message) {
|
||||||
|
return WriteToStdoutImpl(message) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XPlatform::Syscall::WriteToStdoutImpl(const char* message) {
|
||||||
|
auto* const stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
if (stdout_handle == INVALID_HANDLE_VALUE || stdout_handle == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long bytes_written = 0;
|
||||||
|
const auto message_len = lstrlen(message);
|
||||||
|
const auto result =
|
||||||
|
WriteFile(stdout_handle, message, message_len, &bytes_written, nullptr);
|
||||||
|
return result && static_cast<unsigned long>(message_len) == bytes_written;
|
||||||
|
}
|
@ -16,7 +16,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "x-platform/utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
Loading…
Reference in New Issue
Block a user