<commit_before>/*
 * %CopyrightBegin%
 *
 * Copyright Ericsson AB 1996-2011. All Rights Reserved.
 *
 * The contents of this file are subject to the Erlang Public License,
 * Version 1.1, (the "License"); you may not use this file except in
 * compliance with the License. You should have received a copy of the
 * Erlang Public License along with this software. If not, it can be
 * retrieved online at http://www.erlang.org/.
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * %CopyrightEnd%
 */
/*
 * Purpose: Provides file and directory operations.
 *
 * This file is generic, and does the work of decoding the commands
 * and encoding the responses.  System-specific functions are found in
 * the unix_efile.c and win_efile.c files.
 */

/* Operations */

#define FILE_OPEN		 1 /* Essential for startup */
#define FILE_READ		 2
#define FILE_LSEEK		 3
#define FILE_WRITE		 4
#define FILE_FSTAT		 5 /* Essential for startup */
#define FILE_PWD                 6 /* Essential for startup */
#define FILE_READDIR             7 /* Essential for startup */
#define FILE_CHDIR               8
#define FILE_FSYNC               9
#define FILE_MKDIR              10
#define FILE_DELETE             11
#define FILE_RENAME             12
#define FILE_RMDIR              13
#define FILE_TRUNCATE           14
#define FILE_READ_FILE          15 /* Essential for startup */
#define FILE_WRITE_INFO		16
#define FILE_LSTAT            	19
#define FILE_READLINK        	20
#define FILE_LINK             	21
#define FILE_SYMLINK          	22
#define FILE_CLOSE		23
#define FILE_PWRITEV		24
#define FILE_PREADV		25
#define FILE_SETOPT		26
#define FILE_IPREAD             27
#define FILE_ALTNAME            28
#define FILE_READ_LINE          29
#define FILE_FDATASYNC          30
#define FILE_FADVISE            31
#define FILE_SENDFILE           32

/* Return codes */

#define FILE_RESP_OK         0
#define FILE_RESP_ERROR      1
#define FILE_RESP_DATA       2
#define FILE_RESP_NUMBER     3
#define FILE_RESP_INFO       4
#define FILE_RESP_NUMERR     5
#define FILE_RESP_LDATA      6
#define FILE_RESP_N2DATA     7
#define FILE_RESP_EOF        8
#define FILE_RESP_FNAME      9
#define FILE_RESP_ALL_DATA  10
#define FILE_RESP_LFNAME    11

/* Options */

#define FILE_OPT_DELAYED_WRITE 0
#define FILE_OPT_READ_AHEAD    1

/* IPREAD variants */

#define IPREAD_S32BU_P32BU 0

/* Limits */

#define FILE_SEGMENT_READ  (256*1024)
#define FILE_SEGMENT_WRITE (256*1024)

/* Internal */

/* Set to 1 to test having read_ahead implicitly for read_line */ 
#define ALWAYS_READ_LINE_AHEAD 0


/* Must not be possible to get from malloc()! */
#define FILE_FD_INVALID ((Sint)(-1))

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif
#include <stdlib.h>

// Need (NON)BLOCKING macros for sendfile
#ifndef WANT_NONBLOCKING
#define WANT_NONBLOCKING
#endif

#include "sys.h"

#include "erl_driver.h"
#include "erl_efile.h"
#include "erl_threads.h"
#include "zlib.h"
#include "gzio.h"
#include <ctype.h>
#include <sys/types.h>

void erl_exit(int n, char *fmt, ...);

static ErlDrvSysInfo sys_info;


/* #define TRACE 1 */
#ifdef TRACE
#    define TRACE_C(c) do { putchar(c); fflush(stdout); } while (0)
#    define TRACE_S(s) do { fputs((s), stdout); fflush(stdout); } while (0)
#    define TRACE_F(args) do { printf args ;fflush(stdout); } while (0)
#else
#    define TRACE_C(c) ((void)(0))
#    define TRACE_S(s) ((void)(0))
#    define TRACE_F(args) ((void)(0))
#endif


#ifdef USE_THREADS
#define IF_THRDS if (sys_info.async_threads > 0)
#ifdef HARDDEBUG /* HARDDEBUG in io.c is expected too */
#define TRACE_DRIVER fprintf(stderr, "Efile: ")
#else
#define TRACE_DRIVER
#endif
#define MUTEX_INIT(m, p) do { IF_THRDS { TRACE_DRIVER; (m = driver_pdl_create(p)); } } while (0)
#define MUTEX_LOCK(m)    do { IF_THRDS { TRACE_DRIVER; driver_pdl_lock(m);   } } while (0)
#define MUTEX_UNLOCK(m)  do { IF_THRDS { TRACE_DRIVER; driver_pdl_unlock(m); } } while (0)
#else
#define MUTEX_INIT(m, p)
#define MUTEX_LOCK(m)
#define MUTEX_UNLOCK(m)
#endif


/**
 * On DARWIN sendfile can deadlock with close if called in
 * different threads. So until Apple fixes so that sendfile
 * is not buggy we disable usage of the async pool for
 * DARWIN. The testcase t_sendfile_crashduring reproduces
 * this error when using +A 10.
 */
#if !defined(DARWIN)
#define USE_THRDS_FOR_SENDFILE (sys_info.async_threads > 0)
#else
#define USE_THRDS_FOR_SENDFILE 0
#endif /* !DARWIN */



#if 0<commit_msg>Fix ifdef to check if we are on OS X<commit_after>/*
 * %CopyrightBegin%
 *
 * Copyright Ericsson AB 1996-2011. All Rights Reserved.
 *
 * The contents of this file are subject to the Erlang Public License,
 * Version 1.1, (the "License"); you may not use this file except in
 * compliance with the License. You should have received a copy of the
 * Erlang Public License along with this software. If not, it can be
 * retrieved online at http://www.erlang.org/.
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * %CopyrightEnd%
 */
/*
 * Purpose: Provides file and directory operations.
 *
 * This file is generic, and does the work of decoding the commands
 * and encoding the responses.  System-specific functions are found in
 * the unix_efile.c and win_efile.c files.
 */

/* Operations */

#define FILE_OPEN		 1 /* Essential for startup */
#define FILE_READ		 2
#define FILE_LSEEK		 3
#define FILE_WRITE		 4
#define FILE_FSTAT		 5 /* Essential for startup */
#define FILE_PWD                 6 /* Essential for startup */
#define FILE_READDIR             7 /* Essential for startup */
#define FILE_CHDIR               8
#define FILE_FSYNC               9
#define FILE_MKDIR              10
#define FILE_DELETE             11
#define FILE_RENAME             12
#define FILE_RMDIR              13
#define FILE_TRUNCATE           14
#define FILE_READ_FILE          15 /* Essential for startup */
#define FILE_WRITE_INFO		16
#define FILE_LSTAT            	19
#define FILE_READLINK        	20
#define FILE_LINK             	21
#define FILE_SYMLINK          	22
#define FILE_CLOSE		23
#define FILE_PWRITEV		24
#define FILE_PREADV		25
#define FILE_SETOPT		26
#define FILE_IPREAD             27
#define FILE_ALTNAME            28
#define FILE_READ_LINE          29
#define FILE_FDATASYNC          30
#define FILE_FADVISE            31
#define FILE_SENDFILE           32

/* Return codes */

#define FILE_RESP_OK         0
#define FILE_RESP_ERROR      1
#define FILE_RESP_DATA       2
#define FILE_RESP_NUMBER     3
#define FILE_RESP_INFO       4
#define FILE_RESP_NUMERR     5
#define FILE_RESP_LDATA      6
#define FILE_RESP_N2DATA     7
#define FILE_RESP_EOF        8
#define FILE_RESP_FNAME      9
#define FILE_RESP_ALL_DATA  10
#define FILE_RESP_LFNAME    11

/* Options */

#define FILE_OPT_DELAYED_WRITE 0
#define FILE_OPT_READ_AHEAD    1

/* IPREAD variants */

#define IPREAD_S32BU_P32BU 0

/* Limits */

#define FILE_SEGMENT_READ  (256*1024)
#define FILE_SEGMENT_WRITE (256*1024)

/* Internal */

/* Set to 1 to test having read_ahead implicitly for read_line */ 
#define ALWAYS_READ_LINE_AHEAD 0


/* Must not be possible to get from malloc()! */
#define FILE_FD_INVALID ((Sint)(-1))

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif
#include <stdlib.h>

// Need (NON)BLOCKING macros for sendfile
#ifndef WANT_NONBLOCKING
#define WANT_NONBLOCKING
#endif

#include "sys.h"

#include "erl_driver.h"
#include "erl_efile.h"
#include "erl_threads.h"
#include "zlib.h"
#include "gzio.h"
#include <ctype.h>
#include <sys/types.h>

void erl_exit(int n, char *fmt, ...);

static ErlDrvSysInfo sys_info;


/* #define TRACE 1 */
#ifdef TRACE
#    define TRACE_C(c) do { putchar(c); fflush(stdout); } while (0)
#    define TRACE_S(s) do { fputs((s), stdout); fflush(stdout); } while (0)
#    define TRACE_F(args) do { printf args ;fflush(stdout); } while (0)
#else
#    define TRACE_C(c) ((void)(0))
#    define TRACE_S(s) ((void)(0))
#    define TRACE_F(args) ((void)(0))
#endif


#ifdef USE_THREADS
#define IF_THRDS if (sys_info.async_threads > 0)
#ifdef HARDDEBUG /* HARDDEBUG in io.c is expected too */
#define TRACE_DRIVER fprintf(stderr, "Efile: ")
#else
#define TRACE_DRIVER
#endif
#define MUTEX_INIT(m, p) do { IF_THRDS { TRACE_DRIVER; (m = driver_pdl_create(p)); } } while (0)
#define MUTEX_LOCK(m)    do { IF_THRDS { TRACE_DRIVER; driver_pdl_lock(m);   } } while (0)
#define MUTEX_UNLOCK(m)  do { IF_THRDS { TRACE_DRIVER; driver_pdl_unlock(m); } } while (0)
#else
#define MUTEX_INIT(m, p)
#define MUTEX_LOCK(m)
#define MUTEX_UNLOCK(m)
#endif


/**
 * On DARWIN sendfile can deadlock with close if called in
 * different threads. So until Apple fixes so that sendfile
 * is not buggy we disable usage of the async pool for
 * DARWIN. The testcase t_sendfile_crashduring reproduces
 * this error when using +A 10.
 */
#if defined(__APPLE__) && defined(__MACH__)
#define USE_THRDS_FOR_SENDFILE 0
#else
#define USE_THRDS_FOR_SENDFILE (sys_info.async_threads > 0)
#endif /* defined(__APPLE__) && defined(__MACH__) */



#if 0
{'fraction_non_alphanumeric': 0.09308283518360376, 'fraction_numerical': 0.024765157984628524, 'mean_word_length': 3.3254847645429364, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5437441', 'n_tokens_mistral': 3388, 'n_tokens_neox': 3199, 'n_words': 1030}